From 1ffb8e3cc21603b29ccd78152f82cca7f61a09b1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 May 2011 02:11:56 -0400 Subject: - Added API docs for ``pyramid.httpexceptions.abort`` and ``pyramid.httpexceptions.redirect``. - Added "HTTP Exceptions" section to Views narrative chapter including a description of ``pyramid.httpexceptions.abort``; adjusted redirect section to note ``pyramid.httpexceptions.redirect``. - A default exception view for the context ``webob.exc.HTTPException`` (aka ``pyramid.httpexceptions.HTTPException``) is now registered by default. This means that an instance of any exception class imported from ``pyramid.httpexceptions`` (such as ``HTTPFound``) can now be raised from within view code; when raised, this exception view will render the exception to a response. - New functions named ``pyramid.httpexceptions.abort`` and ``pyramid.httpexceptions.redirect`` perform the equivalent of their Pylons brethren when an HTTP exception handler is registered. These functions take advantage of the newly registered exception view for ``webob.exc.HTTPException``. - The Configurator now accepts an additional keyword argument named ``httpexception_view``. By default, this argument is populated with a default exception view function that will be used when an HTTP exception is raised. When ``None`` is passed for this value, an exception view for HTTP exceptions will not be registered. Passing ``None`` returns the behavior of raising an HTTP exception to that of Pyramid 1.0 (the exception will propagate to middleware and to the WSGI server). --- docs/narr/views.rst | 249 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 179 insertions(+), 70 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 5c9bd91af..465cd3c0d 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -51,14 +51,14 @@ the request object contains everything your application needs to know about the specific HTTP request being made. A view callable's ultimate responsibility is to create a :mod:`Pyramid` -:term:`Response` object. This can be done by creating the response -object in the view callable code and returning it directly, as we will -be doing in this chapter. However, if a view callable does not return a -response itself, it can be configured to use a :term:`renderer` that -converts its return value into a :term:`Response` object. Using -renderers is the common way that templates are used with view callables -to generate markup. See the :ref:`renderers_chapter` chapter for -details. +:term:`Response` object. This can be done by creating the response object in +the view callable code and returning it directly, as we will be doing in this +chapter. However, if a view callable does not return a response itself, it +can be configured to use a :term:`renderer` that converts its return value +into a :term:`Response` object. Using renderers is the common way that +templates are used with view callables to generate markup: see the +:ref:`renderers_chapter` chapter for details. In some cases, a response may +also be generated by raising an exception within a view callable. .. index:: single: view calling convention @@ -234,8 +234,8 @@ You don't need to always use :class:`~pyramid.response.Response` to represent a response. :app:`Pyramid` provides a range of different "exception" classes which can act as response objects too. For example, an instance of the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response object -(see :ref:`http_redirect`). A view can actually return any object that has -the following attributes. +(see :ref:`http_exceptions` and ref:`http_redirect`). A view can actually +return any object that has the following attributes. status The HTTP status code (including the name) for the response as a string. @@ -254,46 +254,6 @@ app_iter These attributes form the structure of the "Pyramid Response interface". -.. index:: - single: view http redirect - single: http redirect (from a view) - -.. _http_redirect: - -Using a View Callable to Do an HTTP Redirect --------------------------------------------- - -You can issue an HTTP redirect from within a view by returning a particular -kind of response. - -.. code-block:: python - :linenos: - - from pyramid.httpexceptions import HTTPFound - - def myview(request): - return HTTPFound(location='http://example.com') - -All exception types from the :mod:`pyramid.httpexceptions` module implement -the :term:`Response` interface; any can be returned as the response from a -view. See :mod:`pyramid.httpexceptions` for the documentation for the -``HTTPFound`` exception; it also includes other response types that imply -other HTTP response codes, such as ``HTTPUnauthorized`` for ``401 -Unauthorized``. - -.. note:: - - Although exception types from the :mod:`pyramid.httpexceptions` module are - in fact bona fide Python :class:`Exception` types, the :app:`Pyramid` view - machinery expects them to be *returned* by a view callable rather than - *raised*. - - It is possible, however, in Python 2.5 and above, to configure an - *exception view* to catch these exceptions, and return an appropriate - :class:`~pyramid.response.Response`. The simplest such view could just - catch and return the original exception. See :ref:`exception_views` for - more details. - .. index:: single: view exceptions @@ -304,13 +264,21 @@ Using Special Exceptions In View Callables Usually when a Python exception is raised within a view callable, :app:`Pyramid` allows the exception to propagate all the way out to the -:term:`WSGI` server which invoked the application. +:term:`WSGI` server which invoked the application. It is usually caught and +logged there. -However, for convenience, two special exceptions exist which are always -handled by :app:`Pyramid` itself. These are -:exc:`pyramid.exceptions.NotFound` and :exc:`pyramid.exceptions.Forbidden`. -Both are exception classes which accept a single positional constructor -argument: a ``message``. +However, for convenience, a special set of exceptions exists. When one of +these exceptions is raised within a view callable, it will always cause +:app:`Pyramid` to generate a response. Two categories of special exceptions +exist: internal exceptions and HTTP exceptions. + +Internal Exceptions +~~~~~~~~~~~~~~~~~~~ + +:exc:`pyramid.exceptions.NotFound` and :exc:`pyramid.exceptions.Forbidden` +are exceptions often raised by Pyramid itself when it (respectively) cannot +find a view to service a request or when authorization was forbidden by a +security policy. However, they can also be raised by application developers. If :exc:`~pyramid.exceptions.NotFound` is raised within view code, the result of the :term:`Not Found View` will be returned to the user agent which @@ -320,22 +288,100 @@ If :exc:`~pyramid.exceptions.Forbidden` is raised within view code, the result of the :term:`Forbidden View` will be returned to the user agent which performed the request. -In all cases, the message provided to the exception constructor is made -available to the view which :app:`Pyramid` invokes as +Both are exception classes which accept a single positional constructor +argument: a ``message``. In all cases, the message provided to the exception +constructor is made available to the view which :app:`Pyramid` invokes as ``request.exception.args[0]``. +An example: + +.. code-block:: python + :linenos: + + from pyramid.exceptions import NotFound + + def aview(request): + raise NotFound('not found!') + +Internal exceptions may not be *returned* in order to generate a response, +they must always be *raised*. + +.. index:: + single: HTTP exceptions + +.. _http_exceptions: + +HTTP Exceptions +~~~~~~~~~~~~~~~ + +All exception classes documented in the :mod:`pyramid.httpexceptions` module +implement the :term:`Response` interface; an instance of any of these classes +can be returned or raised from within a view. The instance will be used as +as the view's response. + +For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception +can be raised. This will cause a response to be generated with a ``401 +Unauthorized`` status: + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPUnauthorized + + def aview(request): + raise HTTPUnauthorized() + +A shortcut for importing and raising an HTTP exception is the +:func:`pyramid.httpexceptions.abort` function. This function accepts an HTTP +status code and raises the corresponding HTTP exception. For example, to +raise HTTPUnauthorized, instead of the above, you could do: + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import abort + + def aview(request): + abort(401) + +This is the case because ``401`` is the HTTP status code for "HTTP +Unauthorized". Therefore, ``abort(401)`` is functionally equivalent to +``raise HTTPUnauthorized()``. Other exceptions in +:mod:`pyramid.httpexceptions` can be raised via +:func:`pyramid.httpexceptions.abort` as well, as long as the status code +associated with the exception is provided to the function. + +An HTTP exception, instead of being raised, can alternately be *returned* +(HTTP exceptions are also valid response objects): + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPUnauthorized + + def aview(request): + return HTTPUnauthorized() + +Note that :class:`pyramid.exceptions.NotFound` is *not* the same as +:class:`pyramid.httpexceptions.HTTPNotFound`. If the latter is raised, the +:term:`Not Found view` will *not* be called automatically. Likewise, +:class:`pyramid.exceptions.Foribdden` is not the same exception as +:class:`pyramid.httpexceptions.HTTPForbidden`. If the latter is raised, the +:term:`Forbidden view` will not be called automatically. + .. index:: single: exception views .. _exception_views: -Exception Views ---------------- +Custom Exception Views +---------------------- -The machinery which allows the special :exc:`~pyramid.exceptions.NotFound` and -:exc:`~pyramid.exceptions.Forbidden` exceptions to be caught by specialized -views as described in :ref:`special_exceptions_in_callables` can also be used -by application developers to convert arbitrary exceptions to responses. +The machinery which allows :exc:`~pyramid.exceptions.NotFound`, +:exc:`~pyramid.exceptions.Forbidden` and HTTP exceptions to be caught by +specialized views as described in :ref:`special_exceptions_in_callables` can +also be used by application developers to convert arbitrary exceptions to +responses. To register a view that should be called whenever a particular exception is raised from with :app:`Pyramid` view code, use the exception class or one of @@ -359,6 +405,7 @@ raises a ``helloworld.exceptions.ValidationFailure`` exception: .. code-block:: python :linenos: + from pyramid.view import view_config from helloworld.exceptions import ValidationFailure @view_config(context=ValidationFailure) @@ -380,12 +427,13 @@ exception view registration: :linenos: from pyramid.view import view_config - from pyramid.exceptions import NotFound - from pyramid.httpexceptions import HTTPNotFound + from helloworld.exceptions import ValidationFailure - @view_config(context=NotFound, route_name='home') - def notfound_view(request): - return HTTPNotFound() + @view_config(context=ValidationFailure, route_name='home') + def failed_validation(exc, request): + response = Response('Failed validation: %s' % exc.msg) + response.status_int = 500 + return response The above exception view names the ``route_name`` of ``home``, meaning that it will only be called when the route matched has a name of ``home``. You @@ -407,7 +455,68 @@ exception views which have a name will be ignored. can use an exception as ``context`` for a normal view. Exception views can be configured with any view registration mechanism: -``@view_config`` decorator, ZCML, or imperative ``add_view`` styles. +``@view_config`` decorator or imperative ``add_view`` styles. + +.. index:: + single: view http redirect + single: http redirect (from a view) + +.. _http_redirect: + +Using a View Callable to Do an HTTP Redirect +-------------------------------------------- + +Two methods exist to redirect to another URL from within a view callable: a +short form and a long form. The short form should be preferred when +possible. + +Short Form +~~~~~~~~~~ + +You can issue an HTTP redirect from within a view callable by using the +:func:`pyramid.httpexceptions.redirect` function. This function raises an +:class:`pyramid.httpexceptions.HTTPFound` exception (a "302"), which is +caught by an exception handler and turned into a response. + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import redirect + + def myview(request): + redirect('http://example.com') + +Long Form +~~~~~~~~~ + +You can issue an HTTP redirect from within a view "by hand" instead of +relying on the :func:`pyramid.httpexceptions.redirect` function to do it for +you. + +To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` +instance. + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPFound + + def myview(request): + return HTTPFound(location='http://example.com') + +Or, alternately, you can *raise* an HTTPFound exception instead of returning +one. + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPFound + + def myview(request): + raise HTTPFound(location='http://example.com') + +The above form of generating a response by raising HTTPFound is completely +equivalent to ``redirect('http://example.com')``. .. index:: single: unicode, views, and forms -- cgit v1.2.3 From e1e0df9ff85d5d31b355527549e0b5654cce3af9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 May 2011 02:19:37 -0400 Subject: typo --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 465cd3c0d..66e9919e2 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -365,7 +365,7 @@ An HTTP exception, instead of being raised, can alternately be *returned* Note that :class:`pyramid.exceptions.NotFound` is *not* the same as :class:`pyramid.httpexceptions.HTTPNotFound`. If the latter is raised, the :term:`Not Found view` will *not* be called automatically. Likewise, -:class:`pyramid.exceptions.Foribdden` is not the same exception as +:class:`pyramid.exceptions.Forbidden` is not the same exception as :class:`pyramid.httpexceptions.HTTPForbidden`. If the latter is raised, the :term:`Forbidden view` will not be called automatically. -- cgit v1.2.3 From a7e625785f65c41e5a6dc017b31bd0d74821474e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 31 May 2011 14:40:05 -0400 Subject: the canonical import location for HTTP exceptions/responses is now pyramid.response --- docs/narr/hooks.rst | 48 +++++++++++++-------------- docs/narr/renderers.rst | 31 ++++++++++++------ docs/narr/router.rst | 53 +++++++++++++++--------------- docs/narr/testing.rst | 13 ++++---- docs/narr/urldispatch.rst | 6 ++-- docs/narr/views.rst | 82 +++++++++++++++++++++-------------------------- docs/narr/webob.rst | 36 ++++----------------- 7 files changed, 124 insertions(+), 145 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 7e3fe0a5c..d620b5672 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -21,7 +21,7 @@ configuration. The :term:`not found view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "not found" view consists -only of naming the :exc:`pyramid.exceptions.NotFound` class as the +only of naming the :exc:`pyramid.response.HTTPNotFound` class as the ``context`` of the view configuration. If your application uses :term:`imperative configuration`, you can replace @@ -31,9 +31,9 @@ method to register an "exception view": .. code-block:: python :linenos: - from pyramid.exceptions import NotFound + from pyramid.response import HTTPNotFound from helloworld.views import notfound_view - config.add_view(notfound_view, context=NotFound) + config.add_view(notfound_view, context=HTTPNotFound) Replace ``helloworld.views.notfound_view`` with a reference to the :term:`view callable` you want to use to represent the Not Found view. @@ -42,7 +42,7 @@ Like any other view, the notfound view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``request`` is the current :term:`request` representing the denied action. The ``context`` (if used in the call signature) will be the instance of the -:exc:`~pyramid.exceptions.NotFound` exception that caused the view to be +:exc:`~pyramid.response.HTTPNotFound` exception that caused the view to be called. Here's some sample code that implements a minimal NotFound view callable: @@ -50,25 +50,25 @@ Here's some sample code that implements a minimal NotFound view callable: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPNotFound + from pyramid.response import HTTPNotFound def notfound_view(request): return HTTPNotFound() .. note:: When a NotFound view callable is invoked, it is passed a - :term:`request`. The ``exception`` attribute of the request will - be an instance of the :exc:`~pyramid.exceptions.NotFound` - exception that caused the not found view to be called. The value - of ``request.exception.args[0]`` will be a value explaining why the - not found error was raised. This message will be different when - the ``debug_notfound`` environment setting is true than it is when - it is false. + :term:`request`. The ``exception`` attribute of the request will be an + instance of the :exc:`~pyramid.response.HTTPNotFound` exception that + caused the not found view to be called. The value of + ``request.exception.args[0]`` will be a value explaining why the not found + error was raised. This message will be different when the + ``debug_notfound`` environment setting is true than it is when it is + false. .. warning:: When a NotFound view callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` passed as the first argument to the view callable will be the - :exc:`~pyramid.exceptions.NotFound` exception instance. If available, the - resource context will still be available as ``request.context``. + :exc:`~pyramid.response.HTTPNotFound` exception instance. If available, + the resource context will still be available as ``request.context``. .. index:: single: forbidden view @@ -85,7 +85,7 @@ the view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "not found" view consists -only of naming the :exc:`pyramid.exceptions.Forbidden` class as the +only of naming the :exc:`pyramid.response.HTTPForbidden` class as the ``context`` of the view configuration. You can replace the forbidden view by using the @@ -96,8 +96,8 @@ view": :linenos: from helloworld.views import forbidden_view - from pyramid.exceptions import Forbidden - config.add_view(forbidden_view, context=Forbidden) + from pyramid.response import HTTPForbidden + config.add_view(forbidden_view, context=HTTPForbidden) Replace ``helloworld.views.forbidden_view`` with a reference to the Python :term:`view callable` you want to use to represent the Forbidden view. @@ -121,13 +121,13 @@ Here's some sample code that implements a minimal forbidden view: return Response('forbidden') .. note:: When a forbidden view callable is invoked, it is passed a - :term:`request`. The ``exception`` attribute of the request will - be an instance of the :exc:`~pyramid.exceptions.Forbidden` - exception that caused the forbidden view to be called. The value - of ``request.exception.args[0]`` will be a value explaining why the - forbidden was raised. This message will be different when the - ``debug_authorization`` environment setting is true than it is when - it is false. + :term:`request`. The ``exception`` attribute of the request will be an + instance of the :exc:`~pyramid.response.HTTPForbidden` exception that + caused the forbidden view to be called. The value of + ``request.exception.args[0]`` will be a value explaining why the forbidden + was raised. This message will be different when the + ``debug_authorization`` environment setting is true than it is when it is + false. .. index:: single: request factory diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index c3533648b..c7a3d7837 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -73,30 +73,43 @@ When this configuration is added to an application, the which renders view return values to a :term:`JSON` response serialization. Other built-in renderers include renderers which use the :term:`Chameleon` -templating language to render a dictionary to a response. +templating language to render a dictionary to a response. Additional +renderers can be added by developers to the system as necessary (see +:ref:`adding_and_overriding_renderers`). + +Views which use a renderer can vary non-body response attributes (such as +headers and the HTTP status code) by attaching a property to the +``request.response`` attribute See :ref:`request_response_attr`. If the :term:`view callable` associated with a :term:`view configuration` returns a Response object directly (an object with the attributes ``status``, ``headerlist`` and ``app_iter``), any renderer associated with the view configuration is ignored, and the response is passed back to :app:`Pyramid` unchanged. For example, if your view callable returns an instance of the -:class:`pyramid.httpexceptions.HTTPFound` class as a response, no renderer -will be employed. +:class:`pyramid.response.HTTPFound` class as a response, no renderer will be +employed. .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPFound + from pyramid.response import HTTPFound def view(request): return HTTPFound(location='http://example.com') # any renderer avoided -Views which use a renderer can vary non-body response attributes (such as -headers and the HTTP status code) by attaching a property to the -``request.response`` attribute See :ref:`request_response_attr`. +Likewise for a "plain old response": + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def view(request): + return Response('OK') # any renderer avoided -Additional renderers can be added by developers to the system as necessary -(see :ref:`adding_and_overriding_renderers`). +Mutations to ``request.response`` in views which return a Response object +like this directly (unless that response *is* ``request.response``) will be +ignored. .. index:: single: renderers (built-in) diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 11f84d4ea..44fa9835b 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -77,40 +77,37 @@ processing? #. A :class:`~pyramid.events.ContextFound` :term:`event` is sent to any subscribers. -#. :app:`Pyramid` looks up a :term:`view` callable using the - context, the request, and the view name. If a view callable - doesn't exist for this combination of objects (based on the type of - the context, the type of the request, and the value of the view - name, and any :term:`predicate` attributes applied to the view - configuration), :app:`Pyramid` raises a - :class:`~pyramid.exceptions.NotFound` exception, which is meant - to be caught by a surrounding exception handler. +#. :app:`Pyramid` looks up a :term:`view` callable using the context, the + request, and the view name. If a view callable doesn't exist for this + combination of objects (based on the type of the context, the type of the + request, and the value of the view name, and any :term:`predicate` + attributes applied to the view configuration), :app:`Pyramid` raises a + :class:`~pyramid.response.HTTPNotFound` exception, which is meant to be + caught by a surrounding exception handler. #. If a view callable was found, :app:`Pyramid` attempts to call the view function. -#. If an :term:`authorization policy` is in use, and the view was - protected by a :term:`permission`, :app:`Pyramid` passes the - context, the request, and the view_name to a function which - determines whether the view being asked for can be executed by the - requesting user, based on credential information in the request and - security information attached to the context. If it returns - ``True``, :app:`Pyramid` calls the view callable to obtain a - response. If it returns ``False``, it raises a - :class:`~pyramid.exceptions.Forbidden` exception, which is meant - to be called by a surrounding exception handler. +#. If an :term:`authorization policy` is in use, and the view was protected + by a :term:`permission`, :app:`Pyramid` passes the context, the request, + and the view_name to a function which determines whether the view being + asked for can be executed by the requesting user, based on credential + information in the request and security information attached to the + context. If it returns ``True``, :app:`Pyramid` calls the view callable + to obtain a response. If it returns ``False``, it raises a + :class:`~pyramid.response.HTTPForbidden` exception, which is meant to be + called by a surrounding exception handler. #. If any exception was raised within a :term:`root factory`, by - :term:`traversal`, by a :term:`view callable` or by - :app:`Pyramid` itself (such as when it raises - :class:`~pyramid.exceptions.NotFound` or - :class:`~pyramid.exceptions.Forbidden`), the router catches the - exception, and attaches it to the request as the ``exception`` - attribute. It then attempts to find a :term:`exception view` for - the exception that was caught. If it finds an exception view - callable, that callable is called, and is presumed to generate a - response. If an :term:`exception view` that matches the exception - cannot be found, the exception is reraised. + :term:`traversal`, by a :term:`view callable` or by :app:`Pyramid` itself + (such as when it raises :class:`~pyramid.response.HTTPNotFound` or + :class:`~pyramid.response.HTTPForbidden`), the router catches the + exception, and attaches it to the request as the ``exception`` attribute. + It then attempts to find a :term:`exception view` for the exception that + was caught. If it finds an exception view callable, that callable is + called, and is presumed to generate a response. If an :term:`exception + view` that matches the exception cannot be found, the exception is + reraised. #. The following steps occur only when a :term:`response` could be successfully generated by a normal :term:`view callable` or an diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index bd45388c2..862eda9f0 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -191,11 +191,11 @@ function. :linenos: from pyramid.security import has_permission - from pyramid.exceptions import Forbidden + from pyramid.response import HTTPForbidden def view_fn(request): if not has_permission('edit', request.context, request): - raise Forbidden + raise HTTPForbidden return {'greeting':'hello'} Without doing anything special during a unit test, the call to @@ -207,7 +207,7 @@ application registry is not created and populated (e.g. by initializing the configurator with an authorization policy), like when you invoke application code via a unit test, :app:`Pyramid` API functions will tend to either fail or return default results. So how do you test the branch of the code in this -view function that raises :exc:`Forbidden`? +view function that raises :exc:`HTTPForbidden`? The testing API provided by :app:`Pyramid` allows you to simulate various application registry registrations for use under a unit testing framework @@ -230,16 +230,15 @@ without needing to invoke the actual application configuration implied by its testing.tearDown() def test_view_fn_forbidden(self): - from pyramid.exceptions import Forbidden + from pyramid.response import HTTPForbidden from my.package import view_fn self.config.testing_securitypolicy(userid='hank', permissive=False) request = testing.DummyRequest() request.context = testing.DummyResource() - self.assertRaises(Forbidden, view_fn, request) + self.assertRaises(HTTPForbidden, view_fn, request) def test_view_fn_allowed(self): - from pyramid.exceptions import Forbidden from my.package import view_fn self.config.testing_securitypolicy(userid='hank', permissive=True) @@ -265,7 +264,7 @@ We call the function being tested with the manufactured request. When the function is called, :func:`pyramid.security.has_permission` will call the "dummy" authentication policy we've registered through :meth:`~pyramid.config.Configuration.testing_securitypolicy`, which denies -access. We check that the view function raises a :exc:`Forbidden` error. +access. We check that the view function raises a :exc:`HTTPForbidden` error. The second test method, named ``test_view_fn_allowed`` tests the alternate case, where the authentication policy allows access. Notice that we pass diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 5df1eb3af..e5228b81e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -917,7 +917,7 @@ the application's startup configuration, adding the following stanza: :linenos: config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.exceptions.NotFound') + context='pyramid.response.HTTPNotFound') See :ref:`view_module` and :ref:`changing_the_notfound_view` for more information about the slash-appending not found view and for a more general @@ -945,14 +945,14 @@ view as the first argument to its constructor. For instance: .. code-block:: python :linenos: - from pyramid.exceptions import NotFound + from pyramid.response import HTTPNotFound from pyramid.view import AppendSlashNotFoundViewFactory def notfound_view(context, request): return HTTPNotFound('It aint there, stop trying!') custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) - config.add_view(custom_append_slash, context=NotFound) + config.add_view(custom_append_slash, context=HTTPNotFound) The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 66e9919e2..73a7c2e2a 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -233,7 +233,7 @@ implements the :term:`Response` interface is to return a You don't need to always use :class:`~pyramid.response.Response` to represent a response. :app:`Pyramid` provides a range of different "exception" classes which can act as response objects too. For example, an instance of the class -:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object +:class:`pyramid.response.HTTPFound` is also a valid response object (see :ref:`http_exceptions` and ref:`http_redirect`). A view can actually return any object that has the following attributes. @@ -275,17 +275,18 @@ exist: internal exceptions and HTTP exceptions. Internal Exceptions ~~~~~~~~~~~~~~~~~~~ -:exc:`pyramid.exceptions.NotFound` and :exc:`pyramid.exceptions.Forbidden` -are exceptions often raised by Pyramid itself when it (respectively) cannot -find a view to service a request or when authorization was forbidden by a -security policy. However, they can also be raised by application developers. +:exc:`pyramid.response.HTTPNotFound` and +:exc:`pyramid.response.HTTPForbidden` are exceptions often raised by Pyramid +itself when it (respectively) cannot find a view to service a request or when +authorization was forbidden by a security policy. However, they can also be +raised by application developers. -If :exc:`~pyramid.exceptions.NotFound` is raised within view code, the result -of the :term:`Not Found View` will be returned to the user agent which +If :exc:`~pyramid.response.HTTPNotFound` is raised within view code, the +result of the :term:`Not Found View` will be returned to the user agent which performed the request. -If :exc:`~pyramid.exceptions.Forbidden` is raised within view code, the result -of the :term:`Forbidden View` will be returned to the user agent which +If :exc:`~pyramid.response.HTTPForbidden` is raised within view code, the +result of the :term:`Forbidden View` will be returned to the user agent which performed the request. Both are exception classes which accept a single positional constructor @@ -298,13 +299,10 @@ An example: .. code-block:: python :linenos: - from pyramid.exceptions import NotFound + from pyramid.response import HTTPNotFound def aview(request): - raise NotFound('not found!') - -Internal exceptions may not be *returned* in order to generate a response, -they must always be *raised*. + raise HTTPNotFound('not found!') .. index:: single: HTTP exceptions @@ -314,32 +312,33 @@ they must always be *raised*. HTTP Exceptions ~~~~~~~~~~~~~~~ -All exception classes documented in the :mod:`pyramid.httpexceptions` module -implement the :term:`Response` interface; an instance of any of these classes -can be returned or raised from within a view. The instance will be used as -as the view's response. +All classes documented in the :mod:`pyramid.response` module as inheriting +from the :class:`pryamid.response.Response` object implement the +:term:`Response` interface; an instance of any of these classes can be +returned or raised from within a view. The instance will be used as as the +view's response. -For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception +For example, the :class:`pyramid.response.HTTPUnauthorized` exception can be raised. This will cause a response to be generated with a ``401 Unauthorized`` status: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPUnauthorized + from pyramid.response import HTTPUnauthorized def aview(request): raise HTTPUnauthorized() A shortcut for importing and raising an HTTP exception is the -:func:`pyramid.httpexceptions.abort` function. This function accepts an HTTP +:func:`pyramid.response.abort` function. This function accepts an HTTP status code and raises the corresponding HTTP exception. For example, to raise HTTPUnauthorized, instead of the above, you could do: .. code-block:: python :linenos: - from pyramid.httpexceptions import abort + from pyramid.response import abort def aview(request): abort(401) @@ -347,8 +346,8 @@ raise HTTPUnauthorized, instead of the above, you could do: This is the case because ``401`` is the HTTP status code for "HTTP Unauthorized". Therefore, ``abort(401)`` is functionally equivalent to ``raise HTTPUnauthorized()``. Other exceptions in -:mod:`pyramid.httpexceptions` can be raised via -:func:`pyramid.httpexceptions.abort` as well, as long as the status code +:mod:`pyramid.response` can be raised via +:func:`pyramid.response.abort` as well, as long as the status code associated with the exception is provided to the function. An HTTP exception, instead of being raised, can alternately be *returned* @@ -357,18 +356,11 @@ An HTTP exception, instead of being raised, can alternately be *returned* .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPUnauthorized + from pyramid.response import HTTPUnauthorized def aview(request): return HTTPUnauthorized() -Note that :class:`pyramid.exceptions.NotFound` is *not* the same as -:class:`pyramid.httpexceptions.HTTPNotFound`. If the latter is raised, the -:term:`Not Found view` will *not* be called automatically. Likewise, -:class:`pyramid.exceptions.Forbidden` is not the same exception as -:class:`pyramid.httpexceptions.HTTPForbidden`. If the latter is raised, the -:term:`Forbidden view` will not be called automatically. - .. index:: single: exception views @@ -377,11 +369,11 @@ Note that :class:`pyramid.exceptions.NotFound` is *not* the same as Custom Exception Views ---------------------- -The machinery which allows :exc:`~pyramid.exceptions.NotFound`, -:exc:`~pyramid.exceptions.Forbidden` and HTTP exceptions to be caught by -specialized views as described in :ref:`special_exceptions_in_callables` can -also be used by application developers to convert arbitrary exceptions to -responses. +The machinery which allows :exc:`~pyramid.response.HTTPNotFound`, +:exc:`~pyramid.response.HTTPForbidden` and other responses to be used as +exceptions and caught by specialized views as described in +:ref:`special_exceptions_in_callables` can also be used by application +developers to convert arbitrary exceptions to responses. To register a view that should be called whenever a particular exception is raised from with :app:`Pyramid` view code, use the exception class or one of @@ -474,14 +466,14 @@ Short Form ~~~~~~~~~~ You can issue an HTTP redirect from within a view callable by using the -:func:`pyramid.httpexceptions.redirect` function. This function raises an -:class:`pyramid.httpexceptions.HTTPFound` exception (a "302"), which is -caught by an exception handler and turned into a response. +:func:`pyramid.response.redirect` function. This function raises an +:class:`pyramid.response.HTTPFound` exception (a "302"), which is caught by +the default exception response handler and turned into a response. .. code-block:: python :linenos: - from pyramid.httpexceptions import redirect + from pyramid.response import redirect def myview(request): redirect('http://example.com') @@ -490,16 +482,16 @@ Long Form ~~~~~~~~~ You can issue an HTTP redirect from within a view "by hand" instead of -relying on the :func:`pyramid.httpexceptions.redirect` function to do it for +relying on the :func:`pyramid.response.redirect` function to do it for you. -To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` +To do so, you can *return* a :class:`pyramid.response.HTTPFound` instance. .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPFound + from pyramid.response import HTTPFound def myview(request): return HTTPFound(location='http://example.com') @@ -510,7 +502,7 @@ one. .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPFound + from pyramid.response import HTTPFound def myview(request): raise HTTPFound(location='http://example.com') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 072ca1c74..6cd9418ce 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -362,11 +362,11 @@ To facilitate error responses like ``404 Not Found``, the module :mod:`webob.exc` contains classes for each kind of error response. These include boring, but appropriate error bodies. The exceptions exposed by this module, when used under :app:`Pyramid`, should be imported from the -:mod:`pyramid.httpexceptions` "facade" module. This import location is merely -a facade for the original location of these exceptions: ``webob.exc``. +:mod:`pyramid.response` module. This import location contains subclasses and +replacements that mirror those in the original ``webob.exc``. -Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the reason -for the error. For instance, :class:`pyramid.httpexceptions.HTTPNotFound`. It +Each class is named ``pyramid.response.HTTP*``, where ``*`` is the reason for +the error. For instance, :class:`pyramid.response.HTTPNotFound`. It subclasses :class:`pyramid.Response`, so you can manipulate the instances in the same way. A typical example is: @@ -374,40 +374,18 @@ the same way. A typical example is: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPNotFound - from pyramid.httpexceptions import HTTPMovedPermanently + from pyramid.response import HTTPNotFound + from pyramid.response import HTTPMovedPermanently response = HTTPNotFound('There is no such resource') # or: response = HTTPMovedPermanently(location=new_url) -These are not exceptions unless you are using Python 2.5+, because -they are new-style classes which are not allowed as exceptions until -Python 2.5. To get an exception object use ``response.exception``. -You can use this like: - -.. code-block:: python - :linenos: - - from pyramid.httpexceptions import HTTPException - from pyramid.httpexceptions import HTTPNotFound - - def aview(request): - try: - # ... stuff ... - raise HTTPNotFound('No such resource').exception - except HTTPException, e: - return request.get_response(e) - -The exceptions are still WSGI applications, but you cannot set -attributes like ``content_type``, ``charset``, etc. on these exception -objects. - More Details ++++++++++++ More details about the response object API are available in the :mod:`pyramid.response` documentation. More details about exception responses -are in the :mod:`pyramid.httpexceptions` API documentation. The `WebOb +are in the :mod:`pyramid.response` API documentation. The `WebOb documentation `_ is also useful. -- cgit v1.2.3 From df15ed98612e7962e3122da52d8d5f5b9d8882b2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 4 Jun 2011 18:43:25 -0400 Subject: - It is now possible to control how the Pyramid router calls the WSGI ``start_response`` callable and obtains the WSGI ``app_iter`` based on adapting the response object to the new ``pyramid.interfaces.IResponder`` interface. The default ``IResponder`` uses Pyramid 1.0's logic to do this. To override the responder:: from pyramid.interfaces import IResponder from pyramid.response import Response from myapp import MyResponder config.registry.registerAdapter(MyResponder, (Response,), IResponder, name='') This makes it possible to reuse response object implementations which have, for example, their own ``__call__`` expected to be used as a WSGI application (like ``pyramid.response.Response``), e.g.: class MyResponder(object): def __init__(self, response): """ Obtain a reference to the response """ self.response = response def __call__(self, request, start_response): """ Call start_response and return an app_iter """ app_iter = self.response(request.environ, start_response) return app_iter --- docs/narr/hooks.rst | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index d620b5672..aa151d281 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -521,6 +521,42 @@ The default context URL generator is available for perusal as the class `_ of the :term:`Pylons` GitHub Pyramid repository. +.. index:: + single: IResponder + +.. _using_iresponder: + +Changing How Pyramid Treats Response Objects +-------------------------------------------- + +It is possible to control how the Pyramid :term:`router` calls the WSGI +``start_response`` callable and obtains the WSGI ``app_iter`` based on +adapting the response object to the :class: `pyramid.interfaces.IResponder` +interface. The default ``IResponder`` uses the three attributes ``status``, +``headerlist``, and ``app_iter`` attached to the response object, and calls +``start_response`` with the status and headerlist, returning the +``app_iter``. To override the responder:: + + from pyramid.interfaces import IResponder + from pyramid.response import Response + from myapp import MyResponder + + config.registry.registerAdapter(MyResponder, (Response,), + IResponder, name='') + +Overriding makes it possible to reuse response object implementations which +have, for example, their own ``__call__`` expected to be used as a WSGI +application (like :class:`pyramid.response.Response`), e.g.: + + class MyResponder(object): + def __init__(self, response): + """ Obtain a reference to the response """ + self.response = response + def __call__(self, request, start_response): + """ Call start_response and return an app_iter """ + app_iter = self.response(request.environ, start_response) + return app_iter + .. index:: single: view mapper -- cgit v1.2.3 From 99edc51a3b05309c7f5d98ff96289ec51b1d7660 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 11 Jun 2011 05:35:27 -0400 Subject: - Pyramid now expects Response objects to have a __call__ method which implements the WSGI application interface instead of the three webob attrs status, headerlist and app_iter. Backwards compatibility exists for code which returns response objects that do not have a __call__. - pyramid.response.Response is no longer an exception (and therefore cannot be raised in order to generate a response). - Changed my mind about moving stuff from pyramid.httpexceptions to pyramid.response. The stuff I moved over has been moved back to pyramid.httpexceptions. --- docs/narr/hooks.rst | 42 +++++----- docs/narr/renderers.rst | 69 +++++++++++---- docs/narr/router.rst | 12 +-- docs/narr/testing.rst | 4 +- docs/narr/urldispatch.rst | 4 +- docs/narr/views.rst | 209 +++++++++++++++++++--------------------------- docs/narr/webob.rst | 23 ++--- 7 files changed, 185 insertions(+), 178 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index aa151d281..b6a781417 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -21,7 +21,7 @@ configuration. The :term:`not found view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "not found" view consists -only of naming the :exc:`pyramid.response.HTTPNotFound` class as the +only of naming the :exc:`pyramid.httpexceptions.HTTPNotFound` class as the ``context`` of the view configuration. If your application uses :term:`imperative configuration`, you can replace @@ -31,7 +31,7 @@ method to register an "exception view": .. code-block:: python :linenos: - from pyramid.response import HTTPNotFound + from pyramid.httpexceptions import HTTPNotFound from helloworld.views import notfound_view config.add_view(notfound_view, context=HTTPNotFound) @@ -42,22 +42,22 @@ Like any other view, the notfound view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``request`` is the current :term:`request` representing the denied action. The ``context`` (if used in the call signature) will be the instance of the -:exc:`~pyramid.response.HTTPNotFound` exception that caused the view to be -called. +:exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the view to +be called. Here's some sample code that implements a minimal NotFound view callable: .. code-block:: python :linenos: - from pyramid.response import HTTPNotFound + from pyramid.httpexceptions import HTTPNotFound def notfound_view(request): return HTTPNotFound() .. note:: When a NotFound view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will be an - instance of the :exc:`~pyramid.response.HTTPNotFound` exception that + instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the not found view to be called. The value of ``request.exception.args[0]`` will be a value explaining why the not found error was raised. This message will be different when the @@ -67,8 +67,9 @@ Here's some sample code that implements a minimal NotFound view callable: .. warning:: When a NotFound view callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` passed as the first argument to the view callable will be the - :exc:`~pyramid.response.HTTPNotFound` exception instance. If available, - the resource context will still be available as ``request.context``. + :exc:`~pyramid.httpexceptions.HTTPNotFound` exception instance. If + available, the resource context will still be available as + ``request.context``. .. index:: single: forbidden view @@ -85,7 +86,7 @@ the view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "not found" view consists -only of naming the :exc:`pyramid.response.HTTPForbidden` class as the +only of naming the :exc:`pyramid.httpexceptions.HTTPForbidden` class as the ``context`` of the view configuration. You can replace the forbidden view by using the @@ -96,7 +97,7 @@ view": :linenos: from helloworld.views import forbidden_view - from pyramid.response import HTTPForbidden + from pyramid.httpexceptions import HTTPForbidden config.add_view(forbidden_view, context=HTTPForbidden) Replace ``helloworld.views.forbidden_view`` with a reference to the Python @@ -122,8 +123,8 @@ Here's some sample code that implements a minimal forbidden view: .. note:: When a forbidden view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will be an - instance of the :exc:`~pyramid.response.HTTPForbidden` exception that - caused the forbidden view to be called. The value of + instance of the :exc:`~pyramid.httpexceptions.HTTPForbidden` exception + that caused the forbidden view to be called. The value of ``request.exception.args[0]`` will be a value explaining why the forbidden was raised. This message will be different when the ``debug_authorization`` environment setting is true than it is when it is @@ -532,10 +533,10 @@ Changing How Pyramid Treats Response Objects It is possible to control how the Pyramid :term:`router` calls the WSGI ``start_response`` callable and obtains the WSGI ``app_iter`` based on adapting the response object to the :class: `pyramid.interfaces.IResponder` -interface. The default ``IResponder`` uses the three attributes ``status``, -``headerlist``, and ``app_iter`` attached to the response object, and calls -``start_response`` with the status and headerlist, returning the -``app_iter``. To override the responder:: +interface. The default responder uses the ``__call__`` method of a response +object, passing it the WSGI environ and the WSGI ``start_response`` callable +(the response is assumed to be a WSGI application). To override the +responder:: from pyramid.interfaces import IResponder from pyramid.response import Response @@ -545,8 +546,9 @@ interface. The default ``IResponder`` uses the three attributes ``status``, IResponder, name='') Overriding makes it possible to reuse response object implementations which -have, for example, their own ``__call__`` expected to be used as a WSGI -application (like :class:`pyramid.response.Response`), e.g.: +have, for example, the ``app_iter``, ``headerlist`` and ``status`` attributes +of an object returned as a response instead of trying to use the object's +``__call__`` method:: class MyResponder(object): def __init__(self, response): @@ -554,8 +556,8 @@ application (like :class:`pyramid.response.Response`), e.g.: self.response = response def __call__(self, request, start_response): """ Call start_response and return an app_iter """ - app_iter = self.response(request.environ, start_response) - return app_iter + start_response(self.response.status, self.response.headerlist) + return self.response.app_iter .. index:: single: view mapper diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index c7a3d7837..99ee14908 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -11,7 +11,6 @@ Response interface, :app:`Pyramid` will attempt to use a .. code-block:: python :linenos: - from pyramid.response import Response from pyramid.view import view_config @view_config(renderer='json') @@ -77,39 +76,52 @@ templating language to render a dictionary to a response. Additional renderers can be added by developers to the system as necessary (see :ref:`adding_and_overriding_renderers`). -Views which use a renderer can vary non-body response attributes (such as -headers and the HTTP status code) by attaching a property to the -``request.response`` attribute See :ref:`request_response_attr`. +Views which use a renderer and return a non-Response value can vary non-body +response attributes (such as headers and the HTTP status code) by attaching a +property to the ``request.response`` attribute See +:ref:`request_response_attr`. If the :term:`view callable` associated with a :term:`view configuration` -returns a Response object directly (an object with the attributes ``status``, -``headerlist`` and ``app_iter``), any renderer associated with the view +returns a Response object directly, any renderer associated with the view configuration is ignored, and the response is passed back to :app:`Pyramid` unchanged. For example, if your view callable returns an instance of the -:class:`pyramid.response.HTTPFound` class as a response, no renderer will be -employed. +:class:`pyramid.response.Response` class as a response, no renderer +will be employed. .. code-block:: python :linenos: - from pyramid.response import HTTPFound + from pyramid.response import Response + from pyramid.view import view_config + @view_config(renderer='json') def view(request): - return HTTPFound(location='http://example.com') # any renderer avoided + return Response('OK') # json renderer avoided -Likewise for a "plain old response": +Likewise for an :term:`HTTP exception` response: .. code-block:: python :linenos: - from pyramid.response import Response + from pyramid.httpexceptions import HTTPNotFound + from pyramid.view import view_config + @view_config(renderer='json') def view(request): - return Response('OK') # any renderer avoided + return HTTPFound(location='http://example.com') # json renderer avoided -Mutations to ``request.response`` in views which return a Response object -like this directly (unless that response *is* ``request.response``) will be -ignored. +You can of course also return the ``request.response`` attribute instead to +avoid rendering: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + @view_config(renderer='json') + def view(request): + request.response.body = 'OK' + return request.response # json renderer avoided .. index:: single: renderers (built-in) @@ -377,6 +389,31 @@ callable that uses a renderer, assign the ``status`` attribute to the request.response.status = '404 Not Found' return {'URL':request.URL} +Note that mutations of ``request.response`` in views which return a Response +object directly will have no effect unless the response object returned *is* +``request.response``. For example, the following example calls +``request.response.set_cookie``, but this call will have no effect, because a +different Response object is returned. + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def view(request): + request.response.set_cookie('abc', '123') # this has no effect + return Response('OK') # because we're returning a different response + +If you mutate ``request.response`` and you'd like the mutations to have an +effect, you must return ``request.response``: + +.. code-block:: python + :linenos: + + def view(request): + request.response.set_cookie('abc', '123') + return request.response + For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of ``request.response``, see :class:`pyramid.response.Response`. diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 44fa9835b..30d54767e 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -82,8 +82,8 @@ processing? combination of objects (based on the type of the context, the type of the request, and the value of the view name, and any :term:`predicate` attributes applied to the view configuration), :app:`Pyramid` raises a - :class:`~pyramid.response.HTTPNotFound` exception, which is meant to be - caught by a surrounding exception handler. + :class:`~pyramid.httpexceptions.HTTPNotFound` exception, which is meant to + be caught by a surrounding :term:`exception view`. #. If a view callable was found, :app:`Pyramid` attempts to call the view function. @@ -95,13 +95,13 @@ processing? information in the request and security information attached to the context. If it returns ``True``, :app:`Pyramid` calls the view callable to obtain a response. If it returns ``False``, it raises a - :class:`~pyramid.response.HTTPForbidden` exception, which is meant to be - called by a surrounding exception handler. + :class:`~pyramid.httpexceptions.HTTPForbidden` exception, which is meant + to be called by a surrounding :term:`exception view`. #. If any exception was raised within a :term:`root factory`, by :term:`traversal`, by a :term:`view callable` or by :app:`Pyramid` itself - (such as when it raises :class:`~pyramid.response.HTTPNotFound` or - :class:`~pyramid.response.HTTPForbidden`), the router catches the + (such as when it raises :class:`~pyramid.httpexceptions.HTTPNotFound` or + :class:`~pyramid.httpexceptions.HTTPForbidden`), the router catches the exception, and attaches it to the request as the ``exception`` attribute. It then attempts to find a :term:`exception view` for the exception that was caught. If it finds an exception view callable, that callable is diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 862eda9f0..05e851fde 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -191,7 +191,7 @@ function. :linenos: from pyramid.security import has_permission - from pyramid.response import HTTPForbidden + from pyramid.httpexceptions import HTTPForbidden def view_fn(request): if not has_permission('edit', request.context, request): @@ -230,7 +230,7 @@ without needing to invoke the actual application configuration implied by its testing.tearDown() def test_view_fn_forbidden(self): - from pyramid.response import HTTPForbidden + from pyramid.httpexceptions import HTTPForbidden from my.package import view_fn self.config.testing_securitypolicy(userid='hank', permissive=False) diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index e5228b81e..f94ed3ba8 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -917,7 +917,7 @@ the application's startup configuration, adding the following stanza: :linenos: config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.response.HTTPNotFound') + context='pyramid.httpexceptions.HTTPNotFound') See :ref:`view_module` and :ref:`changing_the_notfound_view` for more information about the slash-appending not found view and for a more general @@ -945,7 +945,7 @@ view as the first argument to its constructor. For instance: .. code-block:: python :linenos: - from pyramid.response import HTTPNotFound + from pyramid.httpexceptions import HTTPNotFound from pyramid.view import AppendSlashNotFoundViewFactory def notfound_view(context, request): diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 73a7c2e2a..990828f80 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -230,29 +230,29 @@ implements the :term:`Response` interface is to return a def view(request): return Response('OK') -You don't need to always use :class:`~pyramid.response.Response` to represent -a response. :app:`Pyramid` provides a range of different "exception" classes -which can act as response objects too. For example, an instance of the class -:class:`pyramid.response.HTTPFound` is also a valid response object -(see :ref:`http_exceptions` and ref:`http_redirect`). A view can actually -return any object that has the following attributes. - -status - The HTTP status code (including the name) for the response as a string. - E.g. ``200 OK`` or ``401 Unauthorized``. - -headerlist - A sequence of tuples representing the list of headers that should be - set in the response. E.g. ``[('Content-Type', 'text/html'), - ('Content-Length', '412')]`` - -app_iter - An iterable representing the body of the response. This can be a - list, e.g. ``['Hello - world!']`` or it can be a file-like object, or any - other sort of iterable. - -These attributes form the structure of the "Pyramid Response interface". +You don't need to use :class:`~pyramid.response.Response` to represent a +response. A view can actually return any object that has a ``__call__`` +method that implements the :term:`WSGI` application call interface. For +example, an instance of the following class could be successfully returned by +a view callable as a response object: + +.. code-block:: python + :linenos: + + class SimpleResponse(object): + def __call__(self, environ, start_response): + """ Call the ``start_response`` callback and return + an iterable """ + body = 'Hello World!' + headers = [('Content-Type', 'text/plain'), + ('Content-Length', str(len(body)))] + start_response('200 OK', headers) + return [body] + +:app:`Pyramid` provides a range of different "exception" classes which can +act as response objects too. For example, an instance of the class +:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object +(see :ref:`http_exceptions` and ref:`http_redirect`). .. index:: single: view exceptions @@ -269,40 +269,8 @@ logged there. However, for convenience, a special set of exceptions exists. When one of these exceptions is raised within a view callable, it will always cause -:app:`Pyramid` to generate a response. Two categories of special exceptions -exist: internal exceptions and HTTP exceptions. - -Internal Exceptions -~~~~~~~~~~~~~~~~~~~ - -:exc:`pyramid.response.HTTPNotFound` and -:exc:`pyramid.response.HTTPForbidden` are exceptions often raised by Pyramid -itself when it (respectively) cannot find a view to service a request or when -authorization was forbidden by a security policy. However, they can also be -raised by application developers. - -If :exc:`~pyramid.response.HTTPNotFound` is raised within view code, the -result of the :term:`Not Found View` will be returned to the user agent which -performed the request. - -If :exc:`~pyramid.response.HTTPForbidden` is raised within view code, the -result of the :term:`Forbidden View` will be returned to the user agent which -performed the request. - -Both are exception classes which accept a single positional constructor -argument: a ``message``. In all cases, the message provided to the exception -constructor is made available to the view which :app:`Pyramid` invokes as -``request.exception.args[0]``. - -An example: - -.. code-block:: python - :linenos: - - from pyramid.response import HTTPNotFound - - def aview(request): - raise HTTPNotFound('not found!') +:app:`Pyramid` to generate a response. These are known as :term:`HTTP +exception` objects. .. index:: single: HTTP exceptions @@ -312,54 +280,77 @@ An example: HTTP Exceptions ~~~~~~~~~~~~~~~ -All classes documented in the :mod:`pyramid.response` module as inheriting -from the :class:`pryamid.response.Response` object implement the -:term:`Response` interface; an instance of any of these classes can be -returned or raised from within a view. The instance will be used as as the -view's response. +All classes documented in the :mod:`pyramid.httpexceptions` module documented +as inheriting from the :class:`pryamid.httpexceptions.HTTPException` are +:term:`http exception` objects. An instances of an HTTP exception object may +either be *returned* or *raised* from within view code. In either case +(return or raise) the instance will be used as as the view's response. -For example, the :class:`pyramid.response.HTTPUnauthorized` exception +For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception can be raised. This will cause a response to be generated with a ``401 Unauthorized`` status: .. code-block:: python :linenos: - from pyramid.response import HTTPUnauthorized + from pyramid.httpexceptions import HTTPUnauthorized def aview(request): raise HTTPUnauthorized() -A shortcut for importing and raising an HTTP exception is the -:func:`pyramid.response.abort` function. This function accepts an HTTP -status code and raises the corresponding HTTP exception. For example, to -raise HTTPUnauthorized, instead of the above, you could do: +An HTTP exception, instead of being raised, can alternately be *returned* +(HTTP exceptions are also valid response objects): .. code-block:: python :linenos: - from pyramid.response import abort + from pyramid.httpexceptions import HTTPUnauthorized def aview(request): - abort(401) - -This is the case because ``401`` is the HTTP status code for "HTTP -Unauthorized". Therefore, ``abort(401)`` is functionally equivalent to -``raise HTTPUnauthorized()``. Other exceptions in -:mod:`pyramid.response` can be raised via -:func:`pyramid.response.abort` as well, as long as the status code -associated with the exception is provided to the function. + return HTTPUnauthorized() -An HTTP exception, instead of being raised, can alternately be *returned* -(HTTP exceptions are also valid response objects): +A shortcut for creating an HTTP exception is the +:func:`pyramid.httpexceptions.responsecode` function. This function accepts +an HTTP status code and returns the corresponding HTTP exception. For +example, instead of importing and constructing a +:class:`~pyramid.httpexceptions.HTTPUnauthorized` response object, you can +use the :func:`~pyramid.httpexceptions.responsecode` function to construct +and return the same object. .. code-block:: python :linenos: - from pyramid.response import HTTPUnauthorized + from pyramid.httpexceptions import responsecode def aview(request): - return HTTPUnauthorized() + raise responsecode(401) + +This is the case because ``401`` is the HTTP status code for "HTTP +Unauthorized". Therefore, ``raise responsecode(401)`` is functionally +equivalent to ``raise HTTPUnauthorized()``. Documentation which maps each +HTTP response code to its purpose and its associated HTTP exception object is +provided within :mod:`pyramid.httpexceptions`. + +How Pyramid Uses HTTP Exceptions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +HTTP exceptions are meant to be used directly by application application +developers. However, Pyramid itself will raise two HTTP exceptions at +various points during normal operations: +:exc:`pyramid.httpexceptions.HTTPNotFound` and +:exc:`pyramid.httpexceptions.HTTPForbidden`. Pyramid will raise the +:exc:`~pyramid.httpexceptions.HTTPNotFound` exception are raised when it +cannot find a view to service a request. Pyramid will raise the +:exc:`~pyramid.httpexceptions.Forbidden` exception or when authorization was +forbidden by a security policy. + +If :exc:`~pyramid.httpexceptions.HTTPNotFound` is raised by Pyramid itself or +within view code, the result of the :term:`Not Found View` will be returned +to the user agent which performed the request. + +If :exc:`~pyramid.httpexceptions.HTTPForbidden` is raised by Pyramid itself +within view code, the result of the :term:`Forbidden View` will be returned +to the user agent which performed the request. .. index:: single: exception views @@ -369,11 +360,10 @@ An HTTP exception, instead of being raised, can alternately be *returned* Custom Exception Views ---------------------- -The machinery which allows :exc:`~pyramid.response.HTTPNotFound`, -:exc:`~pyramid.response.HTTPForbidden` and other responses to be used as -exceptions and caught by specialized views as described in -:ref:`special_exceptions_in_callables` can also be used by application -developers to convert arbitrary exceptions to responses. +The machinery which allows HTTP exceptions to be raised and caught by +specialized views as described in :ref:`special_exceptions_in_callables` can +also be used by application developers to convert arbitrary exceptions to +responses. To register a view that should be called whenever a particular exception is raised from with :app:`Pyramid` view code, use the exception class or one of @@ -409,8 +399,8 @@ raises a ``helloworld.exceptions.ValidationFailure`` exception: Assuming that a :term:`scan` was run to pick up this view registration, this view callable will be invoked whenever a ``helloworld.exceptions.ValidationFailure`` is raised by your application's -view code. The same exception raised by a custom root factory or a custom -traverser is also caught and hooked. +view code. The same exception raised by a custom root factory, a custom +traverser, or a custom view or route predicate is also caught and hooked. Other normal view predicates can also be used in combination with an exception view registration: @@ -458,57 +448,34 @@ Exception views can be configured with any view registration mechanism: Using a View Callable to Do an HTTP Redirect -------------------------------------------- -Two methods exist to redirect to another URL from within a view callable: a -short form and a long form. The short form should be preferred when -possible. - -Short Form -~~~~~~~~~~ - -You can issue an HTTP redirect from within a view callable by using the -:func:`pyramid.response.redirect` function. This function raises an -:class:`pyramid.response.HTTPFound` exception (a "302"), which is caught by -the default exception response handler and turned into a response. - -.. code-block:: python - :linenos: - - from pyramid.response import redirect - - def myview(request): - redirect('http://example.com') - -Long Form -~~~~~~~~~ - -You can issue an HTTP redirect from within a view "by hand" instead of -relying on the :func:`pyramid.response.redirect` function to do it for -you. +You can issue an HTTP redirect by using the +:class:`pyramid.httpexceptions.HTTPFound` class. Raising or returning an +instance of this class will cause the client to receive a "302 Found" +response. -To do so, you can *return* a :class:`pyramid.response.HTTPFound` +To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` instance. .. code-block:: python :linenos: - from pyramid.response import HTTPFound + from pyramid.httpexceptions import HTTPFound def myview(request): return HTTPFound(location='http://example.com') -Or, alternately, you can *raise* an HTTPFound exception instead of returning -one. +Alternately, you can *raise* an HTTPFound exception instead of returning one. .. code-block:: python :linenos: - from pyramid.response import HTTPFound + from pyramid.httpexceptions import HTTPFound def myview(request): raise HTTPFound(location='http://example.com') -The above form of generating a response by raising HTTPFound is completely -equivalent to ``redirect('http://example.com')``. +When the instance is raised, it is caught by the default :term:`exception +response` handler and turned into a response. .. index:: single: unicode, views, and forms diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 6cd9418ce..70ab5eea8 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -362,20 +362,21 @@ To facilitate error responses like ``404 Not Found``, the module :mod:`webob.exc` contains classes for each kind of error response. These include boring, but appropriate error bodies. The exceptions exposed by this module, when used under :app:`Pyramid`, should be imported from the -:mod:`pyramid.response` module. This import location contains subclasses and -replacements that mirror those in the original ``webob.exc``. +:mod:`pyramid.httpexceptions` module. This import location contains +subclasses and replacements that mirror those in the original ``webob.exc``. -Each class is named ``pyramid.response.HTTP*``, where ``*`` is the reason for -the error. For instance, :class:`pyramid.response.HTTPNotFound`. It -subclasses :class:`pyramid.Response`, so you can manipulate the instances in -the same way. A typical example is: +Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the +reason for the error. For instance, +:class:`pyramid.httpexceptions.HTTPNotFound` subclasses +:class:`pyramid.Response`, so you can manipulate the instances in the same +way. A typical example is: .. ignore-next-block .. code-block:: python :linenos: - from pyramid.response import HTTPNotFound - from pyramid.response import HTTPMovedPermanently + from pyramid.httpexceptions import HTTPNotFound + from pyramid.httpexceptions import HTTPMovedPermanently response = HTTPNotFound('There is no such resource') # or: @@ -385,7 +386,7 @@ More Details ++++++++++++ More details about the response object API are available in the -:mod:`pyramid.response` documentation. More details about exception responses -are in the :mod:`pyramid.response` API documentation. The `WebOb -documentation `_ is also useful. +:mod:`pyramid.response` documentation. More details about exception +responses are in the :mod:`pyramid.httpexceptions` API documentation. The +`WebOb documentation `_ is also useful. -- cgit v1.2.3 From d868fff7597c5a05acd1f5c024fc45dde9880413 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 13 Jun 2011 06:17:00 -0400 Subject: - Remove IResponder abstraction in favor of more general IResponse abstraction. - It is now possible to return an arbitrary object from a Pyramid view callable even if a renderer is not used, as long as a suitable adapter to ``pyramid.interfaces.IResponse`` is registered for the type of the returned object. See the section in the Hooks chapter of the documentation entitled "Changing How Pyramid Treats View Responses". - The Pyramid router now, by default, expects response objects returned from view callables to implement the ``pyramid.interfaces.IResponse`` interface. Unlike the Pyramid 1.0 version of this interface, objects which implement IResponse now must define a ``__call__`` method that accepts ``environ`` and ``start_response``, and which returns an ``app_iter`` iterable, among other things. Previously, it was possible to return any object which had the three WebOb ``app_iter``, ``headerlist``, and ``status`` attributes as a response, so this is a backwards incompatibility. It is possible to get backwards compatibility back by registering an adapter to IResponse from the type of object you're now returning from view callables. See the section in the Hooks chapter of the documentation entitled "Changing How Pyramid Treats View Responses". - The ``pyramid.interfaces.IResponse`` interface is now much more extensive. Previously it defined only ``app_iter``, ``status`` and ``headerlist``; now it is basically intended to directly mirror the ``webob.Response`` API, which has many methods and attributes. - Documentation changes to support above. --- docs/narr/assets.rst | 2 +- docs/narr/hooks.rst | 134 +++++++++++++++++++++++++++++++++++------------- docs/narr/renderers.rst | 2 +- docs/narr/router.rst | 6 +-- docs/narr/views.rst | 36 +++++-------- docs/narr/webob.rst | 66 ++++++++++++------------ 6 files changed, 150 insertions(+), 96 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 8d0e7058c..0d50b0106 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -358,7 +358,7 @@ do so, do things "by hand". First define the view callable. :linenos: import os - from webob import Response + from pyramid.response import Response def favicon_view(request): here = os.path.dirname(__file__) diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b6a781417..0db8ce5e0 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -523,41 +523,103 @@ The default context URL generator is available for perusal as the class :term:`Pylons` GitHub Pyramid repository. .. index:: - single: IResponder - -.. _using_iresponder: - -Changing How Pyramid Treats Response Objects --------------------------------------------- - -It is possible to control how the Pyramid :term:`router` calls the WSGI -``start_response`` callable and obtains the WSGI ``app_iter`` based on -adapting the response object to the :class: `pyramid.interfaces.IResponder` -interface. The default responder uses the ``__call__`` method of a response -object, passing it the WSGI environ and the WSGI ``start_response`` callable -(the response is assumed to be a WSGI application). To override the -responder:: - - from pyramid.interfaces import IResponder - from pyramid.response import Response - from myapp import MyResponder - - config.registry.registerAdapter(MyResponder, (Response,), - IResponder, name='') - -Overriding makes it possible to reuse response object implementations which -have, for example, the ``app_iter``, ``headerlist`` and ``status`` attributes -of an object returned as a response instead of trying to use the object's -``__call__`` method:: - - class MyResponder(object): - def __init__(self, response): - """ Obtain a reference to the response """ - self.response = response - def __call__(self, request, start_response): - """ Call start_response and return an app_iter """ - start_response(self.response.status, self.response.headerlist) - return self.response.app_iter + single: IResponse + +.. _using_iresponse: + +Changing How Pyramid Treats View Responses +------------------------------------------ + +It is possible to control how Pyramid treats the result of calling a view +callable on a per-type basis by using a hook involving +:class:`pyramid.interfaces.IResponse`. + +.. note:: This feature is new as of Pyramid 1.1. + +Pyramid, in various places, adapts the result of calling a view callable to +the :class:`~pyramid.interfaces.IResponse` interface to ensure that the +object returned by the view callable is a "true" response object. The vast +majority of time, the result of this adaptation is the result object itself, +as view callables written by "civilians" who read the narrative documentation +contained in this manual will always return something that implements the +:class:`~pyramid.interfaces.IResponse` interface. Most typically, this will +be an instance of the :class:`pyramid.response.Response` class or a subclass. +If a civilian returns a non-Response object from a view callable that isn't +configured to use a :term:`renderer`, he will typically expect the router to +raise an error. However, you can hook Pyramid in such a way that users can +return arbitrary values from a view callable by providing an adapter which +converts the arbitrary return value into something that implements +:class:`~pyramid.interfaces.IResponse`. + +For example, if you'd like to allow view callables to return bare string +objects (without requiring a a :term:`renderer` to convert a string to a +response object), you can register an adapter which converts the string to a +Response: + +.. code-block:: python + :linenos: + + from pyramid.interfaces import IResponse + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + return response + + # config is an instance of pyramid.config.Configurator + + config.registry.registerAdapter(string_response_adapter, (str,), + IResponse) + +Likewise, if you want to be able to return a simplified kind of response +object from view callables, you can use the IResponse hook to register an +adapter to the more complex IResponse interface: + +.. code-block:: python + :linenos: + + from pyramid.interfaces import IResponse + from pyramid.response import Response + + class SimpleResponse(object): + def __init__(self, body): + self.body = body + + def simple_response_adapter(simple_response): + response = Response(simple_response.body) + return response + + # config is an instance of pyramid.config.Configurator + + config.registry.registerAdapter(simple_response_adapter, + (SimpleResponse,), + IResponse) + +If you want to implement your own Response object instead of using the +:class:`pyramid.response.Response` object in any capacity at all, you'll have +to make sure the object implements every attribute and method outlined in +:class:`pyramid.interfaces.IResponse` *and* you'll have to ensure that it's +marked up with ``zope.interface.implements(IResponse)``: + + from pyramid.interfaces import IResponse + from zope.interface import implements + + class MyResponse(object): + implements(IResponse) + # ... an implementation of every method and attribute + # documented in IResponse should follow ... + +When an alternate response object implementation is returned by a view +callable, if that object asserts that it implements +:class:`~pyramid.interfaces.IResponse` (via +``zope.interface.implements(IResponse)``) , an adapter needn't be registered +for the object; Pyramid will use it directly. + +An IResponse adapter for ``webob.Response`` (as opposed to +:class:`pyramid.response.Response`) is registered by Pyramid by default at +startup time, as by their nature, instances of this class (and instances of +subclasses of the class) will natively provide IResponse. The adapter +registered for ``webob.Response`` simply returns the response object. .. index:: single: view mapper @@ -628,7 +690,7 @@ A user might make use of these framework components like so: # user application - from webob import Response + from pyramid.response import Response from pyramid.config import Configurator import pyramid_handlers from paste.httpserver import serve diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 99ee14908..c4a37c23d 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -416,7 +416,7 @@ effect, you must return ``request.response``: For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of -``request.response``, see :class:`pyramid.response.Response`. +``request.response``, see :attr:`pyramid.request.Request.response`. .. _response_prefixed_attrs: diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 30d54767e..0812f7ec7 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -115,9 +115,9 @@ processing? any :term:`response callback` functions attached via :meth:`~pyramid.request.Request.add_response_callback`. A :class:`~pyramid.events.NewResponse` :term:`event` is then sent to any - subscribers. The response object's ``app_iter``, ``status``, and - ``headerlist`` attributes are then used to generate a WSGI response. The - response is sent back to the upstream WSGI server. + subscribers. The response object's ``__call__`` method is then used to + generate a WSGI response. The response is sent back to the upstream WSGI + server. #. :app:`Pyramid` will attempt to execute any :term:`finished callback` functions attached via diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 990828f80..e3d0a37e5 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -230,29 +230,19 @@ implements the :term:`Response` interface is to return a def view(request): return Response('OK') -You don't need to use :class:`~pyramid.response.Response` to represent a -response. A view can actually return any object that has a ``__call__`` -method that implements the :term:`WSGI` application call interface. For -example, an instance of the following class could be successfully returned by -a view callable as a response object: - -.. code-block:: python - :linenos: - - class SimpleResponse(object): - def __call__(self, environ, start_response): - """ Call the ``start_response`` callback and return - an iterable """ - body = 'Hello World!' - headers = [('Content-Type', 'text/plain'), - ('Content-Length', str(len(body)))] - start_response('200 OK', headers) - return [body] - -:app:`Pyramid` provides a range of different "exception" classes which can -act as response objects too. For example, an instance of the class -:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object -(see :ref:`http_exceptions` and ref:`http_redirect`). +:app:`Pyramid` provides a range of different "exception" classes which +inherit from :class:`pyramid.response.Response`. For example, an instance of +the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response +object because it inherits from :class:`~pyramid.response.Response`. For +examples, see :ref:`http_exceptions` and ref:`http_redirect`. + +You can also return objects from view callables that aren't instances of (or +instances of classes which are subclasses of) +:class:`pyramid.response.Response` in various circumstances. This can be +helpful when writing tests and when attempting to share code between view +callables. See :ref:`renderers_chapter` for the common way to allow for +this. A much less common way to allow for view callables to return +non-Response objects is documented in :ref:`using_iresponse`. .. index:: single: view exceptions diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 70ab5eea8..0ff8e1de7 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -10,15 +10,15 @@ Request and Response Objects .. note:: This chapter is adapted from a portion of the :term:`WebOb` documentation, originally written by Ian Bicking. -:app:`Pyramid` uses the :term:`WebOb` package to supply +:app:`Pyramid` uses the :term:`WebOb` package as a basis for its :term:`request` and :term:`response` object implementations. The -:term:`request` object that is passed to a :app:`Pyramid` -:term:`view` is an instance of the :class:`pyramid.request.Request` -class, which is a subclass of :class:`webob.Request`. The -:term:`response` returned from a :app:`Pyramid` :term:`view` -:term:`renderer` is an instance of the :mod:`webob.Response` class. -Users can also return an instance of :mod:`webob.Response` directly -from a view as necessary. +:term:`request` object that is passed to a :app:`Pyramid` :term:`view` is an +instance of the :class:`pyramid.request.Request` class, which is a subclass +of :class:`webob.Request`. The :term:`response` returned from a +:app:`Pyramid` :term:`view` :term:`renderer` is an instance of the +:mod:`pyramid.response.Response` class, which is a subclass of the +:class:`webob.Response` class. Users can also return an instance of +:class:`pyramid.response.Response` directly from a view as necessary. WebOb is a project separate from :app:`Pyramid` with a separate set of authors and a fully separate `set of documentation @@ -26,16 +26,15 @@ authors and a fully separate `set of documentation standard WebOb request, which is documented in the :ref:`request_module` API documentation. -WebOb provides objects for HTTP requests and responses. Specifically -it does this by wrapping the `WSGI `_ request -environment and response status/headers/app_iter (body). +WebOb provides objects for HTTP requests and responses. Specifically it does +this by wrapping the `WSGI `_ request environment and +response status, header list, and app_iter (body) values. -WebOb request and response objects provide many conveniences for -parsing WSGI requests and forming WSGI responses. WebOb is a nice way -to represent "raw" WSGI requests and responses; however, we won't -cover that use case in this document, as users of :app:`Pyramid` -don't typically need to use the WSGI-related features of WebOb -directly. The `reference documentation +WebOb request and response objects provide many conveniences for parsing WSGI +requests and forming WSGI responses. WebOb is a nice way to represent "raw" +WSGI requests and responses; however, we won't cover that use case in this +document, as users of :app:`Pyramid` don't typically need to use the +WSGI-related features of WebOb directly. The `reference documentation `_ shows many examples of creating requests and using response objects in this manner, however. @@ -170,9 +169,9 @@ of the request. I'll show various values for an example URL Methods +++++++ -There are `several methods -`_ but -only a few you'll use often: +There are methods of request objects documented in +:class:`pyramid.request.Request` but you'll find that you won't use very many +of them. Here are a couple that might be useful: ``Request.blank(base_url)``: Creates a new request with blank information, based at the given @@ -183,9 +182,9 @@ only a few you'll use often: subrequests). ``req.get_response(wsgi_application)``: - This method calls the given WSGI application with this request, - and returns a `Response`_ object. You can also use this for - subrequests, or testing. + This method calls the given WSGI application with this request, and + returns a :class:`pyramid.response.Response` object. You can also use + this for subrequests, or testing. .. index:: single: request (and unicode) @@ -259,8 +258,10 @@ Response ~~~~~~~~ The :app:`Pyramid` response object can be imported as -:class:`pyramid.response.Response`. This import location is merely a facade -for its original location: ``webob.Response``. +:class:`pyramid.response.Response`. This class is a subclass of the +``webob.Response`` class. The subclass does not add or change any +functionality, so the WebOb Response documentation will be completely +relevant for this class as well. A response object has three fundamental parts: @@ -283,8 +284,8 @@ A response object has three fundamental parts: ``response.body_file`` (a file-like object; writing to it appends to ``app_iter``). -Everything else in the object derives from this underlying state. -Here's the highlights: +Everything else in the object typically derives from this underlying state. +Here are some highlights: ``response.content_type`` The content type *not* including the ``charset`` parameter. @@ -359,11 +360,12 @@ Exception Responses +++++++++++++++++++ To facilitate error responses like ``404 Not Found``, the module -:mod:`webob.exc` contains classes for each kind of error response. These -include boring, but appropriate error bodies. The exceptions exposed by this -module, when used under :app:`Pyramid`, should be imported from the -:mod:`pyramid.httpexceptions` module. This import location contains -subclasses and replacements that mirror those in the original ``webob.exc``. +:mod:`pyramid.httpexceptions` contains classes for each kind of error +response. These include boring, but appropriate error bodies. The +exceptions exposed by this module, when used under :app:`Pyramid`, should be +imported from the :mod:`pyramid.httpexceptions` module. This import location +contains subclasses and replacements that mirror those in the ``webob.exc`` +module. Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the reason for the error. For instance, -- cgit v1.2.3 From 1a6fc7062f803b9f15b7677db9a9257a4f00bfcb Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 14 Jun 2011 02:36:07 -0400 Subject: - Added new add_response_adapter method to Configurator. - Fix Configurator docstring wrt exception responses. - Speed up registry.queryAdapterOrSelf --- docs/narr/hooks.rst | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 0db8ce5e0..8e5b93ed4 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -532,7 +532,7 @@ Changing How Pyramid Treats View Responses It is possible to control how Pyramid treats the result of calling a view callable on a per-type basis by using a hook involving -:class:`pyramid.interfaces.IResponse`. +:method:`pyramid.config.Configurator.add_response_adapter`. .. note:: This feature is new as of Pyramid 1.1. @@ -559,7 +559,6 @@ Response: .. code-block:: python :linenos: - from pyramid.interfaces import IResponse from pyramid.response import Response def string_response_adapter(s): @@ -568,8 +567,7 @@ Response: # config is an instance of pyramid.config.Configurator - config.registry.registerAdapter(string_response_adapter, (str,), - IResponse) + config.add_response_adapter(string_response_adapter, str) Likewise, if you want to be able to return a simplified kind of response object from view callables, you can use the IResponse hook to register an @@ -578,7 +576,6 @@ adapter to the more complex IResponse interface: .. code-block:: python :linenos: - from pyramid.interfaces import IResponse from pyramid.response import Response class SimpleResponse(object): @@ -591,14 +588,12 @@ adapter to the more complex IResponse interface: # config is an instance of pyramid.config.Configurator - config.registry.registerAdapter(simple_response_adapter, - (SimpleResponse,), - IResponse) + config.add_response_adapter(simple_response_adapter, SimpleResponse) If you want to implement your own Response object instead of using the :class:`pyramid.response.Response` object in any capacity at all, you'll have to make sure the object implements every attribute and method outlined in -:class:`pyramid.interfaces.IResponse` *and* you'll have to ensure that it's +:class:`pyramid.interfaces.IResponse` and you'll have to ensure that it's marked up with ``zope.interface.implements(IResponse)``: from pyramid.interfaces import IResponse -- cgit v1.2.3 From 4fd3e66d5ae48acf53534a21ebf900e74f714541 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Jun 2011 23:09:53 -0400 Subject: fix rendering --- 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 8426f11fd..e5b85dfbf 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -532,7 +532,7 @@ Changing How Pyramid Treats View Responses It is possible to control how Pyramid treats the result of calling a view callable on a per-type basis by using a hook involving -:method:`pyramid.config.Configurator.add_response_adapter`. +:meth:`pyramid.config.Configurator.add_response_adapter`. .. note:: This feature is new as of Pyramid 1.1. -- cgit v1.2.3 From d69ae60b9a195c7cb72122b59335ba886bfffe50 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 20 Jun 2011 00:37:59 -0400 Subject: - Register the default exception view for context of webob.exc.WSGIHTTPException (convenience). - Use ``exc.message`` in docs rather than ``exc.args[0]`` now that we control this. --- docs/narr/hooks.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index e5b85dfbf..1c8a64fd7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -59,7 +59,7 @@ Here's some sample code that implements a minimal NotFound view callable: :term:`request`. The ``exception`` attribute of the request will be an instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the not found view to be called. The value of - ``request.exception.args[0]`` will be a value explaining why the not found + ``request.exception.message`` will be a value explaining why the not found error was raised. This message will be different when the ``debug_notfound`` environment setting is true than it is when it is false. @@ -125,8 +125,9 @@ Here's some sample code that implements a minimal forbidden view: :term:`request`. The ``exception`` attribute of the request will be an instance of the :exc:`~pyramid.httpexceptions.HTTPForbidden` exception that caused the forbidden view to be called. The value of - ``request.exception.args[0]`` will be a value explaining why the forbidden - was raised. This message will be different when the + ``request.exception.message`` will be a value explaining why the forbidden + was raised and ``request.exception.result`` will be extended information + about the forbidden exception. These messages will be different when the ``debug_authorization`` environment setting is true than it is when it is false. -- cgit v1.2.3 From f8f08bac0ea9edcac40fae2b3ad56e6a1ac7f47f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 20 Jun 2011 00:57:30 -0400 Subject: responsecode -> exception_response --- docs/narr/views.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index e3d0a37e5..cbd8fcfb7 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -300,27 +300,30 @@ An HTTP exception, instead of being raised, can alternately be *returned* return HTTPUnauthorized() A shortcut for creating an HTTP exception is the -:func:`pyramid.httpexceptions.responsecode` function. This function accepts -an HTTP status code and returns the corresponding HTTP exception. For -example, instead of importing and constructing a +:func:`pyramid.httpexceptions.exception_response` function. This function +accepts an HTTP status code and returns the corresponding HTTP exception. +For example, instead of importing and constructing a :class:`~pyramid.httpexceptions.HTTPUnauthorized` response object, you can -use the :func:`~pyramid.httpexceptions.responsecode` function to construct -and return the same object. +use the :func:`~pyramid.httpexceptions.exception_response` function to +construct and return the same object. .. code-block:: python :linenos: - from pyramid.httpexceptions import responsecode + from pyramid.httpexceptions import exception_response def aview(request): - raise responsecode(401) + raise exception_response(401) This is the case because ``401`` is the HTTP status code for "HTTP -Unauthorized". Therefore, ``raise responsecode(401)`` is functionally +Unauthorized". Therefore, ``raise exception_response(401)`` is functionally equivalent to ``raise HTTPUnauthorized()``. Documentation which maps each HTTP response code to its purpose and its associated HTTP exception object is provided within :mod:`pyramid.httpexceptions`. +.. note:: The :func:`~pyramid.httpexceptions.exception_response` function is + new as of Pyramid 1.1. + How Pyramid Uses HTTP Exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 8bd6cf291b91977f22d8e153328cc13d38d00ff2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 26 Jun 2011 03:46:47 -0400 Subject: - Added ``mako.preprocessor`` config file parameter; allows for a Mako preprocessor to be specified as a Python callable or Python dotted name. See https://github.com/Pylons/pyramid/pull/183 for rationale. Closes #183. --- docs/narr/environment.rst | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 3b938c09c..a57b316e1 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -227,11 +227,11 @@ should be changed accordingly. Mako Error Handler ++++++++++++++++++ -Python callable which is called whenever Mako compile or runtime exceptions -occur. The callable is passed the current context as well as the exception. If -the callable returns True, the exception is considered to be handled, else it -is re-raised after the function completes. Is used to provide custom -error-rendering functions. +A callable (or a :term:`dotted Python name` which names a callable) which is +called whenever Mako compile or runtime exceptions occur. The callable is +passed the current context as well as the exception. If the callable returns +True, the exception is considered to be handled, else it is re-raised after +the function completes. Is used to provide custom error-rendering functions. +-----------------------------+ | Config File Setting Name | @@ -290,6 +290,25 @@ default, this is ``false``. | | +-----------------------------+ +Mako Preprocessor ++++++++++++++++++ + +A callable (or a :term:`dotted Python name` which names a callable) which is +called to preprocess the source before the template is called. The callable +will be passed the full template source before it is parsed. The return +result of the callable will be used as the template source code. + +.. note:: This feature is new in Pyramid 1.1. + ++-----------------------------+ +| Config File Setting Name | ++=============================+ +| ``mako.preprocessor`` | +| | +| | +| | ++-----------------------------+ + Examples -------- -- cgit v1.2.3 From c1f3d0fd89eb7f62a7de365ca5c0ef5600ffd900 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 1 Jul 2011 00:59:11 -0400 Subject: Add JSONP renderer --- docs/narr/renderers.rst | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 18cc8e539..f329a7af9 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -228,6 +228,74 @@ Views which use the JSON renderer can vary non-body response attributes by using the api of the ``request.response`` attribute. See :ref:`request_response_attr`. +.. _jsonp_renderer: + +JSONP Renderer +-------------- + +.. note:: This feature is new in Pyramid 1.1. + +:class:`pyramid.renderers.JSONP` is a `JSONP +`_ renderer factory helper which +implements a hybrid json/jsonp renderer. JSONP is useful for making +cross-domain AJAX requests. + +Unlike other renderers, a JSONP renderer needs to be configured at startup +time "by hand". Configure a JSONP renderer using the +:meth:`pyramid.config.Configurator.add_renderer` method: + +.. code-block:: python + + from pyramid.config import Configurator + + config = Configurator() + config.add_renderer('jsonp', JSONP(param_name='callback')) + +Once this renderer is registered via +:meth:`~pyramid.config.Configurator.add_renderer` as above, you can use +``jsonp`` as the ``renderer=`` parameter to ``@view_config`` or +:meth:`pyramid.config.Configurator.add_view``: + +.. code-block:: python + + from pyramid.view import view_config + + @view_config(renderer='jsonp') + def myview(request): + return {'greeting':'Hello world'} + +When a view is called that uses a JSONP renderer: + +- If there is a parameter in the request's HTTP query string (aka + ``request.GET``) that matches the ``param_name`` of the registered JSONP + renderer (by default, ``callback``), the renderer will return a JSONP + response. + +- If there is no callback parameter in the request's query string, the + renderer will return a 'plain' JSON response. + +Javscript library AJAX functionality will help you make JSONP requests. +For example, JQuery has a `getJSON function +`_, and has equivalent (but more +complicated) functionality in its `ajax function +`_. + +For example (Javascript): + +.. code-block:: javascript + + var api_url = 'http://api.geonames.org/timezoneJSON' + + '?lat=38.301733840000004' + + '&lng=-77.45869621' + + '&username=fred' + + '&callback=?'; + jqhxr = $.getJSON(api_url); + +The string ``callback=?`` above in the the ``url`` param to the JQuery +``getAjax`` function indicates to jQuery that the query should be made as +a JSONP request; the ``callback`` parameter will be automatically filled +in for you and used. + .. index:: pair: renderer; chameleon -- cgit v1.2.3 From b7f33b5fdd062e007723d0eb60001442f35c0bf7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 1 Jul 2011 01:24:39 -0400 Subject: - Deprecated the ``set_renderer_globals_factory`` method of the Configurator and the ``renderer_globals`` Configurator constructor parameter. --- docs/narr/hooks.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 1c8a64fd7..56c566a4c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -183,6 +183,10 @@ already constructed a :term:`configurator` it can also be registered via the Adding Renderer Globals ----------------------- +.. warning:: this feature is deprecated as of Pyramid 1.1. A non-deprecated + mechanism which allows event subscribers to add renderer global values + is documented in :ref:`beforerender_event`. + Whenever :app:`Pyramid` handles a request to perform a rendering (after a view with a ``renderer=`` configuration attribute is invoked, or when any of the methods beginning with ``render`` within the :mod:`pyramid.renderers` @@ -227,9 +231,6 @@ already constructed a :term:`configurator` it can also be registered via the config = Configurator() config.set_renderer_globals_factory(renderer_globals_factory) -Another mechanism which allows event subscribers to add renderer global values -exists in :ref:`beforerender_event`. - .. index:: single: before render event -- cgit v1.2.3 From ac7a9aac93392ca035a983b138df4848b6a333b6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 2 Jul 2011 17:00:09 -0400 Subject: reorder --- docs/narr/hooks.rst | 86 +++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 56c566a4c..94701c9f9 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -175,13 +175,55 @@ already constructed a :term:`configurator` it can also be registered via the config = Configurator() config.set_request_factory(MyRequest) +.. index:: + single: before render event + single: adding renderer globals + +.. _beforerender_event: + +Using The Before Render Event +----------------------------- + +Subscribers to the :class:`pyramid.events.BeforeRender` event may introspect +and modify the set of :term:`renderer globals` before they are passed to a +:term:`renderer`. This event object iself has a dictionary-like interface +that can be used for this purpose. For example: + +.. code-block:: python + :linenos: + + from pyramid.events import subscriber + from pyramid.events import BeforeRender + + @subscriber(BeforeRender) + def add_global(event): + event['mykey'] = 'foo' + +An object of this type is sent as an event just before a :term:`renderer` is +invoked (but *after* the application-level renderer globals factory added via +:class:`~pyramid.config.Configurator.set_renderer_globals_factory`, if any, +has injected its own keys into the renderer globals dictionary). + +If a subscriber attempts to add a key that already exist in the renderer +globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced +because event subscribers do not possess any relative ordering. The set of +keys added to the renderer globals dictionary by all +:class:`pyramid.events.BeforeRender` subscribers and renderer globals +factories must be unique. + +See the API documentation for the :class:`~pyramid.events.BeforeRender` event +interface at :class:`pyramid.interfaces.IBeforeRender`. + +Another (deprecated) mechanism which allows event subscribers more control +when adding renderer global values exists in :ref:`adding_renderer_globals`. + .. index:: single: renderer globals .. _adding_renderer_globals: -Adding Renderer Globals ------------------------ +Adding Renderer Globals (Deprecated) +------------------------------------ .. warning:: this feature is deprecated as of Pyramid 1.1. A non-deprecated mechanism which allows event subscribers to add renderer global values @@ -231,46 +273,6 @@ already constructed a :term:`configurator` it can also be registered via the config = Configurator() config.set_renderer_globals_factory(renderer_globals_factory) -.. index:: - single: before render event - -.. _beforerender_event: - -Using The Before Render Event ------------------------------ - -Subscribers to the :class:`pyramid.events.BeforeRender` event may introspect -and modify the set of :term:`renderer globals` before they are passed to a -:term:`renderer`. This event object iself has a dictionary-like interface -that can be used for this purpose. For example: - -.. code-block:: python - :linenos: - - from pyramid.events import subscriber - from pyramid.events import BeforeRender - - @subscriber(BeforeRender) - def add_global(event): - event['mykey'] = 'foo' - -An object of this type is sent as an event just before a :term:`renderer` is -invoked (but *after* the application-level renderer globals factory added via -:class:`~pyramid.config.Configurator.set_renderer_globals_factory`, if any, -has injected its own keys into the renderer globals dictionary). - -If a subscriber attempts to add a key that already exist in the renderer -globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced -because event subscribers do not possess any relative ordering. The set of -keys added to the renderer globals dictionary by all -:class:`pyramid.events.BeforeRender` subscribers and renderer globals -factories must be unique. - -See the API documentation for the :class:`~pyramid.events.BeforeRender` event -interface at :class:`pyramid.interfaces.IBeforeRender`. - -Another mechanism which allows event subscribers more control when adding -renderer global values exists in :ref:`adding_renderer_globals`. .. index:: single: response callback -- cgit v1.2.3 From 0fa1993d2abe87e197374f6abd3e45e62afb8a19 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 4 Jul 2011 01:07:45 -0400 Subject: - A new value ``http_cache`` can be used as a view configuration parameter. When you supply an ``http_cache`` value to a view configuration, the ``Expires`` and ``Cache-Control`` headers of a response generated by the associated view callable are modified. The value for ``http_cache`` may be one of the following: - A nonzero integer. If it's a nonzero integer, it's treated as a number of seconds. This number of seconds will be used to compute the ``Expires`` header and the ``Cache-Control: max-age`` parameter of responses to requests which call this view. For example: ``http_cache=3600`` instructs the requesting browser to 'cache this response for an hour, please'. - A ``datetime.timedelta`` instance. If it's a ``datetime.timedelta`` instance, it will be converted into a number of seconds, and that number of seconds will be used to compute the ``Expires`` header and the ``Cache-Control: max-age`` parameter of responses to requests which call this view. For example: ``http_cache=datetime.timedelta(days=1)`` instructs the requesting browser to 'cache this response for a day, please'. - Zero (``0``). If the value is zero, the ``Cache-Control`` and ``Expires`` headers present in all responses from this view will be composed such that client browser cache (and any intermediate caches) are instructed to never cache the response. - A two-tuple. If it's a two tuple (e.g. ``http_cache=(1, {'public':True})``), the first value in the tuple may be a nonzero integer or a ``datetime.timedelta`` instance; in either case this value will be used as the number of seconds to cache the response. The second value in the tuple must be a dictionary. The values present in the dictionary will be used as input to the ``Cache-Control`` response header. For example: ``http_cache=(3600, {'public':True})`` means 'cache for an hour, and add ``public`` to the Cache-Control header of the response'. All keys and values supported by the ``webob.cachecontrol.CacheControl`` interface may be added to the dictionary. Supplying ``{'public':True}`` is equivalent to calling ``response.cache_control.public = True``. Providing a non-tuple value as ``http_cache`` is equivalent to calling ``response.cache_expires(value)`` within your view's body. Providing a two-tuple value as ``http_cache`` is equivalent to calling ``response.cache_expires(value[0], **value[1])`` within your view's body. If you wish to avoid influencing, the ``Expires`` header, and instead wish to only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` with the first element of ``None``, e.g.: ``(None, {'public':True})``. --- docs/narr/viewconfig.rst | 54 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 5640800a2..ec42446ff 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -160,6 +160,55 @@ Non-Predicate Arguments view callable itself returns a :term:`response` (see :ref:`the_response`), the specified renderer implementation is never called. +``http_cache`` + When you supply an ``http_cache`` value to a view configuration, the + ``Expires`` and ``Cache-Control`` headers of a response generated by the + associated view callable are modified. The value for ``http_cache`` may be + one of the following: + + - A nonzero integer. If it's a nonzero integer, it's treated as a number + of seconds. This number of seconds will be used to compute the + ``Expires`` header and the ``Cache-Control: max-age`` parameter of + responses to requests which call this view. For example: + ``http_cache=3600`` instructs the requesting browser to 'cache this + response for an hour, please'. + + - A ``datetime.timedelta`` instance. If it's a ``datetime.timedelta`` + instance, it will be converted into a number of seconds, and that number + of seconds will be used to compute the ``Expires`` header and the + ``Cache-Control: max-age`` parameter of responses to requests which call + this view. For example: ``http_cache=datetime.timedelta(days=1)`` + instructs the requesting browser to 'cache this response for a day, + please'. + + - Zero (``0``). If the value is zero, the ``Cache-Control`` and + ``Expires`` headers present in all responses from this view will be + composed such that client browser cache (and any intermediate caches) are + instructed to never cache the response. + + - A two-tuple. If it's a two tuple (e.g. ``http_cache=(1, + {'public':True})``), the first value in the tuple may be a nonzero + integer or a ``datetime.timedelta`` instance; in either case this value + will be used as the number of seconds to cache the response. The second + value in the tuple must be a dictionary. The values present in the + dictionary will be used as input to the ``Cache-Control`` response + header. For example: ``http_cache=(3600, {'public':True})`` means 'cache + for an hour, and add ``public`` to the Cache-Control header of the + response'. All keys and values supported by the + ``webob.cachecontrol.CacheControl`` interface may be added to the + dictionary. Supplying ``{'public':True}`` is equivalent to calling + ``response.cache_control.public = True``. + + Providing a non-tuple value as ``http_cache`` is equivalent to calling + ``response.cache_expires(value)`` within your view's body. + + Providing a two-tuple value as ``http_cache`` is equivalent to calling + ``response.cache_expires(value[0], **value[1])`` within your view's body. + + If you wish to avoid influencing, the ``Expires`` header, and instead wish + to only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` + with the first element of ``None``, e.g.: ``(None, {'public':True})``. + ``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`` @@ -400,8 +449,9 @@ configuration stanza: .. code-block:: python :linenos: - config.add_view('mypackage.views.my_view', name='my_view', request_method='POST', - context=MyResource, permission='read') + config.add_view('mypackage.views.my_view', name='my_view', + request_method='POST', context=MyResource, + permission='read') All arguments to ``view_config`` may be omitted. For example: -- cgit v1.2.3 From e8561f919548e2fe17f82d98e2a13e1e4e85bf40 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 7 Jul 2011 01:57:18 -0500 Subject: Added/updated documentation for the new interactive shell. --- docs/narr/project.rst | 96 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 33 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 631412f42..be673c370 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -258,8 +258,9 @@ develop``, you can use an interactive Python shell to examine your :app:`Pyramid` project's :term:`resource` and :term:`view` objects from a Python prompt. To do so, use your virtualenv's ``paster pshell`` command. -The first argument to ``pshell`` is the path to your application's ``.ini`` -file. The second is the ``app`` section name inside the ``.ini`` file which +The argument to ``pshell`` follows the format ``config_file#section_name`` +where ``config_file`` is the path to your application's ``.ini`` file and +``section_name`` is the ``app`` section name inside the ``.ini`` file which points to *your application* as opposed to any other section within the ``.ini`` file. For example, if your application ``.ini`` file might have a ``[app:MyProject]`` section that looks like so: @@ -280,16 +281,21 @@ name ``MyProject`` as a section name: .. code-block:: text - [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini MyProject + [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini#MyProject Python 2.4.5 (#1, Aug 29 2008, 12:27:37) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin - Type "help" for more information. "root" is the Pyramid app root object, - "registry" is the Pyramid registry object. + + Default Variables: + app The WSGI Application + root The root of the default resource tree. + registry The Pyramid registry object. + settings The Pyramid settings object. + >>> root >>> registry - >>> registry.settings['debug_notfound'] + >>> settings['debug_notfound'] False >>> from myproject.views import my_view >>> from pyramid.request import Request @@ -297,31 +303,16 @@ name ``MyProject`` as a section name: >>> my_view(r) {'project': 'myproject'} -Two names are made available to the pshell user as globals: ``root`` and -``registry``. ``root`` is the the object returned by the default :term:`root -factory` in your application. ``registry`` is the :term:`application -registry` object associated with your project's application (often accessed -within view code as ``request.registry``). - -If you have `IPython `_ installed in -the interpreter you use to invoke the ``paster`` command, the ``pshell`` -command will use an IPython interactive shell instead of a standard Python -interpreter shell. If you don't want this to happen, even if you have -IPython installed, you can pass the ``--disable-ipython`` flag to the -``pshell`` command to use a standard Python interpreter shell -unconditionally. - -.. code-block:: text - - [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ - development.ini MyProject +The WSGI application that is loaded will be available in the shell as the +``app`` global. Also, if the application that is loaded is the +:app:`Pyramid` app with no surrounding middleware, the ``root`` object +returned by the default :term:`root factory`, ``registry``, and ``settings`` +will be available. -You should always use a section name argument that refers to the actual -``app`` section within the Paste configuration file that points at your -:app:`Pyramid` application *without any middleware wrapping*. In particular, -a section name is inappropriate as the second argument to ``pshell`` if the -configuration section it names is a ``pipeline`` rather than an ``app``. For -example, if you have the following ``.ini`` file content: +The interactive shell will not be able to load some of the globals like +``root``, ``registry`` and ``settings`` if the section name specified when +loading ``pshell`` is not referencing your :app:`Pyramid` application directly. +For example, if you have the following ``.ini`` file content: .. code-block:: ini :linenos: @@ -341,12 +332,51 @@ example, if you have the following ``.ini`` file content: Use ``MyProject`` instead of ``main`` as the section name argument to ``pshell`` against the above ``.ini`` file (e.g. ``paster pshell -development.ini MyProject``). If you use ``main`` instead, an error will -occur. Use the most specific reference to your application within the -``.ini`` file possible as the section name argument. +development.ini#MyProject``). Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). +Extending the Shell +~~~~~~~~~~~~~~~~~~~ + +It is sometimes convenient when using the interactive shell often to have +some variables significant to your application already loaded as globals +when you start the ``pshell``. To facilitate this, ``pshell`` will look +for a special ``[pshell]`` section in your INI file and expose the subsequent +key/value pairs to the shell. + +For example, you want to expose your model to the shell, along with the +database session so that you can mutate the model on an actual database. +Here, we'll assume your model is stored in the ``myapp.models`` package. + +.. code-block:: ini + :linenos: + + [pshell] + m = myapp.models + session = myapp.models.DBSession + t = transaction + +When this INI file is loaded, the extra variables ``m``, ``session`` and +``t`` will be available for use immediately. This happens regardless of +whether the ``registry`` and other special variables are loaded. + +IPython +~~~~~~~ + +If you have `IPython `_ installed in +the interpreter you use to invoke the ``paster`` command, the ``pshell`` +command will use an IPython interactive shell instead of a standard Python +interpreter shell. If you don't want this to happen, even if you have +IPython installed, you can pass the ``--disable-ipython`` flag to the +``pshell`` command to use a standard Python interpreter shell +unconditionally. + +.. code-block:: text + + [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ + development.ini#MyProject + .. index:: single: running an application single: paster serve -- cgit v1.2.3 From 9e7162eb7f584e8afdbc2f04846d0d7e1fcf676c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 7 Jul 2011 02:02:48 -0500 Subject: Updated proutes and pviews docs. --- docs/narr/urldispatch.rst | 9 +++++---- docs/narr/viewconfig.rst | 11 ++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f94ed3ba8..51a840b8d 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1084,16 +1084,17 @@ Displaying All Application Routes You can use the ``paster proutes`` command in a terminal window to print a summary of routes related to your application. Much like the ``paster pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` -command accepts two arguments. The first argument to ``proutes`` is the path -to your application's ``.ini`` file. The second is the ``app`` section name -inside the ``.ini`` file which points to your application. +command accepts one argument with the format ``config_file#section_name``. +The ``config_file`` is the path to your application's ``.ini`` file, +and ``section_name`` is the ``app`` section name inside the ``.ini`` file +which points to your application. For example: .. code-block:: text :linenos: - [chrism@thinko MyProject]$ ../bin/paster proutes development.ini MyProject + [chrism@thinko MyProject]$ ../bin/paster proutes development.ini#MyProject Name Pattern View ---- ------- ---- home / diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index ec42446ff..67ac39259 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -795,10 +795,11 @@ 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 ``paster pviews`` command in a terminal window to print a summary of matching routes and views for a given URL in your -application. The ``paster pviews`` command accepts three arguments. The -first argument to ``pviews`` is the path to your application's ``.ini`` file. -The second is the ``app`` section name inside the ``.ini`` file which points -to your application. The third is the URL to test for matching views. +application. The ``paster pviews`` command accepts two arguments. The +first argument to ``pviews`` is the path to your application's ``.ini`` file +and section name inside the ``.ini`` file which points to your application. +This should be of the format ``config_file#section_name``. The second argument +is the URL to test for matching views. Here is an example for a simple view configuration using :term:`traversal`: @@ -829,7 +830,7 @@ A more complex configuration might generate something like this: .. code-block:: text :linenos: - $ ../bin/paster pviews development.ini shootout /about + $ ../bin/paster pviews development.ini#shootout /about URL = /about -- cgit v1.2.3 From 35259d7b1f029391a839c96f7750d6b3433ad2c9 Mon Sep 17 00:00:00 2001 From: ejo Date: Sat, 9 Jul 2011 13:29:38 -0700 Subject: Old sentence was grammatically incorrect, literally meant that the URL or button in question did not know it was redirecting the user. It is the user who does not know, so "unwittingly" is replaced with "secretly"; "surreptitiously" would be another accurate alternative. An alternative sentence construction that maintains the word "unwittingly" would be, e.g., "...might click on a URL or button on another website and be unwittingly redirected to your application to perform some command that requires elevated privileges." --- docs/narr/sessions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 97e3ebc55..365ee395b 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -288,7 +288,7 @@ Preventing Cross-Site Request Forgery Attacks `Cross-site request forgery `_ attacks are a phenomenon whereby a user with an identity on your website might click on a -URL or button on another website which unwittingly redirects the user to your +URL or button on another website which secretly redirects the user to your application to perform some command that requires elevated privileges. You can avoid most of these attacks by making sure that the correct *CSRF -- cgit v1.2.3 From 6a0602b3ce4d2a6de9dca25d8e0d390796a79267 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 9 Jul 2011 21:12:06 -0400 Subject: request.json -> request.json_body; add some docs for json_body --- docs/narr/webob.rst | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 0ff8e1de7..373ae5896 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -78,6 +78,10 @@ object: ``PUT``. You can also get ``req.body_file`` for a file-like object. +``req.json_body`` + The JSON-decoded contents of the body of the request. See + :ref:`request_json_body`. + ``req.cookies``: A simple dictionary of all the cookies. @@ -239,6 +243,57 @@ tuples; all the keys are ordered, and all the values are ordered. API documentation for a multidict exists as :class:`pyramid.interfaces.IMultiDict`. +.. _request_json_body: + +Dealing With A JSON-Encoded Request Body +++++++++++++++++++++++++++++++++++++++++ + +.. note:: this feature is new as of Pyramid 1.1. + +:attr:`pyramid.request.Request.json_body` is a property that returns a +:term:`JSON` -decoded representation of the request body. If the request +does not have a body, or the body is not a properly JSON-encoded value, an +exception will be raised when this attribute is accessed. + +This attribute is useful when you invoke a Pyramid view callable via +e.g. jQuery's ``$.post`` or ``$.ajax`` functions, which have the potential to +send a JSON-encoded body or parameters. + +Using ``request.json_body`` is equivalent to: + +.. code-block:: python + + from json import loads + loads(request.body, encoding=request.charset) + +Here's how to construct an AJAX request in Javascript using :term:`jQuery` +that allows you to use the ``request.json_body`` attribute when the request +is sent to a Pyramid application: + +.. code-block:: javascript + + jQuery.ajax({type:'POST', + url: 'http://localhost:6543/', // the pyramid server + data: JSON.stringify({'a':1}), + contentType: 'application/json; charset=utf-8', + dataType: 'json'}); + +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 + + @view_config(renderer='json') + def aview(request): + print request.json_body + return {'result':'OK'} + +For the above view, printed to the console will be: + +.. code-block:: python + + {u'a': 1} + More Details ++++++++++++ -- cgit v1.2.3 From e3349693c533c17fb9b6a770a8360b64ec337c68 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 9 Jul 2011 21:24:14 -0400 Subject: make less confusing --- docs/narr/webob.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 373ae5896..beb319084 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -256,8 +256,8 @@ does not have a body, or the body is not a properly JSON-encoded value, an exception will be raised when this attribute is accessed. This attribute is useful when you invoke a Pyramid view callable via -e.g. jQuery's ``$.post`` or ``$.ajax`` functions, which have the potential to -send a JSON-encoded body or parameters. +e.g. jQuery's ``$.ajax`` function, which has the potential to send a request +with a JSON-encoded body. Using ``request.json_body`` is equivalent to: @@ -275,18 +275,17 @@ is sent to a Pyramid application: jQuery.ajax({type:'POST', url: 'http://localhost:6543/', // the pyramid server data: JSON.stringify({'a':1}), - contentType: 'application/json; charset=utf-8', - dataType: 'json'}); + contentType: 'application/json; charset=utf-8'}); 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 - @view_config(renderer='json') + @view_config(renderer='string') def aview(request): print request.json_body - return {'result':'OK'} + return 'OK' For the above view, printed to the console will be: -- cgit v1.2.3 From 7565006cf1f3b929d9ea54256214f3a39385936a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 10 Jul 2011 00:30:30 -0400 Subject: add info to changes.txt and whatsnew about pshell changes; removed unused import and unwrap string --- docs/narr/project.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index be673c370..ab7023561 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -336,6 +336,8 @@ development.ini#MyProject``). Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). +.. _extending_pshell: + Extending the Shell ~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 546ae051d076de48496b721f13fd74c3f4c12a67 Mon Sep 17 00:00:00 2001 From: ejo Date: Sun, 10 Jul 2011 10:38:01 -0700 Subject: Adding 'I' to example custom AuthenticationPolicy; it's an interface. --- docs/narr/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index c7a07b857..322e905f6 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -562,7 +562,7 @@ that implements the following interface: .. code-block:: python :linenos: - class AuthenticationPolicy(object): + class IAuthenticationPolicy(object): """ An object representing a Pyramid authentication policy. """ def authenticated_userid(self, request): -- cgit v1.2.3 From e005c27ae54f12d5f9579451c1c894a534eb7d48 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 10 Jul 2011 22:06:51 -0500 Subject: Modified docs to reference webob's new website. --- docs/narr/views.rst | 2 +- docs/narr/webob.rst | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index cbd8fcfb7..ca5aac508 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -483,7 +483,7 @@ various other clients. In :app:`Pyramid`, form submission handling logic is always part of a :term:`view`. For a general overview of how to handle form submission data using the :term:`WebOb` API, see :ref:`webob_chapter` and `"Query and POST variables" within the WebOb documentation -`_. +`_. :app:`Pyramid` defers to WebOb for its request and response implementations, and handling form submission data is a property of the request implementation. Understanding WebOb's request API is the key to diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index beb319084..0d928e532 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -22,9 +22,9 @@ of :class:`webob.Request`. The :term:`response` returned from a WebOb is a project separate from :app:`Pyramid` with a separate set of authors and a fully separate `set of documentation -`_. Pyramid adds some functionality to the -standard WebOb request, which is documented in the :ref:`request_module` API -documentation. +`_. Pyramid adds some +functionality to the standard WebOb request, which is documented in the +:ref:`request_module` API documentation. WebOb provides objects for HTTP requests and responses. Specifically it does this by wrapping the `WSGI `_ request environment and @@ -35,7 +35,7 @@ requests and forming WSGI responses. WebOb is a nice way to represent "raw" WSGI requests and responses; however, we won't cover that use case in this document, as users of :app:`Pyramid` don't typically need to use the WSGI-related features of WebOb directly. The `reference documentation -`_ shows many examples of +`_ shows many examples of creating requests and using response objects in this manner, however. .. index:: @@ -300,8 +300,8 @@ More detail about the request object API is available in: - The :class:`pyramid.request.Request` API documentation. -- The `WebOb documentation `_. All - methods and attributes of a ``webob.Request`` documented within the +- The `WebOb documentation `_. + All methods and attributes of a ``webob.Request`` documented within the WebOb documentation will work with request objects created by :app:`Pyramid`. @@ -385,7 +385,7 @@ properties. These are parsed, so you can do things like ``response.last_modified = os.path.getmtime(filename)``. The details are available in the `extracted Response documentation -`_. +`_. .. index:: single: response (creating) @@ -444,5 +444,6 @@ More Details More details about the response object API are available in the :mod:`pyramid.response` documentation. More details about exception responses are in the :mod:`pyramid.httpexceptions` API documentation. The -`WebOb documentation `_ is also useful. +`WebOb documentation `_ is also +useful. -- cgit v1.2.3 From 71a5ae65dc74a7d4e07f0c74c911a449576237b5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 03:52:15 -0400 Subject: move alternate calling convention to chapter bottom; fix reference --- docs/narr/views.rst | 150 ++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 75 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index cbd8fcfb7..6207ae00a 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -134,80 +134,6 @@ related view callables. special kind of view class which provides more automation when your application uses :term:`URL dispatch` solely. -.. index:: - single: view calling convention - -.. _request_and_context_view_definitions: - -Alternate View Callable Argument/Calling Conventions ----------------------------------------------------- - -Usually, view callables are defined to accept only a single argument: -``request``. However, view callables may alternately be defined as classes, -functions, or any callable that accept *two* positional arguments: a -:term:`context` resource as the first argument and a :term:`request` as the -second argument. - -The :term:`context` and :term:`request` arguments passed to a view function -defined in this style can be defined as follows: - -context - - The :term:`resource` object found via tree :term:`traversal` or :term:`URL - dispatch`. - -request - A :app:`Pyramid` Request object representing the current WSGI request. - -The following types work as view callables in this style: - -#. Functions that accept two arguments: ``context``, and ``request``, - e.g.: - - .. code-block:: python - :linenos: - - from pyramid.response import Response - - def view(context, request): - return Response('OK') - -#. Classes that have an ``__init__`` method that accepts ``context, - request`` and a ``__call__`` method which accepts no arguments, e.g.: - - .. code-block:: python - :linenos: - - from pyramid.response import Response - - class view(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return Response('OK') - -#. Arbitrary callables that have a ``__call__`` method that accepts - ``context, request``, e.g.: - - .. code-block:: python - :linenos: - - from pyramid.response import Response - - class View(object): - def __call__(self, context, request): - return Response('OK') - view = View() # this is the view callable - -This style of calling convention is most useful for :term:`traversal` based -applications, where the context object is frequently used within the view -callable code itself. - -No matter which view calling convention is used, the view code always has -access to the context via ``request.context``. - .. index:: single: view response single: response @@ -234,7 +160,7 @@ implements the :term:`Response` interface is to return a inherit from :class:`pyramid.response.Response`. For example, an instance of the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response object because it inherits from :class:`~pyramid.response.Response`. For -examples, see :ref:`http_exceptions` and ref:`http_redirect`. +examples, see :ref:`http_exceptions` and :ref:`http_redirect`. You can also return objects from view callables that aren't instances of (or instances of classes which are subclasses of) @@ -591,3 +517,77 @@ using your own response object, you will need to ensure you do this yourself. configuration. The keys are still (byte) strings. +.. index:: + single: view calling convention + +.. _request_and_context_view_definitions: + +Alternate View Callable Argument/Calling Conventions +---------------------------------------------------- + +Usually, view callables are defined to accept only a single argument: +``request``. However, view callables may alternately be defined as classes, +functions, or any callable that accept *two* positional arguments: a +:term:`context` resource as the first argument and a :term:`request` as the +second argument. + +The :term:`context` and :term:`request` arguments passed to a view function +defined in this style can be defined as follows: + +context + + The :term:`resource` object found via tree :term:`traversal` or :term:`URL + dispatch`. + +request + A :app:`Pyramid` Request object representing the current WSGI request. + +The following types work as view callables in this style: + +#. Functions that accept two arguments: ``context``, and ``request``, + e.g.: + + .. code-block:: python + :linenos: + + from pyramid.response import Response + + def view(context, request): + return Response('OK') + +#. Classes that have an ``__init__`` method that accepts ``context, + request`` and a ``__call__`` method which accepts no arguments, e.g.: + + .. code-block:: python + :linenos: + + from pyramid.response import Response + + class view(object): + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return Response('OK') + +#. Arbitrary callables that have a ``__call__`` method that accepts + ``context, request``, e.g.: + + .. code-block:: python + :linenos: + + from pyramid.response import Response + + class View(object): + def __call__(self, context, request): + return Response('OK') + view = View() # this is the view callable + +This style of calling convention is most useful for :term:`traversal` based +applications, where the context object is frequently used within the view +callable code itself. + +No matter which view calling convention is used, the view code always has +access to the context via ``request.context``. + -- cgit v1.2.3 From f98cb5d2acd274df2507f822bdc269860e39a169 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 03:57:25 -0400 Subject: move mention of controllers to end --- docs/narr/views.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 2a0aae0ed..6acb1d28d 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -129,11 +129,6 @@ statements with different ``attr`` values, each pointing at a different method of the class if you'd like the class to represent a collection of related view callables. -.. note:: A package named :term:`pyramid_handlers` (available from PyPI) - provides an analogue of :term:`Pylons` -style "controllers", which are a - special kind of view class which provides more automation when your - application uses :term:`URL dispatch` solely. - .. index:: single: view response single: response @@ -591,3 +586,11 @@ callable code itself. No matter which view calling convention is used, the view code always has access to the context via ``request.context``. +Pylons-1.0-Style "Controller" Dispatch +-------------------------------------- + +A package named :term:`pyramid_handlers` (available from PyPI) provides an +analogue of :term:`Pylons` -style "controllers", which are a special kind of +view class which provides more automation when your application uses +:term:`URL dispatch` solely. + -- cgit v1.2.3 From 026da8ec4711d3532e5e4d8265bf445d4a329245 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 04:13:38 -0400 Subject: earlier info referenced later info, fix --- docs/narr/viewconfig.rst | 54 +++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 67ac39259..f7509e9db 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -47,7 +47,7 @@ to be invoked. A view configuration statement is made about information present in the :term:`context` resource and the :term:`request`. -View configuration is performed in one of these ways: +View configuration is performed in one of two ways: - by running a :term:`scan` against application source code which has a :class:`pyramid.view.view_config` decorator attached to a Python object as @@ -56,17 +56,6 @@ View configuration is performed in one of these ways: - by using the :meth:`pyramid.config.Configurator.add_view` method as per :ref:`mapping_views_using_imperative_config_section`. -- By specifying a view within a :term:`route configuration`. View - configuration via a route configuration is performed by using the - :meth:`pyramid.config.Configurator.add_route` method, passing a ``view`` - argument specifying a view callable. This pattern of view configuration is - deprecated as of :app:`Pyramid` 1.1. - -.. note:: A package named ``pyramid_handlers`` (available from PyPI) provides - an analogue of :term:`Pylons` -style "controllers", which are a special - kind of view class which provides more automation when your application - uses :term:`URL dispatch` solely. - .. _view_configuration_parameters: View Configuration Parameters @@ -408,26 +397,25 @@ configured view. View Configuration Using the ``@view_config`` Decorator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -For better locality of reference, you may use the -:class:`pyramid.view.view_config` decorator to associate your view functions -with URLs instead of using imperative configuration for the same purpose. - .. warning:: Using this feature tends to slows down application startup slightly, as more work is performed at application startup to scan for view - declarations. + declarations. For maximum startup performance, use the view configuration + method described in :ref:`mapping_views_using_imperative_config_section` + instead. Usage of the ``view_config`` decorator is a form of :term:`declarative -configuration` in decorator form. :class:`~pyramid.view.view_config` can be -used to associate :term:`view configuration` information -- as done via the -equivalent imperative code -- with a function that acts as a :app:`Pyramid` -view callable. All arguments to the -:meth:`pyramid.config.Configurator.add_view` method (save for the ``view`` -argument) are available in decorator form and mean precisely the same thing. +configuration`. The :class:`~pyramid.view.view_config` decorator can be used +to associate :term:`view configuration` information with a function that acts +as a :app:`Pyramid` view callable. All arguments to the +:class:`~pyramid.view.view_config` decorator mean precisely the same thing as +they would if they were passed as arguments to the +:meth:`pyramid.config.Configurator.add_view` method save for the ``view`` +argument. -An example of the :class:`~pyramid.view.view_config` decorator might reside in -a :app:`Pyramid` application module ``views.py``: +Here's an example of the :class:`~pyramid.view.view_config` decorator that +lives within a :app:`Pyramid` application module ``views.py``: .. ignore-next-block .. code-block:: python @@ -618,9 +606,10 @@ View Registration Using :meth:`~pyramid.config.Configurator.add_view` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`pyramid.config.Configurator.add_view` method within -:ref:`configuration_module` is used to configure a view imperatively. The -arguments to this method are very similar to the arguments that you provide -to the ``@view_config`` decorator. For example: +:ref:`configuration_module` is used to configure a view "imperatively" +(without a :class:`~pyramid.view.view_config` decorator. The arguments to +this method are very similar to the arguments that you provide to the +:class:`~pyramid.view.view_config` decorator. For example: .. code-block:: python :linenos: @@ -636,8 +625,13 @@ to the ``@view_config`` decorator. For example: The first argument, ``view``, is required. It must either be a Python object which is the view itself or a :term:`dotted Python name` to such an object. -All other arguments are optional. See -:meth:`pyramid.config.Configurator.add_view` for more information. +In the above example, ``view`` is the ``hello_world`` function. All other +arguments are optional. See :meth:`pyramid.config.Configurator.add_view` for +more information. + +When you use only :meth:`~pyramid.config.Configurator.add_view` to add view +configurations, you don't need to issue a :term:`scan` in order for the view +configuration to take effect. .. index:: single: resource interfaces -- cgit v1.2.3 From e81ad8ca6355d85462508f03496fe7b088986601 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 04:26:26 -0400 Subject: simplify wording --- docs/narr/viewconfig.rst | 91 ++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 50 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index f7509e9db..326d97506 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -2,38 +2,23 @@ .. _view_configuration: +.. _view_lookup: + View Configuration ================== .. index:: single: view lookup -:term:`View configuration` controls how :term:`view lookup` operates in -your application. In earlier chapters, you have been exposed to a few -simple view configuration declarations without much explanation. In this -chapter we will explore the subject in detail. - -.. _view_lookup: - -View Lookup and Invocation --------------------------- - :term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding -an invoking a :term:`view callable`. The view lookup subsystem is passed a -:term:`context` and a :term:`request` object. - -:term:`View configuration` information stored within in the -:term:`application registry` is compared against the context and request by -the view lookup subsystem in order to find the "best" view callable for the -set of circumstances implied by the context and request. - -:term:`View predicate` attributes are an important part of view -configuration that enables the :term:`View lookup` subsystem to find and -invoke the appropriate view. Predicate attributes can be thought of -like "narrowers". In general, the greater number of predicate -attributes possessed by a view's configuration, the more specific the -circumstances need to be before the registered view callable will be -invoked. +an invoking a :term:`view callable`. :term:`View configuration` controls how +:term:`view lookup` operates in your application. During any given request, +view configuration information is compared against request data by the view +lookup subsystem in order to find the "best" view callable for that request. + +In earlier chapters, you have been exposed to a few simple view configuration +declarations without much explanation. In this chapter we will explore the +subject in detail. Mapping a Resource or URL Pattern to a View Callable ---------------------------------------------------- @@ -68,12 +53,15 @@ arguments. View predicate arguments used during view configuration are used to narrow the set of circumstances in which :term:`view lookup` will find a particular view callable. -In general, the fewer number of predicates which are supplied to a -particular view configuration, the more likely it is that the associated -view callable will be invoked. The greater the number supplied, the -less likely. A view with five predicates will always be found and -evaluated before a view with two, for example. All predicates must -match for the associated view to be called. +:term:`View predicate` attributes are an important part of view configuration +that enables the :term:`view lookup` subsystem to find and invoke the +appropriate view. The greater number of predicate attributes possessed by a +view's configuration, the more specific the circumstances need to be before +the registered view callable will be invoked. The fewer number of predicates +which are supplied to a particular view configuration, the more likely it is +that the associated view callable will be invoked. A view with five +predicates will always be found and evaluated before a view with two, for +example. All predicates must match for the associated view to be called. This does not mean however, that :app:`Pyramid` "stops looking" when it finds a view registration with predicates that don't match. If one set @@ -88,8 +76,8 @@ the request, :app:`Pyramid` will return an error to the user's browser, representing a "not found" (404) page. See :ref:`changing_the_notfound_view` for more information about changing the default notfound view. -Some view configuration arguments are non-predicate arguments. These tend to -modify the response of the view callable or prevent the view callable from +Other view configuration arguments are non-predicate arguments. These tend +to modify the response of the view callable or prevent the view callable from being invoked due to an authorization policy. The presence of non-predicate arguments in a view configuration does not narrow the circumstances in which the view callable will be invoked. @@ -394,25 +382,20 @@ configured view. .. _mapping_views_using_a_decorator_section: -View Configuration Using the ``@view_config`` Decorator -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Adding View Configuration Using the ``@view_config`` Decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. warning:: Using this feature tends to slows down application startup slightly, as more work is performed at application startup to scan for view - declarations. For maximum startup performance, use the view configuration - method described in :ref:`mapping_views_using_imperative_config_section` - instead. - -Usage of the ``view_config`` decorator is a form of :term:`declarative -configuration`. The :class:`~pyramid.view.view_config` decorator can be used -to associate :term:`view configuration` information with a function that acts -as a :app:`Pyramid` view callable. All arguments to the -:class:`~pyramid.view.view_config` decorator mean precisely the same thing as -they would if they were passed as arguments to the -:meth:`pyramid.config.Configurator.add_view` method save for the ``view`` -argument. + configuration declarations. For maximum startup performance, use the view + configuration method described in + :ref:`mapping_views_using_imperative_config_section` instead. + +The :class:`~pyramid.view.view_config` decorator can be used to associate +:term:`view configuration` information with a function, method, or class that +acts as a :app:`Pyramid` view callable. Here's an example of the :class:`~pyramid.view.view_config` decorator that lives within a :app:`Pyramid` application module ``views.py``: @@ -482,6 +465,14 @@ See :ref:`configuration_module` for additional API arguments to the allows you to supply a ``package`` argument to better control exactly *which* code will be scanned. +All arguments to the :class:`~pyramid.view.view_config` decorator mean +precisely the same thing as they would if they were passed as arguments to +the :meth:`pyramid.config.Configurator.add_view` method save for the ``view`` +argument. Usage of the :class:`~pyramid.view.view_config` decorator is a +form of :term:`declarative configuration`, while +:meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative +configuration`. However, they both do the same thing. + ``@view_config`` Placement ++++++++++++++++++++++++++ @@ -602,12 +593,12 @@ against the ``amethod`` method could be spelled equivalently as the below: .. _mapping_views_using_imperative_config_section: -View Registration Using :meth:`~pyramid.config.Configurator.add_view` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Adding View Configuration Using :meth:`~pyramid.config.Configurator.add_view` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`pyramid.config.Configurator.add_view` method within :ref:`configuration_module` is used to configure a view "imperatively" -(without a :class:`~pyramid.view.view_config` decorator. The arguments to +(without a :class:`~pyramid.view.view_config` decorator). The arguments to this method are very similar to the arguments that you provide to the :class:`~pyramid.view.view_config` decorator. For example: -- cgit v1.2.3 From 4e1199fdb3219ed7ed3635f8ed96fb0cff18abe1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 04:35:53 -0400 Subject: simplify --- docs/narr/configuration.rst | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 6360dc574..4c2870562 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -23,6 +23,10 @@ standardized ways that code gets plugged into a deployment of the framework itself. When you plug code into the :app:`Pyramid` framework, you are "configuring" :app:`Pyramid` to create a particular application. +There are two ways to configure a :app:`Pyramid` application: +:term:`imperative configuration` and :term:`declarative configuration`. Both +are described below. + .. index:: single: imperative configuration @@ -31,8 +35,9 @@ itself. When you plug code into the :app:`Pyramid` framework, you are Imperative Configuration ------------------------ -Here's one of the simplest :app:`Pyramid` applications, configured -imperatively: +"Imperative configuration" just means configuration done by Python +statements, one after the next. Here's one of the simplest :app:`Pyramid` +applications, configured imperatively: .. code-block:: python :linenos: @@ -64,19 +69,17 @@ including conditionals, can be employed in this mode of configuration. .. _decorations_and_code_scanning: -Configuration Decorations and Code Scanning -------------------------------------------- +Declarative Configuration +------------------------- -A different mode of configuration gives more *locality of reference* to a -:term:`configuration declaration`. It's sometimes painful to have all -configuration done in imperative code, because often the code for a single -application may live in many files. If the configuration is centralized in -one place, you'll need to have at least two files open at once to see the -"big picture": the file that represents the configuration, and the file that -contains the implementation objects referenced by the configuration. To -avoid this, :app:`Pyramid` allows you to insert :term:`configuration -decoration` statements very close to code that is referred to by the -declaration itself. For example: +It's sometimes painful to have all configuration done by imperative code, +because often the code for a single application may live in many files. If +the configuration is centralized in one place, you'll need to have at least +two files open at once to see the "big picture": the file that represents the +configuration, and the file that contains the implementation objects +referenced by the configuration. To avoid this, :app:`Pyramid` allows you to +insert :term:`configuration decoration` statements very close to code that is +referred to by the declaration itself. For example: .. code-block:: python :linenos: @@ -135,6 +138,9 @@ the scanner, a set of calls are made to a :term:`Configurator` on your behalf: these calls replace the need to add imperative configuration statements that don't live near the code being configured. +The combination of :term:`configuration decoration` and the invocation of a +:term:`scan` is collectively known as :term:`declarative configuration`. + In the example above, the scanner translates the arguments to :class:`~pyramid.view.view_config` into a call to the :meth:`pyramid.config.Configurator.add_view` method, effectively: @@ -145,13 +151,3 @@ In the example above, the scanner translates the arguments to config.add_view(hello) -Declarative Configuration -------------------------- - -A third mode of configuration can be employed when you create a -:app:`Pyramid` application named *declarative configuration*. This mode uses -an XML language known as :term:`ZCML` to represent configuration statements -rather than Python. ZCML is not built-in to Pyramid, but almost everything -that can be configured imperatively can also be configured via ZCML if you -install the :term:`pyramid_zcml` package. - -- cgit v1.2.3 From 0784123a4042353beedc84960bbbf51068eec295 Mon Sep 17 00:00:00 2001 From: Manuel Hermann Date: Mon, 11 Jul 2011 16:47:38 +0200 Subject: Decorator version of config.add_response_adapter. --- docs/narr/hooks.rst | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 94701c9f9..0dcbcd371 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -536,7 +536,8 @@ Changing How Pyramid Treats View Responses It is possible to control how Pyramid treats the result of calling a view callable on a per-type basis by using a hook involving -:meth:`pyramid.config.Configurator.add_response_adapter`. +:meth:`pyramid.config.Configurator.add_response_adapter` or the +:class:`~pyramid.response.response_adapter` decorator. .. note:: This feature is new as of Pyramid 1.1. @@ -573,6 +574,20 @@ Response: config.add_response_adapter(string_response_adapter, str) +The above example using the :class:`~pyramid.response.response_adapter` +decorator: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.response import response_adapter + + @response_adapter(str) + def string_response_adapter(s): + response = Response(s) + return response + Likewise, if you want to be able to return a simplified kind of response object from view callables, you can use the IResponse hook to register an adapter to the more complex IResponse interface: -- cgit v1.2.3 From 0388722bcfee9fce6b241264ea4535a8d0d5fd8c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 23:35:20 -0400 Subject: we no longer support 24. --- docs/narr/install.rst | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index fe8459c6f..c4ea978ec 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -9,17 +9,14 @@ Installing :app:`Pyramid` Before You Install ------------------ -You will need `Python `_ version 2.4 or better to +You will need `Python `_ version 2.5 or better to run :app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python - 2.4.6, Python 2.5.4 and Python 2.6.2, and Python 2.7. To ensure - backwards compatibility, development of :app:`Pyramid` is - currently done primarily under Python 2.4 and Python 2.5. - :app:`Pyramid` does not run under any version of Python before - 2.4, and does not yet run under Python 3.X. + As of this writing, :app:`Pyramid` has been tested under Python 2.5.5 and + Python 2.6.6, and Python 2.7.2. :app:`Pyramid` does not run under any + version of Python before 2.5, and does not yet run under Python 3.X. :app:`Pyramid` is known to run on all popular Unix-like systems such as Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also @@ -143,15 +140,15 @@ setuptools`` within the Python interpreter you'd like to run .. code-block:: text [chrism@vitaminf pyramid]$ python - Python 2.4.5 (#1, Aug 29 2008, 12:27:37) - [GCC 4.0.1 (Apple Inc. build 5465)] on darwin + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) + [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import setuptools If running ``import setuptools`` does not raise an ``ImportError``, it means that setuptools is already installed into your Python interpreter. If ``import setuptools`` fails, you will need to install -setuptools manually. Note that above we're using a Python 2.4-series +setuptools manually. Note that above we're using a Python 2.6-series interpreter on Mac OS X; your output may differ if you're using a later Python version or a different platform. -- cgit v1.2.3 From 7a505dbfc9ae9a5c933072653ac44e4086d26e59 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 23:36:36 -0400 Subject: simplify --- docs/narr/introduction.rst | 82 ++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 46 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a0b682e25..d26f1b8bf 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -10,11 +10,8 @@ ============================== :app:`Pyramid` is a general, open source, Python web application development -*framework*. Its primary goal is to make it easier for a developer to create -web applications. The type of application being created could be a -spreadsheet, a corporate intranet, or a social networking platform; Pyramid's -generality enables it to be used to build an unconstrained variety of web -applications. +*framework*. Its primary goal is to make it easier for a Python developer to +create web applications. .. sidebar:: Frameworks vs. Libraries @@ -33,34 +30,30 @@ applications. own via a set of libraries if the framework provides a set of facilities that fits your application requirements. -The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made -in July of 2008. We have worked hard to ensure that Pyramid continues to -follow the design and engineering principles that we consider to be the core -characteristics of a successful framework: +Pyramid attempts to follow follow these design and engineering principles: Simplicity - :app:`Pyramid` takes a *"pay only for what you eat"* approach. This means - that you can get results even if you have only a partial understanding of - :app:`Pyramid`. It doesn’t force you to use any particular technology to - produce an application, and we try to keep the core set of concepts that - you need to understand to a minimum. + :app:`Pyramid` takes a *"pay only for what you eat"* approach. You can get + results even if you have only a partial understanding of :app:`Pyramid`. + It doesn’t force you to use any particular technology to produce an + application, and we try to keep the core set of concepts that you need to + understand to a minimum. Minimalism - :app:`Pyramid` concentrates on providing fast, high-quality solutions to - the fundamental problems of creating a web application: the mapping of URLs - to code, templating, security and serving static assets. We consider these - to be the core activities that are common to nearly all web applications. + :app:`Pyramid` tries to solve only the the fundamental problems of creating + a web application: the mapping of URLs to code, templating, security and + serving static assets. We consider these to be the core activities that are + common to nearly all web applications. Documentation - Pyramid's minimalism means that it is relatively easy for us to maintain - extensive and up-to-date documentation. It is our goal that no aspect of - Pyramid remains undocumented. + Pyramid's minimalism means that it is easier for us to maintain complete + and up-to-date documentation. It is our goal that no aspect of Pyramid + is undocumented. Speed :app:`Pyramid` is designed to provide noticeably fast execution for common - tasks such as templating and simple response generation. Although the - “hardware is cheap” mantra may appear to offer a ready solution to speed - problems, the limits of this approach become painfully evident when one + tasks such as templating and simple response generation. Although “hardware + is cheap", the limits of this approach become painfully evident when one finds him or herself responsible for managing a great many machines. Reliability @@ -75,7 +68,6 @@ Openness .. index:: single: Pylons - single: Agendaless Consulting single: repoze namespace package What Is The Pylons Project? @@ -83,7 +75,7 @@ What Is The Pylons Project? :app:`Pyramid` is a member of the collection of software published under the Pylons Project. Pylons software is written by a loose-knit community of -contributors. The `Pylons Project website `_ +contributors. The `Pylons Project website `_ includes details about how :app:`Pyramid` relates to the Pylons Project. .. index:: @@ -96,23 +88,22 @@ includes details about how :app:`Pyramid` relates to the Pylons Project. :app:`Pyramid` and Other Web Frameworks ------------------------------------------ -Until the end of 2010, :app:`Pyramid` was known as :mod:`repoze.bfg`; it was -merged into the Pylons project as :app:`Pyramid` in November of that year. +The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made +in July of 2008. At the end of 2010, we changed the name of +:mod:`repoze.bfg` to :app:`Pyramid`. It was merged into the Pylons project +as :app:`Pyramid` in November of that year. :app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version 1.0) and :term:`Django`. As a result, :app:`Pyramid` borrows several concepts and features from each, combining them into a unique web framework. -Many features of :app:`Pyramid` trace their origins back to -:term:`Zope`. Like Zope applications, :app:`Pyramid` applications -can be configured via a set of declarative configuration files. Like -Zope applications, :app:`Pyramid` applications can be easily -extended: if you obey certain constraints, the application you produce -can be reused, modified, re-integrated, or extended by third-party -developers without forking the original application. The concepts of -:term:`traversal` and declarative security in :app:`Pyramid` were -pioneered first in Zope. +Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. +Like Zope applications, :app:`Pyramid` applications can be easily extended: +if you obey certain constraints, the application you produce can be reused, +modified, re-integrated, or extended by third-party developers without +forking the original application. The concepts of :term:`traversal` and +declarative security in :app:`Pyramid` were pioneered first in Zope. The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the :term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons @@ -127,15 +118,14 @@ The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be by Django. :app:`Pyramid` has a documentation culture more like Django's than like Zope's. -Like :term:`Pylons` version 1.0, but unlike :term:`Zope`, a -:app:`Pyramid` application developer may use completely imperative -code to perform common framework configuration tasks such as adding a -view or a route. In Zope, :term:`ZCML` is typically required for -similar purposes. In :term:`Grok`, a Zope-based web framework, -:term:`decorator` objects and class-level declarations are used for -this purpose. :app:`Pyramid` supports :term:`ZCML` and -decorator-based configuration, but does not require either. See -:ref:`configuration_narr` for more information. +Like :term:`Pylons` version 1.0, but unlike :term:`Zope`, a :app:`Pyramid` +application developer may use completely imperative code to perform common +framework configuration tasks such as adding a view or a route. In Zope, +:term:`ZCML` is typically required for similar purposes. In :term:`Grok`, a +Zope-based web framework, :term:`decorator` objects and class-level +declarations are used for this purpose. :app:`Pyramid` supports :term:`ZCML` +and decorator-based :term:`declarative configuration`, but does not require +either. See :ref:`configuration_narr` for more information. Also unlike :term:`Zope` and unlike other "full-stack" frameworks such as :term:`Django`, :app:`Pyramid` makes no assumptions about which -- cgit v1.2.3 From f05c3819cc8bfa1dd829a24f3c8cc82c4094a6cd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 23:43:24 -0400 Subject: add PyPy --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c4ea978ec..837db5a94 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -20,7 +20,7 @@ run :app:`Pyramid`. :app:`Pyramid` is known to run on all popular Unix-like systems such as Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on Google's App Engine and :term:`Jython`. +known to run on Google's App Engine, :term:`PyPy`, and :term:`Jython`. :app:`Pyramid` installation does not require the compilation of any C code, so you need only a Python interpreter that meets the -- cgit v1.2.3 From 7c48ff7bde21fda813ce74a7691c89bedd2b54cc Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 23:58:57 -0400 Subject: simplify --- docs/narr/configuration.rst | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 4c2870562..3ecb4b06a 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -6,22 +6,15 @@ Application Configuration ========================= -Each deployment of an application written using :app:`Pyramid` implies a -specific *configuration* of the framework itself. For example, an -application which serves up MP3 files for your listening enjoyment might plug -code into the framework that manages song files, while an application that -manages corporate data might plug in code that manages accounting -information. The way in which code is plugged in to :app:`Pyramid` for a -specific application is referred to as "configuration". - -Most people understand "configuration" as coarse settings that inform the -high-level operation of a specific application deployment. For instance, -it's easy to think of the values implied by a ``.ini`` file parsed at -application startup time as "configuration". :app:`Pyramid` extends this -pattern to application development, using the term "configuration" to express -standardized ways that code gets plugged into a deployment of the framework -itself. When you plug code into the :app:`Pyramid` framework, you are -"configuring" :app:`Pyramid` to create a particular application. +The way in which code is plugged in to :app:`Pyramid` for a specific +application is referred to as "configuration". Most people understand +"configuration" as coarse settings that inform the high-level operation of a +specific application deployment. For instance, it's easy to think of the +values implied by a ``.ini`` file parsed at application startup time as +"configuration". However, :app:`Pyramid` also uses the word "configuration" +to express standardized ways that code gets plugged into a deployment of the +framework itself. When you plug code into the :app:`Pyramid` framework, you +are "configuring" :app:`Pyramid` to create a particular application. There are two ways to configure a :app:`Pyramid` application: :term:`imperative configuration` and :term:`declarative configuration`. Both -- cgit v1.2.3 From 8027d1621e859f44e94a063c7b87c818d9096c85 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:01:30 -0400 Subject: remove unnecessary clause --- docs/narr/firstapp.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index f5adad905..87487b444 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -12,8 +12,7 @@ more detail how it works. Hello World, Goodbye World -------------------------- -Here's one of the very simplest :app:`Pyramid` applications, configured -imperatively: +Here's one of the very simplest :app:`Pyramid` applications: .. code-block:: python :linenos: -- cgit v1.2.3 From f4a80417c886938dec83071a4d62238c78bf8810 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:10:54 -0400 Subject: add docs about logging config --- docs/narr/project.rst | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ab7023561..4a7f63176 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -12,9 +12,9 @@ A project is a directory that contains at least one Python :term:`package`. You'll use a scaffold to create a project, and you'll create your application logic within a package that lives inside the project. Even if your application is extremely simple, it is useful to place code that drives the -application within a package, because a package is more easily extended with -new code. An application that lives inside a package can also be distributed -more easily than one which does not live within a package. +application within a package, because: 1) a package is more easily extended +with new code and 2) an application that lives inside a package can also be +distributed more easily than one which does not live within a package. :app:`Pyramid` comes with a variety of scaffolds that you can use to generate a project. Each scaffold makes different configuration assumptions about @@ -559,7 +559,8 @@ The generated ``development.ini`` file looks like so: :linenos: This file contains several "sections" including ``[app:MyProject]``, -``[pipeline:main]``, and ``[server:main]``. +``[pipeline:main]``, ``[server:main]`` and several other sections related to +logging configuration. The ``[app:MyProject]`` section represents configuration for your application. This section name represents the ``MyProject`` application (and @@ -643,6 +644,16 @@ for each request. application be nonblocking as all application code will run in its own thread, provided by the server you're using. +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 +``paster serve`` or ``paster pshell`` commands are executed. The default +configuration sends application logging output to the standard error output +of your terminal. + See the :term:`PasteDeploy` documentation for more information about other types of things you can put into this ``.ini`` file, such as other applications, :term:`middleware` and alternate :term:`WSGI` server -- cgit v1.2.3 From 46ad10d4ea3f57c19d7ce54a1539a66d7ed621d2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:13:38 -0400 Subject: add docs about logging config --- docs/narr/startup.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index e2c43b17e..788896de9 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -53,6 +53,10 @@ Here's a high-level time-ordered overview of what happens when you press that particular composite to understand how to make it refer to your :app:`Pyramid` application. +#. The PasteDeploy framework finds all :mod:`logging` related configuration + in the ``.ini`` file and uses it to configure the Python standard library + logging system for this application. + #. The application's *constructor* (named by the entry point reference or dotted Python name on the ``use=`` line of the section representing your :app:`Pyramid` application) is passed the key/value parameters mentioned -- cgit v1.2.3 From 7278cf91ea041222f3af814d19e3d1c2f0536ba0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:28:09 -0400 Subject: remove deprecated mechanism to associate views with routes; add description of scan mechanism --- docs/narr/urldispatch.rst | 113 ++++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 79 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 51a840b8d..8e2d240fa 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -12,10 +12,10 @@ patterns is checked one-by-one. If one of the patterns matches the path information associated with a request, a particular :term:`view callable` is invoked. -:term:`URL dispatch` is one of two ways to perform :term:`resource -location` in :app:`Pyramid`; the other way is using :term:`traversal`. -If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls -back to :term:`traversal` to handle the :term:`request`. +:term:`URL dispatch` is one of two ways to perform :term:`resource location` +in :app:`Pyramid`; the other way is to use :term:`traversal`. If no route is +matched using :term:`URL dispatch`, :app:`Pyramid` falls back to +:term:`traversal` to handle the :term:`request`. It is the responsibility of the :term:`resource location` subsystem (i.e., :term:`URL dispatch` or :term:`traversal`) to find the resource @@ -67,8 +67,8 @@ attributes. .. _config-add-route: -Configuring a Route via The ``add_route`` Configurator Method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Configuring a Route to Match a View +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`pyramid.config.Configurator.add_route` method adds a single :term:`route configuration` to the :term:`application registry`. Here's an @@ -84,90 +84,45 @@ example: config.add_route('myroute', '/prefix/{one}/{two}') config.add_view(myview, route_name='myroute') -.. versionchanged:: 1.0a4 - Prior to 1.0a4, routes allow for a marker starting with a ``:``, for - example ``/prefix/:one/:two``. This style is now deprecated - in favor of ``{}`` usage which allows for additional functionality. +When a :term:`view callable` added to the configuration by way of +:meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route +via its ``route_name`` predicate, that view callable will always be found +and invoked when the associated route pattern matches during a request. -.. index:: - single: route configuration; view callable - -.. _add_route_view_config: - -Route Configuration That Names a View Callable -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. warning:: This section describes a feature which has been deprecated in - Pyramid 1.1 and higher. In order to reduce confusion and documentation - burden, passing view-related parameters to - :meth:`~pyramid.config.Configurator.add_route` is deprecated. - - In versions earlier than 1.1, a view was permitted to be connected to a - route using a set of ``view*`` parameters passed to the - :meth:`~pyramid.config.Configurator.add_route`. This was a shorthand - which replaced the need to perform a subsequent call to - :meth:`~pyramid.config.Configurator.add_view` as described in - :ref:`config-add-route`. For example, it was valid (and often recommended) - to do: - - .. code-block:: python +More commonly, you will not use any ``add_view`` statements in your project's +"setup" code, instead only using ``add_route`` statements using a +:term:`scan` for to associate view callables with routes. For example, if +this is a portion of your project's ``__init__.py``: - config.add_route('home', '/', view='mypackage.views.myview', - view_renderer='some/renderer.pt') - - Instead of the equivalent: - - .. code-block:: python - - config.add_route('home', '/') - config.add_view('mypackage.views.myview', route_name='home') - renderer='some/renderer.pt') - - Passing ``view*`` arguments to ``add_route`` as shown in the first - example above is now deprecated in favor of connecting a view to a - predefined route via :meth:`~pyramid.config.Configurator.add_view` using - the route's ``route_name`` parameter, as shown in the second example - above. +.. code-block:: python - A deprecation warning is now issued when any view-related parameter is - passed to ``Configurator.add_route``. The recommended way to associate a - view with a route is documented in :ref:`config-add-route`. + # in your project's __init__.py (mypackage.__init__) -When a route configuration declaration names a ``view`` attribute, the value -of the attribute will reference a :term:`view callable`. This view callable -will be invoked when the route matches. A view callable, as described in -:ref:`views_chapter`, is developer-supplied code that "does stuff" as the -result of a request. + config.add_route('myroute', '/prefix/{one}/{two}') + config.scan('mypackage') -Here's an example route configuration that references a view callable: +Note that we don't call :meth:`~pyramid.config.Configurator.add_view` in this +setup code. However, the above :term:`scan` execution +``config.scan('mypackage')`` will pick up all :term:`configuration +decoration`, including any objects decorated with the +:class:`pyramid.view.view_config` decorator in the ``mypackage`` Python +pakage. For example, if you have a ``views.py`` in your package, a scan will +pick up any of its configuration decorators, so we can add one there that +that references ``myroute`` as a ``route_name`` parameter: .. code-block:: python - :linenos: - - # "config" below is presumed to be an instance of the - # pyramid.config.Configurator class; "myview" is assumed - # to be a "view callable" function - from myproject.views import myview - config.add_route('myroute', '/prefix/{one}/{two}', view=myview) - -You can also pass a :term:`dotted Python name` as the ``view`` argument -rather than an actual callable: -.. code-block:: python - :linenos: + # in your project's views.py module (mypackage.views) - # "config" below is presumed to be an instance of the - # pyramid.config.Configurator class; "myview" is assumed - # to be a "view callable" function - config.add_route('myroute', '/prefix/{one}/{two}', - view='myproject.views.myview') + from pyramid.view import view_config + from pyramid.response import Response -When a route configuration names a ``view`` attribute, the :term:`view -callable` named as that ``view`` attribute will always be found and invoked -when the associated route pattern matches during a request. + @view_config(route_name='myroute') + def myview(request): + return Response('OK) -See :meth:`pyramid.config.Configurator.add_route` for a description of -view-related arguments. +THe above combination of ``add_route`` and ``scan`` is completely equivalent +to using the previous combination of ``add_route`` and ``add_view``. .. index:: single: route path pattern syntax -- cgit v1.2.3 From 321e34669f0b9119894cd1ee8c115361deba29f6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:33:56 -0400 Subject: remove references to add_route view-related configuration --- docs/narr/urldispatch.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 8e2d240fa..779a884fb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -394,13 +394,14 @@ the associated route to be considered a match during the route matching process. Examples of route predicate arguments are ``pattern``, ``xhr``, and ``request_method``. -Other arguments are view configuration related arguments. These only have an -effect when the route configuration names a ``view``. These arguments have -been deprecated as of :app:`Pyramid` 1.1 (see :ref:`add_route_view_config`). - Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. +.. warning:: Some arguments are view-configuration related arguments, such as + ``view_renderer``. These only have an effect when the route configuration + names a ``view`` and these arguments have been deprecated as of + :app:`Pyramid` 1.1. + .. _custom_route_predicates: Custom Route Predicates -- cgit v1.2.3 From e4770d391bd87c5d6164affb1a2f79b77b35b58b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 00:36:12 -0400 Subject: fix sample --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 779a884fb..52311682e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -119,7 +119,7 @@ that references ``myroute`` as a ``route_name`` parameter: @view_config(route_name='myroute') def myview(request): - return Response('OK) + return Response('OK') THe above combination of ``add_route`` and ``scan`` is completely equivalent to using the previous combination of ``add_route`` and ``add_view``. -- cgit v1.2.3 From f9896b60700ea4334f3df0a83f9b291e167b322d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 03:31:08 -0400 Subject: reviewed --- 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 94701c9f9..a156426ae 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -284,8 +284,8 @@ Using Response Callbacks Unlike many other web frameworks, :app:`Pyramid` does not eagerly create a global response object. Adding a :term:`response callback` allows an -application to register an action to be performed against a response object -once it is created, usually in order to mutate it. +application to register an action to be performed against whatever response +object is returned by a view, usually in order to mutate the response. The :meth:`pyramid.request.Request.add_response_callback` method is used to register a response callback. -- cgit v1.2.3 From e573d4356ed0371f5ba34ff3ff396fefd2e55913 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 20:56:53 -0400 Subject: - New environment setting ``PYRAMID_PREVENT_HTTP_CACHE`` and new configuration file value ``prevent_http_cache``. These are synomymous and allow you to prevent HTTP cache headers from being set by Pyramid's ``http_cache`` machinery globally in a process. see the "Influencing HTTP Caching" section of the "View Configuration" narrative chapter and the detailed documentation for this setting in the "Environment Variables and Configuration Settings" narrative chapter. - New documentation section in View Configuration narrative chapter: "Influencing HTTP Caching". --- docs/narr/environment.rst | 19 ++++++++++++++++++ docs/narr/viewconfig.rst | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index a57b316e1..7f8e3953d 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -117,6 +117,25 @@ this value is true. See also :ref:`debug_routematch_section`. | | | +---------------------------------+-----------------------------+ +.. _preventing_http_caching: + +Preventing HTTP Caching +------------------------ + +Prevent the ``http_cache`` view configuration argument from having any effect +globally in this process when this value is true. No http caching-related +response headers will be set by the Pyramid ``http_cache`` view configuration +feature when this is true. See also :ref:`influencing_http_caching`. + ++---------------------------------+-----------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+=============================+ +| ``PYRAMID_PREVENT_HTTP_CACHE`` | ``prevent_http_cache`` | +| | | +| | | +| | | ++---------------------------------+-----------------------------+ + Debugging All ------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 326d97506..1ef40e89f 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -82,6 +82,8 @@ being invoked due to an authorization policy. The presence of non-predicate arguments in a view configuration does not narrow the circumstances in which the view callable will be invoked. +.. _nonpredicate_view_args: + Non-Predicate Arguments +++++++++++++++++++++++ @@ -767,6 +769,54 @@ found will be printed to ``stderr``, and the browser representation of the error will include the same information. See :ref:`environment_chapter` for more information about how, and where to set these values. +.. index:: + single: HTTP caching + +.. _influencing_http_caching: + +Influencing HTTP Caching +------------------------ + +.. note:: This feature is new in Pyramid 1.1. + +When a non-``None`` ``http_cache`` argument is passed to a view +configuration, Pyramid will set ``Expires`` and ``Cache-Control`` response +headers in the resulting response, causing browsers to cache the response +data for some time. See ``http_cache`` in :ref:`nonpredicate_view_args` for +the its allowable values and what they mean. + +Sometimes it's undesirable to have these headers set as the result of +returning a response from a view, even though you'd like to decorate the view +with a view configuration decorator that has ``http_cache``. Perhaps there's +an alternate branch in your view code that returns a response that should +never be cacheable, while the "normal" branch returns something that should +always be cacheable. If this is the case, set the ``prevent_auto`` attribute +of the ``response.cache_control`` object to a non-``False`` value. For +example, the below view callable is configured with a ``@view_config`` +decorator that indicates any response from the view should be cached for 3600 +seconds. However, the view itself prevents caching from taking place unless +there's a ``should_cache`` GET or POST variable: + +.. code-block:: python + + from pyramid.view import view_config + + @view_config(http_cache=3600) + def view(request): + response = Response() + if not 'should_cache' in request.params: + response.cache_control.prevent_auto = True + return response + +Note that the ``http_cache`` machinery will overwrite or add to caching +headers you set within the view itself unless you use ``preserve_auto``. + +You can also turn of the effect of ``http_cache`` entirely for the duration +of a Pyramid application lifetime. To do so, set the +``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the +``prevent_http_cache`` configuration value setting to a true value. For more +information, see :ref:`preventing_http_caching`. + .. index:: pair: matching views; printing single: paster pviews -- cgit v1.2.3 From 5fa17fdefe848d8004ca9a6daab19e1e1ea17b29 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 20:59:11 -0400 Subject: clarify --- docs/narr/viewconfig.rst | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 1ef40e89f..d33d78752 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -817,6 +817,11 @@ of a Pyramid application lifetime. To do so, set the ``prevent_http_cache`` configuration value setting to a true value. For more information, see :ref:`preventing_http_caching`. +Note that setting ``prevent_http_cache`` will have no effect on caching +headers that your application code itself sets. It will only prevent caching +headers that would have been set by the Pyramid HTTP caching machinery +invoked as the result of the ``http_cache`` argument to view configuration. + .. index:: pair: matching views; printing single: paster pviews -- cgit v1.2.3 From ae4c577d12a16396b45515e81415b2b16f8e93e8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 13 Jul 2011 20:48:38 -0400 Subject: move all paster commands to a separate chapter --- docs/narr/commandline.rst | 288 ++++++++++++++++++++++++++++++++++++++++++++++ docs/narr/project.rst | 148 ++---------------------- docs/narr/urldispatch.rst | 43 +------ docs/narr/viewconfig.rst | 103 +---------------- 4 files changed, 308 insertions(+), 274 deletions(-) create mode 100644 docs/narr/commandline.rst (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst new file mode 100644 index 000000000..0c591f6d1 --- /dev/null +++ b/docs/narr/commandline.rst @@ -0,0 +1,288 @@ +.. _command_line_chapter: + +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: paster pviews + +.. _displaying_matching_views: + +Displaying Matching Views for a Given URL +----------------------------------------- + +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 ``paster pviews`` command in a terminal window to +print a summary of matching routes and views for a given URL in your +application. The ``paster pviews`` command accepts two arguments. The +first argument to ``pviews`` is the path to your application's ``.ini`` file +and section name inside the ``.ini`` file which points to your application. +This should be of the format ``config_file#section_name``. The second argument +is the URL to test for matching views. + +Here is an example for a simple view configuration using :term:`traversal`: + +.. code-block:: text + :linenos: + + $ ../bin/paster pviews development.ini tutorial /FrontPage + + URL = /FrontPage + + context: + view name: + + View: + ----- + tutorial.views.view_page + required permission = view + +The output always has the requested URL at the top and below that all the +views that matched with their view configuration details. In this example +only one view matches, so there is just a single *View* section. For each +matching view, the full code path to the associated view callable is shown, +along with any permissions and predicates that are part of that view +configuration. + +A more complex configuration might generate something like this: + +.. code-block:: text + :linenos: + + $ ../bin/paster pviews development.ini#shootout /about + + URL = /about + + context: + view name: about + + Route: + ------ + route name: about + route pattern: /about + route path: /about + subpath: + route predicates (request method = GET) + + View: + ----- + shootout.views.about_view + required permission = view + view predicates (request_param testing, header X/header) + + Route: + ------ + route name: about_post + route pattern: /about + route path: /about + subpath: + route predicates (request method = POST) + + View: + ----- + shootout.views.about_view_post + required permission = view + view predicates (request_param test) + + View: + ----- + shootout.views.about_view_post2 + required permission = view + view predicates (request_param test2) + +In this case, we are dealing with a :term:`URL dispatch` application. This +specific URL has two matching routes. The matching route information is +displayed first, followed by any views that are associated with that route. +As you can see from the second matching route output, a route can be +associated with more than one view. + +For a URL that doesn't match any views, ``paster pviews`` will simply print +out a *Not found* message. + + +.. index:: + single: interactive shell + single: IPython + single: paster pshell + single: pshell + +.. _interactive_shell: + +The Interactive Shell +--------------------- + +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 "for real". To do so, use the ``paster pshell`` command. + +The argument to ``pshell`` follows the format ``config_file#section_name`` +where ``config_file`` is the path to your application's ``.ini`` file and +``section_name`` is the ``app`` section name inside the ``.ini`` file which +points to *your application* as opposed to any other section within the +``.ini`` file. For example, if your application ``.ini`` file might have a +``[app:MyProject]`` section that looks like so: + +.. code-block:: ini + :linenos: + + [app:MyProject] + use = egg:MyProject + reload_templates = true + debug_authorization = false + debug_notfound = false + debug_templates = true + default_locale_name = en + +If so, you can use the following command to invoke a debug shell using the +name ``MyProject`` as a section name: + +.. code-block:: text + + [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini#MyProject + Python 2.4.5 (#1, Aug 29 2008, 12:27:37) + [GCC 4.0.1 (Apple Inc. build 5465)] on darwin + + Default Variables: + app The WSGI Application + root The root of the default resource tree. + registry The Pyramid registry object. + settings The Pyramid settings object. + + >>> root + + >>> registry + + >>> settings['debug_notfound'] + False + >>> from myproject.views import my_view + >>> from pyramid.request import Request + >>> r = Request.blank('/') + >>> my_view(r) + {'project': 'myproject'} + +The WSGI application that is loaded will be available in the shell as the +``app`` global. Also, if the application that is loaded is the +:app:`Pyramid` app with no surrounding middleware, the ``root`` object +returned by the default :term:`root factory`, ``registry``, and ``settings`` +will be available. + +The interactive shell will not be able to load some of the globals like +``root``, ``registry`` and ``settings`` if the section name specified when +loading ``pshell`` is not referencing your :app:`Pyramid` application directly. +For example, if you have the following ``.ini`` file content: + +.. code-block:: ini + :linenos: + + [app:MyProject] + use = egg:MyProject + reload_templates = true + debug_authorization = false + debug_notfound = false + debug_templates = true + default_locale_name = en + + [pipeline:main] + pipeline = + egg:WebError#evalerror + MyProject + +Use ``MyProject`` instead of ``main`` as the section name argument to +``pshell`` against the above ``.ini`` file (e.g. ``paster pshell +development.ini#MyProject``). + +Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). + +.. _extending_pshell: + +Extending the Shell +~~~~~~~~~~~~~~~~~~~ + +It is sometimes convenient when using the interactive shell often to have +some variables significant to your application already loaded as globals +when you start the ``pshell``. To facilitate this, ``pshell`` will look +for a special ``[pshell]`` section in your INI file and expose the subsequent +key/value pairs to the shell. + +For example, you want to expose your model to the shell, along with the +database session so that you can mutate the model on an actual database. +Here, we'll assume your model is stored in the ``myapp.models`` package. + +.. code-block:: ini + :linenos: + + [pshell] + m = myapp.models + session = myapp.models.DBSession + t = transaction + +When this INI file is loaded, the extra variables ``m``, ``session`` and +``t`` will be available for use immediately. This happens regardless of +whether the ``registry`` and other special variables are loaded. + +IPython +~~~~~~~ + +If you have `IPython `_ installed in +the interpreter you use to invoke the ``paster`` command, the ``pshell`` +command will use an IPython interactive shell instead of a standard Python +interpreter shell. If you don't want this to happen, even if you have +IPython installed, you can pass the ``--disable-ipython`` flag to the +``pshell`` command to use a standard Python interpreter shell +unconditionally. + +.. code-block:: text + + [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ + development.ini#MyProject + + +.. index:: + pair: routes; printing + single: paster proutes + single: proutes + +.. _displaying_application_routes: + +Displaying All Application Routes +--------------------------------- + +You can use the ``paster proutes`` command in a terminal window to print a +summary of routes related to your application. Much like the ``paster +pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` +command accepts one argument with the format ``config_file#section_name``. +The ``config_file`` is the path to your application's ``.ini`` file, +and ``section_name`` is the ``app`` section name inside the ``.ini`` file +which points to your application. + +For example: + +.. code-block:: text + :linenos: + + [chrism@thinko MyProject]$ ../bin/paster proutes development.ini#MyProject + Name Pattern View + ---- ------- ---- + home / + home2 / + another /another None + static/ static/*subpath + catchall /*subpath + +``paster proutes`` generates a table. The table has three columns: a Name +name column, a Pattern column, and a View column. The items listed in the +Name column are route names, the items listen in the Pattern column are route +patterns, and the items listed in the View column are representations of the +view callable that will be invoked when a request matches the associated +route pattern. The view column may show ``None`` if no associated view +callable could be found. If no routes are configured within your +application, nothing will be printed to the console when ``paster proutes`` +is executed. + diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4a7f63176..4b08d09f6 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -194,7 +194,8 @@ Elided output from a run of this command is shown below: This will install a :term:`distribution` representing your project into the interpreter's library set so it can be found by ``import`` statements and by -:term:`PasteDeploy` commands such as ``paster serve`` and ``paster pshell``. +:term:`PasteDeploy` commands such as ``paster serve``, ``paster pshell``, +``paster proutes`` and ``paster pviews``. .. index:: single: running tests @@ -243,142 +244,6 @@ The tests themselves are found in the ``tests.py`` module in your ``paster create`` -generated project. Within a project generated by the ``pyramid_starter`` scaffold, a single sample test exists. -.. index:: - single: interactive shell - single: IPython - single: paster pshell - -.. _interactive_shell: - -The Interactive Shell ---------------------- - -Once you've installed your program for development using ``setup.py -develop``, you can use an interactive Python shell to examine your -:app:`Pyramid` project's :term:`resource` and :term:`view` objects from a -Python prompt. To do so, use your virtualenv's ``paster pshell`` command. - -The argument to ``pshell`` follows the format ``config_file#section_name`` -where ``config_file`` is the path to your application's ``.ini`` file and -``section_name`` is the ``app`` section name inside the ``.ini`` file which -points to *your application* as opposed to any other section within the -``.ini`` file. For example, if your application ``.ini`` file might have a -``[app:MyProject]`` section that looks like so: - -.. code-block:: ini - :linenos: - - [app:MyProject] - use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en - -If so, you can use the following command to invoke a debug shell using the -name ``MyProject`` as a section name: - -.. code-block:: text - - [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini#MyProject - Python 2.4.5 (#1, Aug 29 2008, 12:27:37) - [GCC 4.0.1 (Apple Inc. build 5465)] on darwin - - Default Variables: - app The WSGI Application - root The root of the default resource tree. - registry The Pyramid registry object. - settings The Pyramid settings object. - - >>> root - - >>> registry - - >>> settings['debug_notfound'] - False - >>> from myproject.views import my_view - >>> from pyramid.request import Request - >>> r = Request.blank('/') - >>> my_view(r) - {'project': 'myproject'} - -The WSGI application that is loaded will be available in the shell as the -``app`` global. Also, if the application that is loaded is the -:app:`Pyramid` app with no surrounding middleware, the ``root`` object -returned by the default :term:`root factory`, ``registry``, and ``settings`` -will be available. - -The interactive shell will not be able to load some of the globals like -``root``, ``registry`` and ``settings`` if the section name specified when -loading ``pshell`` is not referencing your :app:`Pyramid` application directly. -For example, if you have the following ``.ini`` file content: - -.. code-block:: ini - :linenos: - - [app:MyProject] - use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en - - [pipeline:main] - pipeline = - egg:WebError#evalerror - MyProject - -Use ``MyProject`` instead of ``main`` as the section name argument to -``pshell`` against the above ``.ini`` file (e.g. ``paster pshell -development.ini#MyProject``). - -Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). - -.. _extending_pshell: - -Extending the Shell -~~~~~~~~~~~~~~~~~~~ - -It is sometimes convenient when using the interactive shell often to have -some variables significant to your application already loaded as globals -when you start the ``pshell``. To facilitate this, ``pshell`` will look -for a special ``[pshell]`` section in your INI file and expose the subsequent -key/value pairs to the shell. - -For example, you want to expose your model to the shell, along with the -database session so that you can mutate the model on an actual database. -Here, we'll assume your model is stored in the ``myapp.models`` package. - -.. code-block:: ini - :linenos: - - [pshell] - m = myapp.models - session = myapp.models.DBSession - t = transaction - -When this INI file is loaded, the extra variables ``m``, ``session`` and -``t`` will be available for use immediately. This happens regardless of -whether the ``registry`` and other special variables are loaded. - -IPython -~~~~~~~ - -If you have `IPython `_ installed in -the interpreter you use to invoke the ``paster`` command, the ``pshell`` -command will use an IPython interactive shell instead of a standard Python -interpreter shell. If you don't want this to happen, even if you have -IPython installed, you can pass the ``--disable-ipython`` flag to the -``pshell`` command to use a standard Python interpreter shell -unconditionally. - -.. code-block:: text - - [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ - development.ini#MyProject - .. index:: single: running an application single: paster serve @@ -1067,4 +932,13 @@ This pattern can be used to rearrage code referred to by any Pyramid API argument which accepts a :term:`dotted Python name` or direct object reference. +Using the Interactive Shell +--------------------------- + +It is possible to use a Python interpreter prompt loaded with a similar +configuration as would be loaded if you were running your Pyramid application +via ``paster serve``. This can be a useful debugging tool. See +:ref:`interactive_shell` for more details. + + diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 52311682e..b0a7009e3 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1028,46 +1028,9 @@ which you started the application from. For example: See :ref:`environment_chapter` for more information about how, and where to set these values. -.. index:: - pair: routes; printing - single: paster proutes - -.. _displaying_application_routes: - -Displaying All Application Routes ---------------------------------- - -You can use the ``paster proutes`` command in a terminal window to print a -summary of routes related to your application. Much like the ``paster -pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` -command accepts one argument with the format ``config_file#section_name``. -The ``config_file`` is the path to your application's ``.ini`` file, -and ``section_name`` is the ``app`` section name inside the ``.ini`` file -which points to your application. - -For example: - -.. code-block:: text - :linenos: - - [chrism@thinko MyProject]$ ../bin/paster proutes development.ini#MyProject - Name Pattern View - ---- ------- ---- - home / - home2 / - another /another None - static/ static/*subpath - catchall /*subpath - -``paster proutes`` generates a table. The table has three columns: a Name -name column, a Pattern column, and a View column. The items listed in the -Name column are route names, the items listen in the Pattern column are route -patterns, and the items listed in the View column are representations of the -view callable that will be invoked when a request matches the associated -route pattern. The view column may show ``None`` if no associated view -callable could be found. If no routes are configured within your -application, nothing will be printed to the console when ``paster proutes`` -is executed. +You can also use the ``paster proutes`` command to see a display of all the +routes configured in your application; for more information, see +:ref:`displaying_application_routes`. Route View Callable Registration and Lookup Details --------------------------------------------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index d33d78752..a45ebae32 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -822,101 +822,10 @@ headers that your application code itself sets. It will only prevent caching headers that would have been set by the Pyramid HTTP caching machinery invoked as the result of the ``http_cache`` argument to view configuration. -.. index:: - pair: matching views; printing - single: paster pviews - -.. _displaying_matching_views: - -Displaying Matching Views for a Given URL ------------------------------------------ - -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 ``paster pviews`` command in a terminal window to -print a summary of matching routes and views for a given URL in your -application. The ``paster pviews`` command accepts two arguments. The -first argument to ``pviews`` is the path to your application's ``.ini`` file -and section name inside the ``.ini`` file which points to your application. -This should be of the format ``config_file#section_name``. The second argument -is the URL to test for matching views. - -Here is an example for a simple view configuration using :term:`traversal`: - -.. code-block:: text - :linenos: - - $ ../bin/paster pviews development.ini tutorial /FrontPage - - URL = /FrontPage - - context: - view name: - - View: - ----- - tutorial.views.view_page - required permission = view - -The output always has the requested URL at the top and below that all the -views that matched with their view configuration details. In this example -only one view matches, so there is just a single *View* section. For each -matching view, the full code path to the associated view callable is shown, -along with any permissions and predicates that are part of that view -configuration. - -A more complex configuration might generate something like this: - -.. code-block:: text - :linenos: - - $ ../bin/paster pviews development.ini#shootout /about - - URL = /about - - context: - view name: about - - Route: - ------ - route name: about - route pattern: /about - route path: /about - subpath: - route predicates (request method = GET) - - View: - ----- - shootout.views.about_view - required permission = view - view predicates (request_param testing, header X/header) - - Route: - ------ - route name: about_post - route pattern: /about - route path: /about - subpath: - route predicates (request method = POST) - - View: - ----- - shootout.views.about_view_post - required permission = view - view predicates (request_param test) - - View: - ----- - shootout.views.about_view_post2 - required permission = view - view predicates (request_param test2) - -In this case, we are dealing with a :term:`URL dispatch` application. This -specific URL has two matching routes. The matching route information is -displayed first, followed by any views that are associated with that route. -As you can see from the second matching route output, a route can be -associated with more than one view. - -For a URL that doesn't match any views, ``paster pviews`` will simply print -out a *Not found* message. +Debugging View Configuration +---------------------------- +See :ref:`displaying_matching_views` for information about how to display +each of the view callables that might match for a given URL. This can be an +effective way to figure out why a particular view callable is being called +instead of the one you'd like to be called. -- cgit v1.2.3 From 56d0fe4a9f97daa4d5fd0c28ea83c6ef32856b3d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 14 Jul 2011 01:13:27 -0400 Subject: - New API class: ``pyramid.static.static_view``. This supersedes the deprecated ``pyramid.view.static`` class. ``pyramid.satic.static_view`` by default serves up documents as the result of the request's ``path_info``, attribute rather than it's ``subpath`` attribute (the inverse was true of ``pyramid.view.static``, and still is). ``pyramid.static.static_view`` exposes a ``use_subpath`` flag for use when you don't want the static view to behave like the older deprecated version. - The ``pyramid.view.static`` class has been deprecated in favor of the newer ``pyramid.static.static_view`` class. A deprecation warning is raised when it is used. You should replace it with a reference to ``pyramid.static.static_view`` with the ``use_subpath=True`` argument. --- docs/narr/assets.rst | 29 +++++++++++++++-------------- docs/narr/hybrid.rst | 17 +++++++++++------ 2 files changed, 26 insertions(+), 20 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 0d50b0106..d57687477 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -299,7 +299,7 @@ URLs against assets made accessible by registering a custom static view. Root-Relative Custom Static View (URL Dispatch Only) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :class:`pyramid.view.static` helper class generates a Pyramid view +The :class:`pyramid.static.static_view` helper class generates a Pyramid view callable. This view callable can serve static assets from a directory. An instance of this class is actually used by the :meth:`~pyramid.config.Configurator.add_static_view` configuration method, so @@ -310,26 +310,27 @@ its behavior is almost exactly the same once it's configured. exclusively. The root-relative route we'll be registering will always be matched before traversal takes place, subverting any views registered via ``add_view`` (at least those without a ``route_name``). A - :class:`~pyramid.view.static` static view cannot be made root-relative when - you use traversal. + :class:`~pyramid.static.static_view` static view cannot be made + root-relative when you use traversal unless it's registered as a + :term:`NotFound view`. To serve files within a directory located on your filesystem at ``/path/to/static/dir`` as the result of a "catchall" route hanging from the root that exists at the end of your routing table, create an instance of the -:class:`~pyramid.view.static` class inside a ``static.py`` file in your -application root as below. +:class:`~pyramid.static.static_view` class inside a ``static.py`` file in +your application root as below. .. ignore-next-block .. code-block:: python :linenos: - from pyramid.view import static - static_view = static('/path/to/static/dir') + from pyramid.static import static + static_view = static_view('/path/to/static/dir', use_subpath=True) .. note:: For better cross-system flexibility, use an :term:`asset - specification` as the argument to :class:`~pyramid.view.static` instead of - a physical absolute filesystem path, e.g. ``mypackage:static`` instead of - ``/path/to/mypackage/static``. + specification` as the argument to :class:`~pyramid.static.static_view` + instead of a physical absolute filesystem path, e.g. ``mypackage:static`` + instead of ``/path/to/mypackage/static``. Subsequently, you may wire the files that are served by this view up to be accessible as ``/`` using a configuration method in your @@ -345,8 +346,8 @@ application's startup code. config.add_view('myapp.static.static_view', route_name='catchall_static') The special name ``*subpath`` above is used by the -:class:`~pyramid.view.static` view callable to signify the path of the file -relative to the directory you're serving. +:class:`~pyramid.static.static_view` view callable to signify the path of the +file relative to the directory you're serving. Registering A View Callable to Serve a "Static" Asset ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -425,10 +426,10 @@ feature, a :term:`Configurator` API exists named - A directory containing multiple Chameleon templates. - Individual static files served up by an instance of the - ``pyramid.view.static`` helper class. + ``pyramid.static.static_view`` helper class. - A directory of static files served up by an instance of the - ``pyramid.view.static`` helper class. + ``pyramid.static.static_view`` helper class. - Any other asset (or set of assets) addressed by code that uses the setuptools :term:`pkg_resources` API. diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 97adaeafd..a0a6a108c 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -431,8 +431,9 @@ Using ``*subpath`` in a Route Pattern There are certain extremely rare cases when you'd like to influence the traversal :term:`subpath` when a route matches without actually performing traversal. For instance, the :func:`pyramid.wsgi.wsgiapp2` decorator and the -:class:`pyramid.view.static` helper attempt to compute ``PATH_INFO`` from the -request's subpath, so it's useful to be able to influence this value. +:class:`pyramid.static.static_view` helper attempt to compute ``PATH_INFO`` +from the request's subpath when its ``use_subpath`` argument is ``True``, so +it's useful to be able to influence this value. When ``*subpath`` exists in a pattern, no path is actually traversed, but the traversal algorithm will return a :term:`subpath` list implied @@ -442,12 +443,16 @@ commonly in route declarations that look like this: .. code-block:: python :linenos: + from pryamid.static import static_view + + www = static_view('mypackage:static', use_subpath=True) + config.add_route('static', '/static/*subpath') - config.add_view('mypackage.views.static_view', route_name='static') + config.add_view(www, route_name='static') -Where ``mypackage.views.static_view`` is an instance of -:class:`pyramid.view.static`. This effectively tells the static helper to -traverse everything in the subpath as a filename. +``mypackage.views.www`` is an instance of +:class:`pyramid.static.static_view`. This effectively tells the static +helper to traverse everything in the subpath as a filename. Corner Cases ------------ -- cgit v1.2.3 From 9343b6f9f2e243f878ccf8d126ff9cc4bd5878ee Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Thu, 14 Jul 2011 09:18:44 -0700 Subject: eliminated repeated word --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 0c591f6d1..5fad9e227 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -277,7 +277,7 @@ For example: catchall /*subpath ``paster proutes`` generates a table. The table has three columns: a Name -name column, a Pattern column, and a View column. The items listed in the +column, a Pattern column, and a View column. The items listed in the Name column are route names, the items listen in the Pattern column are route patterns, and the items listed in the View column are representations of the view callable that will be invoked when a request matches the associated -- cgit v1.2.3 From f7afa751d7ca36a97474099c30923eeeade33b03 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Thu, 14 Jul 2011 09:19:51 -0700 Subject: corrected typo --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 5fad9e227..68078ab70 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -278,7 +278,7 @@ For example: ``paster proutes`` generates a table. The table has three columns: a Name column, a Pattern column, and a View column. The items listed in the -Name column are route names, the items listen in the Pattern column are route +Name column are route names, the items listed in the Pattern column are route patterns, and the items listed in the View column are representations of the view callable that will be invoked when a request matches the associated route pattern. The view column may show ``None`` if no associated view -- cgit v1.2.3 From 01895d10b5de268089ebf4f0f4ab2812c1d0cc85 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Thu, 14 Jul 2011 11:07:39 -0700 Subject: Removed superfluous 'and' --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 837db5a94..be35d9fc2 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -14,7 +14,7 @@ run :app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.5.5 and + As of this writing, :app:`Pyramid` has been tested under Python 2.5.5, Python 2.6.6, and Python 2.7.2. :app:`Pyramid` does not run under any version of Python before 2.5, and does not yet run under Python 3.X. -- cgit v1.2.3 From 11027dc3d17dc687a51551dddb37da929ca2c0ba Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Thu, 14 Jul 2011 11:12:39 -0700 Subject: Sentence was badly structured and also had a word capitalized after a comma --- docs/narr/install.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index be35d9fc2..5b9e22182 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -73,9 +73,9 @@ manager. For example, this works to do so on an Ubuntu Linux system: On Mac OS X, installing `XCode `_ has much the same effect. -Once you've got development tools installed on your system, On the -same system, to install a Python 2.6 interpreter from *source*, use -the following commands: +Once you've got development tools installed on your system, you can +install a Python 2.6 interpreter from *source*, on the same system, +using the following commands: .. code-block:: text -- cgit v1.2.3 From cab6fc74a00f1e205c717ba08012a3ef0f20e0b4 Mon Sep 17 00:00:00 2001 From: AnneGilles Date: Thu, 14 Jul 2011 16:03:40 -0700 Subject: Edited docs/narr/viewconfig.rst via GitHub --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index a45ebae32..54d3fc4ff 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -11,7 +11,7 @@ View Configuration single: view lookup :term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding -an invoking a :term:`view callable`. :term:`View configuration` controls how +and invoking a :term:`view callable`. :term:`View configuration` controls how :term:`view lookup` operates in your application. During any given request, view configuration information is compared against request data by the view lookup subsystem in order to find the "best" view callable for that request. -- cgit v1.2.3 From c515d77de5b2f62727251ebc32d1292e67811771 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 15 Jul 2011 10:13:07 -0400 Subject: - get_root2 -> prepare - change prepare return value to a dict, and return the registry, request, etc - various docs and changelog entries. --- 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 d57687477..f35f6dd7d 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -312,7 +312,7 @@ its behavior is almost exactly the same once it's configured. ``add_view`` (at least those without a ``route_name``). A :class:`~pyramid.static.static_view` static view cannot be made root-relative when you use traversal unless it's registered as a - :term:`NotFound view`. + :term:`Not Found view`. To serve files within a directory located on your filesystem at ``/path/to/static/dir`` as the result of a "catchall" route hanging from the -- cgit v1.2.3 From 5fb458c0dd70096e5d619e42992390bb1af071e1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Jul 2011 01:08:43 -0400 Subject: - Added a section entitled "Writing a Script" to the "Command-Line Pyramid" chapter. --- docs/narr/commandline.rst | 151 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 68078ab70..fccf095d3 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -286,3 +286,154 @@ callable could be found. If no routes are configured within your application, nothing will be printed to the console when ``paster proutes`` is executed. +.. _writing_a_script: + +Writing a Script +---------------- + +All web applications are, at their hearts, systems which accept a request and +return a response. When a request is accepted by a :app:`Pyramid` +application, the system receives state from the request which is later relied +on your application code. For example, one :term:`view callable` may assume +it's working against a request that has a ``request.matchdict`` of a +particular composition, while another assumes a different composition of the +matchdict. + +In the meantime, it's convenient to be able to write a Python script that can +work "in a Pyramid environment", for instance to update database tables used +by your :app:`Pyramid` application. But a "real" Pyramid environment doesn't +have a completely static state independent of a request; your application +(and Pyramid itself) is almost always reliant on being able to obtain +information from a request. When you run a Python script that simply imports +code from your application and tries to run it, there just is no request +data, because there isn't any real web request. Therefore some parts of your +application and some Pyramid APIs will not work. + +For this reason, :app:`Pyramid` makes it possible to run a script in an +environment much like the environment produced when a particular +:term:`request` reaches your :app:`Pyramid` application. This is achieved by +using the :func:`pyramid.paster.bootstrap` command in the body of your +script. + +In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a +single argument, which accepts the :term:`PasteDeploy` ``.ini`` file +representing Pyramid your application configuration as a single argument: + +.. code-block:: python + + from pyramid.paster import bootstrap + info = bootstrap('/path/to/my/development.ini') + print info['request'].route_url('home') + +:func:`pyramid.paster.bootstrap` returns a dictionary containing +framework-related information. This dictionary will always contain a +:term:`request` object as its ``request`` key. + +The following keys are also available in the ``info`` dictionary returned by +:func:`~pyramid.paster.bootstrap`: + +request + + A :class:`pyramid.request.Request` object implying the current request + state for your script. + +app + + The :term:`WSGI` application object generated by bootstrapping. + +root + + The :term:`resource` root of your :app:`Pyramid` application. This is an + object generated by the :term:`root factory` configured in your + application. + +registry + + The :term:`application registry` of your :app:`Pyramid` application. + +closer + + A parameterless callable that can be used to pop an internal + :app:`Pyramid` threadlocal stack (used by + :func:`pyramid.threadlocal.get_current_registry` and + :func:`pyramid.threadlocal.get_current_request`) when your scripting job + is finished. + +Let's assume that the ``/path/to/my/development.ini`` file used in the +example above looks like so: + +.. code-block:: ini + + [pipeline:main] + pipeline = egg:WebError#evalerror + another + + [app:another] + use = egg:MyProject + +The configuration loaded by the above bootstrap example will use the +configuration implied by the ``[pipeline:main]`` section of your +configuration file by default. Specifying ``/path/to/my/development.ini`` is +logically equivalent to specifying ``/path/to/my/development.ini#main``. In +this case, we'll be using a configuration that includes an ``app`` object +which is wrapped in the WebError ``evalerror`` middleware. + +You can also specify a particular *section* of the PasteDeploy ``.ini`` file +to load. By default, Pyramid assumes the section name you want to load is +``main``: + +.. code-block:: python + + from pyramid.paster import bootstrap + info = bootstrap('/path/to/my/development.ini#another') + print info['request'].route_url('home') + +The above example specifies the ``another`` ``app``, ``pipeline``, or +``composite`` section of your PasteDeploy configuration file. In the case +that we're using a configuration file that looks like this: + +.. code-block:: ini + + [pipeline:main] + pipeline = egg:WebError#evalerror + another + + [app:another] + use = egg:MyProject + +It will mean that the ``/path/to/my/development.ini#another`` argument passed +to bootstrap will imply the ``[app:another]`` section in our configuration +file. Therefore, it will not wrap the WSGI application present in the info +dictionary as ``app`` using WebError's ``evalerror`` middleware. The ``app`` +object present in the info dictionary returned by +:func:`~pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` +instead. + +By default, Pyramid will general a suitable request object in the ``info`` +dictionary anchored at the root path (``/``). You can alternately supply +your own :class:`pyramid.request.Request` instance to the +:func:`~pyramid.paster.bootstrap` function, to set up request parameters +beforehand: + +.. code-block:: python + + from pyramid.request import Request + request = Request.blank('/another/url') + from pyramid.paster import bootstrap + info = bootstrap('/path/to/my/development.ini#another', request=request) + print info['request'].path_info # will print '/another/url' + +When your scripting logic finishes, it's good manners (but not required) to +call the ``closer`` callback: + +.. code-block:: python + + from pyramid.paster import bootstrap + info = bootstrap('/path/to/my/development.ini') + + # .. do stuff ... + + info['closer']() + + + -- cgit v1.2.3 From 12382c2b61660f65d7f2dc852102e346ad0d46ed Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Jul 2011 01:18:01 -0400 Subject: note version reqt; fix dangling ref --- docs/narr/commandline.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index fccf095d3..6691ea70a 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -315,6 +315,8 @@ environment much like the environment produced when a particular using the :func:`pyramid.paster.bootstrap` command in the body of your script. +.. note:: This feature is new as of :app:`Pyramid` 1.1. + In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a single argument, which accepts the :term:`PasteDeploy` ``.ini`` file representing Pyramid your application configuration as a single argument: @@ -329,7 +331,7 @@ representing Pyramid your application configuration as a single argument: framework-related information. This dictionary will always contain a :term:`request` object as its ``request`` key. -The following keys are also available in the ``info`` dictionary returned by +The following keys are available in the ``info`` dictionary returned by :func:`~pyramid.paster.bootstrap`: request @@ -379,8 +381,7 @@ this case, we'll be using a configuration that includes an ``app`` object which is wrapped in the WebError ``evalerror`` middleware. You can also specify a particular *section* of the PasteDeploy ``.ini`` file -to load. By default, Pyramid assumes the section name you want to load is -``main``: +to load instead of ``main``: .. code-block:: python @@ -409,9 +410,9 @@ object present in the info dictionary returned by :func:`~pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` instead. -By default, Pyramid will general a suitable request object in the ``info`` -dictionary anchored at the root path (``/``). You can alternately supply -your own :class:`pyramid.request.Request` instance to the +By default, Pyramid will general a request object in the ``info`` dictionary +anchored at the root path (``/``). You can alternately supply your own +:class:`pyramid.request.Request` instance to the :func:`~pyramid.paster.bootstrap` function, to set up request parameters beforehand: -- cgit v1.2.3 From 8a8724de56c8dcce763fdb5630c77cb69a149572 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Jul 2011 01:29:52 -0400 Subject: promote bootstrap to major feature --- docs/narr/commandline.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 6691ea70a..b2a921eef 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -437,4 +437,3 @@ call the ``closer`` callback: info['closer']() - -- cgit v1.2.3 From 795aec4ba786c4920be60f9ac80e650816ea044f Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 16 Jul 2011 09:39:04 -0700 Subject: typo in func name --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index b2a921eef..98b06c1ba 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -332,7 +332,7 @@ framework-related information. This dictionary will always contain a :term:`request` object as its ``request`` key. The following keys are available in the ``info`` dictionary returned by -:func:`~pyramid.paster.bootstrap`: +:func:`pyramid.paster.bootstrap`: request -- cgit v1.2.3 From fcece8fe59e2ba17d54209a296edb70bd0f63b29 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 16 Jul 2011 09:58:19 -0700 Subject: Mmm, maybe the bad func name was pasted from an emacs buffer --- docs/narr/commandline.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 98b06c1ba..bc210904f 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -407,13 +407,13 @@ to bootstrap will imply the ``[app:another]`` section in our configuration file. Therefore, it will not wrap the WSGI application present in the info dictionary as ``app`` using WebError's ``evalerror`` middleware. The ``app`` object present in the info dictionary returned by -:func:`~pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` +:func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` instead. By default, Pyramid will general a request object in the ``info`` dictionary anchored at the root path (``/``). You can alternately supply your own :class:`pyramid.request.Request` instance to the -:func:`~pyramid.paster.bootstrap` function, to set up request parameters +:func:`pyramid.paster.bootstrap` function, to set up request parameters beforehand: .. code-block:: python -- cgit v1.2.3 From 42eaadb95ae2bfabc364ffbfa2769ad131d943be Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 16 Jul 2011 14:05:44 -0500 Subject: garden --- docs/narr/commandline.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index bc210904f..9adb04d4b 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -294,7 +294,7 @@ Writing a Script All web applications are, at their hearts, systems which accept a request and return a response. When a request is accepted by a :app:`Pyramid` application, the system receives state from the request which is later relied -on your application code. For example, one :term:`view callable` may assume +on by your application code. For example, one :term:`view callable` may assume it's working against a request that has a ``request.matchdict`` of a particular composition, while another assumes a different composition of the matchdict. @@ -410,7 +410,7 @@ object present in the info dictionary returned by :func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` instead. -By default, Pyramid will general a request object in the ``info`` dictionary +By default, Pyramid will generate a request object in the ``info`` dictionary anchored at the root path (``/``). You can alternately supply your own :class:`pyramid.request.Request` instance to the :func:`pyramid.paster.bootstrap` function, to set up request parameters -- cgit v1.2.3 From 795ddb42a12777f12fc5605fa908106a8d65cffd Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 16 Jul 2011 14:05:53 -0500 Subject: Renamed the 'info' dict to 'env' in scripting. --- docs/narr/commandline.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 9adb04d4b..c43145b4c 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -324,14 +324,14 @@ representing Pyramid your application configuration as a single argument: .. code-block:: python from pyramid.paster import bootstrap - info = bootstrap('/path/to/my/development.ini') - print info['request'].route_url('home') + env = bootstrap('/path/to/my/development.ini') + print env['request'].route_url('home') :func:`pyramid.paster.bootstrap` returns a dictionary containing framework-related information. This dictionary will always contain a :term:`request` object as its ``request`` key. -The following keys are available in the ``info`` dictionary returned by +The following keys are available in the ``env`` dictionary returned by :func:`pyramid.paster.bootstrap`: request @@ -386,8 +386,8 @@ to load instead of ``main``: .. code-block:: python from pyramid.paster import bootstrap - info = bootstrap('/path/to/my/development.ini#another') - print info['request'].route_url('home') + env = bootstrap('/path/to/my/development.ini#another') + print env['request'].route_url('home') The above example specifies the ``another`` ``app``, ``pipeline``, or ``composite`` section of your PasteDeploy configuration file. In the case @@ -404,13 +404,13 @@ that we're using a configuration file that looks like this: It will mean that the ``/path/to/my/development.ini#another`` argument passed to bootstrap will imply the ``[app:another]`` section in our configuration -file. Therefore, it will not wrap the WSGI application present in the info +file. Therefore, it will not wrap the WSGI application present in the ``env`` dictionary as ``app`` using WebError's ``evalerror`` middleware. The ``app`` -object present in the info dictionary returned by +object present in the ``env`` dictionary returned by :func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` instead. -By default, Pyramid will generate a request object in the ``info`` dictionary +By default, Pyramid will generate a request object in the ``env`` dictionary anchored at the root path (``/``). You can alternately supply your own :class:`pyramid.request.Request` instance to the :func:`pyramid.paster.bootstrap` function, to set up request parameters @@ -421,8 +421,8 @@ beforehand: from pyramid.request import Request request = Request.blank('/another/url') from pyramid.paster import bootstrap - info = bootstrap('/path/to/my/development.ini#another', request=request) - print info['request'].path_info # will print '/another/url' + env = bootstrap('/path/to/my/development.ini#another', request=request) + print env['request'].path_info # will print '/another/url' When your scripting logic finishes, it's good manners (but not required) to call the ``closer`` callback: @@ -430,10 +430,10 @@ call the ``closer`` callback: .. code-block:: python from pyramid.paster import bootstrap - info = bootstrap('/path/to/my/development.ini') + env = bootstrap('/path/to/my/development.ini') # .. do stuff ... - info['closer']() + env['closer']() -- cgit v1.2.3 From 69452f63ab2efa39c9273646959341287ba5ee15 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 16 Jul 2011 18:26:12 -0500 Subject: Changed the URL generation example to be more practical. --- docs/narr/commandline.rst | 60 +++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 25 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index c43145b4c..30e678f07 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -390,39 +390,50 @@ to load instead of ``main``: print env['request'].route_url('home') The above example specifies the ``another`` ``app``, ``pipeline``, or -``composite`` section of your PasteDeploy configuration file. In the case -that we're using a configuration file that looks like this: +``composite`` section of your PasteDeploy configuration file. The ``app`` +object present in the ``env`` dictionary returned by +:func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router`. -.. code-block:: ini +Changing the Request +~~~~~~~~~~~~~~~~~~~~ - [pipeline:main] - pipeline = egg:WebError#evalerror - another +By default, Pyramid will generate a request object in the ``env`` dictionary +for the URL ``http://localhost:80/``. This means that any URLs generated +by Pyramid during the execution of your script will be anchored here. This +is generally not what you want. - [app:another] - use = egg:MyProject +So how do we make Pyramid generate the correct URLs? -It will mean that the ``/path/to/my/development.ini#another`` argument passed -to bootstrap will imply the ``[app:another]`` section in our configuration -file. Therefore, it will not wrap the WSGI application present in the ``env`` -dictionary as ``app`` using WebError's ``evalerror`` middleware. The ``app`` -object present in the ``env`` dictionary returned by -:func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router` -instead. +Assuming that you have a route configured in your application like so: -By default, Pyramid will generate a request object in the ``env`` dictionary -anchored at the root path (``/``). You can alternately supply your own -:class:`pyramid.request.Request` instance to the -:func:`pyramid.paster.bootstrap` function, to set up request parameters -beforehand: +.. code-block:: python + + config.add_route('verify', '/verify/{code}') + +You need to inform the Pyramid environment that the WSGI application is +handling requests from a certain base. For example, we want to mount our +application at `example.com/prefix` and the generated URLs should use HTTPS. +This can be done by mutating the request object: .. code-block:: python - from pyramid.request import Request - request = Request.blank('/another/url') from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini#another', request=request) - print env['request'].path_info # will print '/another/url' + env = bootstrap('/path/to/my/development.ini#another') + env['request'].host = 'example.com' + env['request'].scheme = 'https' + env['request'].script_name = '/prefix' + print env['request'].application_url + # will print 'https://example.com/prefix/another/url' + +Now you can readily use Pyramid's APIs for generating URLs: + +.. code-block:: python + + route_url('verify', env['request'], code='1337') + # will return 'https://example.com/prefix/verify/1337' + +Cleanup +~~~~~~~ When your scripting logic finishes, it's good manners (but not required) to call the ``closer`` callback: @@ -436,4 +447,3 @@ call the ``closer`` callback: env['closer']() - -- cgit v1.2.3 From 7141f0dfc4b77817017a530cfd2dbb62b4836332 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Jul 2011 20:25:49 -0400 Subject: mention manual logging config --- docs/narr/commandline.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 30e678f07..890f42c42 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -447,3 +447,15 @@ call the ``closer`` callback: env['closer']() +Setting Up Logging +~~~~~~~~~~~~~~~~~~ + +By default, :func:`pyramid.paster.bootstrap` does not configure logging +parameters present in the configuration file. If you'd like to configure +logging based on ``[logger]`` and related sections in the configuration file, +use the following command: + +.. code-block:: python + + import logging + logging.fileConfig('/path/to/my/development.ini') -- cgit v1.2.3 From af056046970db9b1d3732f4c5978fcb3fb863d1f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Jul 2011 21:23:07 -0400 Subject: - Change paster pviews and paster proutes to use bootstrap. --- docs/narr/commandline.rst | 125 ++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 61 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 890f42c42..b52faed20 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -20,18 +20,19 @@ 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 ``paster pviews`` command in a terminal window to print a summary of matching routes and views for a given URL in your -application. The ``paster pviews`` command accepts two arguments. The -first argument to ``pviews`` is the path to your application's ``.ini`` file -and section name inside the ``.ini`` file which points to your application. -This should be of the format ``config_file#section_name``. The second argument -is the URL to test for matching views. +application. The ``paster pviews`` command accepts two arguments. The first +argument to ``pviews`` is the path to your application's ``.ini`` file and +section name inside the ``.ini`` file which points to your application. This +should be of the format ``config_file#section_name``. The second argument is +the URL to test for matching views. The ``section_name`` may be omitted; if +it is, it's considered to be ``main``. Here is an example for a simple view configuration using :term:`traversal`: .. code-block:: text :linenos: - $ ../bin/paster pviews development.ini tutorial /FrontPage + $ ../bin/paster pviews development.ini#tutorial /FrontPage URL = /FrontPage @@ -125,9 +126,8 @@ application runs "for real". To do so, use the ``paster pshell`` command. The argument to ``pshell`` follows the format ``config_file#section_name`` where ``config_file`` is the path to your application's ``.ini`` file and ``section_name`` is the ``app`` section name inside the ``.ini`` file which -points to *your application* as opposed to any other section within the -``.ini`` file. For example, if your application ``.ini`` file might have a -``[app:MyProject]`` section that looks like so: +points to your application. For example, if your application ``.ini`` file +might have a ``[app:MyProject]`` section that looks like so: .. code-block:: ini :linenos: @@ -145,58 +145,41 @@ name ``MyProject`` as a section name: .. code-block:: text - [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini#MyProject - Python 2.4.5 (#1, Aug 29 2008, 12:27:37) - [GCC 4.0.1 (Apple Inc. build 5465)] on darwin - - Default Variables: - app The WSGI Application - root The root of the default resource tree. - registry The Pyramid registry object. - settings The Pyramid settings object. - - >>> root - - >>> registry - - >>> settings['debug_notfound'] - False - >>> from myproject.views import my_view - >>> from pyramid.request import Request - >>> r = Request.blank('/') - >>> my_view(r) - {'project': 'myproject'} + chrism@thinko env26]$ bin/paster pshell starter/development.ini#MyProject + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) + [GCC 4.4.3] on linux2 + Type "help" for more information. + + Environment: + app The WSGI application. + registry Active Pyramid registry. + request Active request object. + root Root of the default resource tree. + root_factory Default root factory used to create `root`. + >>> root + + >>> registry + + >>> registry.settings['debug_notfound'] + False + >>> from myproject.views import my_view + >>> from pyramid.request import Request + >>> r = Request.blank('/') + >>> my_view(r) + {'project': 'myproject'} The WSGI application that is loaded will be available in the shell as the -``app`` global. Also, if the application that is loaded is the -:app:`Pyramid` app with no surrounding middleware, the ``root`` object -returned by the default :term:`root factory`, ``registry``, and ``settings`` -will be available. +``app`` global. Also, if the application that is loaded is the :app:`Pyramid` +app with no surrounding middleware, the ``root`` object returned by the +default :term:`root factory`, ``registry``, and ``request`` will be +available. -The interactive shell will not be able to load some of the globals like -``root``, ``registry`` and ``settings`` if the section name specified when -loading ``pshell`` is not referencing your :app:`Pyramid` application directly. -For example, if you have the following ``.ini`` file content: +You can also simply rely on the ``main`` default section name by omitting any +hash after the filename: -.. code-block:: ini - :linenos: - - [app:MyProject] - use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en - - [pipeline:main] - pipeline = - egg:WebError#evalerror - MyProject +.. code-block:: text -Use ``MyProject`` instead of ``main`` as the section name argument to -``pshell`` against the above ``.ini`` file (e.g. ``paster pshell -development.ini#MyProject``). + chrism@thinko env26]$ bin/paster pshell starter/development.ini Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). @@ -224,8 +207,27 @@ Here, we'll assume your model is stored in the ``myapp.models`` package. t = transaction When this INI file is loaded, the extra variables ``m``, ``session`` and -``t`` will be available for use immediately. This happens regardless of -whether the ``registry`` and other special variables are loaded. +``t`` will be available for use immediately. For example: + +.. code-block:: text + + chrism@thinko env26]$ bin/paster pshell starter/development.ini + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) + [GCC 4.4.3] on linux2 + Type "help" for more information. + + Environment: + app The WSGI application. + registry Active Pyramid registry. + request Active request object. + root Root of the default resource tree. + root_factory Default root factory used to create `root`. + + Custom Variables: + m myapp.models + session myapp.models.DBSession + t transaction + >>> IPython ~~~~~~~ @@ -258,9 +260,10 @@ You can use the ``paster proutes`` command in a terminal window to print a summary of routes related to your application. Much like the ``paster pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` command accepts one argument with the format ``config_file#section_name``. -The ``config_file`` is the path to your application's ``.ini`` file, -and ``section_name`` is the ``app`` section name inside the ``.ini`` file -which points to your application. +The ``config_file`` is the path to your application's ``.ini`` file, and +``section_name`` is the ``app`` section name inside the ``.ini`` file which +points to your application. By default, the ``section_name`` is ``main`` and +can be omitted. For example: -- cgit v1.2.3 From 6ce1e0cf1a141767ee0aca70786c15dd993347c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 06:10:38 -0400 Subject: add more index markers --- docs/narr/advconfig.rst | 9 ++++++++- docs/narr/assets.rst | 5 +++++ docs/narr/commandline.rst | 10 ++++++++++ docs/narr/environment.rst | 6 ++++++ docs/narr/firstapp.rst | 3 +++ docs/narr/hooks.rst | 3 ++- docs/narr/hybrid.rst | 13 +++++++++++++ docs/narr/i18n.rst | 23 +++++++++++++++++++++++ docs/narr/install.rst | 15 ++++++++++++++- docs/narr/introduction.rst | 3 +-- docs/narr/muchadoabouttraversal.rst | 15 ++++++++++++--- docs/narr/project.rst | 20 +++++++++++++++++++- docs/narr/renderers.rst | 15 ++++++++++++--- docs/narr/resources.rst | 18 ++++++++++++++++++ docs/narr/router.rst | 1 + docs/narr/security.rst | 4 ++++ docs/narr/sessions.rst | 24 +++++++++++++++++++++++- docs/narr/startup.rst | 4 ++++ docs/narr/templates.rst | 14 +++++++++++++- docs/narr/urldispatch.rst | 24 ++++++++++++++++++++++++ docs/narr/vhosting.rst | 3 +++ docs/narr/viewconfig.rst | 15 ++++++++++++++- docs/narr/views.rst | 6 ++++++ docs/narr/webob.rst | 5 ++++- 24 files changed, 242 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 3bd9c2a4e..8040a465f 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -14,7 +14,7 @@ you to ignore relative configuration statement ordering in some circumstances. .. index:: - single: imperative configuration + pair: configuration; conflict detection .. _conflict_detection: @@ -299,6 +299,9 @@ These are the methods of the configurator which provide conflict detection: provides conflict detection, because it's implemented in terms of the conflict-aware ``add_route`` and ``add_view`` methods. +.. index:: + pair: configuration; including from external sources + .. _including_configuration: Including Configuration from External Sources @@ -397,6 +400,10 @@ constraints: the routes they imply require relative ordering. Such ordering constraints are not absolved by two-phase configuration. Routes are still added in configuration execution order. +.. index:: + single: add_directive + pair: configurator; adding directives + .. _add_directive: Adding Methods to the Configurator via ``add_directive`` diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index f35f6dd7d..e609a3eab 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -35,6 +35,9 @@ static assets. For example, there's a ``static`` directory which contains ``.css``, ``.js``, and ``.gif`` files. These asset files are delivered when a user visits an application URL. +.. index:: + single: asset specifications + .. _asset_specifications: Understanding Asset Specifications @@ -85,6 +88,7 @@ individual documentation. .. index:: single: add_static_view + pair: assets; serving .. _static_assets_section: @@ -186,6 +190,7 @@ discussed in more detail later in this chapter. .. index:: single: generating static asset urls single: static asset urls + pair: assets; generating urls .. _generating_static_asset_urls: diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index b52faed20..a6ba99e17 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -183,6 +183,9 @@ hash after the filename: Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). +.. index:: + pair: pshell; extending + .. _extending_pshell: Extending the Shell @@ -229,6 +232,9 @@ When this INI file is loaded, the extra variables ``m``, ``session`` and t transaction >>> +.. index:: + single: IPython + IPython ~~~~~~~ @@ -289,6 +295,10 @@ callable could be found. If no routes are configured within your application, nothing will be printed to the console when ``paster proutes`` is executed. +.. index:: + single: scripting + single: bootstrap + .. _writing_a_script: Writing a Script diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 7f8e3953d..53234cba1 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -8,9 +8,12 @@ single: debug_all single: reload_all single: debug settings + single: debug_routematch + single: prevent_http_cache single: reload settings single: default_locale_name single: environment variables + single: Mako environment settings single: ini file settings single: PasteDeploy settings @@ -419,6 +422,9 @@ around in overridden asset directories. ``reload_assets`` makes the system *very slow* when templates are in use. Never set ``reload_assets`` to ``True`` on a production system. +.. index:: + par: settings; adding custom + .. _adding_a_custom_setting: Adding A Custom Setting diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 87487b444..42711784b 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -1,3 +1,6 @@ +.. index:: + single: hello world program + .. _firstapp_chapter: Creating Your First :app:`Pyramid` Application diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a156426ae..2a6414e1f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -218,7 +218,7 @@ Another (deprecated) mechanism which allows event subscribers more control when adding renderer global values exists in :ref:`adding_renderer_globals`. .. index:: - single: renderer globals + single: adding renderer globals .. _adding_renderer_globals: @@ -528,6 +528,7 @@ The default context URL generator is available for perusal as the class .. index:: single: IResponse + single: special view responses .. _using_iresponse: diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index a0a6a108c..ab1bf20bb 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -79,6 +79,9 @@ Typically, an application that uses traversal exclusively won't perform any calls to :meth:`pyramid.config.Configurator.add_route` in its startup code. +.. index:: + single: hybrid applications + Hybrid Applications ------------------- @@ -177,6 +180,9 @@ match is straightforward. When a route is matched: root factory were explained previously within :ref:`the_resource_tree`. +.. index:: + pair: hybrid applications; *traverse route pattern + .. _using_traverse_in_a_route_pattern: Using ``*traverse`` In a Route Pattern @@ -400,6 +406,9 @@ Traversal will begin at the root object implied by this route (either the global root, or the object returned by the ``factory`` associated with this route). +.. index:: + pair: hybrid applications; global views + Making Global Views Match +++++++++++++++++++++++++ @@ -420,6 +429,7 @@ attribute. config.add_view('myproject.views.bazbuz', name='bazbuz') .. index:: + pair: hybrid applications; *subpath single: route subpath single: subpath (route) @@ -454,6 +464,9 @@ commonly in route declarations that look like this: :class:`pyramid.static.static_view`. This effectively tells the static helper to traverse everything in the subpath as a filename. +.. index:: + pair: hybrid applications; corner cases + Corner Cases ------------ diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index c21a19b5b..924fb047a 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -353,6 +353,9 @@ The message catalog ``.pot`` template will end up in: ``myapplication/locale/myapplication.pot``. +.. index:: + single: translation domains + Translation Domains +++++++++++++++++++ @@ -494,6 +497,8 @@ translations will be available to :app:`Pyramid`. .. index:: single: localizer single: get_localizer + single: translation + single: pluralization Using a Localizer ----------------- @@ -744,6 +749,9 @@ this support out of the box and may need special code to do an equivalent. For those, you can always use the more manual translation facility described in :ref:`performing_a_translation`. +.. index:: + single: Mako i18n + Mako Pyramid I18N Support ------------------------- @@ -798,6 +806,9 @@ If this setting is supplied within the :app:`Pyramid` application settings = get_current_registry().settings default_locale_name = settings['default_locale_name'] +.. index:: + single: detecting langauges + "Detecting" Available Languages ------------------------------- @@ -857,6 +868,9 @@ languages" configuration scheme as necessary. pair: locale; negotiator single: translation directory +.. index:: + pair: activating; translation + .. _activating_translation: Activating Translation @@ -869,6 +883,9 @@ To turn translation on, you must: - ensure that your application sets the :term:`locale name` correctly. +.. index:: + pair: translation directory; adding + .. _adding_a_translation_directory: Adding a Translation Directory @@ -906,6 +923,9 @@ will be merged into translations from a message catalog added earlier if both translation directories contain translations for the same locale and :term:`translation domain`. +.. index:: + pair: setting; locale + Setting the Locale ~~~~~~~~~~~~~~~~~~ @@ -936,6 +956,9 @@ things before any translations need to be performed: function into that application as required. See :ref:`custom_locale_negotiator`. +.. index:: + single: locale negotiator + .. _locale_negotiators: Locale Negotiators diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 5b9e22182..71988469a 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -34,6 +34,9 @@ you can 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 ++++++++++++++++++++++ @@ -52,6 +55,9 @@ command: Once these steps are performed, the Python interpreter will usually be invokable via ``python2.6`` from a shell prompt. +.. index:: + pair: install; Python (from source, UNIX) + Source Compile Method +++++++++++++++++++++ @@ -95,6 +101,9 @@ Once these steps are performed, the Python interpreter will be invokable via ``$HOME/opt/Python-2.6.4/bin/python`` from a shell prompt. +.. index:: + pair: install; Python (from package, Windows) + If You Don't Yet Have A Python Interpreter (Windows) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -180,7 +189,7 @@ the script. To remediate this, you may need to do: $ sudo python ez_setup.py .. index:: - single: virtualenv + pair: install; virtualenv Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -204,6 +213,7 @@ to install it as your system's administrative user. For example: .. index:: single: virtualenv + pair: Python; virtual environment Creating the Virtual Python Environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -312,6 +322,9 @@ Installing :app:`Pyramid` on Google App Engine :ref:`appengine_tutorial` documents the steps required to install a :app:`Pyramid` application on Google App Engine. +.. index:: + single: installing on Jython + Installing :app:`Pyramid` on Jython -------------------------------------- diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d26f1b8bf..6cc5a87e5 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -67,8 +67,7 @@ Openness open source license `_. .. index:: - single: Pylons - single: repoze namespace package + single: Pylons Project What Is The Pylons Project? --------------------------- diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index a4709ef18..6ad33c1ce 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -39,6 +39,9 @@ web developer so you know when you might want to use them. :term:`Traversal` is actually a straightforward metaphor easily comprehended by anyone who's ever used a run-of-the-mill file system with folders and files. +.. index:: + single: URL dispatch + URL Dispatch ------------ @@ -100,12 +103,12 @@ from this process to the client as the final result. The server configuration specified which files would trigger some dynamic code, with the default case being to just serve the static file. +.. index:: + single: traversal + Traversal (aka Resource Location) --------------------------------- -.. index:: - single: traversal overview - Believe it or not, if you understand how serving files from a file system works, you understand traversal. And if you understand that a server might do something different based on what type of file a given request specifies, @@ -141,6 +144,9 @@ generated anywhere along the way, :app:`Pyramid` will return 404. (This isn't precisely true, as you'll see when we learn about view lookup below, but the basic idea holds.) +.. index:: + single: resource + What Is a "Resource"? --------------------- @@ -194,6 +200,9 @@ system. Traversal is in fact a superset of file system lookup. .. note:: See the chapter entitled :ref:`resources_chapter` for a more technical overview of resources. +.. index:: + single: view lookup + View Lookup ----------- diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4b08d09f6..cdf57729d 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -249,7 +249,6 @@ create`` -generated project. Within a project generated by the single: paster serve single: reload single: startup - single: mod_wsgi Running The Project Application ------------------------------- @@ -295,6 +294,10 @@ For more detailed information about the startup process, see configuration file settings that influence startup and runtime behavior, see :ref:`environment_chapter`. +.. index:: + single: mod_wsgi + single: WSGI + Viewing the Application ----------------------- @@ -533,6 +536,9 @@ implementations. to your application's ``main`` function as ``global_config`` (see the reference to the ``main`` function in :ref:`init_py`). +.. index:: + single: production.ini + ``production.ini`` ~~~~~~~~~~~~~~~~~~~ @@ -658,6 +664,9 @@ who want to use your application. setuptools add-on such as ``setuptools-git`` or ``setuptools-hg`` for this behavior to work properly. +.. index:: + single: setup.cfg + ``setup.cfg`` ~~~~~~~~~~~~~ @@ -753,6 +762,9 @@ also informs Python that the directory which contains it is a *package*. Line 12 returns a :term:`WSGI` application to the caller of the function (Paste). +.. index:: + single: views.py + ``views.py`` ~~~~~~~~~~~~ @@ -823,6 +835,9 @@ about which sort of data storage you'll want to use, so the sample application uses an instance of :class:`myproject.resources.Root` to represent the root. +.. index:: + single: static directory + ``static`` ~~~~~~~~~~ @@ -863,6 +878,9 @@ example. See :ref:`testing_chapter` for more information about writing :app:`Pyramid` unit tests. +.. index:: + pair: modifying; package structure + .. _modifying_package_structure: Modifying Package Structure diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index f329a7af9..572d5855e 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -228,6 +228,9 @@ Views which use the JSON renderer can vary non-body response attributes by using the api of the ``request.response`` attribute. See :ref:`request_response_attr`. +.. index:: + pair: renderer; JSONP + .. _jsonp_renderer: JSONP Renderer @@ -522,9 +525,6 @@ people with older code bases. returning various values in the ``response_headerlist``, this is purely a convenience. -.. index:: - single: renderer (adding) - .. _adding_and_overriding_renderers: Adding and Changing Renderers @@ -550,6 +550,9 @@ The first argument is the renderer name. The second argument is a reference to an implementation of a :term:`renderer factory` or a :term:`dotted Python name` referring to such an object. +.. index:: + pair: renderer; adding + .. _adding_a_renderer: Adding a New Renderer @@ -676,6 +679,9 @@ ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed to the ``MyJinja2Renderer`` constructor will be the full value that was set as ``renderer=`` in the view configuration. +.. index:: + pair: renderer; changing + Changing an Existing Renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -715,6 +721,9 @@ the ``name`` attribute to the renderer tag: config.add_renderer(None, 'mypackage.json_renderer_factory') +.. index:: + pair: renderer; overriding at runtime + Overriding A Renderer At Runtime -------------------------------- diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index fa8ccc549..0e0d00020 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -286,6 +286,9 @@ The shortcut method of the :term:`request` named For more information about generating resource URLs, see the documentation for :func:`pyramid.url.resource_url`. +.. index:: + pair: resource URL generation; overriding + .. _overriding_resource_url_generation: Overriding Resource URL Generation @@ -333,6 +336,9 @@ qualified, should end in a slash, and should not contain any query string or anchor elements (only path elements) to work best with :func:`~pyramid.url.resource_url`. +.. index:: + single: resource path generation + Generating the Path To a Resource --------------------------------- @@ -368,6 +374,9 @@ The resource passed in must be :term:`location`-aware. The presence or absence of a :term:`virtual root` has no impact on the behavior of :func:`~pyramid.traversal.resource_path`. +.. index:: + pair: resource; finding by path + Finding a Resource by Path -------------------------- @@ -404,6 +413,9 @@ tree does not exist), a :exc:`KeyError` will be raised. See the :func:`pyramid.traversal.find_resource` documentation for more information about resolving a path to a resource. +.. index:: + pair: resource; lineage + Obtaining the Lineage of a Resource ----------------------------------- @@ -471,6 +483,9 @@ parent (or one of its parent's parents, etc.) is an ancestor. See :func:`pyramid.location.inside` for more information. +.. index:: + pair: resource; finding root + Finding the Root Resource ------------------------- @@ -617,6 +632,9 @@ directly provided by an instance instead of overwriting them like For more information about how resource interfaces can be used by view configuration, see :ref:`using_resource_interfaces`. +.. index:: + pair: resource; finding by interface or class + Finding a Resource With a Class or Interface in Lineage ------------------------------------------------------- diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 0812f7ec7..d08261b17 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -2,6 +2,7 @@ single: request processing single: request single: router + single: request lifecycle .. _router_chapter: diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 322e905f6..65f3d7cf0 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -168,6 +168,9 @@ normal application operations, the requesting user will need to possess the to invoke the ``blog_entry_add_view`` view. If he does not, the :term:`Forbidden view` will be invoked. +.. index:: + pair: permission; default + .. _setting_a_default_permission: Setting a Default Permission @@ -212,6 +215,7 @@ When a default permission is registered: .. index:: single: ACL single: access control list + pair: resource; ACL .. _assigning_acls: diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 365ee395b..6ff9e3dea 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -15,6 +15,9 @@ implementations :app:`Pyramid` provides out of the box, how to store and retrieve data from sessions, and two session-specific features: flash messages, and cross-site request forgery attack prevention. +.. index:: + single: session factory (default) + .. _using_the_default_session_factory: Using The Default Session Factory @@ -65,6 +68,9 @@ application by using the ``session_factory`` argument to the the server) for anything but the most basic of applications where "session security doesn't matter". +.. index:: + single: session object + Using a Session Object ---------------------- @@ -137,6 +143,7 @@ Some gotchas: .. index:: single: pyramid_beaker single: Beaker + single: session factory (alternates) .. _using_alternate_session_factories: @@ -153,7 +160,7 @@ based sessions, and encrypted cookie-based sessions. See ``pyramid_beaker``. .. index:: - single: session factory + single: session factory (custom) Creating Your Own Session Factory --------------------------------- @@ -184,6 +191,9 @@ log messages for single-time display without having direct access to an HTML template. The user interface consists of a number of methods of the :term:`session` object. +.. index:: + single: session.flash + Using the ``session.flash`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -222,6 +232,9 @@ The ``allow_duplicate`` argument defaults to ``True``. If this is ``False``, and you attempt to add a message value which is already present in the queue, it will not be added. +.. index:: + single: session.pop_flash + Using the ``session.pop_flash`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -255,6 +268,9 @@ been popped. >>> request.session.pop_flash() [] +.. index:: + single: session.peek_flash + Using the ``session.peek_flash`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -298,6 +314,9 @@ post. To use CSRF token support, you must enable a :term:`session factory` as described in :ref:`using_the_default_session_factory` or :ref:`using_alternate_session_factories`. +.. index:: + single: session.get_csrf_token + Using the ``session.get_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -330,6 +349,9 @@ input field named ``csrf_token``: if token != request.POST['csrf_token']: raise ValueError('CSRF token did not match') +.. index:: + single: session.new_csrf_token + Using the ``session.new_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 788896de9..8661c8f6a 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -140,6 +140,10 @@ Here's a high-level time-ordered overview of what happens when you press The server serves the application, and the application is running, waiting to receive requests. +.. index:: + pair: settings; deployment + single: custom settings + .. _deployment_settings: Deployment Settings diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 150b173e3..7c575b9bf 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -241,6 +241,9 @@ of :func:`~pyramid.renderers.render` (a string): single: renderer (template) +.. index:: + pair: renderer; system values + .. _renderer_system_values: System Values Used During Rendering @@ -277,6 +280,9 @@ renderer itself, but most template renderers, including Chameleon and Mako renderers, make these names available as top-level template variables. +.. index:: + pair: renderer; templates + .. _templates_used_as_renderers: Templates Used as Renderers via Configuration @@ -426,7 +432,7 @@ See also :ref:`built_in_renderers` for more general information about renderers, including Chameleon ZPT renderers. .. index:: - single: sample template + single: ZPT template (sample) A Sample ZPT Template ~~~~~~~~~~~~~~~~~~~~~ @@ -596,6 +602,9 @@ Note that I always name my Chameleon ZPT template files with a ``.pt`` extension and my Chameleon text template files with a ``.txt`` extension so that these ``svn:ignore`` patterns work. +.. index:: + pair: debugging; templates + .. _debug_templates_section: Nicer Exceptions in Chameleon Templates @@ -724,6 +733,9 @@ in the ``templates`` subdirectory of the ``mypackage`` Python package. See ``mako.directories`` setting and other Mako-related settings that can be placed into the application's ``ini`` file. +.. index:: + single: Mako template (sample) + A Sample Mako Template ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index b0a7009e3..a25f47690 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -50,6 +50,9 @@ a context object). But ironically, using URL dispatch (instead of terms of "resources" entirely, because it allows you to directly map a :term:`view callable` to a route. +.. index:: + single: route configuration + Route Configuration ------------------- @@ -381,6 +384,9 @@ a separate :term:`ACL`, as documented in combine URL dispatch with :term:`traversal` as documented within :ref:`hybrid_chapter`. +.. index:: + single: route configuration arguments + Route Configuration Arguments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -402,6 +408,9 @@ neither predicates nor view configuration information. names a ``view`` and these arguments have been deprecated as of :app:`Pyramid` 1.1. +.. index:: + single: route predicates (custom) + .. _custom_route_predicates: Custom Route Predicates @@ -534,6 +543,9 @@ that the year match argument is '2010' if and only if the route name is See also :class:`pyramid.interfaces.IRoute` for more API documentation about route objects. +.. index:: + single: route matching + Route Matching -------------- @@ -745,6 +757,9 @@ representing a :term:`SQLAlchemy` model. single: matching the root URL single: root url (matching) +.. index:: + pair: matching; root URL + Matching the Root URL --------------------- @@ -914,6 +929,9 @@ The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the exception object). +.. index:: + single: cleaning up after request + .. _cleaning_up_after_a_request: Cleaning Up After a Request @@ -997,6 +1015,9 @@ our sample ``Article`` factory class is not very ambitious. .. note:: See :ref:`security_chapter` for more information about :app:`Pyramid` security and ACLs. +.. index:: + pair: debugging; route matching + .. _debug_routematch_section: Debugging Route Matching @@ -1032,6 +1053,9 @@ You can also use the ``paster proutes`` command to see a display of all the routes configured in your application; for more information, see :ref:`displaying_application_routes`. +.. index:: + pair: route; view callable lookup details + Route View Callable Registration and Lookup Details --------------------------------------------------- diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index d3ff260e3..5679cc2e2 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -14,6 +14,9 @@ URL space that it does not "naturally" inhabit. a URL "prefix", as well as serving a *portion* of a :term:`traversal` based application under a root URL. +.. index:: + single: hosting an app under a prefix + Hosting an Application Under a URL Prefix ----------------------------------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 54d3fc4ff..94b80a3f2 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -20,6 +20,10 @@ In earlier chapters, you have been exposed to a few simple view configuration declarations without much explanation. In this chapter we will explore the subject in detail. +.. index:: + pair: resource; mapping to view callable + pair: URL pattern; mapping to view callable + Mapping a Resource or URL Pattern to a View Callable ---------------------------------------------------- @@ -41,6 +45,9 @@ View configuration is performed in one of two ways: - by using the :meth:`pyramid.config.Configurator.add_view` method as per :ref:`mapping_views_using_imperative_config_section`. +.. index:: + single: view configuration parameters + .. _view_configuration_parameters: View Configuration Parameters @@ -475,6 +482,9 @@ form of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. +.. index:: + single: view_config placement + ``@view_config`` Placement ++++++++++++++++++++++++++ @@ -822,7 +832,10 @@ headers that your application code itself sets. It will only prevent caching headers that would have been set by the Pyramid HTTP caching machinery invoked as the result of the ``http_cache`` argument to view configuration. -Debugging View Configuration +.. index:: + pair: view configuration; debugging + +ebugging View Configuration ---------------------------- See :ref:`displaying_matching_views` for information about how to display diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 6acb1d28d..1c9529860 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -35,6 +35,9 @@ This chapter describes how view callables work. In the :ref:`view_config_chapter` chapter, there are details about performing view configuration, and a detailed explanation of view lookup. +.. index:: + single: view callables + View Callables -------------- @@ -586,6 +589,9 @@ callable code itself. No matter which view calling convention is used, the view code always has access to the context via ``request.context``. +.. index:: + single: Pylons-style controller dispatch + Pylons-1.0-Style "Controller" Dispatch -------------------------------------- diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 0d928e532..6e8c39523 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -243,6 +243,9 @@ tuples; all the keys are ordered, and all the values are ordered. API documentation for a multidict exists as :class:`pyramid.interfaces.IMultiDict`. +.. index:: + pair: json_body; request + .. _request_json_body: Dealing With A JSON-Encoded Request Body @@ -408,7 +411,7 @@ anything, though if you subclass :class:`pyramid.response.Response` and set ``default_content_type`` you can override this behavior. .. index:: - single: response exceptions + single: exception responses Exception Responses +++++++++++++++++++ -- cgit v1.2.3 From 8cb68208d42899b50025418812bb339f578d553f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 07:16:14 -0400 Subject: - Reordered chapters in narrative section for better new user friendliness. - Added more indexing markers to sections in documentation. --- docs/narr/firstapp.rst | 3 -- docs/narr/renderers.rst | 8 +-- docs/narr/traversal.rst | 97 +++++++++++++++++++++++++++++++++ docs/narr/urldispatch.rst | 123 ++++++++++++++++++------------------------ docs/narr/viewconfig.rst | 133 +++++++--------------------------------------- docs/narr/views.rst | 68 +++++++++--------------- 6 files changed, 198 insertions(+), 234 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 42711784b..6c53f3de0 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -322,6 +322,3 @@ see :class:`~pyramid.config.Configurator` . For more information about :term:`view configuration`, see :ref:`view_config_chapter`. -An example of using *declarative* configuration (:term:`ZCML`) instead of -imperative configuration to create a similar "hello world" is available -within the documentation for :term:`pyramid_zcml`. diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 572d5855e..801741c43 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -3,10 +3,10 @@ Renderers ========= -A view needn't *always* return a :term:`Response` object. If a view -happens to return something which does not implement the Pyramid -Response interface, :app:`Pyramid` will attempt to use a -:term:`renderer` to construct a response. For example: +A view callable needn't *always* return a :term:`Response` object. If a view +happens to return something which does not implement the Pyramid Response +interface, :app:`Pyramid` will attempt to use a :term:`renderer` to construct +a response. For example: .. code-block:: python :linenos: diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index e1715dc25..aa36b4455 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -456,6 +456,103 @@ as the sole argument: ``request``; it is expected to return a response. -specific request attributes are also available as described in :ref:`special_request_attributes`. +.. index:: + single: resource interfaces + +.. _using_resource_interfaces: + +Using Resource Interfaces In View Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of registering your views with a ``context`` that names a Python +resource *class*, you can optionally register a view callable with a +``context`` which is an :term:`interface`. An interface can be attached +arbitrarily to any resource object. View lookup treats context interfaces +specially, and therefore the identity of a resource can be divorced from that +of the class which implements it. As a result, associating a view with an +interface can provide more flexibility for sharing a single view between two +or more different implementations of a resource type. For example, if two +resource objects of different Python class types share the same interface, +you can use the same view configuration to specify both of them as a +``context``. + +In order to make use of interfaces in your application during view dispatch, +you must create an interface and mark up your resource classes or instances +with interface declarations that refer to this interface. + +To attach an interface to a resource *class*, you define the interface and +use the :func:`zope.interface.implements` function to associate the interface +with the class. + +.. code-block:: python + :linenos: + + from zope.interface import Interface + from zope.interface import implements + + class IHello(Interface): + """ A marker interface """ + + class Hello(object): + implements(IHello) + +To attach an interface to a resource *instance*, you define the interface and +use the :func:`zope.interface.alsoProvides` function to associate the +interface with the instance. This function mutates the instance in such a +way that the interface is attached to it. + +.. code-block:: python + :linenos: + + from zope.interface import Interface + from zope.interface import alsoProvides + + class IHello(Interface): + """ A marker interface """ + + class Hello(object): + pass + + def make_hello(): + hello = Hello() + alsoProvides(hello, IHello) + return hello + +Regardless of how you associate an interface, with a resource instance, or a +resource class, the resulting code to associate that interface with a view +callable is the same. Assuming the above code that defines an ``IHello`` +interface lives in the root of your application, and its module is named +"resources.py", the interface declaration below will associate the +``mypackage.views.hello_world`` view with resources that implement, or +provide, this interface. + +.. code-block:: python + :linenos: + + # config is an instance of pyramid.config.Configurator + + config.add_view('mypackage.views.hello_world', name='hello.html', + context='mypackage.resources.IHello') + +Any time a resource that is determined to be the :term:`context` provides +this interface, and a view named ``hello.html`` is looked up against it as +per the URL, the ``mypackage.views.hello_world`` view callable will be +invoked. + +Note, in cases where a view is registered against a resource class, and a +view is also registered against an interface that the resource class +implements, an ambiguity arises. Views registered for the resource class take +precedence over any views registered for any interface the resource class +implements. Thus, if one view configuration names a ``context`` of both the +class type of a resource, and another view configuration names a ``context`` +of interface implemented by the resource's class, and both view +configurations are otherwise identical, the view registered for the context's +class will "win". + +For more information about defining resources with interfaces for use within +view configuration, see :ref:`resources_which_implement_interfaces`. + + References ---------- diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a25f47690..0598cd4f2 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -6,28 +6,12 @@ URL Dispatch ============ -:term:`URL dispatch` provides a simple way to map URLs to :term:`view` -code using a simple pattern matching language. An ordered set of -patterns is checked one-by-one. If one of the patterns matches the path -information associated with a request, a particular :term:`view -callable` is invoked. - -:term:`URL dispatch` is one of two ways to perform :term:`resource location` -in :app:`Pyramid`; the other way is to use :term:`traversal`. If no route is -matched using :term:`URL dispatch`, :app:`Pyramid` falls back to -:term:`traversal` to handle the :term:`request`. - -It is the responsibility of the :term:`resource location` subsystem -(i.e., :term:`URL dispatch` or :term:`traversal`) to find the resource -object that is the :term:`context` of the :term:`request`. Once the -:term:`context` is determined, :term:`view lookup` is then responsible -for finding and invoking a :term:`view callable`. A view callable is a -specific bit of code, defined in your application, that receives the -:term:`request` and returns a :term:`response` object. - -Where appropriate, we will describe how view lookup interacts with -:term:`resource location`. The :ref:`view_config_chapter` chapter describes -the details of :term:`view lookup`. +:term:`URL dispatch` provides a simple way to map URLs to :term:`view` code +using a simple pattern matching language. An ordered set of patterns is +checked one-by-one. If one of the patterns matches the path information +associated with a request, a particular :term:`view callable` is invoked. A +view callable is a specific bit of code, defined in your application, that +receives the :term:`request` and returns a :term:`response` object. High-Level Operational Overview ------------------------------- @@ -37,18 +21,11 @@ If route configuration is present in an application, the :app:`Pyramid` matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request`, -:app:`Pyramid` will invoke :term:`view lookup` using a :term:`context` -resource generated by the route match. +:app:`Pyramid` will invoke :term:`view lookup` to find a matching view. -However, if no route pattern matches the information in the :term:`request` -provided to :app:`Pyramid`, it will fail over to using :term:`traversal` to -perform resource location and view lookup. - -Technically, URL dispatch is a :term:`resource location` mechanism (it finds -a context object). But ironically, using URL dispatch (instead of -:term:`traversal`) allows you to avoid thinking about your application in -terms of "resources" entirely, because it allows you to directly map a -:term:`view callable` to a route. +If no route pattern in the route map matches the information in the +:term:`request` provided in your application, :app:`Pyramid` will fail over +to using :term:`traversal` to perform resource location and view lookup. .. index:: single: route configuration @@ -89,8 +66,8 @@ example: When a :term:`view callable` added to the configuration by way of :meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route -via its ``route_name`` predicate, that view callable will always be found -and invoked when the associated route pattern matches during a request. +via its ``route_name`` predicate, that view callable will always be found and +invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's "setup" code, instead only using ``add_route`` statements using a @@ -323,12 +300,11 @@ Route Declaration Ordering Route configuration declarations are evaluated in a specific order when a request enters the system. As a result, the order of route configuration -declarations is very important. - -The order that routes declarations are evaluated is the order in which they -are added to the application at startup time. This is unlike -:term:`traversal`, which depends on emergent behavior which happens as a -result of traversing a resource tree. +declarations is very important. The order that routes declarations are +evaluated is the order in which they are added to the application at startup +time. (This is unlike a different way of mapping URLs to code that +:app:`Pyramid` provides, named :term:`traversal`, which does not depend on +pattern ordering). For routes added via the :mod:`~pyramid.config.Configurator.add_route` method, the order that routes are evaluated is the order in which they are added to @@ -551,27 +527,30 @@ Route Matching The main purpose of route configuration is to match (or not match) the ``PATH_INFO`` present in the WSGI environment provided during a request -against a URL path pattern. +against a URL path pattern. ``PATH_INFO`` represents the path portion of the +URL that was requested. The way that :app:`Pyramid` does this is very simple. When a request enters the system, for each route configuration declaration present in the system, -:app:`Pyramid` checks the ``PATH_INFO`` against the pattern declared. - -If any route matches, the route matching process stops. The :term:`request` -is decorated with a special :term:`interface` which describes it as a "route -request", the :term:`context` resource is generated, and the context and the -resulting request are handed off to :term:`view lookup`. During view lookup, -if a :term:`view callable` associated with the matched route is found, that -view is called. +:app:`Pyramid` checks the request's ``PATH_INFO`` against the pattern +declared. This checking happens in the order that the routes were declared +via :meth:`pyramid.config.Configurator.add_route`. When a route configuration is declared, it may contain :term:`route predicate` arguments. All route predicates associated with a route declaration must be ``True`` for the route configuration to be used for a -given request. - -If any predicate in the set of :term:`route predicate` arguments provided to -a route configuration returns ``False``, that route is skipped and route -matching continues through the ordered set of routes. +given request during a check. If any predicate in the set of :term:`route +predicate` arguments provided to a route configuration returns ``False`` +during a check, that route is skipped and route matching continues through +the ordered set of routes. + +If any route matches, the route matching process stops and the :term:`view +lookup` subsystem takes over to find the most reasonable view callable for +the matched route. Most often, there's only one view that will match (a view +configured with a ``route_name`` argument matching the matched route). To +gain a better understanding of how routes and views are associated in a real +application, you can use the ``paster pviews`` command, as documented in +:ref:`displaying_matching_views`. If no route matches after all route patterns are exhausted, :app:`Pyramid` falls back to :term:`traversal` to do :term:`resource location` and @@ -1083,24 +1062,28 @@ when the route pattern is matched during a request. To do so: object is decorated with the route-specific interface. - The fact that the request is decorated with a route-specific interface - causes the view lookup machinery to always use the view callable registered - using that interface by the route configuration to service requests that - match the route pattern. - -In this way, we supply a shortcut to the developer. Under the hood, the -:term:`resource location` and :term:`view lookup` subsystems provided by -:app:`Pyramid` are still being utilized, but in a way which does not require -a developer to understand either of them in detail. It also means that we -can allow a developer to combine :term:`URL dispatch` and :term:`traversal` -in various exceptional cases as documented in :ref:`hybrid_chapter`. - -To gain a better understanding of how routes and views are associated in a -real application, you can use the ``paster pviews`` command, as documented -in :ref:`displaying_matching_views`. + causes the :term:`view lookup` machinery to always use the view callable + registered using that interface by the route configuration to service + requests that match the route pattern. + +As we can see from the above description, technically, URL dispatch doesn't +actually map a URL pattern directly to a view callable. Instead, URL +dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` +:term:`resource location` subsystem (i.e., :term:`URL dispatch` or +:term:`traversal`) finds a :term:`resource` object that is the +:term:`context` of a :term:`request`. Once the :term:`context` is determined, +a separate subsystem named :term:`view lookup` is then responsible for +finding and invoking a :term:`view callable` based on information available +in the context and the request. When URL dispatch is used, the resource +location and view lookup subsystems provided by :app:`Pyramid` are still +being utilized, but in a way which does not require a developer to understand +either of them in detail. + +If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back +to :term:`traversal` to handle the :term:`request`. References ---------- A tutorial showing how :term:`URL dispatch` can be used to create a :app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. - diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 94b80a3f2..d776887c8 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -235,8 +235,10 @@ arguments that are supplied, the more specific, and narrower the usage of the configured view. ``name`` - The :term:`view name` required to match this view callable. Read - :ref:`traversal_chapter` to understand the concept of a view name. + The :term:`view name` required to match this view callable. A ``name`` + argument is typically only used when your application uses + :term:`traversal`. Read :ref:`traversal_chapter` to understand the concept + of a view name. If ``name`` is not supplied, the empty string is used (implying the default view). @@ -417,8 +419,7 @@ lives within a :app:`Pyramid` application module ``views.py``: from pyramid.view import view_config from pyramid.response import Response - @view_config(name='my_view', request_method='POST', context=MyResource, - permission='read') + @view_config(route_name='ok', request_method='POST', permission='read') def my_view(request): return Response('OK') @@ -429,9 +430,8 @@ configuration stanza: .. code-block:: python :linenos: - config.add_view('mypackage.views.my_view', name='my_view', - request_method='POST', context=MyResource, - permission='read') + config.add_view('mypackage.views.my_view', route_name='ok', + request_method='POST', permission='read') All arguments to ``view_config`` may be omitted. For example: @@ -499,7 +499,7 @@ If your view callable is a function, it may be used as a function decorator: from pyramid.view import view_config from pyramid.response import Response - @view_config(name='edit') + @view_config(route_name='edit') def edit(request): return Response('edited!') @@ -514,7 +514,7 @@ against a class as when they are applied against a function. For example: from pyramid.response import Response from pyramid.view import view_config - @view_config() + @view_config(route_name='hello') class MyView(object): def __init__(self, request): self.request = request @@ -539,7 +539,7 @@ decorator syntactic sugar, if you wish: def __call__(self): return Response('hello') - my_view = view_config()(MyView) + my_view = view_config(route_name='hello')(MyView) More than one :class:`~pyramid.view.view_config` decorator can be stacked on top of any number of others. Each decorator creates a separate view @@ -551,8 +551,8 @@ registration. For example: from pyramid.view import view_config from pyramid.response import Response - @view_config(name='edit') - @view_config(name='change') + @view_config(route_name='edit') + @view_config(route_name='change') def edit(request): return Response('edited!') @@ -570,7 +570,7 @@ The decorator can also be used against a method of a class: def __init__(self, request): self.request = request - @view_config(name='hello') + @view_config(route_name='hello') def amethod(self): return Response('hello') @@ -592,7 +592,7 @@ against the ``amethod`` method could be spelled equivalently as the below: from pyramid.response import Response from pyramid.view import view_config - @view_config(attr='amethod', name='hello') + @view_config(attr='amethod', route_name='hello') class MyView(object): def __init__(self, request): self.request = request @@ -624,7 +624,7 @@ this method are very similar to the arguments that you provide to the # config is assumed to be an instance of the # pyramid.config.Configurator class - config.add_view(hello_world, name='hello.html') + config.add_view(hello_world, route_name='hello') The first argument, ``view``, is required. It must either be a Python object which is the view itself or a :term:`dotted Python name` to such an object. @@ -636,102 +636,6 @@ When you use only :meth:`~pyramid.config.Configurator.add_view` to add view configurations, you don't need to issue a :term:`scan` in order for the view configuration to take effect. -.. index:: - single: resource interfaces - -.. _using_resource_interfaces: - -Using Resource Interfaces In View Configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Instead of registering your views with a ``context`` that names a Python -resource *class*, you can optionally register a view callable with a -``context`` which is an :term:`interface`. An interface can be attached -arbitrarily to any resource object. View lookup treats context interfaces -specially, and therefore the identity of a resource can be divorced from that -of the class which implements it. As a result, associating a view with an -interface can provide more flexibility for sharing a single view between two -or more different implementations of a resource type. For example, if two -resource objects of different Python class types share the same interface, -you can use the same view configuration to specify both of them as a -``context``. - -In order to make use of interfaces in your application during view dispatch, -you must create an interface and mark up your resource classes or instances -with interface declarations that refer to this interface. - -To attach an interface to a resource *class*, you define the interface and -use the :func:`zope.interface.implements` function to associate the interface -with the class. - -.. code-block:: python - :linenos: - - from zope.interface import Interface - from zope.interface import implements - - class IHello(Interface): - """ A marker interface """ - - class Hello(object): - implements(IHello) - -To attach an interface to a resource *instance*, you define the interface and -use the :func:`zope.interface.alsoProvides` function to associate the -interface with the instance. This function mutates the instance in such a -way that the interface is attached to it. - -.. code-block:: python - :linenos: - - from zope.interface import Interface - from zope.interface import alsoProvides - - class IHello(Interface): - """ A marker interface """ - - class Hello(object): - pass - - def make_hello(): - hello = Hello() - alsoProvides(hello, IHello) - return hello - -Regardless of how you associate an interface, with a resource instance, or a -resource class, the resulting code to associate that interface with a view -callable is the same. Assuming the above code that defines an ``IHello`` -interface lives in the root of your application, and its module is named -"resources.py", the interface declaration below will associate the -``mypackage.views.hello_world`` view with resources that implement, or -provide, this interface. - -.. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator - - config.add_view('mypackage.views.hello_world', name='hello.html', - context='mypackage.resources.IHello') - -Any time a resource that is determined to be the :term:`context` provides -this interface, and a view named ``hello.html`` is looked up against it as -per the URL, the ``mypackage.views.hello_world`` view callable will be -invoked. - -Note, in cases where a view is registered against a resource class, and a -view is also registered against an interface that the resource class -implements, an ambiguity arises. Views registered for the resource class take -precedence over any views registered for any interface the resource class -implements. Thus, if one view configuration names a ``context`` of both the -class type of a resource, and another view configuration names a ``context`` -of interface implemented by the resource's class, and both view -configurations are otherwise identical, the view registered for the context's -class will "win". - -For more information about defining resources with interfaces for use within -view configuration, see :ref:`resources_which_implement_interfaces`. - .. index:: single: view security pair: security; view @@ -753,8 +657,9 @@ configuration using :meth:`~pyramid.config.Configurator.add_view`: # config is an instance of pyramid.config.Configurator - config.add_view('myproject.views.add_entry', name='add.html', - context='myproject.resources.IBlog', permission='add') + config.add_route('add', '/add.html', factory='mypackage.Blog') + config.add_view('myproject.views.add_entry', route_name='add', + permission='add') When an :term:`authorization policy` is enabled, this view will be protected with the ``add`` permission. The view will *not be called* if the user does @@ -835,7 +740,7 @@ invoked as the result of the ``http_cache`` argument to view configuration. .. index:: pair: view configuration; debugging -ebugging View Configuration +Debugging View Configuration ---------------------------- See :ref:`displaying_matching_views` for information about how to display diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 1c9529860..a3fd61098 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -3,10 +3,10 @@ Views ===== -One of the primary jobs of :app:`Pyramid` is to find and invoke a -:term:`view callable` when a :term:`request` reaches your application. View -callables are bits of code which do something interesting in response to a -request made to your application. +One of the primary jobs of :app:`Pyramid` is to find and invoke a :term:`view +callable` when a :term:`request` reaches your application. View callables +are bits of code which do something interesting in response to a request made +to your application. They are the "meat" of any interesting web application. .. note:: @@ -17,23 +17,10 @@ request made to your application. that implements a view *callable*, and the process of view *lookup*. -The :ref:`urldispatch_chapter`, and :ref:`traversal_chapter` chapters -describes how, using information from the :term:`request`, a -:term:`context` resource is computed. But the context resource itself -isn't very useful without an associated :term:`view callable`. A view -callable returns a response to a user, often using the context resource -to do so. - -The job of actually locating and invoking the "best" :term:`view callable` is -the job of the :term:`view lookup` subsystem. The view lookup subsystem -compares the resource supplied by :term:`resource location` and information -in the :term:`request` against :term:`view configuration` statements made by -the developer to choose the most appropriate view callable for a specific -set of circumstances. - -This chapter describes how view callables work. In the -:ref:`view_config_chapter` chapter, there are details about performing -view configuration, and a detailed explanation of view lookup. +This chapter describes how view callables should be defined. We'll have to +wait until a following chapter (entitled :ref:`view_config_chapter`) to find +out how we actually tell :app:`Pyramid` to wire up view callables to +particular URL patterns and other request circumstances. .. index:: single: view callables @@ -42,26 +29,20 @@ View Callables -------------- View callables are, at the risk of sounding obvious, callable Python -objects. Specifically, view callables can be functions, classes, or -instances that implement an ``__call__`` method (making the -instance callable). +objects. Specifically, view callables can be functions, classes, or instances +that implement an ``__call__`` method (making the instance callable). View callables must, at a minimum, accept a single argument named ``request``. This argument represents a :app:`Pyramid` :term:`Request` -object. A request object encapsulates a WSGI environment provided to -:app:`Pyramid` by the upstream :term:`WSGI` server. As you might expect, -the request object contains everything your application needs to know -about the specific HTTP request being made. +object. A request object represents a :term:`WSGI` environment provided to +:app:`Pyramid` by the upstream WSGI server. As you might expect, the request +object contains everything your application needs to know about the specific +HTTP request being made. A view callable's ultimate responsibility is to create a :mod:`Pyramid` -:term:`Response` object. This can be done by creating the response object in -the view callable code and returning it directly, as we will be doing in this -chapter. However, if a view callable does not return a response itself, it -can be configured to use a :term:`renderer` that converts its return value -into a :term:`Response` object. Using renderers is the common way that -templates are used with view callables to generate markup: see the -:ref:`renderers_chapter` chapter for details. In some cases, a response may -also be generated by raising an exception within a view callable. +:term:`Response` object. This can be done by creating a :term:`Response` +object in the view callable code and returning it directly or by raising +special kinds of exceptions from within the body of a view callable. .. index:: single: view calling convention @@ -160,13 +141,14 @@ the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response object because it inherits from :class:`~pyramid.response.Response`. For examples, see :ref:`http_exceptions` and :ref:`http_redirect`. -You can also return objects from view callables that aren't instances of (or -instances of classes which are subclasses of) -:class:`pyramid.response.Response` in various circumstances. This can be -helpful when writing tests and when attempting to share code between view -callables. See :ref:`renderers_chapter` for the common way to allow for -this. A much less common way to allow for view callables to return -non-Response objects is documented in :ref:`using_iresponse`. +.. note:: + + You can also return objects from view callables that aren't instances of + :class:`pyramid.response.Response` in various circumstances. This can be + helpful when writing tests and when attempting to share code between view + callables. See :ref:`renderers_chapter` for the common way to allow for + this. A much less common way to allow for view callables to return + non-Response objects is documented in :ref:`using_iresponse`. .. index:: single: view exceptions -- cgit v1.2.3 From be9bbff6440750e56a73f534bc09511ef5d2b8b4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 07:31:33 -0400 Subject: use less awkward language --- docs/narr/configuration.rst | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 3ecb4b06a..dacf09f18 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -6,15 +6,16 @@ Application Configuration ========================= -The way in which code is plugged in to :app:`Pyramid` for a specific -application is referred to as "configuration". Most people understand -"configuration" as coarse settings that inform the high-level operation of a -specific application deployment. For instance, it's easy to think of the -values implied by a ``.ini`` file parsed at application startup time as -"configuration". However, :app:`Pyramid` also uses the word "configuration" -to express standardized ways that code gets plugged into a deployment of the -framework itself. When you plug code into the :app:`Pyramid` framework, you -are "configuring" :app:`Pyramid` to create a particular application. +Most people already understand "configuration" as settings that influence the +operation of an application. For instance, it's easy to think of the values +in a ``.ini`` file parsed at application startup time as "configuration". +However, if you're reasonably open-minded, it's easy to think of *code* as +configuration too. Since Pyramid, like most other web application platforms, +is a *framework*, it calls into code that you write (as opposed to a +*library*, which is code that exists purely for your to call). The act of +plugging application code that you've written into :app:`Pyramid` is also +referred to within this documentation as "configuration"; you are configuring +:app:`Pyramid` to call the code that makes up your application. There are two ways to configure a :app:`Pyramid` application: :term:`imperative configuration` and :term:`declarative configuration`. Both @@ -144,3 +145,10 @@ In the example above, the scanner translates the arguments to config.add_view(hello) +Summary +------- + +There are two ways to configure a :app:`Pyramid` application: declaratively +and imperatively. You can choose the mode you're most comfortable with; both +are completely equivalent. Examples in this documentation will use both +modes interchangeably. -- cgit v1.2.3 From 87a689d71191a175ee20e52701a9e802548f91a6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 07:32:01 -0400 Subject: typo --- docs/narr/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index dacf09f18..597d48b09 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -12,7 +12,7 @@ in a ``.ini`` file parsed at application startup time as "configuration". However, if you're reasonably open-minded, it's easy to think of *code* as configuration too. Since Pyramid, like most other web application platforms, is a *framework*, it calls into code that you write (as opposed to a -*library*, which is code that exists purely for your to call). The act of +*library*, which is code that exists purely for you to call). The act of plugging application code that you've written into :app:`Pyramid` is also referred to within this documentation as "configuration"; you are configuring :app:`Pyramid` to call the code that makes up your application. -- cgit v1.2.3 From 0bac345c6ff595302e765dfce9bd91e198d61038 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 12:39:35 -0400 Subject: name noncpython versions we work with --- docs/narr/install.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 71988469a..f543753ce 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -20,7 +20,8 @@ run :app:`Pyramid`. :app:`Pyramid` is known to run on all popular Unix-like systems such as Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on Google's App Engine, :term:`PyPy`, and :term:`Jython`. +known to run on Google's App Engine, :term:`PyPy` (1.5), and :term:`Jython` +(2.5.2). :app:`Pyramid` installation does not require the compilation of any C code, so you need only a Python interpreter that meets the -- cgit v1.2.3 From 5adf4c099905cb41f68b38d6443bd2fe62c76889 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 19:03:26 -0400 Subject: add description of keys and values --- docs/narr/commandline.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index a6ba99e17..f4cf951ba 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -192,10 +192,11 @@ Extending the Shell ~~~~~~~~~~~~~~~~~~~ It is sometimes convenient when using the interactive shell often to have -some variables significant to your application already loaded as globals -when you start the ``pshell``. To facilitate this, ``pshell`` will look -for a special ``[pshell]`` section in your INI file and expose the subsequent -key/value pairs to the shell. +some variables significant to your application already loaded as globals when +you start the ``pshell``. To facilitate this, ``pshell`` will look for a +special ``[pshell]`` section in your INI file and expose the subsequent +key/value pairs to the shell. Each key is a variable name that will be +global within the pshell session; each value is a :term:`dotted Python name`. For example, you want to expose your model to the shell, along with the database session so that you can mutate the model on an actual database. -- cgit v1.2.3 From 0b0b2065558649c0af65a08e94cd99894889bea3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 21 Jul 2011 14:41:22 -0400 Subject: urllib2 example of creating a request suitable for producing a json body --- docs/narr/webob.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 6e8c39523..106024db3 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -296,6 +296,20 @@ For the above view, printed to the console will be: {u'a': 1} +For bonus points, here's a bit of client-side code that will produce a +request that has a body suitable for reading via ``request.json_body`` using +Python's ``urllib2`` instead of a Javascript AJAX request: + +.. code-block:: python + + import urllib2 + import json + + json_payload = json.dumps({'a':1}) + headers = {'Content-Type':'application/json; charset=utf-8'} + req = urllib2.Request('http://localhost:6543/', json_payload, headers) + resp = urllib2.urlopen(req) + More Details ++++++++++++ -- cgit v1.2.3 From 39e88a1f2903f840feeff77e572c7bf3efebb875 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 21 Jul 2011 23:08:31 -0400 Subject: - Change all scaffolding templates that point to docs.pylonsproject.org to use ``/projects/pyramid/current`` rather than ``/projects/pyramid/dev``. --- docs/narr/MyProject/myproject/templates/mytemplate.pt | 14 +++++++------- docs/narr/templates.rst | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 632c34876..97f1e1aa3 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -46,7 +46,7 @@

Search documentation

+ action="http://docs.pylonsproject.org/pyramid/current/search.html">
@@ -60,32 +60,32 @@
  • - + Narrative Documentation
  • - + API Documentation
  • - + Tutorials
  • - + Change History
  • - + Sample Applications
  • - + Support and Development
  • diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 7c575b9bf..af7257466 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -454,7 +454,7 @@ Here's what a simple :term:`Chameleon` ZPT template used under

    Welcome to ${project}, an application generated by the pyramid web application framework.

    @@ -752,7 +752,7 @@ look like:

    Welcome to ${project}, an application generated by the pyramid web application framework.

    -- cgit v1.2.3 From 15ac15d60e788c087facfce85b1ead9f7dd4c3ae Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 22 Jul 2011 11:55:19 -0500 Subject: Fixed formatting fail. --- docs/narr/hooks.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2a6414e1f..985934736 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -601,6 +601,9 @@ to make sure the object implements every attribute and method outlined in :class:`pyramid.interfaces.IResponse` and you'll have to ensure that it's marked up with ``zope.interface.implements(IResponse)``: +.. code-block:: python + :linenos: + from pyramid.interfaces import IResponse from zope.interface import implements -- cgit v1.2.3 From b202997e2e0b9eed860afc9baa9497ba5b986fb1 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 23 Jul 2011 01:12:03 -0700 Subject: remove extra word --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 6cc5a87e5..63c31d340 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -30,7 +30,7 @@ create web applications. own via a set of libraries if the framework provides a set of facilities that fits your application requirements. -Pyramid attempts to follow follow these design and engineering principles: +Pyramid attempts to follow these design and engineering principles: Simplicity :app:`Pyramid` takes a *"pay only for what you eat"* approach. You can get -- cgit v1.2.3 From afe76b3bc0f378030d2dbffeb63faba829139f8f Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 23 Jul 2011 22:11:31 -0700 Subject: remove extra word --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 6c53f3de0..eb05f8e6d 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -153,7 +153,7 @@ defined imports and function definitions, placed within the confines of an app = config.make_wsgi_app() serve(app, host='0.0.0.0') -Let's break this down this piece-by-piece. +Let's break this down piece-by-piece. Configurator Construction ~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 84bd9544083c38ded264b58f13958ab945c92e5e Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 23 Jul 2011 22:29:03 -0700 Subject: typo --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index eb05f8e6d..66632e123 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -182,7 +182,7 @@ The ``config = Configurator()`` line above creates an instance of the :class:`~pyramid.config.Configurator` class. The resulting ``config`` object represents an API which the script uses to configure this particular :app:`Pyramid` application. Methods called on the Configurator will cause -registrations to be made in a :term:`application registry` associated with +registrations to be made in an :term:`application registry` associated with the application. .. _adding_configuration: -- cgit v1.2.3 From 0c2141c78c85898c87495f040617699e79a49c04 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 23 Jul 2011 23:14:36 -0700 Subject: Removed repetitive and badly formed sentence --- docs/narr/project.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index cdf57729d..34a641c4a 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -99,9 +99,8 @@ We'll choose the ``pyramid_starter`` scaffold for this purpose. $ bin/paster create -t pyramid_starter -The above command uses the ``paster`` command to create a project using the -``pyramid_starter`` scaffold. The ``paster create`` command creates project -from a scaffold. To use a different scaffold, such as +The above command uses the ``paster create`` command to create a project with the +``pyramid_starter`` scaffold. To use a different scaffold, such as ``pyramid_routesalchemy``, you'd just change the last argument. For example: .. code-block:: text -- cgit v1.2.3 From 82c2fc57e36c65493ba0fa39368733c189d954c6 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 23 Jul 2011 23:55:31 -0700 Subject: replace extra 'the' with 'be' --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 34a641c4a..bf1a610b4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -176,7 +176,7 @@ command ``python setup.py develop`` The file named ``setup.py`` will be in the root of the paster-generated project directory. The ``python`` you're invoking should be the one that lives in the ``bin`` directory of your virtual Python environment. Your -terminal's current working directory *must* the the newly created project +terminal's current working directory *must* be the newly created project directory. For example: .. code-block:: text -- cgit v1.2.3 From 5c05ef41bfe538b1ce802bb163a40dbd8880e757 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 24 Jul 2011 00:10:35 -0700 Subject: extra 's' removed --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index bf1a610b4..32846f848 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -467,7 +467,7 @@ the default. The ``use`` setting is the only setting *required* in the ``[app:MyProject]`` section unless you've changed the callable referred to by the ``egg:MyProject`` entry point to accept more arguments: other settings you -add to this section are passed as keywords arguments to the callable +add to this section are passed as keyword arguments to the callable represented by this entry point (``main`` in our ``__init__.py`` module). You can provide startup-time configuration parameters to your application by adding more settings to this section. -- cgit v1.2.3 From 17fd1443f4f8107023c90286e46362dd035d480c Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 24 Jul 2011 00:14:23 -0700 Subject: typo --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 32846f848..ca7d97ca9 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -481,7 +481,7 @@ template changes will not require an application restart to be detected. See The ``debug_templates`` setting in the ``[app:MyProject]`` section is a :app:`Pyramid` -specific setting which is passed into the framework. If it exists, and its value is ``true``, :term:`Chameleon` template exceptions will -contained more detailed and helpful information about the error than when +contain more detailed and helpful information about the error than when this value is ``false``. See :ref:`debug_templates_section` for more information. -- cgit v1.2.3 From 04e4f2f03d487d5b8c55b52ea1d882b7464574c0 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 24 Jul 2011 00:18:43 -0700 Subject: Removed extra 'if' --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ca7d97ca9..47cdbdc83 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -458,7 +458,7 @@ the default. point can thus be referred to as a "Paste application factory in the ``MyProject`` project which has the entry point named ``main`` where the entry point refers to a ``main`` function in the ``mypackage`` module". - If indeed if you open up the ``__init__.py`` module generated within the + Indeed, if you open up the ``__init__.py`` module generated within the ``myproject`` package, you'll see a ``main`` function. This is the function called by :term:`PasteDeploy` when the ``paster serve`` command is invoked against our application. It accepts a global configuration -- cgit v1.2.3 From b210666d36ef855df45478526d3ed54196955a00 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 24 Jul 2011 00:40:34 -0700 Subject: missing word --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 47cdbdc83..5f4878470 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -846,7 +846,7 @@ template. It includes CSS and images. ``templates/mytemplate.pt`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The single :term:`Chameleon` template exists in the project. Its contents +The single :term:`Chameleon` template that exists in the project. Its contents are too long to show here, but it displays a default page when rendered. It is referenced by the call to ``add_view`` as the ``renderer`` attribute in the ``__init__`` file. See :ref:`views_which_use_a_renderer` for more -- cgit v1.2.3 From 4396c62c5ebb07ffdc418955c251ed4d62d45817 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 24 Jul 2011 11:00:09 -0700 Subject: Rewrote bad sentence --- docs/narr/startup.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 8661c8f6a..68df9d417 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -112,11 +112,11 @@ Here's a high-level time-ordered overview of what happens when you press (which is internal to Paste) such as ``reload_templates``, ``debug_authorization``, etc. -#. The ``main`` function then calls various methods on the an instance of the - class :class:`~pyramid.config.Configurator` method. The intent of - calling these methods is to populate an :term:`application registry`, - which represents the :app:`Pyramid` configuration related to the - application. +#. The ``main`` function then calls various methods on the instance of the + class :class:`~pyramid.config.Configurator` created in the previous step. + The intent of calling these methods is to populate an + :term:`application registry`, which represents the :app:`Pyramid` + configuration related to the application. #. The :meth:`~pyramid.config.Configurator.make_wsgi_app` method is called. The result is a :term:`router` instance. The router is associated with -- cgit v1.2.3 From 1f901ab75c55bafc9c233c3c9588cc1bd92d9d66 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 28 Jul 2011 17:06:29 -0400 Subject: add some edits to the docs for response_adapter decorator; fix renderings --- docs/narr/hooks.rst | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index df081d35c..fc3f01271 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -575,20 +575,6 @@ Response: config.add_response_adapter(string_response_adapter, str) -The above example using the :class:`~pyramid.response.response_adapter` -decorator: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - from pyramid.response import response_adapter - - @response_adapter(str) - def string_response_adapter(s): - response = Response(s) - return response - Likewise, if you want to be able to return a simplified kind of response object from view callables, you can use the IResponse hook to register an adapter to the more complex IResponse interface: @@ -639,6 +625,29 @@ startup time, as by their nature, instances of this class (and instances of subclasses of the class) will natively provide IResponse. The adapter registered for ``webob.Response`` simply returns the response object. +Instead of using :meth:`pyramid.config.Configurator.add_response_adapter`, +you can use the :class:`pyramid.response.response_adapter` decorator: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.response import response_adapter + + @response_adapter(str) + def string_response_adapter(s): + response = Response(s) + return response + +The above example, when scanned, has the same effect as: + +.. code-block:: python + + config.add_response_adapter(string_response_adapter, str) + +The :class:`~pyramid.response.response_adapter` decorator will have no effect +until activated by a :term:`scan`. + .. index:: single: view mapper -- cgit v1.2.3 From 875ded31e7fdd0c85d1c91458248581b9dd729d7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 30 Jul 2011 01:50:24 -0600 Subject: Updated all of the docs to reflect the new pyramid.* settings prefix. --- docs/narr/MyProject/development.ini | 12 +-- docs/narr/MyProject/production.ini | 12 +-- docs/narr/commandline.rst | 12 +-- docs/narr/environment.rst | 162 ++++++++++++++++++------------------ docs/narr/hooks.rst | 8 +- docs/narr/i18n.rst | 18 ++-- docs/narr/project.rst | 16 ++-- docs/narr/renderers.rst | 5 +- docs/narr/security.rst | 4 +- docs/narr/startup.rst | 12 +-- docs/narr/templates.rst | 12 +-- docs/narr/urldispatch.rst | 2 +- docs/narr/viewconfig.rst | 14 ++-- 13 files changed, 145 insertions(+), 144 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 29486ce56..d0db3047c 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -1,11 +1,11 @@ [app:MyProject] use = egg:MyProject -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_routematch = false -debug_templates = true -default_locale_name = en +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 [pipeline:main] pipeline = diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index c1d0eee82..d0ed9628c 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -1,11 +1,11 @@ [app:MyProject] use = egg:MyProject -reload_templates = false -debug_authorization = false -debug_notfound = false -debug_routematch = false -debug_templates = false -default_locale_name = en +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.debug_templates = false +pyramid.default_locale_name = en [filter:weberror] use = egg:WebError#error_catcher diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index f4cf951ba..509af7dd3 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -134,11 +134,11 @@ might have a ``[app:MyProject]`` section that looks like so: [app:MyProject] use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en + pyramid.reload_templates = true + pyramid.debug_authorization = false + pyramid.debug_notfound = false + pyramid.debug_templates = true + pyramid.default_locale_name = en If so, you can use the following command to invoke a debug shell using the name ``MyProject`` as a section name: @@ -160,7 +160,7 @@ name ``MyProject`` as a section name: >>> registry - >>> registry.settings['debug_notfound'] + >>> registry.settings['pyramid.debug_notfound'] False >>> from myproject.views import my_view >>> from pyramid.request import Request diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 53234cba1..6465c2a1e 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -47,14 +47,14 @@ changes to templates take effect immediately during development. This flag is meaningful to Chameleon and Mako templates, as well as most third-party template rendering extensions. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_RELOAD_TEMPLATES`` | ``reload_templates`` | -| | | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------------+--------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+================================+ +| ``PYRAMID_RELOAD_TEMPLATES`` | ``pyramid.reload_templates`` | +| | | +| | | +| | | ++---------------------------------+--------------------------------+ Reloading Assets ---------------- @@ -65,7 +65,7 @@ also :ref:`overriding_assets_section`. +---------------------------------+-----------------------------+ | Environment Variable Name | Config File Setting Name | +=================================+=============================+ -| ``PYRAMID_RELOAD_ASSETS`` | ``reload_assets`` | +| ``PYRAMID_RELOAD_ASSETS`` | ``pyramid.reload_assets`` | | | | | | | | | | @@ -73,7 +73,7 @@ also :ref:`overriding_assets_section`. .. note:: For backwards compatibility purposes, aliases can be used for configurating asset reloading: ``PYRAMID_RELOAD_RESOURCES`` (envvar) - and ``reload_resources`` (config file). + and ``pyramid.reload_resources`` (config file). Debugging Authorization ----------------------- @@ -81,14 +81,14 @@ Debugging Authorization Print view authorization failure and success information to stderr when this value is true. See also :ref:`debug_authorization_section`. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_DEBUG_AUTHORIZATION`` | ``debug_authorization`` | -| | | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------------+-----------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+===================================+ +| ``PYRAMID_DEBUG_AUTHORIZATION`` | ``pyramid.debug_authorization`` | +| | | +| | | +| | | ++---------------------------------+-----------------------------------+ Debugging Not Found Errors -------------------------- @@ -96,14 +96,14 @@ Debugging Not Found Errors Print view-related ``NotFound`` debug messages to stderr when this value is true. See also :ref:`debug_notfound_section`. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_DEBUG_NOTFOUND`` | ``debug_notfound`` | -| | | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------------+------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+==============================+ +| ``PYRAMID_DEBUG_NOTFOUND`` | ``pyramid.debug_notfound`` | +| | | +| | | +| | | ++---------------------------------+------------------------------+ Debugging Route Matching ------------------------ @@ -111,14 +111,14 @@ Debugging Route Matching Print debugging messages related to :term:`url dispatch` route matching when this value is true. See also :ref:`debug_routematch_section`. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_DEBUG_ROUTEMATCH`` | ``debug_routematch`` | -| | | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------------+--------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+================================+ +| ``PYRAMID_DEBUG_ROUTEMATCH`` | ``pyramid.debug_routematch`` | +| | | +| | | +| | | ++---------------------------------+--------------------------------+ .. _preventing_http_caching: @@ -130,14 +130,14 @@ globally in this process when this value is true. No http caching-related response headers will be set by the Pyramid ``http_cache`` view configuration feature when this is true. See also :ref:`influencing_http_caching`. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_PREVENT_HTTP_CACHE`` | ``prevent_http_cache`` | -| | | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------------+----------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+==================================+ +| ``PYRAMID_PREVENT_HTTP_CACHE`` | ``pyramid.prevent_http_cache`` | +| | | +| | | +| | | ++---------------------------------+----------------------------------+ Debugging All ------------- @@ -147,7 +147,7 @@ Turns on all ``debug*`` settings. +---------------------------------+-----------------------------+ | Environment Variable Name | Config File Setting Name | +=================================+=============================+ -| ``PYRAMID_DEBUG_ALL`` | ``debug_all`` | +| ``PYRAMID_DEBUG_ALL`` | ``pyramid.debug_all`` | | | | | | | | | | @@ -161,7 +161,7 @@ Turns on all ``reload*`` settings. +---------------------------------+-----------------------------+ | Environment Variable Name | Config File Setting Name | +=================================+=============================+ -| ``PYRAMID_RELOAD_ALL`` | ``reload_all`` | +| ``PYRAMID_RELOAD_ALL`` | ``pyramid.reload_all`` | | | | | | | | | | @@ -176,14 +176,14 @@ The value supplied here is used as the default locale name when a :term:`locale negotiator` is not registered. See also :ref:`localization_deployment_settings`. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_DEFAULT_LOCALE_NAME`` | ``default_locale_name`` | -| | | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------------+-----------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+===================================+ +| ``PYRAMID_DEFAULT_LOCALE_NAME`` | ``pyramid.default_locale_name`` | +| | | +| | | +| | | ++---------------------------------+-----------------------------------+ .. _mako_template_renderer_settings: @@ -346,8 +346,8 @@ an example of such a section: [app:main] use = egg:MyProject#app - reload_templates = true - debug_authorization = true + pyramid.reload_templates = true + pyramid.debug_authorization = true You can also use environment variables to accomplish the same purpose for settings documented as such. For example, you might start your @@ -364,18 +364,18 @@ respective settings in the ``[app:main]`` section of your application's ``.ini`` file. If you want to turn all ``debug`` settings (every setting that starts -with ``debug_``). on in one fell swoop, you can use +with ``pyramid.debug_``). on in one fell swoop, you can use ``PYRAMID_DEBUG_ALL=1`` as an environment variable setting or you may use -``debug_all=true`` in the config file. Note that this does not affect -settings that do not start with ``debug_*`` such as -``reload_templates``. +``pyramid.debug_all=true`` in the config file. Note that this does not affect +settings that do not start with ``pyramid.debug_*`` such as +``pyramid.reload_templates``. -If you want to turn all ``reload`` settings (every setting that starts -with ``reload_``) on in one fell swoop, you can use +If you want to turn all ``pyramid.reload`` settings (every setting that starts +with ``pyramid.reload_``) on in one fell swoop, you can use ``PYRAMID_RELOAD_ALL=1`` as an environment variable setting or you may use -``reload_all=true`` in the config file. Note that this does not -affect settings that do not start with ``reload_*`` such as -``debug_notfound``. +``pyramid.reload_all=true`` in the config file. Note that this does not +affect settings that do not start with ``pyramid.reload_*`` such as +``pyramid.debug_notfound``. .. note:: Specifying configuration settings via environment variables is generally @@ -392,35 +392,35 @@ affect settings that do not start with ``reload_*`` such as Understanding the Distinction Between ``reload_templates`` and ``reload_assets`` -------------------------------------------------------------------------------- -The difference between ``reload_assets`` and ``reload_templates`` is a bit -subtle. Templates are themselves also treated by :app:`Pyramid` as asset -files (along with other static files), so the distinction can be confusing. -It's helpful to read :ref:`overriding_assets_section` for some context -about assets in general. +The difference between ``pyramid.reload_assets`` and +``pyramid.reload_templates`` is a bit subtle. Templates are themselves also +treated by :app:`Pyramid` as asset files (along with other static files), so the +distinction can be confusing. It's helpful to read +:ref:`overriding_assets_section` for some context about assets in general. -When ``reload_templates`` is true, :app:`Pyramid` takes advantage of the +When ``pyramid.reload_templates`` is true, :app:`Pyramid` takes advantage of the underlying templating systems' ability to check for file modifications to an -individual template file. When ``reload_templates`` is true but -``reload_assets`` is *not* true, the template filename returned by the +individual template file. When ``pyramid.reload_templates`` is true but +``pyramid.reload_assets`` is *not* true, the template filename returned by the ``pkg_resources`` package (used under the hood by asset resolution) is cached by :app:`Pyramid` on the first request. Subsequent requests for the same template file will return a cached template filename. The underlying templating system checks for modifications to this particular file for every -request. Setting ``reload_templates`` to ``True`` doesn't affect performance -dramatically (although it should still not be used in production because it -has some effect). +request. Setting ``pyramid.reload_templates`` to ``True`` doesn't affect +performance dramatically (although it should still not be used in production +because it has some effect). -However, when ``reload_assets`` is true, :app:`Pyramid` will not cache the -template filename, meaning you can see the effect of changing the content of -an overridden asset directory for templates without restarting the server +However, when ``pyramid.reload_assets`` is true, :app:`Pyramid` will not cache +the template filename, meaning you can see the effect of changing the content +of an overridden asset directory for templates without restarting the server after every change. Subsequent requests for the same template file may return different filenames based on the current state of overridden asset -directories. Setting ``reload_assets`` to ``True`` affects performance +directories. Setting ``pyramid.reload_assets`` to ``True`` affects performance *dramatically*, slowing things down by an order of magnitude for each template rendering. However, it's convenient to enable when moving files -around in overridden asset directories. ``reload_assets`` makes the system -*very slow* when templates are in use. Never set ``reload_assets`` to -``True`` on a production system. +around in overridden asset directories. ``pyramid.reload_assets`` makes the +system *very slow* when templates are in use. Never set +``pyramid.reload_assets`` to ``True`` on a production system. .. index:: par: settings; adding custom diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index fc3f01271..4f493c854 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -61,8 +61,8 @@ Here's some sample code that implements a minimal NotFound view callable: caused the not found view to be called. The value of ``request.exception.message`` will be a value explaining why the not found error was raised. This message will be different when the - ``debug_notfound`` environment setting is true than it is when it is - false. + ``pyramid.debug_notfound`` environment setting is true than it is when it + is false. .. warning:: When a NotFound view callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` @@ -128,8 +128,8 @@ Here's some sample code that implements a minimal forbidden view: ``request.exception.message`` will be a value explaining why the forbidden was raised and ``request.exception.result`` will be extended information about the forbidden exception. These messages will be different when the - ``debug_authorization`` environment setting is true than it is when it is - false. + ``pyramid.debug_authorization`` environment setting is true than it is when + it is false. .. index:: single: request factory diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 924fb047a..ba5490b31 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -623,7 +623,7 @@ You can obtain the locale name related to a request by using the This returns the locale name negotiated by the currently active :term:`locale negotiator` or the :term:`default locale name` if the locale negotiator returns ``None``. You can change the default locale -name by changing the ``default_locale_name`` setting; see +name by changing the ``pyramid.default_locale_name`` setting; see :ref:`default_locale_name_setting`. Once :func:`~pyramid.i18n.get_locale_name` is first run, the locale @@ -768,7 +768,7 @@ Internationalization" which explains how to add idiomatic I18N support to Localization-Related Deployment Settings ---------------------------------------- -A :app:`Pyramid` application will have a ``default_locale_name`` +A :app:`Pyramid` application will have a ``pyramid.default_locale_name`` setting. This value represents the :term:`default locale name` used when the :term:`locale negotiator` returns ``None``. Pass it to the :mod:`~pyramid.config.Configurator` constructor at startup @@ -778,9 +778,9 @@ time: :linenos: from pyramid.config import Configurator - config = Configurator(settings={'default_locale_name':'de'}) + config = Configurator(settings={'pyramid.default_locale_name':'de'}) -You may alternately supply a ``default_locale_name`` via an +You may alternately supply a ``pyramid.default_locale_name`` via an application's Paster ``.ini`` file: .. code-block:: ini @@ -788,10 +788,10 @@ application's Paster ``.ini`` file: [app:main] use = egg:MyProject#app - reload_templates = true - debug_authorization = false - debug_notfound = false - default_locale_name = de + pyramid.reload_templates = true + pyramid.debug_authorization = false + pyramid.debug_notfound = false + pyramid.default_locale_name = de If this value is not supplied via the Configurator constructor or via a Paste config file, it will default to ``en``. @@ -804,7 +804,7 @@ If this setting is supplied within the :app:`Pyramid` application from pyramid.threadlocal import get_current_registry settings = get_current_registry().settings - default_locale_name = settings['default_locale_name'] + default_locale_name = settings['pyramid.default_locale_name'] .. index:: single: detecting langauges diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 5f4878470..3b1b45eda 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -472,22 +472,22 @@ represented by this entry point (``main`` in our ``__init__.py`` module). You can provide startup-time configuration parameters to your application by adding more settings to this section. -The ``reload_templates`` setting in the ``[app:MyProject]`` section is a -:app:`Pyramid` -specific setting which is passed into the framework. If it +The ``pyramid.reload_templates`` setting in the ``[app:MyProject]`` section is +a :app:`Pyramid` -specific setting which is passed into the framework. If it exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako` template changes will not require an application restart to be detected. See :ref:`reload_templates_section` for more information. -The ``debug_templates`` setting in the ``[app:MyProject]`` section is a +The ``pyramid.debug_templates`` setting in the ``[app:MyProject]`` section is a :app:`Pyramid` -specific setting which is passed into the framework. If it exists, and its value is ``true``, :term:`Chameleon` template exceptions will contain more detailed and helpful information about the error than when this value is ``false``. See :ref:`debug_templates_section` for more information. -.. warning:: The ``reload_templates`` and ``debug_templates`` options should - be turned off for production applications, as template rendering is slowed - when either is turned on. +.. warning:: The ``pyramid.reload_templates`` and ``pyramid.debug_templates`` + options should be turned off for production applications, as template + rendering is slowed when either is turned on. Various other settings may exist in this section having to do with debugging or influencing runtime behavior of a :app:`Pyramid` application. See @@ -795,14 +795,14 @@ file call to ``add_view``). See :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. -.. note:: Because our ``development.ini`` has a ``reload_templates = +.. note:: Because our ``development.ini`` has a ``pyramid.reload_templates = true`` directive indicating that templates should be reloaded when they change, you won't need to restart the application server to see changes you make to templates. During development, this is handy. If this directive had been ``false`` (or if the directive did not exist), you would need to restart the application server for each template change. For production applications, you should - set your project's ``reload_templates`` to ``false`` to increase + set your project's ``pyramid.reload_templates`` to ``false`` to increase the speed at which templates may be rendered. .. index:: diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 801741c43..ed391f4fe 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -425,8 +425,9 @@ The above configuration will use the file named ``foo.mak`` in the ``templates`` directory of the ``mypackage`` package. The ``Mako`` template renderer can take additional arguments beyond the -standard ``reload_templates`` setting, see the :ref:`environment_chapter` for -additional :ref:`mako_template_renderer_settings`. +standard ``pyramid.reload_templates`` setting, see the +:ref:`environment_chapter` for additional +:ref:`mako_template_renderer_settings`. .. index:: single: response headers (from a renderer) diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 65f3d7cf0..ce304ed9f 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -517,7 +517,7 @@ which ACL permitted or denied the authorization based on authentication information. This behavior can also be turned on in the application ``.ini`` file -by setting the ``debug_authorization`` key to ``true`` within the +by setting the ``pyramid.debug_authorization`` key to ``true`` within the application's configuration section, e.g.: .. code-block:: ini @@ -525,7 +525,7 @@ application's configuration section, e.g.: [app:main] use = egg:MyProject#app - debug_authorization = true + pyramid.debug_authorization = true With this debug flag turned on, the response sent to the browser will also contain security debugging information in its body. diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 68df9d417..c9ed01f83 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -92,10 +92,10 @@ 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 ``{'reload_templates':'true', - 'debug_authorization':'false', 'debug_notfound':'false', - 'debug_routematch':'false', 'debug_templates':'true', - 'default_locale_name':'en'}``. + 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'}``. #. The ``main`` function first constructs a :class:`~pyramid.config.Configurator` instance, passing a root resource @@ -109,8 +109,8 @@ Here's a high-level time-ordered overview of what happens when you press The ``settings`` dictionary contains all the options in the ``[app:MyProject]`` section of our .ini file except the ``use`` option - (which is internal to Paste) such as ``reload_templates``, - ``debug_authorization``, etc. + (which is internal to Paste) such as ``pyramid.reload_templates``, + ``pyramid.debug_authorization``, etc. #. The ``main`` function then calls various methods on the instance of the class :class:`~pyramid.config.Configurator` created in the previous step. diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index af7257466..0f46f6422 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -632,15 +632,15 @@ variable set to ``1``, For example: $ PYRAMID_DEBUG_TEMPLATES=1 bin/paster serve myproject.ini To use a setting in the application ``.ini`` file for the same -purpose, set the ``debug_templates`` key to ``true`` within the -application's configuration section, e.g.: +purpose, set the ``pyramid.debug_templates`` key to ``true`` within +the application's configuration section, e.g.: .. code-block:: ini :linenos: [app:MyProject] use = egg:MyProject#app - debug_templates = true + pyramid.debug_templates = true With template debugging off, a :exc:`NameError` exception resulting from rendering a template with an undefined variable @@ -677,7 +677,7 @@ displaying the arguments passed to the template itself. .. note:: - Turning on ``debug_templates`` has the same effect as using the + Turning on ``pyramid.debug_templates`` has the same effect as using the Chameleon environment variable ``CHAMELEON_DEBUG``. See `Chameleon Environment Variables `_ @@ -793,7 +793,7 @@ variable set to ``1``, For example: $ PYRAMID_RELOAD_TEMPLATES=1 bin/paster serve myproject.ini To use a setting in the application ``.ini`` file for the same -purpose, set the ``reload_templates`` key to ``true`` within the +purpose, set the ``pyramid.reload_templates`` key to ``true`` within the application's configuration section, e.g.: .. code-block:: ini @@ -801,7 +801,7 @@ application's configuration section, e.g.: [app:main] use = egg:MyProject#app - reload_templates = true + pyramid.reload_templates = true .. index:: single: template system bindings diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 0598cd4f2..61c9770c6 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1005,7 +1005,7 @@ Debugging Route Matching It's useful to be able to take a peek under the hood when requests that enter your application arent matching your routes as you expect them to. To debug route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or the -``debug_routematch`` configuration file setting (set either to ``true``). +``pyramid.debug_routematch`` configuration file setting (set either to ``true``). Details of the route matching decision for a particular request to the :app:`Pyramid` application will be printed to the ``stderr`` of the console which you started the application from. For example: diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index d776887c8..a1b12ad2a 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -679,10 +679,10 @@ per :ref:`protecting_views`. It's useful to be able to debug :exc:`NotFound` error responses when they occur unexpectedly due to an application registry misconfiguration. To debug these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the -``debug_notfound`` configuration file setting. Details of why a view was not -found will be printed to ``stderr``, and the browser representation of the -error will include the same information. See :ref:`environment_chapter` for -more information about how, and where to set these values. +``pyramid.debug_notfound`` configuration file setting. Details of why a view +was not found will be printed to ``stderr``, and the browser representation of +the error will include the same information. See :ref:`environment_chapter` +for more information about how, and where to set these values. .. index:: single: HTTP caching @@ -729,10 +729,10 @@ headers you set within the view itself unless you use ``preserve_auto``. You can also turn of the effect of ``http_cache`` entirely for the duration of a Pyramid application lifetime. To do so, set the ``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the -``prevent_http_cache`` configuration value setting to a true value. For more -information, see :ref:`preventing_http_caching`. +``pyramid.prevent_http_cache`` configuration value setting to a true value. +For more information, see :ref:`preventing_http_caching`. -Note that setting ``prevent_http_cache`` will have no effect on caching +Note that setting ``pyramid.prevent_http_cache`` will have no effect on caching headers that your application code itself sets. It will only prevent caching headers that would have been set by the Pyramid HTTP caching machinery invoked as the result of the ``http_cache`` argument to view configuration. -- cgit v1.2.3 From 1311321d454ded6226b09f929ebc9e4aa2c12771 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 6 Aug 2011 18:58:26 -0400 Subject: add tweens module, add docs for ptweens and tweens to hooks --- docs/narr/commandline.rst | 75 ++++++++++++++++++++++++++- docs/narr/hooks.rst | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 509af7dd3..6f969196f 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -297,8 +297,79 @@ application, nothing will be printed to the console when ``paster proutes`` is executed. .. index:: - single: scripting - single: bootstrap + pair: tweens; printing + single: paster ptweens + single: ptweens + +.. _displaying_tweens: + +Displaying "Tweens" +------------------- + +A user can get a representation of both the implicit :term:`tween` ordering +(the ordering specified by calls to +:meth:`pyramid.config.Configurator.add_tween`) and the explicit tween +ordering (specified by the ``pyramid.tweens`` configuration setting) +orderings using the ``paster ptweens`` command. Handler factories which are +functions or classes will show up as a standard Python dotted name in the +``paster ptweens`` output. Tween factories which are *instances* will show +their module and class name; the Python object id of the instance will be +appended. + +For example, here's the ``paster pwteens`` command run against a system +configured without any explicit tweens: + +.. code-block:: text + :linenos: + + [chrism@thinko starter]$ ../bin/paster ptweens development.ini + "pyramid.tweens" config value NOT set (implicitly ordered tweens used) + + Position Name + -------- ---- + 0 pyramid.router.excview_tween_factory + +Here's the ``paster pwteens`` command run against a system configured *with* +explicit tweens defined in its ``development.ini`` file: + +.. code-block:: text + :linenos: + + [chrism@thinko starter]$ ../bin/paster ptweens development.ini + "pyramid.tweens" config value set (explicitly ordered tweens used) + + Explicit Tween Chain (used) + + Position Name + -------- ---- + 0 pyramid.tweens.excview_tween_factory + 1 starter.tween_factory1 + 2 starter.tween_factory2 + + Implicit Tween Chain (not used) + + Position Name + -------- ---- + 0 pyramid.tweens.excview_tween_factory + +Here's the application configuration section of the ``development.ini`` used +by the above ``paster ptweens`` command which reprorts that the explicit +tween chain is used: + +.. code-block:: text + :linenos: + + [app:starter] + use = egg:starter + 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 + pyramid.tweens = pyramid.tweens.excview_tween_factory + starter.tween_factory1 + starter.tween_factory2 .. _writing_a_script: diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4f493c854..7290876e6 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -828,3 +828,131 @@ performed, enabling you to set up the utility in advance: For full details, please read the `Venusian documentation `_. +.. _registering_tweens: + +Registering "Tweens" +-------------------- + +.. note:: Tweens are a feature which were added in Pyramid 1.1.1. They are + not available in any previous version. + +A :term:`tween` (think: "between") is a bit of code that sits between the +Pyramid router's main request handling function and the upstream WSGI +component that uses :app:`Pyramid` as its "app". This is a feature that may +be used by Pyramid framework extensions, to provide, for example, +Pyramid-specific view timing support bookkeeping code that examines +exceptions before they are returned to the upstream WSGI application. Tweens +behave a bit like :term:`WSGI` middleware but they have the benefit of +running in a context in which they have access to the Pyramid +:term:`application registry` as well as the Pyramid rendering machinery. + +To make use of tweens, you must construct a "tween factory". A tween factory +must be a callable (or a :term:`dotted Python name` to such a callable) which +accepts two arguments: ``handler`` and ``registry``. ``handler`` will be the +either the main Pyramid request handling function or another tween (if more +than one tween is configured into the request handling chain). ``registry`` +will be the Pyramid :term:`application registry` represented by this +Configurator. A tween factory must return a tween when it is called. + +A tween is a callable which accepts a :term:`request` object and returns a +two-tuple consisting of a :term:`request` object and a :term:`response` +object. + +Once you've created a tween factory, you can register it using the +:meth:`pyramid.config.Configurator.add_tween` method. + +Here's an example creating a tween factory and registering it: + +.. code-block:: python + :lineno: + + import time + from pyramid.settings import asbool + import logging + + log = logging.getLogger(__name__) + + def timing_tween_factory(handler, registry): + if asbool(registry.settings.get('do_timing')): + # if timing support is enabled, return a wrapper + def timing_tween(request): + start = time.time() + try: + request, response = handler(request) + finally: + end = time.time() + log.debug('The request took %s seconds' % + (end - start)) + return request, response + return timing_tween + # if timing support is not enabled, return the original + # handler + return handler + + from pyramid.config import Configurator + + config = Configurator() + config.add_tween(timing_tween_factory) + +The ``request`` argument to a tween will be the request created by Pyramid's +router when it receives a WSGI request. + +If more than one call to :meth:`pyramid.config.Configurator.add_tween` is +made within a single application configuration, the added tweens will be +chained together. The first tween factory added will be called with the +default Pyramid request handler as its ``handler`` argument, the second tween +factory added will be called with the result of the first tween factory as +its ``handler`` argument, and so on, ad infinitum. The Pyramid router will +use the outermost tween produced by this chain (the tween generated by the +very last tween factory added) as its request handler function. + +Pyramid will prevent the same tween factory from being added to the implicit +tween chain more than once using configuration conflict detection. If you +wish to add the same tween factory more than once in a configuration, you +should either: a) use a tween factory that is an instance rather than a +function or class, b) use a function or class as a tween factory with the +same logic as the other tween factory it conflicts with but with a different +``__name__`` attribute or c) call :meth:`pyramid.config.Configurator.commit` +between calls to :meth:`pyramid.config.Configurator.add_tween`. + +By default, the ordering of the chain is controlled entirely by the relative +ordering of calls to :meth:`pyramid.config.Configurator.add_tween`. However, +the deploying user can override tween inclusion and ordering entirely in his +Pyramid configuration using the ``pyramid.tweens`` settings value. When +used, this settings value will be a list of Python dotted names which imply +the ordering (and inclusion) of tween factories in the tween chain. For +example: + +.. code-block:: ini + :linenos: + + [app:main] + use = egg:MyApp + pyramid.reload_templates = true + pyramid.debug_authorization = false + pyramid.debug_notfound = false + pyramid.debug_routematch = false + pyramid.debug_templates = true + pyramid.tweens = pyramid.tweens.excview_tween_factory + myapp.my_cool_tween_factory + +In the above configuration, calls made during configuration to +:meth:`pyramid.config.Configurator.add_tween` are ignored, and the user is +telling the system to use the tween factories he has listed in the +``pyramid.tweens`` configuration setting (each is a:term:`Python dotted name` +which points to a tween factory). The *last* tween factory in the +``pyramid.tweens`` list will be used as the producer of the effective +:app:`Pyramid` request handling function; it will wrap the tween factory +declared directly "above" it, ad infinitum. + +.. note:: Pyramid's own :term:`exception view` handling logic is implemented + as a tween factory function: :func:`pyramid.tweens.excview_tween_factory`. + If Pyramid exception view handling is desired, and tween factories are + specified via the ``pyramid.tweens`` configuration setting, the + :func:`pyramid.tweens.excview_tween_factory` function must be added to the + ``pyramid.tweens`` configuration setting list explicitly. If it is not + present, Pyramid will not perform exception view handling. + +The ``paster ptweens`` command-line utility can be used to report the current +tween chain used by an application. See :ref:`displaying_tweens`. + -- cgit v1.2.3 From 8d1533d95ceebbef641a220236b77d9b3931cc31 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 6 Aug 2011 20:22:43 -0400 Subject: change return value of tween to just response --- docs/narr/hooks.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 7290876e6..c6438dfdf 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -855,8 +855,7 @@ will be the Pyramid :term:`application registry` represented by this Configurator. A tween factory must return a tween when it is called. A tween is a callable which accepts a :term:`request` object and returns a -two-tuple consisting of a :term:`request` object and a :term:`response` -object. +two-tuple a :term:`response` object. Once you've created a tween factory, you can register it using the :meth:`pyramid.config.Configurator.add_tween` method. @@ -878,12 +877,12 @@ Here's an example creating a tween factory and registering it: def timing_tween(request): start = time.time() try: - request, response = handler(request) + response = handler(request) finally: end = time.time() log.debug('The request took %s seconds' % (end - start)) - return request, response + return response return timing_tween # if timing support is not enabled, return the original # handler -- cgit v1.2.3 From 18a99ae15e7f36cd21da6e2d2e70d61d1733bf30 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 6 Aug 2011 20:35:34 -0400 Subject: docs rendering --- 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 c6438dfdf..889e8d6d8 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -863,7 +863,7 @@ Once you've created a tween factory, you can register it using the Here's an example creating a tween factory and registering it: .. code-block:: python - :lineno: + :linenos: import time from pyramid.settings import asbool -- cgit v1.2.3 From 05f610e6ed66f8d5aca9d77ae0748feb0c8f8479 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 8 Aug 2011 23:26:59 -0400 Subject: document under and over params --- docs/narr/commandline.rst | 74 ++++++++++------- docs/narr/hooks.rst | 208 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 213 insertions(+), 69 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 6f969196f..0f23c153c 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -306,15 +306,16 @@ is executed. Displaying "Tweens" ------------------- -A user can get a representation of both the implicit :term:`tween` ordering -(the ordering specified by calls to -:meth:`pyramid.config.Configurator.add_tween`) and the explicit tween -ordering (specified by the ``pyramid.tweens`` configuration setting) -orderings using the ``paster ptweens`` command. Handler factories which are -functions or classes will show up as a standard Python dotted name in the -``paster ptweens`` output. Tween factories which are *instances* will show -their module and class name; the Python object id of the instance will be -appended. +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 calls to :meth:`pyramid.config.Configurator.add_tween`) and the +explicit tween ordering (specified by the ``pyramid.tweens`` configuration +setting) orderings using the ``paster ptweens`` command. Handler factories +which are functions or classes will show up as a standard Python dotted name +in the ``paster ptweens`` output. Tween factories which are *instances* will +show their module and class name; the Python object id of the instance will +be appended. For example, here's the ``paster pwteens`` command run against a system configured without any explicit tweens: @@ -322,12 +323,17 @@ configured without any explicit tweens: .. code-block:: text :linenos: - [chrism@thinko starter]$ ../bin/paster ptweens development.ini + [chrism@thinko pyramid]$ paster ptweens development.ini "pyramid.tweens" config value NOT set (implicitly ordered tweens used) - Position Name - -------- ---- - 0 pyramid.router.excview_tween_factory + Implicit Tween Chain + + Position Name Alias + -------- ---- ----- + - - INGRESS + 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory pdbt + 1 pyramid.tweens.excview_tween_factory excview + - - MAIN Here's the ``paster pwteens`` command run against a system configured *with* explicit tweens defined in its ``development.ini`` file: @@ -335,22 +341,27 @@ explicit tweens defined in its ``development.ini`` file: .. code-block:: text :linenos: - [chrism@thinko starter]$ ../bin/paster ptweens development.ini + [chrism@thinko pyramid]$ paster ptweens development.ini "pyramid.tweens" config value set (explicitly ordered tweens used) Explicit Tween Chain (used) - Position Name - -------- ---- - 0 pyramid.tweens.excview_tween_factory - 1 starter.tween_factory1 - 2 starter.tween_factory2 + Position Name + -------- ---- + - INGRESS + 0 starter.tween_factory2 + 1 starter.tween_factory1 + 2 pyramid.tweens.excview_tween_factory + - MAIN Implicit Tween Chain (not used) - Position Name - -------- ---- - 0 pyramid.tweens.excview_tween_factory + Position Name Alias + -------- ---- ----- + - - INGRESS + 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory pdbt + 1 pyramid.tweens.excview_tween_factory excview + - - MAIN Here's the application configuration section of the ``development.ini`` used by the above ``paster ptweens`` command which reprorts that the explicit @@ -361,15 +372,18 @@ tween chain is used: [app:starter] use = egg:starter - 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 - pyramid.tweens = pyramid.tweens.excview_tween_factory + reload_templates = true + debug_authorization = false + debug_notfound = false + debug_routematch = false + debug_templates = true + default_locale_name = en + pyramid.include = pyramid_debugtoolbar + pyramid.tweens = starter.tween_factory2 starter.tween_factory1 - starter.tween_factory2 + pyramid.tweens.excview_tween_factory + +See :ref:`registering_tweens` for more information about tweens. .. _writing_a_script: diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 889e8d6d8..f7ee82821 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -836,11 +836,11 @@ Registering "Tweens" .. note:: Tweens are a feature which were added in Pyramid 1.1.1. They are not available in any previous version. -A :term:`tween` (think: "between") is a bit of code that sits between the -Pyramid router's main request handling function and the upstream WSGI -component that uses :app:`Pyramid` as its "app". This is a feature that may -be used by Pyramid framework extensions, to provide, for example, -Pyramid-specific view timing support bookkeeping code that examines +A :term:`tween` (a contraction of the word "between") is a bit of code that +sits between the Pyramid router's main request handling function and the +upstream WSGI component that uses :app:`Pyramid` as its "app". This is a +feature that may be used by Pyramid framework extensions, to provide, for +example, Pyramid-specific view timing support bookkeeping code that examines exceptions before they are returned to the upstream WSGI application. Tweens behave a bit like :term:`WSGI` middleware but they have the benefit of running in a context in which they have access to the Pyramid @@ -857,8 +857,8 @@ Configurator. A tween factory must return a tween when it is called. A tween is a callable which accepts a :term:`request` object and returns a two-tuple a :term:`response` object. -Once you've created a tween factory, you can register it using the -:meth:`pyramid.config.Configurator.add_tween` method. +Once you've created a tween factory, you can register it into the implicit +tween chain using the :meth:`pyramid.config.Configurator.add_tween` method. Here's an example creating a tween factory and registering it: @@ -897,30 +897,145 @@ The ``request`` argument to a tween will be the request created by Pyramid's router when it receives a WSGI request. If more than one call to :meth:`pyramid.config.Configurator.add_tween` is -made within a single application configuration, the added tweens will be -chained together. The first tween factory added will be called with the -default Pyramid request handler as its ``handler`` argument, the second tween -factory added will be called with the result of the first tween factory as -its ``handler`` argument, and so on, ad infinitum. The Pyramid router will -use the outermost tween produced by this chain (the tween generated by the -very last tween factory added) as its request handler function. - -Pyramid will prevent the same tween factory from being added to the implicit -tween chain more than once using configuration conflict detection. If you -wish to add the same tween factory more than once in a configuration, you -should either: a) use a tween factory that is an instance rather than a -function or class, b) use a function or class as a tween factory with the -same logic as the other tween factory it conflicts with but with a different -``__name__`` attribute or c) call :meth:`pyramid.config.Configurator.commit` -between calls to :meth:`pyramid.config.Configurator.add_tween`. - -By default, the ordering of the chain is controlled entirely by the relative -ordering of calls to :meth:`pyramid.config.Configurator.add_tween`. However, -the deploying user can override tween inclusion and ordering entirely in his -Pyramid configuration using the ``pyramid.tweens`` settings value. When -used, this settings value will be a list of Python dotted names which imply -the ordering (and inclusion) of tween factories in the tween chain. For -example: +made within a single application configuration, the tweens will be chained +together at application startup time. The *first* tween factory added via +``add_tween`` will be called with the Pyramid exception view tween factory as +its ``handler`` argument, then the tween factory added directly after that +one will be called with the result of the first tween factory as its +``handler`` argument, and so on, ad infinitum until all tween factories have +been called. The Pyramid router will use the outermost tween produced by this +chain (the tween generated by the very last tween factory added) as its +request handler function. For example: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + config = Configurator() + config.add_tween('myapp.tween_factory1') + config.add_tween('myapp.tween_factory2') + +The above example will generate an implicit tween chain that looks like +this:: + + INGRESS (implicit) + myapp.tween_factory2 + myapp.tween_factory1 + pyramid.tweens.excview_tween_factory (implicit) + MAIN (implicit) + +By default, as described above, the ordering of the chain is controlled +entirely by the relative ordering of calls to +:meth:`pyramid.config.Configurator.add_tween`. However, the caller of +add_tween can provide an optional hint that can influence the implicit tween +chain ordering by supplying ``under`` or ``over`` (or both) arguments to +:meth:`~pyramid.config.Configurator.add_tween`. These hints are only used +used when an explicit tween chain is not used (when the ``pyramid.tweens`` +configuration value is not set). + +Allowable values for ``under`` or ``over`` (or both) are: + +- ``None`` (the default). + +- A :term:`dotted Python name` to a tween factory: a string representing the + predicted dotted name of a tween factory added in a call to ``add_tween`` + in the same configuration session. + +- A "tween alias": a string representing the predicted value of ``alias`` in + a separate call to ``add_tween`` in the same configuration session + +- One of the constants :attr:`pyramid.tweens.MAIN`, + :attr:`pyramid.tweens.INGRESS`, or :attr:`pyramid.tweens.EXCVIEW`. + +Effectively, ``under`` means "closer to the main Pyramid application than", +``over`` means "closer to the request ingress than". + +For example, the following call to +:meth:`~pyramid.config.Configurator.add_tween` will attempt to place the +tween factory represented by ``myapp.tween_factory`` directly 'above' (in +``paster ptweens`` order) the main Pyramid request handler. + +.. code-block:: python + :linenos: + + import pyramid.tweens + + config.add_tween('myapp.tween_factory', over=pyramid.tweens.MAIN) + +The above example will generate an implicit tween chain that looks like +this:: + + INGRESS (implicit) + pyramid.tweens.excview_tween_factory (implicit) + myapp.tween_factory + MAIN (implicit) + +Likewise, calling the following call to +:meth:`~pyramid.config.Configurator.add_tween` will attempt to place this +tween factory 'above' the main handler but 'below' a separately added tween +factory: + +.. code-block:: python + :linenos: + + import pyramid.tweens + + config.add_tween('myapp.tween_factory1', + over=pyramid.tweens.MAIN) + config.add_tween('myapp.tween_factory2', + over=pyramid.tweens.MAIN, + under='myapp.tween_factory1') + +The above example will generate an implicit tween chain that looks like +this:: + + INGRESS (implicit) + pyramid.tweens.excview_tween_factory (implicit) + myapp.tween_factory1 + myapp.tween_factory2 + MAIN (implicit) + +Specifying neither ``over`` nor ``under`` is equivalent to specifying +``under=INGRESS``. + +If an ``under`` or ``over`` value is provided that does not match a tween +factory dotted name or alias in the current configuration, that value will be +ignored. It is not an error to provide an ``under`` or ``over`` value that +matches an unused tween factory. + +:meth:`~pyramid.config.Configurator.add_tween` also accepts an ``alias`` +argument. If ``alias`` is not ``None``, should be a string. The string will +represent a value that other callers of ``add_tween`` may pass as an +``under`` and ``over`` argument instead of a dotted name to a tween factory. +For example: + +.. code-block:: python + :linenos: + + import pyramid.tweens + + config.add_tween('myapp.tween_factory1', + alias='one' + over=pyramid.tweens.MAIN) + config.add_tween('myapp.tween_factory2', + alias='two' + over=pyramid.tweens.MAIN, + under='one') + +Alias names are only useful in relation to ``under`` and ``over`` values. +They cannot be used in explicit tween chain configuration, or anywhere else. + +Implicit tween ordering is obviously only best-effort. Pyramid will attempt +to provide an implicit order of tweens as best it can using hints provided by +calls to :meth:`~pyramid.config.Configurator.add_tween`, but because it's +only best-effort, if very precise tween ordering is required, the only +surefire way to get it is to use an explicit tween order. The deploying user +can override the implicit tween inclusion and ordering implied by calls to +:meth:`~pyramid.config.Configurator.add_tween` entirely by using the +``pyramid.tweens`` settings value. When used, this settings value must be a +list of Python dotted names which will override the ordering (and inclusion) +of tween factories in the implicit tween chain. For example: .. code-block:: ini :linenos: @@ -932,17 +1047,19 @@ example: pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true - pyramid.tweens = pyramid.tweens.excview_tween_factory - myapp.my_cool_tween_factory + pyramid.tweens = myapp.my_cool_tween_factory + pyramid.tweens.excview_tween_factory In the above configuration, calls made during configuration to :meth:`pyramid.config.Configurator.add_tween` are ignored, and the user is telling the system to use the tween factories he has listed in the -``pyramid.tweens`` configuration setting (each is a:term:`Python dotted name` -which points to a tween factory). The *last* tween factory in the -``pyramid.tweens`` list will be used as the producer of the effective +``pyramid.tweens`` configuration setting (each is a :term:`dotted Python +name` which points to a tween factory) instead of any tween factories added +via :meth:`pyramid.config.Configurator.add_tween`. The *first* tween factory +in the ``pyramid.tweens`` list will be used as the producer of the effective :app:`Pyramid` request handling function; it will wrap the tween factory -declared directly "above" it, ad infinitum. +declared directly "below" it, ad infinitum. The "main" Pyramid request +handler is implicit, and always "at the bottom". .. note:: Pyramid's own :term:`exception view` handling logic is implemented as a tween factory function: :func:`pyramid.tweens.excview_tween_factory`. @@ -952,6 +1069,19 @@ declared directly "above" it, ad infinitum. ``pyramid.tweens`` configuration setting list explicitly. If it is not present, Pyramid will not perform exception view handling. -The ``paster ptweens`` command-line utility can be used to report the current -tween chain used by an application. See :ref:`displaying_tweens`. +Pyramid will prevent the same tween factory from being added to the tween +chain more than once using configuration conflict detection. If you wish to +add the same tween factory more than once in a configuration, you should +either: a) use a tween factory that is an instance rather than a function or +class, b) use a function or class as a tween factory with the same logic as +the other tween factory it conflicts with but with a different ``__name__`` +attribute or c) call :meth:`pyramid.config.Configurator.commit` between calls +to :meth:`pyramid.config.Configurator.add_tween`. +If a cycle is detected in implicit tween ordering when ``over`` and ``under`` +are used in any call to "add_tween", an exception will be raised at startup +time. + +The ``paster ptweens`` command-line utility can be used to report the current +implict and explicit tween chains used by an application. See +:ref:`displaying_tweens`. -- cgit v1.2.3 From 4dea53b033a2bb25857187bb9006bbd52df739bd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 9 Aug 2011 09:59:15 -0400 Subject: dont call hook_zca when we already are using the global reg --- docs/narr/zca.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index a99fd8b24..96aac6a80 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -245,7 +245,6 @@ registry at startup time instead of constructing a new one: globalreg = getGlobalSiteManager() config = Configurator(registry=globalreg) config.setup_registry(settings=settings) - config.hook_zca() config.include('some.other.application') return config.make_wsgi_app() -- cgit v1.2.3 From c6d9f191e920536fdb274d15ef956a5e8151bbc2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 9 Aug 2011 14:18:32 -0400 Subject: fix project.rst to deal with scaffold changes --- docs/narr/MyProject/development.ini | 3 ++- docs/narr/MyProject/production.ini | 1 + docs/narr/MyProject/setup.py | 2 +- docs/narr/project.png | Bin 84679 -> 128727 bytes docs/narr/project.rst | 51 +++++++++++++++++++++++++++--------- 5 files changed, 42 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index d0db3047c..1818e387b 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -1,15 +1,16 @@ [app:MyProject] use = egg:MyProject + 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 +pyramid.include = pyramid_debugtoolbar [pipeline:main] pipeline = - egg:WebError#evalerror MyProject [server:main] diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index d0ed9628c..7a5674d23 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -1,5 +1,6 @@ [app:MyProject] use = egg:MyProject + pyramid.reload_templates = false pyramid.debug_authorization = false pyramid.debug_notfound = false diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index a64d65ba6..a0b6fab9e 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -6,7 +6,7 @@ here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() -requires = ['pyramid', 'WebError'] +requires = ['pyramid', 'pyramid_debugtoolbar', 'WebError'] setup(name='MyProject', version='0.0', diff --git a/docs/narr/project.png b/docs/narr/project.png index da5bc870b..fc00ec086 100644 Binary files a/docs/narr/project.png and b/docs/narr/project.png differ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 3b1b45eda..b4a0e1d45 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -99,18 +99,18 @@ We'll choose the ``pyramid_starter`` scaffold for this purpose. $ bin/paster create -t pyramid_starter -The above command uses the ``paster create`` command to create a project with the -``pyramid_starter`` scaffold. To use a different scaffold, such as +The above command uses the ``paster create`` command to create a project with +the ``pyramid_starter`` scaffold. To use a different scaffold, such as ``pyramid_routesalchemy``, you'd just change the last argument. For example: .. code-block:: text $ bin/paster create -t pyramid_routesalchemy -``paster create`` will ask you a single question: the *name* of the -project. You should use a string without spaces and with only letters -in it. Here's sample output from a run of ``paster create`` for a -project we name ``MyProject``: +``paster create`` will ask you a single question: the *name* of the project. +You should use a string without spaces and with only letters in it. Here's +sample output from a run of ``paster create`` for a project we name +``MyProject``: .. code-block:: text @@ -309,6 +309,23 @@ browser like what is displayed in the following image: This is the page shown by default when you visit an unmodified ``paster create`` -generated ``pyramid_starter`` application in a browser. +If you click on the image shown at the right hand top of the page ("^DT"), +you'll be presented with a debug toolbar that provides various niceties while +you're developing. This image will float above every HTML page served by +:app:`Pyramid` while you develop an application, and allows you show the +toolbar as necessary. Click on ``Hide`` to hide the toolbar and show the +image again. + +.. image:: project-debug.png + +For more information about what the debug toolbar allows you to do, see `the +documentation for pyramid_debugtoolbar +`_. + +The debug toolbar will not be shown (and all debugging will be turned off) +when you use the ``production.ini`` file instead of the ``development.ini`` +ini file to run the application. + .. sidebar:: Using an Alternate WSGI Server The code generated by a :app:`Pyramid` scaffold assumes that you @@ -419,8 +436,6 @@ serve``, as well as the deployment settings provided to that application. The generated ``development.ini`` file looks like so: -.. latexbroken? - .. literalinclude:: MyProject/development.ini :language: ini :linenos: @@ -489,6 +504,14 @@ information. options should be turned off for production applications, as template rendering is slowed when either is turned on. +The ``pyramid.include`` setting in the ``[app:MyProject]`` section tells +Pyramid to "include" configuration from another package. In this case, the +line ``pyramid.include = pyramid_debugtoolbar`` tells Pyramid to include +configuration from the ``pyramid_debugtoolbar`` package. This turns on a +debugging panel in development mode which will be shown on the right hand +side of the screen. Including the debug toolbar will also make it possible +to interactively debug exceptions when an error occurs. + Various other settings may exist in this section having to do with debugging or influencing runtime behavior of a :app:`Pyramid` application. See :ref:`environment_chapter` for more information about these settings. @@ -543,11 +566,13 @@ implementations. The ``production.ini`` file is a :term:`PasteDeploy` configuration file with a purpose much like that of ``development.ini``. However, it disables the -WebError interactive debugger, replacing it with a logger which outputs -exception messages to ``stderr`` by default. It also turns off template -development options such that templates are not automatically reloaded when -changed, and turns off all debugging options. You can use this file instead -of ``development.ini`` when you put your application into production. +debug toolbar, replacing it with a logger which outputs exception messages to +``stderr`` by default. It also turns off template development options such +that templates are not automatically reloaded when changed, and turns off all +debugging options. It allows you to configure a ``weberror#error_catcher`` +section that will cause exceptions to be sent to an email address when they +are uncaught. You can use this file instead of ``development.ini`` when you +put your application into production. .. index:: single: MANIFEST.in -- cgit v1.2.3 From 06247f77d3a7f6757c6082badb00154b6f626922 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 9 Aug 2011 14:21:55 -0400 Subject: instructions about how to turn the toolbar off --- docs/narr/project.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b4a0e1d45..baf4c86fa 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -326,6 +326,28 @@ The debug toolbar will not be shown (and all debugging will be turned off) when you use the ``production.ini`` file instead of the ``development.ini`` ini file to run the application. +You can also turn the debug toolbar off by editing ``development.ini`` and +commenting out the line ``pyramid.include = pyramid_debugtoolbar``. For +example, instead of: + +.. code-block:: ini + :linenos: + + [app:MyApp] + ... + pyramid.include = pyramid_debugtoolbar + +Put a hash mark in front of the ``pyramid.include`` line: + +.. code-block:: ini + :linenos: + + [app:MyApp] + ... + #pyramid.include = pyramid_debugtoolbar + +Then restart the application to see that the toolbar has been turned off. + .. sidebar:: Using an Alternate WSGI Server The code generated by a :app:`Pyramid` scaffold assumes that you -- cgit v1.2.3 From 7b771318141be700a5f4fd72dcafdd26d179211b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 9 Aug 2011 14:22:09 -0400 Subject: add the debug image --- docs/narr/project-debug.png | Bin 0 -> 153807 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/narr/project-debug.png (limited to 'docs/narr') diff --git a/docs/narr/project-debug.png b/docs/narr/project-debug.png new file mode 100644 index 000000000..d13a91736 Binary files /dev/null and b/docs/narr/project-debug.png differ -- cgit v1.2.3 From fecefff5f0c3a6aaafdd43d902aaed15edb8559e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 9 Aug 2011 23:26:12 -0500 Subject: Added the `pyramid.security.NO_PERMISSION_REQUIRED` constant. Removed the undocumented version from pyramid.interfaces. --- docs/narr/security.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index ce304ed9f..a61578e21 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -200,9 +200,9 @@ When a default permission is registered: permission is ignored for that view registration, and the view-configuration-named permission is used. -- If a view configuration names an explicit permission as the string - ``__no_permission_required__``, the default permission is ignored, - and the view is registered *without* a permission (making it +- If a view configuration names the permission + :data:`pyramid.security.NO_PERMISSION_REQUIRED`, the default permission + is ignored, and the view is registered *without* a permission (making it available to all callers regardless of their credentials). .. warning:: @@ -210,7 +210,8 @@ When a default permission is registered: When you register a default permission, *all* views (even :term:`exception view` views) are protected by a permission. For all views which are truly meant to be anonymously accessible, you will need to associate the view's - configuration with the ``__no_permission_required__`` permission. + configuration with the :data:`pyramid.security.NO_PERMISSION_REQUIRED` + permission. .. index:: single: ACL -- cgit v1.2.3 From 57144ec3a2387abc46abea1e00d36c23b25cc1b7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 10 Aug 2011 20:52:06 -0400 Subject: trunk is 1.2dev, who are we fooling --- 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 f7ee82821..f81385c93 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -833,7 +833,7 @@ For full details, please read the `Venusian documentation Registering "Tweens" -------------------- -.. note:: Tweens are a feature which were added in Pyramid 1.1.1. They are +.. note:: Tweens are a feature which were added in Pyramid 1.2. They are not available in any previous version. A :term:`tween` (a contraction of the word "between") is a bit of code that -- cgit v1.2.3 From 83bf91aed8495cc42023e276a0e811445f98407d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 10 Aug 2011 21:24:14 -0400 Subject: - Added a ``route_prefix`` argument to the ``pyramid.config.Configurator.include`` method. This argument allows you to compose URL dispatch applications together. See the section entitled "Using a Route Prefix to Compose Applications" in the "URL Dispatch" narrative documentation chapter. - Added a section entitled "Using a Route Prefix to Compose Applications" to the "URL Dispatch" narrative documentation chapter. --- docs/narr/extending.rst | 2 ++ docs/narr/urldispatch.rst | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index f62c7e6bb..9c96248f2 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -62,6 +62,8 @@ Pyramid applications are *extensible*. .. index:: single: extensible application +.. _building_an_extensible_app: + Rules for Building An Extensible Application -------------------------------------------- diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 61c9770c6..c0197743b 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1082,6 +1082,96 @@ either of them in detail. If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back to :term:`traversal` to handle the :term:`request`. +.. _route_prefix: + +Using a Route Prefix to Compose Applications +-------------------------------------------- + +.. note:: This feature is new as of :app:`Pyramid` 1.2. + +The :meth:`pyramid.config.Configurator.include` method allows configuration +statements to be included from separate files. See +:ref:`building_an_extensible_app` for information about this method. Using +:meth:`pyramid.config.Configurator.include` allows you to build your +application from small and potentially reusable components. + +The :meth:`pyramid.config.Configurator.include` method accepts an argument +named ``route_prefix`` which can be useful to authors of URL-dispatch-based +applications. If ``route_prefix`` is supplied to the include method, it must +be a string. This string represents a route prefix that will be prepended to +all route patterns added by the *included* configuration. Any calls to +:meth:`pyramid.config.Configurator.add_route` within the included callable +will have their pattern prefixed with the value of ``route_prefix``. This can +be used to help mount a set of routes at a different location than the +included callable's author intended while still maintaining the same route +names. For example: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def users_include(config): + config.add_route('show_users', '/show') + + def main(global_config, **settings): + config = Configurator() + config.include(users_include, route_prefix='/users') + +In the above configuration, the ``show_users`` route will have an effective +route pattern of ``/users/show``, instead of ``/show`` because the +``route_prefix`` argument will be prepended to the pattern. The route will +then only match if the URL path is ``/users/show``, and when the +:func:`pyramid.url.route_url` function is called with the route name +``show_users``, it will generate a URL with that same path. + +Route prefixes are recursive, so if a callable executed via an include itself +turns around and includes another callable, the second-level route prefix +will be prepended with the first: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def timing_include(config): + config.add_route('show_times', /times') + + def users_include(config): + config.add_route('show_users', '/show') + config.include(timing_include, route_prefix='/timing') + + def main(global_config, **settings): + config = Configurator() + config.include(users_include, route_prefix='/users') + +In the above configuration, the ``show_users`` route will still have an +effective route pattern of ``/users/show``. The ``show_times`` route +however, will have an effective pattern of ``/users/timing/show_times``. + +Route prefixes have no impact on the requirement that the set of route +*names* in any given Pyramid configuration must be entirely unique. If you +compose your URL dispatch application out of many small subapplications using +:meth:`pyramid.config.Configurator.include`, it's wise to use a dotted name +for your route names, so they'll be unlikely to conflict with other packages +that may be added in the future. For example: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def timing_include(config): + config.add_route('timing.show_times', /times') + + def users_include(config): + config.add_route('users.show_users', '/show') + config.include(timing_include, route_prefix='/timing') + + def main(global_config, **settings): + config = Configurator() + config.include(users_include, route_prefix='/users') + References ---------- -- cgit v1.2.3 From 8cd013ed14f22b85096784ace1bac480f3825414 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 11 Aug 2011 23:28:52 -0400 Subject: add docs for pyramid.includes; allow space-separated or cr separated items or both for tweens and includes --- docs/narr/environment.rst | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 6465c2a1e..cb6bc6a5d 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -185,6 +185,104 @@ The value supplied here is used as the default locale name when a | | | +---------------------------------+-----------------------------------+ +Including Packages +------------------ + +``pyramid.includes`` instructs your application to include other packages. +Using the setting is equivalent to using the +:meth:`pyramid.config.Configurator.include` method. + ++---------------------------------+ +| Config File Setting Name | ++=================================+ +| ``pyramid.includes`` | +| | +| | +| | ++---------------------------------+ + +The value supplied as ``pyramid.includes`` should be a sequence. The +sequence can take several different forms. + +1) It can be a string. + + If it is a string, the package names can be separated by spaces:: + + package1 package2 package3 + + The package names can also be separated by carriage returns:: + + package1 + package2 + package3 + +2) It can be a Python list, where the values are strings:: + + ['package1', 'package2', 'package3'] + +Each value in the sequence should be a :term:`dotted Python name`. + +``pyramid.includes`` vs. :meth:`pyramid.config.Configurator.include` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PasteDeploy ++++++++++++ + +Using the following ``pyramid.includes`` setting in the PasteDeploy ``.ini`` +file in your application: + +.. code-block:: ini + + [app:myapp] + pyramid.includes = pyramid_debugtoolbar + pyramid_tm + +Is equivalent to using the following statements in your configuration code: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def main(global_config, **settings): + config = Configurator(settings=settings) + # ... + config.include('pyramid_debugtoolbar') + config.include('pyramid_tm') + # ... + +It is fine to use both or either form. + +Plain Python +++++++++++++ + +Using the following ``pyramid.includes`` setting in your plain-Python Pyramid +application: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + if __name__ == '__main__': + settings = {'pyramid.includes':'pyramid_debugtoolbar pyramid_tm'} + config = Configurator(settings=settings) + +Is equivalent to using the following statements in your configuration code: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + if __name__ == '__main__': + settings = {} + config = Configurator(settings=settings) + config.include('pyramid_debugtoolbar') + config.include('pyramid_tm') + +It is fine to use both or either form. + .. _mako_template_renderer_settings: Mako Template Render Settings -- cgit v1.2.3 From efd07ccf6889e965f67b1dd0ef1a09f0efacbf2f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 11 Aug 2011 23:38:34 -0400 Subject: fix docs, scaffolds, and tutorials to use pyramid.includes --- docs/narr/MyProject/development.ini | 2 +- docs/narr/project.rst | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 1818e387b..e134e9f06 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -7,7 +7,7 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.include = pyramid_debugtoolbar +pyramid.includes = pyramid_debugtoolbar [pipeline:main] pipeline = diff --git a/docs/narr/project.rst b/docs/narr/project.rst index baf4c86fa..e59d04ee1 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -327,7 +327,7 @@ when you use the ``production.ini`` file instead of the ``development.ini`` ini file to run the application. You can also turn the debug toolbar off by editing ``development.ini`` and -commenting out the line ``pyramid.include = pyramid_debugtoolbar``. For +commenting out the line ``pyramid.includes = pyramid_debugtoolbar``. For example, instead of: .. code-block:: ini @@ -335,16 +335,16 @@ example, instead of: [app:MyApp] ... - pyramid.include = pyramid_debugtoolbar + pyramid.includes = pyramid_debugtoolbar -Put a hash mark in front of the ``pyramid.include`` line: +Put a hash mark in front of the ``pyramid.includes`` line: .. code-block:: ini :linenos: [app:MyApp] ... - #pyramid.include = pyramid_debugtoolbar + #pyramid.includes = pyramid_debugtoolbar Then restart the application to see that the toolbar has been turned off. @@ -526,9 +526,9 @@ information. options should be turned off for production applications, as template rendering is slowed when either is turned on. -The ``pyramid.include`` setting in the ``[app:MyProject]`` section tells +The ``pyramid.includes`` setting in the ``[app:MyProject]`` section tells Pyramid to "include" configuration from another package. In this case, the -line ``pyramid.include = pyramid_debugtoolbar`` tells Pyramid to include +line ``pyramid.includes = pyramid_debugtoolbar`` tells Pyramid to include configuration from the ``pyramid_debugtoolbar`` package. This turns on a debugging panel in development mode which will be shown on the right hand side of the screen. Including the debug toolbar will also make it possible -- cgit v1.2.3 From be46dacfd3b197ce3d8cb907532daa49c93fb8df Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 12 Aug 2011 00:08:16 -0400 Subject: add pyramid.tweens configuration value docs --- docs/narr/environment.rst | 83 +++++++++++++++++++++++++++++++++++++++++++++++ docs/narr/hooks.rst | 14 +++++++- 2 files changed, 96 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index cb6bc6a5d..cc858a892 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -283,6 +283,89 @@ Is equivalent to using the following statements in your configuration code: It is fine to use both or either form. +Explicit Tween Configuration +---------------------------- + +This value allows you to perform explicit :term:`tween` ordering in your +configuration. Tweens are bits of code used by add-on authors to extend +Pyramid. They form a chain, and require ordering. + +Ideally, you won't need to use the ``pyramid.tweens`` setting at all. Tweens +are generally ordered and included "implicitly" when an add-on package which +registers a tween is "included". Packages are included when you name a +``pyramid.includes`` setting in your configuration or when you call +:meth:`pyramid.config.Configuration.include`. + +Authors of included add-ons provide "implicit" tween configuration ordering +hints to Pyramid when their packages are included. However, the implicit +tween ordering is only best-effort. Pyramid will attempt to provide an +implicit order of tweens as best it can using hints provided by add-on +authors, but because it's only best-effort, if very precise tween ordering is +required, the only surefire way to get it is to use an explicit tween order. +You may be required to inspect your tween ordering (see +:ref:`displaying_tweens`) and add a ``pyramid.tweens`` configuration value at +the behest of an add-on author. + ++---------------------------------+ +| Config File Setting Name | ++=================================+ +| ``pyramid.tweens`` | +| | +| | +| | ++---------------------------------+ + +The value supplied as ``pyramid.tweens`` should be a sequence. The +sequence can take several different forms. + +1) It can be a string. + + If it is a string, the tween names can be separated by spaces:: + + pkg.tween_factory1 pkg.tween_factory2 pkg.tween_factory3 + + The tween names can also be separated by carriage returns:: + + pkg.tween_factory1 + pkg.tween_factory2 + pkg.tween_factory3 + +2) It can be a Python list, where the values are strings:: + + ['pkg.tween_factory1', 'pkg.tween_factory2', 'pkg.tween_factory3'] + +Each value in the sequence should be a :term:`dotted Python name`. + +Paste Configuration vs. Plain-Python Configuration +++++++++++++++++++++++++++++++++++++++++++++++++++ + +Using the following ``pyramid.tweens`` setting in the PasteDeploy ``.ini`` +file in your application: + +.. code-block:: ini + + [app:myapp] + pyramid.tweens = pyramid_debugtoolbar.toolbar.tween_factory + pyramid.tweens.excview_tween_factory + pyramid_tm.tm_tween_factory + +Is equivalent to using the following statements in your configuration code: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def main(global_config, **settings): + settings['pyramid.tweens'] = [ + 'pyramid_debugtoolbar.toolbar.tween_factory', + 'pyramid.tweebs.excview_tween_factory', + 'pyramid_tm.tm_tween_factory', + ] + config = Configurator(settings=settings) + +It is fine to use both or either form. + .. _mako_template_renderer_settings: Mako Template Render Settings diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index f81385c93..e07dca9bd 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -932,7 +932,8 @@ add_tween can provide an optional hint that can influence the implicit tween chain ordering by supplying ``under`` or ``over`` (or both) arguments to :meth:`~pyramid.config.Configurator.add_tween`. These hints are only used used when an explicit tween chain is not used (when the ``pyramid.tweens`` -configuration value is not set). +configuration value is not set). See :ref:`explicit_tweens` for a +description of how to set an explicit tweens list. Allowable values for ``under`` or ``over`` (or both) are: @@ -1026,6 +1027,11 @@ For example: Alias names are only useful in relation to ``under`` and ``over`` values. They cannot be used in explicit tween chain configuration, or anywhere else. +.. _explicit_tween_ordering: + +Explicit Tween Ordering +~~~~~~~~~~~~~~~~~~~~~~~ + Implicit tween ordering is obviously only best-effort. Pyramid will attempt to provide an implicit order of tweens as best it can using hints provided by calls to :meth:`~pyramid.config.Configurator.add_tween`, but because it's @@ -1069,6 +1075,9 @@ handler is implicit, and always "at the bottom". ``pyramid.tweens`` configuration setting list explicitly. If it is not present, Pyramid will not perform exception view handling. +Tween Conflicts and Ordering Cycles +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Pyramid will prevent the same tween factory from being added to the tween chain more than once using configuration conflict detection. If you wish to add the same tween factory more than once in a configuration, you should @@ -1082,6 +1091,9 @@ If a cycle is detected in implicit tween ordering when ``over`` and ``under`` are used in any call to "add_tween", an exception will be raised at startup time. +Displaying Tween Ordering +~~~~~~~~~~~~~~~~~~~~~~~~~ + The ``paster ptweens`` command-line utility can be used to report the current implict and explicit tween chains used by an application. See :ref:`displaying_tweens`. -- cgit v1.2.3 From 47369747d8050faddd8b98f4cad9f5d0bb263130 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 12 Aug 2011 00:17:52 -0400 Subject: garden changes; fix docs rendering --- docs/narr/environment.rst | 72 +++++++++++++++++++++++++---------------------- docs/narr/hooks.rst | 6 ++-- 2 files changed, 41 insertions(+), 37 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index cc858a892..2f5555840 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -225,31 +225,35 @@ Each value in the sequence should be a :term:`dotted Python name`. ``pyramid.includes`` vs. :meth:`pyramid.config.Configurator.include` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -PasteDeploy -+++++++++++ +Two methods exist for including packages: ``pyramid.includes`` and +:meth:`pyramid.config.Configurator.include`. This section explains their +equivalence. + +Using PasteDeploy ++++++++++++++++++ Using the following ``pyramid.includes`` setting in the PasteDeploy ``.ini`` file in your application: .. code-block:: ini - [app:myapp] - pyramid.includes = pyramid_debugtoolbar - pyramid_tm + [app:myapp] + pyramid.includes = pyramid_debugtoolbar + pyramid_tm Is equivalent to using the following statements in your configuration code: .. code-block:: python :linenos: - from pyramid.config import Configurator + from pyramid.config import Configurator - def main(global_config, **settings): - config = Configurator(settings=settings) - # ... - config.include('pyramid_debugtoolbar') - config.include('pyramid_tm') - # ... + def main(global_config, **settings): + config = Configurator(settings=settings) + # ... + config.include('pyramid_debugtoolbar') + config.include('pyramid_tm') + # ... It is fine to use both or either form. @@ -337,32 +341,32 @@ sequence can take several different forms. Each value in the sequence should be a :term:`dotted Python name`. Paste Configuration vs. Plain-Python Configuration -++++++++++++++++++++++++++++++++++++++++++++++++++ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Using the following ``pyramid.tweens`` setting in the PasteDeploy ``.ini`` file in your application: .. code-block:: ini - [app:myapp] - pyramid.tweens = pyramid_debugtoolbar.toolbar.tween_factory - pyramid.tweens.excview_tween_factory - pyramid_tm.tm_tween_factory + [app:myapp] + pyramid.tweens = pyramid_debugtoolbar.toolbar.tween_factory + pyramid.tweens.excview_tween_factory + pyramid_tm.tm_tween_factory Is equivalent to using the following statements in your configuration code: .. code-block:: python :linenos: - from pyramid.config import Configurator - - def main(global_config, **settings): - settings['pyramid.tweens'] = [ - 'pyramid_debugtoolbar.toolbar.tween_factory', - 'pyramid.tweebs.excview_tween_factory', - 'pyramid_tm.tm_tween_factory', - ] - config = Configurator(settings=settings) + from pyramid.config import Configurator + + def main(global_config, **settings): + settings['pyramid.tweens'] = [ + 'pyramid_debugtoolbar.toolbar.tween_factory', + 'pyramid.tweebs.excview_tween_factory', + 'pyramid_tm.tm_tween_factory', + ] + config = Configurator(settings=settings) It is fine to use both or either form. @@ -379,7 +383,7 @@ Renderer uses a subclass of Mako's `template lookup several arguments to configure it. Mako Directories -++++++++++++++++ +~~~~~~~~~~~~~~~~ The value(s) supplied here are passed in as the template directories. They should be in :term:`asset specification` format, for example: @@ -395,7 +399,7 @@ should be in :term:`asset specification` format, for example: +-----------------------------+ Mako Module Directory -+++++++++++++++++++++ +~~~~~~~~~~~~~~~~~~~~~ The value supplied here tells Mako where to store compiled Mako templates. If omitted, compiled templates will be stored in memory. This value should be an @@ -412,7 +416,7 @@ called ``data/templates`` in the same parent directory as the INI file. +-----------------------------+ Mako Input Encoding -+++++++++++++++++++ +~~~~~~~~~~~~~~~~~~~ The encoding that Mako templates are assumed to have. By default this is set to ``utf-8``. If you wish to use a different template encoding, this value @@ -428,7 +432,7 @@ should be changed accordingly. +-----------------------------+ Mako Error Handler -++++++++++++++++++ +~~~~~~~~~~~~~~~~~~ A callable (or a :term:`dotted Python name` which names a callable) which is called whenever Mako compile or runtime exceptions occur. The callable is @@ -446,7 +450,7 @@ the function completes. Is used to provide custom error-rendering functions. +-----------------------------+ Mako Default Filters -++++++++++++++++++++ +~~~~~~~~~~~~~~~~~~~~ List of string filter names that will be applied to all Mako expressions. @@ -460,7 +464,7 @@ List of string filter names that will be applied to all Mako expressions. +-----------------------------+ Mako Import -+++++++++++ +~~~~~~~~~~~ String list of Python statements, typically individual "import" lines, which will be placed into the module level preamble of all generated Python modules. @@ -477,7 +481,7 @@ will be placed into the module level preamble of all generated Python modules. Mako Strict Undefined -+++++++++++++++++++++ +~~~~~~~~~~~~~~~~~~~~~ ``true`` or ``false``, representing the "strict undefined" behavior of Mako (see `Mako Context Variables @@ -494,7 +498,7 @@ default, this is ``false``. +-----------------------------+ Mako Preprocessor -+++++++++++++++++ +~~~~~~~~~~~~~~~~~ A callable (or a :term:`dotted Python name` which names a callable) which is called to preprocess the source before the template is called. The callable diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index e07dca9bd..cd2109c5c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -931,9 +931,9 @@ entirely by the relative ordering of calls to add_tween can provide an optional hint that can influence the implicit tween chain ordering by supplying ``under`` or ``over`` (or both) arguments to :meth:`~pyramid.config.Configurator.add_tween`. These hints are only used -used when an explicit tween chain is not used (when the ``pyramid.tweens`` -configuration value is not set). See :ref:`explicit_tweens` for a -description of how to set an explicit tweens list. +used when an explicit tween ordering is not used. See +:ref:`explicit_tween_ordering` for a description of how to set an explicit +tween ordering. Allowable values for ``under`` or ``over`` (or both) are: -- cgit v1.2.3 From 9ec766cf34014de1e357a449133830ff944efb19 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 12 Aug 2011 03:08:54 -0500 Subject: Updated the docs with the new over/under tuples. --- docs/narr/hooks.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index f81385c93..fafb407d3 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -948,6 +948,10 @@ Allowable values for ``under`` or ``over`` (or both) are: - One of the constants :attr:`pyramid.tweens.MAIN`, :attr:`pyramid.tweens.INGRESS`, or :attr:`pyramid.tweens.EXCVIEW`. +- An iterable of any combination of the above. This allows the user to specify + fallbacks if the desired tween is not included, as well as compatibility + with multiple other tweens. + Effectively, ``under`` means "closer to the main Pyramid application than", ``over`` means "closer to the request ingress than". @@ -999,10 +1003,14 @@ this:: Specifying neither ``over`` nor ``under`` is equivalent to specifying ``under=INGRESS``. -If an ``under`` or ``over`` value is provided that does not match a tween -factory dotted name or alias in the current configuration, that value will be -ignored. It is not an error to provide an ``under`` or ``over`` value that -matches an unused tween factory. +If all options for ``under`` (or ``over``) cannot be found in the current +configuration, it is an error. If some options are specified purely for +compatibilty with other tweens, just add a fallback of MAIN or INGRESS. +For example, ``under=('someothertween', 'someothertween2', INGRESS)``. +This constraint will require the tween to be located under both the +'someothertween' tween, the 'someothertween2' tween, and INGRESS. If any of +these is not in the current configuration, this constraint will only organize +itself based on the tweens that are present. :meth:`~pyramid.config.Configurator.add_tween` also accepts an ``alias`` argument. If ``alias`` is not ``None``, should be a string. The string will -- cgit v1.2.3 From e518931f909d31014af5dbbab24d1bfd44e0a19b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 12 Aug 2011 16:49:51 -0400 Subject: reduce awkwardness of phrasing --- docs/narr/firstapp.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 66632e123..62389ec5f 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -166,17 +166,19 @@ Configurator Construction The ``if __name__ == '__main__':`` line in the code sample above represents a Python idiom: the code inside this if clause is not invoked unless the script -containing this code is run directly from the command line. For example, if -the file named ``helloworld.py`` contains the entire script body, the code -within the ``if`` statement will only be invoked when ``python -helloworld.py`` is executed from the operating system command line. - -``helloworld.py`` in this case is a Python :term:`module`. Using the ``if`` -clause is necessary -- or at least best practice -- because code in any -Python module may be imported by another Python module. By using this idiom, -the script is indicating that it does not want the code within the ``if`` -statement to execute if this module is imported; the code within the ``if`` -block should only be run during a direct script execution. +containing this code is run directly from the operating system command +line. For example, if the file named ``helloworld.py`` contains the entire +script body, the code within the ``if`` statement will only be invoked when +``python helloworld.py`` is executed from the command line. + +Using the ``if`` clause is necessary -- or at least best practice -- because +code in a Python ``.py`` file may be eventually imported via the Python +``import`` statement by another ``.py`` file. ``.py`` files that are +imported by other ``.py`` files are referred to as *modules*. By using the +``if __name__ == 'main':`` idiom, the script above is indicating that it does +not want the code within the ``if`` statement to execute if this module is +imported from another; the code within the ``if`` block should only be run +during a direct script execution. The ``config = Configurator()`` line above creates an instance of the :class:`~pyramid.config.Configurator` class. The resulting ``config`` object -- cgit v1.2.3 From 391402e63c1257ede0069f220ed5a1cca1b94a9b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Aug 2011 01:00:39 -0400 Subject: - Projects created via a scaffold no longer depend on the ``WebError`` package at all; configuration in the ``production.ini`` file which used to require its ``error_catcher`` middleware has been removed. Configuring error catching / email sending is now the domain of the ``pyramid_exclog`` package (see https://docs.pylonsproject.org/projects/pyramid_exclog/dev/). --- docs/narr/MyProject/production.ini | 15 --------------- docs/narr/commandline.rst | 10 ++++++++-- docs/narr/project.rst | 12 +++++------- 3 files changed, 13 insertions(+), 24 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 7a5674d23..0a2154b15 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -8,23 +8,8 @@ pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -[filter:weberror] -use = egg:WebError#error_catcher -debug = false -;error_log = -;show_exceptions_in_wsgi_errors = true -;smtp_server = localhost -;error_email = janitor@example.com -;smtp_username = janitor -;smtp_password = "janitor's password" -;from_address = paste@localhost -;error_subject_prefix = "Pyramid Error" -;smtp_use_tls = -;error_message = - [pipeline:main] pipeline = - weberror MyProject [server:main] diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 0f23c153c..b1a646aec 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -466,9 +466,14 @@ example above looks like so: .. code-block:: ini [pipeline:main] - pipeline = egg:WebError#evalerror + pipeline = translogger another + [filter:translogger] + filter_app_factory = egg:Paste#translogger + setup_console_handler = False + logger_name = wsgi + [app:another] use = egg:MyProject @@ -477,7 +482,8 @@ configuration implied by the ``[pipeline:main]`` section of your configuration file by default. Specifying ``/path/to/my/development.ini`` is logically equivalent to specifying ``/path/to/my/development.ini#main``. In this case, we'll be using a configuration that includes an ``app`` object -which is wrapped in the WebError ``evalerror`` middleware. +which is wrapped in the Paste "translogger" middleware (which logs requests +to the console). You can also specify a particular *section* of the PasteDeploy ``.ini`` file to load instead of ``main``: diff --git a/docs/narr/project.rst b/docs/narr/project.rst index e59d04ee1..aed93f9c5 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -588,13 +588,11 @@ implementations. The ``production.ini`` file is a :term:`PasteDeploy` configuration file with a purpose much like that of ``development.ini``. However, it disables the -debug toolbar, replacing it with a logger which outputs exception messages to -``stderr`` by default. It also turns off template development options such -that templates are not automatically reloaded when changed, and turns off all -debugging options. It allows you to configure a ``weberror#error_catcher`` -section that will cause exceptions to be sent to an email address when they -are uncaught. You can use this file instead of ``development.ini`` when you -put your application into production. +debug toolbar, and filters all log messages except those above the WARN +level. It also turns off template development options such that templates +are not automatically reloaded when changed, and turns off all debugging +options. This file is appropriate to use instead of ``development.ini`` when +you put your application into production. .. index:: single: MANIFEST.in -- cgit v1.2.3 From 1ae7af86d5d4898788ff64b46e887a06c47e69ea Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Aug 2011 01:43:21 -0400 Subject: - Added a Logging chapter to the narrative docs (based on the Pylons logging docs, thanks Phil). --- docs/narr/logging.rst | 388 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 docs/narr/logging.rst (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst new file mode 100644 index 000000000..120944fac --- /dev/null +++ b/docs/narr/logging.rst @@ -0,0 +1,388 @@ +.. _logging_chapter: + +Logging +======= + +:app:`Pyramid` allows you to make use of the Python standard library +:mod:`logging` module. This chapter describes how to configure logging and +how to send log messages to loggers that you've configured. + +.. warning:: This chapter assumes you've used a :term:`scaffold` to create a + project which contains ``development.ini`` and ``production.ini`` files + which help configure logging. All of the scaffolds which ship along with + :app:`Pyramid` do this. If you're not using a scaffold, or if you've used + a third-party scaffold which does not create these files, the + configuration information in this chapter will not be applicable. + +Logging Configuration +--------------------- + +A :app:`Pyramid` project created from a :term:`scaffold` is configured to +allow you to send messages to `Python standard library logging package +`_ loggers from within your +application. In particular, the :term:`PasteDeploy` ``development.ini`` and +``production.ini`` files created when you use a scaffold include a basic +configuration for the Python :mod:`logging` package. + +PasteDeploy ``.ini`` files use the Python standard library `ConfigParser +format `_; this the same +format used as the Python `logging module's Configuration file format +`_. The +application-related and logging-related sections in the configuration file +can coexist peacefully, and the logging-related sections in the file are used +from when you run ``paster serve``. + +The ``paster serve`` command calls the `logging.fileConfig function +`_ using the specified +ini file if it contains a ``[loggers]`` section (all of the +scaffold-generated ``.ini`` files do). ``logging.fileConfig`` reads the +logging configuration from the ini file upon which ``paster serve`` was +invoked. + +Default logging configuration is provided in both the default +``development.ini`` and the ``production.ini`` file. The logging +configuration in the ``development.ini`` file is as follows: + +.. code-block:: ini + :linenos: + + # Begin logging configuration + + [loggers] + keys = root, {{package_logger}} + + [handlers] + keys = console + + [formatters] + keys = generic + + [logger_root] + level = INFO + handlers = console + + [logger_{{package_logger}}] + level = DEBUG + handlers = + qualname = {{package}} + + [handler_console] + class = StreamHandler + args = (sys.stderr,) + level = NOTSET + formatter = generic + + [formatter_generic] + format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + + # End logging configuration + +The ``production.ini`` file uses the ``WARN`` level in its logger +configuration, but it is otherwise identical. + +The name ``{{package_logger}}`` above will be replaced with the name of your +project's :term:`package`, which is derived from the name you provide to your +project. For instance, if you do: + +.. code-block:: text + :linenos: + + paster create -t pyramid_starter MyApp + +The logging configuration will literally be: + +.. code-block:: ini + :linenos: + + # Begin logging configuration + + [loggers] + keys = root, myapp + + [handlers] + keys = console + + [formatters] + keys = generic + + [logger_root] + level = INFO + handlers = console + + [logger_myapp] + level = DEBUG + handlers = + qualname = myapp + + [handler_console] + class = StreamHandler + args = (sys.stderr,) + level = NOTSET + formatter = generic + + [formatter_generic] + format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + + # End logging configuration + +In this logging configuration: + +- a logger named ``root`` is created that logs messages at a level above + or equal to the ``INFO`` level to stderr, with the following format: + + .. code-block:: text + + 2007-08-17 15:04:08,704 INFO [packagename] + Loading resource, id: 86 + +- a logger named ``myapp`` is configured that logs messages sent at a level + above or equal to ``DEBUG`` to stderr in the same format as the root + logger. + +The ``root`` logger will be used by all applications in the Pyramid process +that ask for a logger (via ``logging.getLogger``) that has a name which +begins with anything except your project's package name (e.g. ``myapp``). +The logger with the same name as your package name is reserved for your own +usage in your Pyramid application. Its existence means that you can log to a +known logging location from any Pyramid application generated via a scaffold. + +Pyramid and many other libraries (such as Beaker, SQLAlchemy, Paste) log a +number of messages to the root logger for debugging purposes. Switching the +root logger level to ``DEBUG`` reveals them: + +.. code-block:: ini + + [logger_root] + #level = INFO + level = DEBUG + handlers = console + +Some scaffolds configure additional loggers for additional subsystems they +use (such as SQLALchemy). Take a look at the ``production.ini`` and +``development.ini`` files rendered when you create a project from a scaffold. + +Sending Logging Messages +------------------------ + +Python's special ``__name__`` variable refers to the current module's fully +qualified name. From any module in a package named ``myapp``, the +``__name__`` builtin variable will always be something like ``myapp``, or +``myapp.subpackage`` or ``myapp.package.subpackage`` if your project is named +``myapp``. Sending a message to this logger will send it to the ``myapp`` +logger. + +To log messages to the package-specific logger configured in your ``.ini`` +file, simply create a logger object using the ``__name__`` builtin and call +methods on it. + +.. code-block:: python + :linenos: + + import logging + log = logging.getLogger(__name__) + + def myview(request): + content_type = 'text/plain' + content = 'Hello World!' + log.debug('Returning: %s (content-type: %s)', content, content_type) + request.response.content_type = content_type + return request.response + +This will result in the following printed to the console, on ``stderr``: + +.. code-block:: text + + 16:20:20,440 DEBUG [myapp.views] Returning: Hello World! + (content-type: text/plain) + +Filtering log messages +---------------------- + +Often there's too much log output to sift through, such as when switching +the root logger's level to ``DEBUG``. + +An example: you're diagnosing database connection issues in your application +and only want to see SQLAlchemy's ``DEBUG`` messages in relation to database +connection pooling. You can leave the root logger's level at the less verbose +``INFO`` level and set that particular SQLAlchemy logger to ``DEBUG`` on its +own, apart from the root logger: + +.. code-block:: ini + + [logger_sqlalchemy.pool] + level = DEBUG + handlers = + qualname = sqlalchemy.pool + +then add it to the list of loggers: + +.. code-block:: ini + + [loggers] + keys = root, myapp, sqlalchemy.pool + +No handlers need to be configured for this logger as by default non root +loggers will propagate their log records up to their parent logger's +handlers. The root logger is the top level parent of all loggers. + +This technique is used in the default ``development.ini``. The root logger's +level is set to ``INFO``, whereas the application's log level is set to +``DEBUG``: + +.. code-block:: ini + + # Begin logging configuration + + [loggers] + keys = root, myapp + + [logger_myapp] + level = DEBUG + handlers = + qualname = helloworld + +All of the child loggers of the ``myapp`` logger will inherit the ``DEBUG`` +level unless they're explicitly set differently. Meaning the ``myapp.views``, +``myapp.models`` (and all your app's modules') loggers by default have an +effective level of ``DEBUG`` too. + +For more advanced filtering, the logging module provides a `Filter +`_ object; however it cannot be used +directly from the configuration file. + +Advanced Configuration +---------------------- + +To capture log output to a separate file, use a `FileHandler +`_ (or a `RotatingFileHandler +`_): + +.. code-block:: ini + + [handler_filelog] + class = FileHandler + args = ('%(here)s/myapp.log','a') + level = INFO + formatter = generic + +Before it's recognized, it needs to be added to the list of Handlers: + +.. code-block:: ini + + [handlers] + keys = console, myapp, filelog + +and finally utilized by a logger. + +.. code-block:: ini + + [logger_root] + level = INFO + handlers = console, filelog + +These final 3 lines of configuration directs all of the root logger's output +to the ``myapp.log`` as well as the console. + +Request logging with Paste's TransLogger +---------------------------------------- + +Paste provides the `TransLogger +`_ middleware for logging +requests using the `Apache Combined Log Format +`_. TransLogger combined +with a FileHandler can be used to create an ``access.log`` file similar to +Apache's. + +Like any standard middleware with a Paste entry point, TransLogger can be +configured to wrap your application in the ``[app:main]`` section of the ini +file: + +.. code-block:: ini + + [filter:translogger] + paste.filter_app_factory = egg:Paste#translogger + setup_console_handler = False + + [pipeline:main] + pipeline = translogger + myapp + +This is equivalent to wrapping your app in a TransLogger instance via the +bottom the ``main`` function of your project's ``__init__`` file: + +.. code-block:: python + + ... + app = config.make_wsgi_app() + from paste.translogger import TransLogger + app = TransLogger(app, setup_console_handler=False) + return app + +TransLogger will automatically setup a logging handler to the console when +called with no arguments, so it 'just works' in environments that don't +configure logging. Since we've configured our own logging handlers, we need +to disable that option via ``setup_console_handler = False``. + +With the filter in place, TransLogger's logger (named the 'wsgi' logger) will +propagate its log messages to the parent logger (the root logger), sending +its output to the console when we request a page: + +.. code-block:: text + + 00:50:53,694 INFO [myapp.views] Returning: Hello World! + (content-type: text/plain) + 00:50:53,695 INFO [wsgi] 192.168.1.111 - - [11/Aug/2011:20:09:33 -0700] "GET /hello + HTTP/1.1" 404 - "-" + "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.6) Gecko/20070725 + Firefox/2.0.0.6" + +To direct TransLogger to an ``access.log`` FileHandler, we need to add that +FileHandler to the wsgi logger's list of handlers: + +.. code-block:: ini + + # Begin logging configuration + + [loggers] + keys = root, myapp, wsgi + + [logger_wsgi] + level = INFO + handlers = handler_accesslog + qualname = wsgi + propagate = 0 + + [handler_accesslog] + class = FileHandler + args = ('%(here)s/access.log','a') + level = INFO + formatter = generic + +As mentioned above, non-root loggers by default propagate their log records +to the root logger's handlers (currently the console handler). Setting +``propagate`` to 0 (false) here disables this; so the ``wsgi`` logger directs +its records only to the ``accesslog`` handler. + +Finally, there's no need to use the ``generic`` formatter with TransLogger as +TransLogger itself provides all the information we need. We'll use a +formatter that passes-through the log messages as is: + +.. code-block:: ini + + [formatters] + keys = generic, accesslog + +.. code-block:: ini + + [formatter_accesslog] + format = %(message)s + +Then wire this new ``accesslog`` Formatter into the FileHandler: + +.. code-block:: ini + + [handler_accesslog] + class = FileHandler + args = ('%(here)s/access.log','a') + level = INFO + formatter = accesslog -- cgit v1.2.3 From bfdbcf4c25e28216060834b648a022045d88146b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Aug 2011 01:55:45 -0400 Subject: mention pyramid_exclog --- docs/narr/logging.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 120944fac..375ab820c 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -265,7 +265,7 @@ To capture log output to a separate file, use a `FileHandler level = INFO formatter = generic -Before it's recognized, it needs to be added to the list of Handlers: +Before it's recognized, it needs to be added to the list of handlers: .. code-block:: ini @@ -283,7 +283,15 @@ and finally utilized by a logger. These final 3 lines of configuration directs all of the root logger's output to the ``myapp.log`` as well as the console. -Request logging with Paste's TransLogger +Logging Exceptions +------------------ + +To log (or email) exceptions generated by your :app:`Pyramid` application, +use the :term:`pyramid_exclog` package. Details about its configuration are +in its `documentation +`_. + +Request Logging with Paste's TransLogger ---------------------------------------- Paste provides the `TransLogger @@ -377,7 +385,7 @@ formatter that passes-through the log messages as is: [formatter_accesslog] format = %(message)s -Then wire this new ``accesslog`` Formatter into the FileHandler: +Then wire this new ``accesslog`` formatter into the FileHandler: .. code-block:: ini -- cgit v1.2.3 From 157c29002377b65834a960fd2d59c40bdd43f417 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Aug 2011 06:11:26 -0400 Subject: disallow adding a tween factory which is an instance without passing its globally importable name --- docs/narr/commandline.rst | 8 +++----- docs/narr/hooks.rst | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index b1a646aec..97004d2b8 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -311,11 +311,9 @@ 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 calls to :meth:`pyramid.config.Configurator.add_tween`) and the explicit tween ordering (specified by the ``pyramid.tweens`` configuration -setting) orderings using the ``paster ptweens`` command. Handler factories -which are functions or classes will show up as a standard Python dotted name -in the ``paster ptweens`` output. Tween factories which are *instances* will -show their module and class name; the Python object id of the instance will -be appended. +setting) orderings using the ``paster ptweens`` command. Tween factories +will show up represented by their standard Python dotted name in the +``paster ptweens`` output. For example, here's the ``paster pwteens`` command run against a system configured without any explicit tweens: diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index c8efc057c..97bee479b 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -847,12 +847,12 @@ running in a context in which they have access to the Pyramid :term:`application registry` as well as the Pyramid rendering machinery. To make use of tweens, you must construct a "tween factory". A tween factory -must be a callable (or a :term:`dotted Python name` to such a callable) which -accepts two arguments: ``handler`` and ``registry``. ``handler`` will be the -either the main Pyramid request handling function or another tween (if more -than one tween is configured into the request handling chain). ``registry`` -will be the Pyramid :term:`application registry` represented by this -Configurator. A tween factory must return a tween when it is called. +must be a globally importable callable (or a :term:`dotted Python name` to +such a callable) which accepts two arguments: ``handler`` and ``registry``. +``handler`` will be the either the main Pyramid request handling function or +another tween. ``registry`` will be the Pyramid :term:`application registry` +represented by this Configurator. A tween factory must return a tween when +it is called. A tween is a callable which accepts a :term:`request` object and returns a two-tuple a :term:`response` object. @@ -1089,11 +1089,12 @@ Tween Conflicts and Ordering Cycles Pyramid will prevent the same tween factory from being added to the tween chain more than once using configuration conflict detection. If you wish to add the same tween factory more than once in a configuration, you should -either: a) use a tween factory that is an instance rather than a function or -class, b) use a function or class as a tween factory with the same logic as -the other tween factory it conflicts with but with a different ``__name__`` -attribute or c) call :meth:`pyramid.config.Configurator.commit` between calls -to :meth:`pyramid.config.Configurator.add_tween`. +either: a) use a tween factory that is a separate globally importable +instance object from the factory that it conflicts with b) use a function or +class as a tween factory with the same logic as the other tween factory it +conflicts with but with a different ``__name__`` attribute or c) call +:meth:`pyramid.config.Configurator.commit` between calls to +:meth:`pyramid.config.Configurator.add_tween`. If a cycle is detected in implicit tween ordering when ``over`` and ``under`` are used in any call to "add_tween", an exception will be raised at startup -- cgit v1.2.3 From 5396466b819692ae0d1ea2b78e6df6093545963a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Aug 2011 23:30:46 -0400 Subject: Require that tween_factory argument to add_tween be a dotted name. --- docs/narr/hooks.rst | 79 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 97bee479b..50758f327 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -846,25 +846,26 @@ behave a bit like :term:`WSGI` middleware but they have the benefit of running in a context in which they have access to the Pyramid :term:`application registry` as well as the Pyramid rendering machinery. +Creating a Tween Factory +~~~~~~~~~~~~~~~~~~~~~~~~ + To make use of tweens, you must construct a "tween factory". A tween factory -must be a globally importable callable (or a :term:`dotted Python name` to -such a callable) which accepts two arguments: ``handler`` and ``registry``. -``handler`` will be the either the main Pyramid request handling function or -another tween. ``registry`` will be the Pyramid :term:`application registry` -represented by this Configurator. A tween factory must return a tween when -it is called. +must be a globally importable callable which accepts two arguments: +``handler`` and ``registry``. ``handler`` will be the either the main +Pyramid request handling function or another tween. ``registry`` will be the +Pyramid :term:`application registry` represented by this Configurator. A +tween factory must return a tween when it is called. A tween is a callable which accepts a :term:`request` object and returns a two-tuple a :term:`response` object. -Once you've created a tween factory, you can register it into the implicit -tween chain using the :meth:`pyramid.config.Configurator.add_tween` method. - -Here's an example creating a tween factory and registering it: +Here's an example of a tween factory: .. code-block:: python :linenos: + # in a module named myapp.tweens + import time from pyramid.settings import asbool import logging @@ -888,13 +889,58 @@ Here's an example creating a tween factory and registering it: # handler return handler - from pyramid.config import Configurator +If you remember, a tween is an object which accepts a :term:`request` object +and which returns a :term:`response` argument. The ``request`` argument to a +tween will be the request created by Pyramid's router when it receives a WSGI +request. The response object will be generated by the downstream Pyramid +application and it should be returned by the tween. + +In the above example, the tween factory defines a ``timing_tween`` tween and +returns it if ``asbool(registry.settings.get('do_timing'))`` is true. It +otherwise simply returns the handler it was given. The ``registry.settings`` +attribute is a handle to the deployment settings provided by the user +(usually in an ``.ini`` file). In this case, if the user has defined a +``do_timing`` setting, and that setting is ``True``, the user has said she +wants to do timing, so the tween factory returns the timing tween; it +otherwise just returns the handler it has been provided, preventing any +timing. + +The example timing tween simply records the start time, calls the downstream +handler, logs the number of seconds consumed by the downstream handler, and +returns the response. + +Registering an Implicit Tween Factory +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - config = Configurator() - config.add_tween(timing_tween_factory) +Once you've created a tween factory, you can register it into the implicit +tween chain using the :meth:`pyramid.config.Configurator.add_tween` method +using its :term:`dotted Python name`. -The ``request`` argument to a tween will be the request created by Pyramid's -router when it receives a WSGI request. +Here's an example of registering the a tween factory as an "implicit" +tween in a Pyramid application: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + config = Configurator() + config.add_tween('myapp.tweens.timing_tween_factory') + +Note that you must use a :term:`dotted Python name` as the first argument to +:meth:`pyramid.config.Configurator.add_tween`; this must point at a tween +factory. You cannot pass the tween factory object itself to the method: it +must be a globally importable object. In the above example, we assume that a +``timing_tween_factory`` tween factory was defined in a module named +``myapp.tweens``, so the tween factory is importable as +``myapp.tweens.timing_tween_factory``. + +When you use :meth:`pyramid.config.Configurator.add_tween`, you're +instructing the system to use your tween factory at startup time unless the +user has provided an explicit tween list in his configuration. This is +what's meant by an "implicit" tween. A user can always elect to supply an +explicit tween list, reordering or disincluding implicitly added tweens. See +:ref:`explicit_tween_ordering` for more information about explicit tween +ordering. If more than one call to :meth:`pyramid.config.Configurator.add_tween` is made within a single application configuration, the tweens will be chained @@ -925,6 +971,9 @@ this:: pyramid.tweens.excview_tween_factory (implicit) MAIN (implicit) +Suggesting Implicit Tween Ordering +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + By default, as described above, the ordering of the chain is controlled entirely by the relative ordering of calls to :meth:`pyramid.config.Configurator.add_tween`. However, the caller of -- cgit v1.2.3 From fb90f0166728af40142ed9a31039d26ca3f97c73 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 14 Aug 2011 04:58:34 -0400 Subject: - The ``route_url``, ``route_path``, ``resource_url``, ``static_url``, and ``current_route_url`` functions in the ``pyramid.url`` package now delegate to a method on the request they've been passed, instead of the other way around. The pyramid.request.Request object now inherits from a mixin named pyramid.url.URLMethodsMixin to make this possible, and all url/path generation logic is embedded in this mixin. - Narrative and API documentation which used the ``route_url``, ``route_path``, ``resource_url``, ``static_url``, and ``current_route_url`` functions in the ``pyramid.url`` package have now been changed to use eponymous methods of the request instead. --- docs/narr/assets.rst | 60 ++++++++++++++++--------------- docs/narr/commandline.rst | 2 +- docs/narr/hooks.rst | 19 +++++----- docs/narr/resources.rst | 92 +++++++++++++++++++++++------------------------ docs/narr/traversal.rst | 4 +-- docs/narr/urldispatch.rst | 15 ++++---- docs/narr/vhosting.rst | 4 +-- 7 files changed, 97 insertions(+), 99 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index e609a3eab..c8508f1b5 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -165,7 +165,8 @@ Instead of representing a URL prefix, the ``name`` argument of a call to *URL*. Each of examples we've seen so far have shown usage of the ``name`` argument as a URL prefix. However, when ``name`` is a *URL*, static assets can be served from an external webserver. In this mode, the ``name`` is used -as the URL prefix when generating a URL using :func:`pyramid.url.static_url`. +as the URL prefix when generating a URL using +:meth:`pyramid.request.Request.static_url`. For example, :meth:`~pyramid.config.Configurator.add_static_view` may be fed a ``name`` argument which is ``http://example.com/images``: @@ -179,13 +180,13 @@ be fed a ``name`` argument which is ``http://example.com/images``: Because :meth:`~pyramid.config.Configurator.add_static_view` is provided with a ``name`` argument that is the URL ``http://example.com/images``, subsequent -calls to :func:`~pyramid.url.static_url` with paths that start with the -``path`` argument passed to +calls to :meth:`~pyramid.request.Request.static_url` with paths that start +with the ``path`` argument passed to :meth:`~pyramid.config.Configurator.add_static_view` will generate a URL something like ``http://example.com/images/logo.png``. The external webserver listening on ``example.com`` must be itself configured to respond -properly to such a request. The :func:`~pyramid.url.static_url` API is -discussed in more detail later in this chapter. +properly to such a request. The :meth:`~pyramid.request.Request.static_url` +API is discussed in more detail later in this chapter. .. index:: single: generating static asset urls @@ -199,9 +200,9 @@ Generating Static Asset URLs When a :meth:`~pyramid.config.Configurator.add_static_view` method is used to register a static asset directory, a special helper API named -:func:`pyramid.url.static_url` can be used to generate the appropriate URL -for an asset that lives in one of the directories named by the static -registration ``path`` attribute. +:meth:`pyramid.request.Request.static_url` can be used to generate the +appropriate URL for an asset that lives in one of the directories named by +the static registration ``path`` attribute. For example, let's assume you create a set of static declarations like so: @@ -219,18 +220,17 @@ visits a URL which begins with ``/static1``, and the assets in the visits a URL which begins with ``/static2``. You needn't generate the URLs to static assets "by hand" in such a -configuration. Instead, use the :func:`~pyramid.url.static_url` API to -generate them for you. For example: +configuration. Instead, use the :meth:`~pyramid.request.Request.static_url` +API to generate them for you. For example: .. code-block:: python :linenos: - from pyramid.url import static_url from pyramid.chameleon_zpt import render_template_to_response def my_view(request): - css_url = static_url('mypackage:assets/1/foo.css', request) - js_url = static_url('mypackage:assets/2/foo.js', request) + css_url = request.static_url('mypackage:assets/1/foo.css') + js_url = request.static_url('mypackage:assets/2/foo.js') return render_template_to_response('templates/my_template.pt', css_url = css_url, js_url = js_url) @@ -240,17 +240,18 @@ If the request "application URL" of the running system is ``http://example.com/static1/foo.css``. The ``js_url`` generated above would be ``http://example.com/static2/foo.js``. -One benefit of using the :func:`~pyramid.url.static_url` function rather than -constructing static URLs "by hand" is that if you need to change the ``name`` -of a static URL declaration, the generated URLs will continue to resolve -properly after the rename. +One benefit of using the :meth:`~pyramid.request.Request.static_url` function +rather than constructing static URLs "by hand" is that if you need to change +the ``name`` of a static URL declaration, the generated URLs will continue to +resolve properly after the rename. -URLs may also be generated by :func:`~pyramid.url.static_url` to static assets -that live *outside* the :app:`Pyramid` application. This will happen when -the :meth:`~pyramid.config.Configurator.add_static_view` API associated with -the path fed to :func:`~pyramid.url.static_url` is a *URL* instead of a view -name. For example, the ``name`` argument may be ``http://example.com`` while -the the ``path`` given may be ``mypackage:images``: +URLs may also be generated by :meth:`~pyramid.request.Request.static_url` to +static assets that live *outside* the :app:`Pyramid` application. This will +happen when the :meth:`~pyramid.config.Configurator.add_static_view` API +associated with the path fed to :meth:`~pyramid.request.Request.static_url` +is a *URL* instead of a view name. For example, the ``name`` argument may be +``http://example.com`` while the the ``path`` given may be +``mypackage:images``: .. code-block:: python :linenos: @@ -265,14 +266,14 @@ assets which begin with ``mypackage:images`` will be prefixed with .. code-block:: python :linenos: - static_url('mypackage:images/logo.png', request) + request.static_url('mypackage:images/logo.png') # -> http://example.com/images/logo.png -Using :func:`~pyramid.url.static_url` in conjunction with a +Using :meth:`~pyramid.request.Request.static_url` in conjunction with a :meth:`~pyramid.configuration.Configurator.add_static_view` makes it possible to put static media on a separate webserver during production (if the -``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is a -URL), while keeping static media package-internal and served by the +``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is +a URL), while keeping static media package-internal and served by the development webserver during development (if the ``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is a URL prefix). To create such a circumstance, we suggest using the @@ -298,8 +299,9 @@ dispatch`, you may want static assets to only be available as a fallback if no previous route matches. Alternately, you might like to serve a particular static asset manually, because its download requires authentication. -Note that you cannot use the :func:`~pyramid.url.static_url` API to generate -URLs against assets made accessible by registering a custom static view. +Note that you cannot use the :meth:`~pyramid.request.Request.static_url` API +to generate URLs against assets made accessible by registering a custom +static view. Root-Relative Custom Static View (URL Dispatch Only) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 97004d2b8..1c9d0b15c 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -532,7 +532,7 @@ Now you can readily use Pyramid's APIs for generating URLs: .. code-block:: python - route_url('verify', env['request'], code='1337') + env['request'].route_url('verify', code='1337') # will return 'https://example.com/prefix/verify/1337' Cleanup diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 50758f327..df5339c8a 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -468,17 +468,18 @@ when the application :term:`root factory` returned an instance of the .. _changing_resource_url: -Changing How :mod:`pyramid.url.resource_url` Generates a URL ------------------------------------------------------------- +Changing How :meth:`pyramid.request.Request.resource_url` Generates a URL +------------------------------------------------------------------------- When you add a traverser as described in :ref:`changing_the_traverser`, it's -often convenient to continue to use the :func:`pyramid.url.resource_url` API. -However, since the way traversal is done will have been modified, the URLs it -generates by default may be incorrect. +often convenient to continue to use the +:meth:`pyramid.request.Request.resource_url` API. However, since the way +traversal is done will have been modified, the URLs it generates by default +may be incorrect. If you've added a traverser, you can change how -:func:`~pyramid.url.resource_url` generates a URL for a specific type of -resource by adding a registerAdapter call for +:meth:`~pyramid.request.Request.resource_url` generates a URL for a specific +type of resource by adding a registerAdapter call for :class:`pyramid.interfaces.IContextURL` to your application: .. code-block:: python @@ -493,8 +494,8 @@ resource by adding a registerAdapter call for IContextURL) In the above example, the ``myapp.traversal.URLGenerator`` class will be used -to provide services to :func:`~pyramid.url.resource_url` any time the -:term:`context` passed to ``resource_url`` is of class +to provide services to :meth:`~pyramid.request.Request.resource_url` any time +the :term:`context` passed to ``resource_url`` is of class ``myapp.resources.MyRoot``. The second argument in the ``(MyRoot, Interface)`` tuple represents the type of interface that must be possessed by the :term:`request` (in this case, any interface, represented by diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 0e0d00020..9335906a0 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -45,8 +45,8 @@ Also: - A resource is exposed to :term:`view` code as the :term:`context` of a view. -- Various helpful :app:`Pyramid` API methods expect a resource as an - argument (e.g. :func:`~pyramid.url.resource_url` and others). +- Various helpful :app:`Pyramid` API methods expect a resource as an argument + (e.g. :meth:`~pyramid.request.Request.resource_url` and others). .. index:: single: resource tree @@ -160,14 +160,14 @@ resource in the resource tree, you will eventually come to the root resource, just like if you keep executing the ``cd ..`` filesystem command, eventually you will reach the filesystem root directory. -.. warning:: If your root resource has a ``__name__`` argument - that is not ``None`` or the empty string, URLs returned by the - :func:`~pyramid.url.resource_url` function and paths generated by - the :func:`~pyramid.traversal.resource_path` and - :func:`~pyramid.traversal.resource_path_tuple` APIs will be - generated improperly. The value of ``__name__`` will be prepended - to every path and URL generated (as opposed to a single leading - slash or empty tuple element). +.. warning:: If your root resource has a ``__name__`` argument that is not + ``None`` or the empty string, URLs returned by the + :func:`~pyramid.request.Request.resource_url` function and paths generated + by the :func:`~pyramid.traversal.resource_path` and + :func:`~pyramid.traversal.resource_path_tuple` APIs will be generated + improperly. The value of ``__name__`` will be prepended to every path and + URL generated (as opposed to a single leading slash or empty tuple + element). .. sidebar:: Using :mod:`pyramid_traversalwrapper` @@ -192,7 +192,8 @@ you will reach the filesystem root directory. Applications which use tree-walking :app:`Pyramid` APIs require location-aware resources. These APIs include (but are not limited to) -:func:`~pyramid.url.resource_url`, :func:`~pyramid.traversal.find_resource`, +:meth:`~pyramid.request.Request.resource_url`, +:func:`~pyramid.traversal.find_resource`, :func:`~pyramid.traversal.find_root`, :func:`~pyramid.traversal.find_interface`, :func:`~pyramid.traversal.resource_path`, @@ -215,23 +216,23 @@ Generating The URL Of A Resource -------------------------------- If your resources are :term:`location` aware, you can use the -:func:`pyramid.url.resource_url` API to generate a URL for the resource. -This URL will use the resource's position in the parent tree to create a -resource path, and it will prefix the path with the current application URL -to form a fully-qualified URL with the scheme, host, port, and path. You can -also pass extra arguments to :func:`~pyramid.url.resource_url` to influence -the generated URL. +:meth:`pyramid.request.Request.resource_url` API to generate a URL for the +resource. This URL will use the resource's position in the parent tree to +create a resource path, and it will prefix the path with the current +application URL to form a fully-qualified URL with the scheme, host, port, +and path. You can also pass extra arguments to +:meth:`~pyramid.request.Request.resource_url` to influence the generated URL. -The simplest call to :func:`~pyramid.url.resource_url` looks like this: +The simplest call to :meth:`~pyramid.request.Request.resource_url` looks like +this: .. code-block:: python :linenos: - from pyramid.url import resource_url - url = resource_url(resource, request) + url = request.resource_url(resource, request) -The ``request`` passed to ``resource_url`` in the above example is an -instance of a :app:`Pyramid` :term:`request` object. +The ``request`` in the above example is an instance of a :app:`Pyramid` +:term:`request` object. If the resource referred to as ``resource`` in the above example was the root resource, and the host that was used to contact the server was @@ -240,51 +241,46 @@ However, if the resource was a child of the root resource named ``a``, the generated URL would be ``http://example.com/a/``. A slash is appended to all resource URLs when -:func:`~pyramid.url.resource_url` is used to generate them in this simple -manner, because resources are "places" in the hierarchy, and URLs are meant -to be clicked on to be visited. Relative URLs that you include on HTML pages -rendered as the result of the default view of a resource are more +:meth:`~pyramid.request.Request.resource_url` is used to generate them in +this simple manner, because resources are "places" in the hierarchy, and URLs +are meant to be clicked on to be visited. Relative URLs that you include on +HTML pages rendered as the result of the default view of a resource are more apt to be relative to these resources than relative to their parent. -You can also pass extra elements to :func:`~pyramid.url.resource_url`: +You can also pass extra elements to +:meth:`~pyramid.request.Request.resource_url`: .. code-block:: python :linenos: - from pyramid.url import resource_url - url = resource_url(resource, request, 'foo', 'bar') + url = request.resource_url(resource, 'foo', 'bar') If the resource referred to as ``resource`` in the above example was the root resource, and the host that was used to contact the server was ``example.com``, the URL generated would be ``http://example.com/foo/bar``. Any number of extra elements can be passed to -:func:`~pyramid.url.resource_url` as extra positional arguments. When extra -elements are passed, they are appended to the resource's URL. A slash is not -appended to the final segment when elements are passed. +:meth:`~pyramid.request.Request.resource_url` as extra positional arguments. +When extra elements are passed, they are appended to the resource's URL. A +slash is not appended to the final segment when elements are passed. You can also pass a query string: .. code-block:: python :linenos: - from pyramid.url import resource_url - url = resource_url(resource, request, query={'a':'1'}) + url = request.resource_url(resource, query={'a':'1'}) If the resource referred to as ``resource`` in the above example was the root resource, and the host that was used to contact the server was ``example.com``, the URL generated would be ``http://example.com/?a=1``. When a :term:`virtual root` is active, the URL generated by -:func:`~pyramid.url.resource_url` for a resource may be "shorter" than its -physical tree path. See :ref:`virtual_root_support` for more information -about virtually rooting a resource. - -The shortcut method of the :term:`request` named -:meth:`pyramid.request.Request.resource_url` can be used instead of -:func:`~pyramid.url.resource_url` to generate a resource URL. +:meth:`~pyramid.request.Request.resource_url` for a resource may be "shorter" +than its physical tree path. See :ref:`virtual_root_support` for more +information about virtually rooting a resource. For more information about generating resource URLs, see the documentation -for :func:`pyramid.url.resource_url`. +for :meth:`pyramid.request.Request.resource_url`. .. index:: pair: resource URL generation; overriding @@ -295,14 +291,14 @@ Overriding Resource URL Generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a resource object implements a ``__resource_url__`` method, this method -will be called when :func:`~pyramid.url.resource_url` is called to generate a -URL for the resource, overriding the default URL returned for the resource by -:func:`~pyramid.url.resource_url`. +will be called when :meth:`~pyramid.request.Request.resource_url` is called +to generate a URL for the resource, overriding the default URL returned for +the resource by :meth:`~pyramid.request.Request.resource_url`. The ``__resource_url__`` hook is passed two arguments: ``request`` and ``info``. ``request`` is the :term:`request` object passed to -:func:`~pyramid.url.resource_url`. ``info`` is a dictionary with two -keys: +:meth:`~pyramid.request.Request.resource_url`. ``info`` is a dictionary with +two keys: ``physical_path`` The "physical path" computed for the resource, as defined by @@ -334,7 +330,7 @@ or port number of the generated URL. Note that the URL generated by ``__resource_url__`` should be fully qualified, should end in a slash, and should not contain any query string or anchor elements (only path elements) to work best with -:func:`~pyramid.url.resource_url`. +:meth:`~pyramid.request.Request.resource_url`. .. index:: single: resource path generation diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index aa36b4455..ef875c8f0 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -565,6 +565,6 @@ See the :ref:`view_config_chapter` chapter for detailed information about The :mod:`pyramid.traversal` module contains API functions that deal with traversal, such as traversal invocation from within application code. -The :func:`pyramid.url.resource_url` function generates a URL when given a -resource retrieved from a resource tree. +The :meth:`pyramid.request.Request.resource_url` method generates a URL when +given a resource retrieved from a resource tree. diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c0197743b..00d36cc76 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -765,20 +765,19 @@ Or provide the literal string ``/`` as the pattern: Generating Route URLs --------------------- -Use the :func:`pyramid.url.route_url` function to generate URLs based on -route patterns. For example, if you've configured a route with the ``name`` -"foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. +Use the :meth:`pyramid.request.Request.route_url` method to generate URLs +based on route patterns. For example, if you've configured a route with the +``name`` "foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. .. ignore-next-block .. code-block:: python :linenos: - from pyramid.url import route_url - url = route_url('foo', request, a='1', b='2', c='3') + url = request.route_url('foo', a='1', b='2', c='3') This would return something like the string ``http://example.com/1/2/3`` (at least if the current protocol and hostname implied ``http://example.com``). -See the :func:`~pyramid.url.route_url` API documentation for more +See the :meth:`~pyramid.request.Request.route_url` API documentation for more information. .. index:: @@ -1122,8 +1121,8 @@ In the above configuration, the ``show_users`` route will have an effective route pattern of ``/users/show``, instead of ``/show`` because the ``route_prefix`` argument will be prepended to the pattern. The route will then only match if the URL path is ``/users/show``, and when the -:func:`pyramid.url.route_url` function is called with the route name -``show_users``, it will generate a URL with that same path. +:meth:`pyramid.request.Request.route_url` function is called with the route +name ``show_users``, it will generate a URL with that same path. Route prefixes are recursive, so if a callable executed via an include itself turns around and includes another callable, the second-level route prefix diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index 5679cc2e2..ddbf1fb4d 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -101,8 +101,8 @@ the WSGI environ named ``HTTP_X_VHM_ROOT`` with a value that is the absolute pathname to the resource object in the resource tree that should behave as the "root" resource. As a result, the traversal machinery will respect this value during traversal (prepending it to the PATH_INFO before traversal -starts), and the :func:`pyramid.url.resource_url` API will generate the -"correct" virtually-rooted URLs. +starts), and the :meth:`pyramid.request.Request.resource_url` API will +generate the "correct" virtually-rooted URLs. An example of an Apache ``mod_proxy`` configuration that will host the ``/cms`` subobject as ``http://www.example.com/`` using this facility -- cgit v1.2.3 From 33a3ead51c9ef4dcc4c4c839aae8616dcab2d3ce Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 16 Aug 2011 04:28:52 -0500 Subject: Added some docs for the new 'setup' option key in [pshell]. --- docs/narr/commandline.rst | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 1c9d0b15c..bb004c446 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -156,6 +156,7 @@ name ``MyProject`` as a section name: request Active request object. root Root of the default resource tree. root_factory Default root factory used to create `root`. + >>> root >>> registry @@ -191,12 +192,18 @@ Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). Extending the Shell ~~~~~~~~~~~~~~~~~~~ -It is sometimes convenient when using the interactive shell often to have -some variables significant to your application already loaded as globals when +It is convenient when using the interactive shell often to have some +variables significant to your application already loaded as globals when you start the ``pshell``. To facilitate this, ``pshell`` will look for a special ``[pshell]`` section in your INI file and expose the subsequent key/value pairs to the shell. Each key is a variable name that will be global within the pshell session; each value is a :term:`dotted Python name`. +If specified, the special key ``setup`` should be a :term:`dotted Python name` +pointing to a callable that accepts the dictionary of globals that will +be loaded into the shell. This allows for some custom initializing code +to be executed each time the ``pshell`` is run. The ``setup`` callable +can also be specified from the commandline using the ``--setup`` option +which will override the key in the INI file. For example, you want to expose your model to the shell, along with the database session so that you can mutate the model on an actual database. @@ -206,12 +213,33 @@ Here, we'll assume your model is stored in the ``myapp.models`` package. :linenos: [pshell] + setup = myapp.lib.pshell.setup m = myapp.models session = myapp.models.DBSession t = transaction +By defining the ``setup`` callable, we will create the module +``myapp.lib.pshell`` containing a callable named ``setup`` that will receive +the global environment before it is exposed to the shell. Here we mutate the +environment's request as well as add a new value containing a WebTest version +of the application to which we can easily submit requests. + +.. code-block:: python + :linenos: + + # myapp/lib/pshell.py + from webtest import TestApp + + def setup(env): + env['request'].host = 'www.example.com' + env['request'].scheme = 'https' + env['testapp'] = TestApp(env['app']) + When this INI file is loaded, the extra variables ``m``, ``session`` and -``t`` will be available for use immediately. For example: +``t`` will be available for use immediately. Since a ``setup`` callable +was also specified, it is executed and a new variable ``testapp`` is +exposed, and the request is configured to generate urls from the host +``http://www.example.com``. For example: .. code-block:: text @@ -226,12 +254,17 @@ When this INI file is loaded, the extra variables ``m``, ``session`` and request Active request object. root Root of the default resource tree. root_factory Default root factory used to create `root`. + testapp Custom Variables: m myapp.models session myapp.models.DBSession t transaction - >>> + + >>> testapp.get('/') + <200 OK text/html body='\n'/3337> + >>> request.route_url('home') + 'https://www.example.com/' .. index:: single: IPython -- cgit v1.2.3 From 4f070b0887e43c6582a06e0e2c318a5c09962340 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 20 Aug 2011 22:10:23 -0400 Subject: remove tween aliases as a concept --- docs/narr/hooks.rst | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index df5339c8a..4afc0506b 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -930,10 +930,10 @@ tween in a Pyramid application: Note that you must use a :term:`dotted Python name` as the first argument to :meth:`pyramid.config.Configurator.add_tween`; this must point at a tween factory. You cannot pass the tween factory object itself to the method: it -must be a globally importable object. In the above example, we assume that a -``timing_tween_factory`` tween factory was defined in a module named -``myapp.tweens``, so the tween factory is importable as -``myapp.tweens.timing_tween_factory``. +must be :term:`dotted Python name` that points to a globally importable +object. In the above example, we assume that a ``timing_tween_factory`` +tween factory was defined in a module named ``myapp.tweens``, so the tween +factory is importable as ``myapp.tweens.timing_tween_factory``. When you use :meth:`pyramid.config.Configurator.add_tween`, you're instructing the system to use your tween factory at startup time unless the @@ -993,9 +993,6 @@ Allowable values for ``under`` or ``over`` (or both) are: predicted dotted name of a tween factory added in a call to ``add_tween`` in the same configuration session. -- A "tween alias": a string representing the predicted value of ``alias`` in - a separate call to ``add_tween`` in the same configuration session - - One of the constants :attr:`pyramid.tweens.MAIN`, :attr:`pyramid.tweens.INGRESS`, or :attr:`pyramid.tweens.EXCVIEW`. @@ -1063,28 +1060,6 @@ This constraint will require the tween to be located under both the these is not in the current configuration, this constraint will only organize itself based on the tweens that are present. -:meth:`~pyramid.config.Configurator.add_tween` also accepts an ``alias`` -argument. If ``alias`` is not ``None``, should be a string. The string will -represent a value that other callers of ``add_tween`` may pass as an -``under`` and ``over`` argument instead of a dotted name to a tween factory. -For example: - -.. code-block:: python - :linenos: - - import pyramid.tweens - - config.add_tween('myapp.tween_factory1', - alias='one' - over=pyramid.tweens.MAIN) - config.add_tween('myapp.tween_factory2', - alias='two' - over=pyramid.tweens.MAIN, - under='one') - -Alias names are only useful in relation to ``under`` and ``over`` values. -They cannot be used in explicit tween chain configuration, or anywhere else. - .. _explicit_tween_ordering: Explicit Tween Ordering -- cgit v1.2.3 From 2c9f3c76403b9a70bf0578f44deab11208b5a542 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 20 Aug 2011 23:25:52 -0400 Subject: - Mention debug toolbar in tutorials. --- docs/narr/project.rst | 64 ++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 29 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index aed93f9c5..d259a9c79 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -309,6 +309,14 @@ browser like what is displayed in the following image: This is the page shown by default when you visit an unmodified ``paster create`` -generated ``pyramid_starter`` application in a browser. +.. index:: + single: debug toolbar + +.. _debug_toolbar: + +The Debug Toolbar +~~~~~~~~~~~~~~~~~ + If you click on the image shown at the right hand top of the page ("^DT"), you'll be presented with a debug toolbar that provides various niceties while you're developing. This image will float above every HTML page served by @@ -348,33 +356,6 @@ Put a hash mark in front of the ``pyramid.includes`` line: Then restart the application to see that the toolbar has been turned off. -.. sidebar:: Using an Alternate WSGI Server - - The code generated by a :app:`Pyramid` scaffold assumes that you - will be using the ``paster serve`` command to start your application while - you do development. However, ``paster serve`` is by no means the only way - to start up and serve a :app:`Pyramid` application. As we saw in - :ref:`firstapp_chapter`, ``paster serve`` needn't be invoked at all to run - a :app:`Pyramid` application. The use of ``paster serve`` to run a - :app:`Pyramid` application is purely conventional based on the output of - its scaffold. - - Any :term:`WSGI` server is capable of running a :app:`Pyramid` - application. Some WSGI servers don't require the :term:`PasteDeploy` - framework's ``paster serve`` command to do server process management at - all. Each :term:`WSGI` server has its own documentation about how it - creates a process to run an application, and there are many of them, so we - cannot provide the details for each here. But the concepts are largely - the same, whatever server you happen to use. - - One popular production alternative to a ``paster``-invoked server is - :term:`mod_wsgi`. You can also use :term:`mod_wsgi` to serve your - :app:`Pyramid` application using the Apache web server rather than any - "pure-Python" server that is started as a result of ``paster serve``. See - :ref:`modwsgi_tutorial` for details. However, it is usually easier to - *develop* an application using a ``paster serve`` -invoked webserver, as - exception and debugging output will be sent to the console. - .. index:: single: project structure @@ -1002,5 +983,30 @@ configuration as would be loaded if you were running your Pyramid application via ``paster serve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. - - +Using an Alternate WSGI Server +------------------------------ + +The code generated by a :app:`Pyramid` scaffold assumes that you will be +using the ``paster serve`` command to start your application while you do +development. However, ``paster serve`` is by no means the only way to start +up and serve a :app:`Pyramid` application. As we saw in +:ref:`firstapp_chapter`, ``paster serve`` needn't be invoked at all to run a +:app:`Pyramid` application. The use of ``paster serve`` to run a +:app:`Pyramid` application is purely conventional based on the output of its +scaffold. + +Any :term:`WSGI` server is capable of running a :app:`Pyramid` application. +Some WSGI servers don't require the :term:`PasteDeploy` framework's ``paster +serve`` command to do server process management at all. Each :term:`WSGI` +server has its own documentation about how it creates a process to run an +application, and there are many of them, so we cannot provide the details for +each here. But the concepts are largely the same, whatever server you happen +to use. + +One popular production alternative to a ``paster``-invoked server is +:term:`mod_wsgi`. You can also use :term:`mod_wsgi` to serve your +:app:`Pyramid` application using the Apache web server rather than any +"pure-Python" server that is started as a result of ``paster serve``. See +:ref:`modwsgi_tutorial` for details. However, it is usually easier to +*develop* an application using a ``paster serve`` -invoked webserver, as +exception and debugging output will be sent to the console. -- cgit v1.2.3 From a8c81dbd55b1e06dd2da1b598670dc27a73ce8b1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 21 Aug 2011 00:23:00 -0400 Subject: add a whatsnew-1.2 doc --- docs/narr/environment.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 2f5555840..352912a81 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -185,6 +185,8 @@ The value supplied here is used as the default locale name when a | | | +---------------------------------+-----------------------------------+ +.. _including_packages: + Including Packages ------------------ @@ -287,6 +289,8 @@ Is equivalent to using the following statements in your configuration code: It is fine to use both or either form. +.. _explicit_tween_config: + Explicit Tween Configuration ---------------------------- -- cgit v1.2.3 From 3d338ea5737b7c113b17120b40684e2694cf3fa9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Aug 2011 02:16:55 -0400 Subject: - Use [app:main] instead of a pipeline in all scaffolds and tutorials and narrative docs. - Break out awkward description of PasteDeploy entry points from project chapter into its own Paste chapter. --- docs/narr/MyProject/development.ini | 6 +- docs/narr/MyProject/production.ini | 6 +- docs/narr/commandline.rst | 6 +- docs/narr/environment.rst | 8 +-- docs/narr/i18n.rst | 4 +- docs/narr/logging.rst | 26 ++++++-- docs/narr/paste.rst | 99 +++++++++++++++++++++++++++++ docs/narr/project.rst | 121 +++++++++++------------------------- docs/narr/security.rst | 2 +- docs/narr/startup.rst | 23 +++---- docs/narr/templates.rst | 6 +- docs/narr/vhosting.rst | 2 +- 12 files changed, 184 insertions(+), 125 deletions(-) create mode 100644 docs/narr/paste.rst (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index e134e9f06..e93266bab 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -1,4 +1,4 @@ -[app:MyProject] +[app:main] use = egg:MyProject pyramid.reload_templates = true @@ -9,10 +9,6 @@ pyramid.debug_templates = true pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar -[pipeline:main] -pipeline = - MyProject - [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 0a2154b15..83bce1ef2 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -1,4 +1,4 @@ -[app:MyProject] +[app:main] use = egg:MyProject pyramid.reload_templates = false @@ -8,10 +8,6 @@ pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -[pipeline:main] -pipeline = - MyProject - [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index bb004c446..cef331e2d 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -127,12 +127,12 @@ The argument to ``pshell`` follows the format ``config_file#section_name`` where ``config_file`` is the path to your application's ``.ini`` file and ``section_name`` is the ``app`` section name inside the ``.ini`` file which points to your application. For example, if your application ``.ini`` file -might have a ``[app:MyProject]`` section that looks like so: +might have a ``[app:main]`` section that looks like so: .. code-block:: ini :linenos: - [app:MyProject] + [app:main] use = egg:MyProject pyramid.reload_templates = true pyramid.debug_authorization = false @@ -401,7 +401,7 @@ tween chain is used: .. code-block:: text :linenos: - [app:starter] + [app:main] use = egg:starter reload_templates = true debug_authorization = false diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 352912a81..a5909e541 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -239,7 +239,7 @@ file in your application: .. code-block:: ini - [app:myapp] + [app:main] pyramid.includes = pyramid_debugtoolbar pyramid_tm @@ -352,7 +352,7 @@ file in your application: .. code-block:: ini - [app:myapp] + [app:main] pyramid.tweens = pyramid_debugtoolbar.toolbar.tween_factory pyramid.tweens.excview_tween_factory pyramid_tm.tm_tween_factory @@ -534,7 +534,7 @@ an example of such a section: :linenos: [app:main] - use = egg:MyProject#app + use = egg:MyProject pyramid.reload_templates = true pyramid.debug_authorization = true @@ -628,7 +628,7 @@ Here's how: .. code-block:: ini - [app:myapp] + [app:main] # .. other settings debug_frobnosticator = True diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index ba5490b31..aef9b59ab 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -787,7 +787,7 @@ application's Paster ``.ini`` file: :linenos: [app:main] - use = egg:MyProject#app + use = egg:MyProject pyramid.reload_templates = true pyramid.debug_authorization = false pyramid.debug_notfound = false @@ -847,7 +847,7 @@ Allow a deployer to modify your application's PasteDeploy .ini file: :linenos: [app:main] - use = egg:MyProject#app + use = egg:MyProject # ... available_languages = fr de en ru diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 375ab820c..8abcba3c7 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -301,22 +301,36 @@ requests using the `Apache Combined Log Format with a FileHandler can be used to create an ``access.log`` file similar to Apache's. -Like any standard middleware with a Paste entry point, TransLogger can be -configured to wrap your application in the ``[app:main]`` section of the ini -file: +Like any standard middleware with a Paste entry point, TransLogger can be +configured to wrap your application using ``.ini`` file syntax. First, +rename your Pyramid ``.ini`` file's ``[app:main]`` section to +``[app:mypyramidapp]``, then add a ``[filter:translogger]`` section, then use +a ``[pipeline:main]`` section file to form a WSGI pipeline with both the +translogger and your application in it. For instance, change from this: .. code-block:: ini + [app:main] + use = egg:MyProject + +To this: + +.. code-block:: ini + + [app:mypyramidapp] + use = egg:MyProject + [filter:translogger] paste.filter_app_factory = egg:Paste#translogger setup_console_handler = False [pipeline:main] pipeline = translogger - myapp + mypyramidapp -This is equivalent to wrapping your app in a TransLogger instance via the -bottom the ``main`` function of your project's ``__init__`` file: +Using PasteDeploy this way to form and serve a pipeline is equivalent to +wrapping your app in a TransLogger instance via the bottom the ``main`` +function of your project's ``__init__`` file: .. code-block:: python diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst new file mode 100644 index 000000000..39ae4f373 --- /dev/null +++ b/docs/narr/paste.rst @@ -0,0 +1,99 @@ +.. _paste_chapter: + +Paste +===== + +Packages generated via a :term:`scaffold` make use of a system created by Ian +Bicking named :term:`Paste`. Paste provides the following features: + +- A way to declare :term:`WSGI` application configuration in an ``.ini`` file + (PasteDeploy). + +- A :term:`WSGI` server runner (``paster serve``) which can accept + PasteDeploy ``.ini`` file values as input. + +- A mechanism for rendering scaffolds into projects (``paster create``). + +Paste is not a particularly integral part of Pyramid. It's more or less used +directly only in projects created from scaffolds. It's possible to create a +Pyramid application which does not use Paste at all. We show a Pyramid +application that doesn't use Paste in :ref:`firstapp_chapter`. However, all +Pyramid scaffolds use the system, to provide new developers with a +standardized way of starting, stopping, and setting deployment values. This +chapter is not a replacement for documentation about Paste or PasteDeploy; it +only contextualizes the use of Paste within Pyramid. For detailed +documentation, see http://pythonpaste.org. + +PasteDeploy +----------- + +:term:`PasteDeploy` is the system that Pyramid uses to allow +:term:`deployment settings` to be spelled using an ``.ini`` configuration +file format. It also allows the ``paster serve`` command to work. Its +configuration format provides a convenient place to define application +:term:`deployment settings` and WSGI server settings, and its server runner +allows you to stop and start a Pyramid application easily. + +.. _pastedeploy_entry_points: + +Entry Points and PasteDeploy ``.ini`` Files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In the :ref:`project_narr` chapter, we breezed over the meaning of a +configuration line in the ``deployment.ini`` file. This was the ``use = +egg:MyProject`` line in the ``[app:main]`` section. We breezed over it +because it's pretty confusing and "too much information" for an introduction +to the system. We'll try to give it a bit of attention here. Let's see the +config file again: + +.. literalinclude:: MyProject/development.ini + :language: ini + :linenos: + +The line in ``[app:main]`` above that says ``use = egg:MyProject`` is +actually shorthand for a longer spelling: ``use = egg:MyProject#main``. The +``#main`` part is omitted for brevity, as ``#main`` is a default defined by +PasteDeploy. ``egg:MyProject#main`` is a string which has meaning to +PasteDeploy. It points at a :term:`setuptools` :term:`entry point` named +``main`` defined in the ``MyProject`` project. + +Take a look at the generated ``setup.py`` file for this project. + +.. literalinclude:: MyProject/setup.py + :language: python + :linenos: + +Note that the ``entry_point`` line in ``setup.py`` points at a string which +looks a lot like an ``.ini`` file. This string representation of an ``.ini`` +file has a section named ``[paste.app_factory]``. Within this section, there +is a key named ``main`` (the entry point name) which has a value +``myproject:main``. The *key* ``main`` is what our ``egg:MyProject#main`` +value of the ``use`` section in our config file is pointing at, although it +is actually shortened to ``egg:MyProject`` there. The value represents a +:term:`dotted Python name` path, which refers to a callable in our +``myproject`` package's ``__init__.py`` module. + +The ``egg:`` prefix in ``egg:MyProject`` indicates that this is an entry +point *URI* specifier, where the "scheme" is "egg". An "egg" is created when +you run ``setup.py install`` or ``setup.py develop`` within your project. + +In English, this entry point can thus be referred to as a "Paste application +factory in the ``MyProject`` project which has the entry point named ``main`` +where the entry point refers to a ``main`` function in the ``mypackage`` +module". Indeed, if you open up the ``__init__.py`` module generated within +any scaffold-generated package, you'll see a ``main`` function. This is the +function called by :term:`PasteDeploy` when the ``paster serve`` command is +invoked against our application. It accepts a global configuration object +and *returns* an instance of our application. + +``[DEFAULTS]`` Section of a PasteDeploy ``.ini`` File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can add a ``[DEFAULT]`` section to your PasteDeploy ``.ini`` file. Such +a section should consists of global parameters that are shared by all the +applications, servers and :term:`middleware` defined within the configuration +file. The values in a ``[DEFAULT]`` section will be passed to your +application's ``main`` function as ``global_config`` (see the reference to +the ``main`` function in :ref:`init_py`). + + diff --git a/docs/narr/project.rst b/docs/narr/project.rst index d259a9c79..9ea5f20dd 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -153,8 +153,7 @@ Another :term:`PasteDeploy` ``.ini`` file named ``production.ini`` will also be created in the project directory. It sports configuration that disables any interactive debugger (to prevent inappropriate access and disclosure), and turns off a number of debugging settings. You can use this file to put -your application into production, and you can modify it to do things like -send email when an exception occurs. +your application into production. The ``MyProject`` project directory contains an additional subdirectory named ``myproject`` (note the case difference) representing a Python @@ -294,7 +293,6 @@ configuration file settings that influence startup and runtime behavior, see :ref:`environment_chapter`. .. index:: - single: mod_wsgi single: WSGI Viewing the Application @@ -341,7 +339,7 @@ example, instead of: .. code-block:: ini :linenos: - [app:MyApp] + [app:main] ... pyramid.includes = pyramid_debugtoolbar @@ -350,7 +348,7 @@ Put a hash mark in front of the ``pyramid.includes`` line: .. code-block:: ini :linenos: - [app:MyApp] + [app:main] ... #pyramid.includes = pyramid_debugtoolbar @@ -443,73 +441,41 @@ The generated ``development.ini`` file looks like so: :language: ini :linenos: -This file contains several "sections" including ``[app:MyProject]``, -``[pipeline:main]``, ``[server:main]`` and several other sections related to -logging configuration. - -The ``[app:MyProject]`` section represents configuration for your -application. This section name represents the ``MyProject`` application (and -it's an ``app`` -lication, thus ``app:MyProject``) - -The ``use`` setting is required in the ``[app:MyProject]`` section. The -``use`` setting points at a :term:`setuptools` :term:`entry point` named -``MyProject`` (the ``egg:`` prefix in ``egg:MyProject`` indicates that this -is an entry point *URI* specifier, where the "scheme" is "egg"). -``egg:MyProject`` is actually shorthand for a longer spelling: -``egg:MyProject#main``. The ``#main`` part is omitted for brevity, as it is -the default. - -.. sidebar:: ``setuptools`` Entry Points and PasteDeploy ``.ini`` Files - - This part of configuration can be confusing so let's try to clear things - up a bit. Take a look at the generated ``setup.py`` file for this - project. Note that the ``entry_point`` line in ``setup.py`` points at a - string which looks a lot like an ``.ini`` file. This string - representation of an ``.ini`` file has a section named - ``[paste.app_factory]``. Within this section, there is a key named - ``main`` (the entry point name) which has a value ``myproject:main``. The - *key* ``main`` is what our ``egg:MyProject#main`` value of the ``use`` - section in our config file is pointing at (although it is actually - shortened to ``egg:MyProject`` there). The value represents a - :term:`dotted Python name` path, which refers to a callable in our - ``myproject`` package's ``__init__.py`` module. In English, this entry - point can thus be referred to as a "Paste application factory in the - ``MyProject`` project which has the entry point named ``main`` where the - entry point refers to a ``main`` function in the ``mypackage`` module". - Indeed, if you open up the ``__init__.py`` module generated within the - ``myproject`` package, you'll see a ``main`` function. This is the - function called by :term:`PasteDeploy` when the ``paster serve`` command - is invoked against our application. It accepts a global configuration - object and *returns* an instance of our application. - -The ``use`` setting is the only setting *required* in the ``[app:MyProject]`` -section unless you've changed the callable referred to by the -``egg:MyProject`` entry point to accept more arguments: other settings you -add to this section are passed as keyword arguments to the callable -represented by this entry point (``main`` in our ``__init__.py`` module). -You can provide startup-time configuration parameters to your application by +This file contains several "sections" including ``[app:main]``, +``[server:main]`` and several other sections related to logging +configuration. + +The ``[app:main]`` section represents configuration for your :app:`Pyramid` +application. The ``use`` setting is the only setting required to be present +in the ``[app:main]`` section. Its default value, ``egg:MyProject``, +indicates that our MyProject project contains the application that should be +served. Other settings added to this section are passed as keyword arguments +to the function named ``main`` in our package's ``__init__.py`` module. You +can provide startup-time configuration parameters to your application by adding more settings to this section. -The ``pyramid.reload_templates`` setting in the ``[app:MyProject]`` section is -a :app:`Pyramid` -specific setting which is passed into the framework. If it +.. note:: See :ref:`pastedeploy_entry_points` for more information about the + meaning of the ``use = egg:MyProject`` value in this section. + +The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a +:app:`Pyramid` -specific setting which is passed into the framework. If it exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako` template changes will not require an application restart to be detected. See :ref:`reload_templates_section` for more information. -The ``pyramid.debug_templates`` setting in the ``[app:MyProject]`` section is a +The ``pyramid.debug_templates`` setting in the ``[app:main]`` section is a :app:`Pyramid` -specific setting which is passed into the framework. If it exists, and its value is ``true``, :term:`Chameleon` template exceptions will -contain more detailed and helpful information about the error than when -this value is ``false``. See :ref:`debug_templates_section` for more -information. +contain more detailed and helpful information about the error than when this +value is ``false``. See :ref:`debug_templates_section` for more information. .. warning:: The ``pyramid.reload_templates`` and ``pyramid.debug_templates`` options should be turned off for production applications, as template rendering is slowed when either is turned on. -The ``pyramid.includes`` setting in the ``[app:MyProject]`` section tells -Pyramid to "include" configuration from another package. In this case, the -line ``pyramid.includes = pyramid_debugtoolbar`` tells Pyramid to include +The ``pyramid.includes`` setting in the ``[app:main]`` section tells Pyramid +to "include" configuration from another package. In this case, the line +``pyramid.includes = pyramid_debugtoolbar`` tells Pyramid to include configuration from the ``pyramid_debugtoolbar`` package. This turns on a debugging panel in development mode which will be shown on the right hand side of the screen. Including the debug toolbar will also make it possible @@ -519,23 +485,15 @@ Various other settings may exist in this section having to do with debugging or influencing runtime behavior of a :app:`Pyramid` application. See :ref:`environment_chapter` for more information about these settings. -``[pipeline:main]``, has the name ``main`` signifying that this is the -default 'application' (although it's actually a pipeline of middleware and an -application) run by ``paster serve`` when it is invoked against this +The name ``main`` in ``[app:main]`` signifies that this is the default +application run by ``paster serve`` when it is invoked against this configuration 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``). The ``Paste#http`` server will create a new thread -for each request. - -.. note:: - - In general, :app:`Pyramid` applications generated from scaffolds - should be threading-aware. It is not required that a :app:`Pyramid` - application be nonblocking as all application code will run in its own - thread, provided by the server you're using. +interfaces (``0.0.0.0``). This means that any remote system which has TCP +access to your system can see your Pyramid application. The sections that live between the markers ``# Begin logging configuration`` and ``# End logging configuration`` represent Python's standard library @@ -545,22 +503,14 @@ configuration engine `_ when the ``paster serve`` or ``paster pshell`` commands are executed. The default configuration sends application logging output to the standard error output -of your terminal. +of your terminal. For more information about logging configuration, see +:ref:`logging_chapter`. See the :term:`PasteDeploy` documentation for more information about other types of things you can put into this ``.ini`` file, such as other applications, :term:`middleware` and alternate :term:`WSGI` server implementations. -.. note:: - - You can add a ``[DEFAULT]`` section to your ``development.ini`` file. - Such a section should consists of global parameters that are shared by all - the applications, servers and :term:`middleware` defined within the - configuration file. The values in a ``[DEFAULT]`` section will be passed - to your application's ``main`` function as ``global_config`` (see - the reference to the ``main`` function in :ref:`init_py`). - .. index:: single: production.ini @@ -644,9 +594,12 @@ will be run when ``setup.py test`` is invoked. We examined ``entry_points`` in our discussion of the ``development.ini`` file; this file defines the ``main`` entry point that represents our project's application. -Usually you only need to think about the contents of the ``setup.py`` file -when distributing your application to other people, or when versioning your -application for your own use. For fun, you can try this command now: +A more exhaustive explanation of the purpose and composition of ``setup.py`` +is available at `The Hitchhiker's Guide to Packaging +`_. Usually you only need to think +about the contents of the ``setup.py`` file when distributing your +application to other people, or when versioning your application for your own +use. For fun, you can try this command now: .. code-block:: text diff --git a/docs/narr/security.rst b/docs/narr/security.rst index a61578e21..8d30a76a7 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -525,7 +525,7 @@ application's configuration section, e.g.: :linenos: [app:main] - use = egg:MyProject#app + use = egg:MyProject pyramid.debug_authorization = true With this debug flag turned on, the response sent to the browser will diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index c9ed01f83..c66264655 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -51,7 +51,9 @@ Here's a high-level time-ordered overview of what happens when you press If instead of a simple application or a pipeline, you're using a Paste "composite" (e.g. ``[composite:main]``), refer to the documentation for that particular composite to understand how to make it refer to your - :app:`Pyramid` application. + :app:`Pyramid` application. In most cases, a Pyramid application built + from a scaffold will have a single ``[app:main]`` section in it, and this + will be the application served. #. The PasteDeploy framework finds all :mod:`logging` related configuration in the ``.ini`` file and uses it to configure the Python standard library @@ -78,10 +80,9 @@ Here's a high-level time-ordered overview of what happens when you press section of an ``.ini`` file. It also accepts a ``**settings`` argument, which collects another set of arbitrary key/value pairs. The arbitrary key/value pairs received by this function in ``**settings`` will be - composed of all the key/value pairs that are present in the - ``[app:MyProject]`` section (except for the ``use=`` setting) when this - function is called by the :term:`PasteDeploy` framework when you run - ``paster serve``. + composed of all the key/value pairs that are present in the ``[app:main]`` + section (except for the ``use=`` setting) when this function is called by + the :term:`PasteDeploy` framework when you run ``paster serve``. Our generated ``development.ini`` file looks like so: @@ -107,9 +108,9 @@ Here's a high-level time-ordered overview of what happens when you press application's root resource. It is not called during startup, only when a request is handled. - The ``settings`` dictionary contains all the options in the - ``[app:MyProject]`` section of our .ini file except the ``use`` option - (which is internal to Paste) such as ``pyramid.reload_templates``, + The ``settings`` dictionary contains all the options in the ``[app:main]`` + section of our .ini file except the ``use`` option (which is internal to + Paste) such as ``pyramid.reload_templates``, ``pyramid.debug_authorization``, etc. #. The ``main`` function then calls various methods on the instance of the @@ -128,9 +129,9 @@ Here's a high-level time-ordered overview of what happens when you press :ref:`events_chapter` for more information about events). #. Assuming there were no errors, the ``main`` function in ``myproject`` - returns the router instance created by ``make_wsgi_app`` back to - PasteDeploy. As far as PasteDeploy is concerned, it is "just another WSGI - application". + returns the router instance created by + :meth:`pyramid.config.Configurator.make_wsgi_app` back to PasteDeploy. As + far as PasteDeploy is concerned, it is "just another WSGI application". #. PasteDeploy starts the WSGI *server* defined within the ``[server:main]`` section. In our case, this is the ``Paste#http`` server (``use = diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 0f46f6422..d5caed4be 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -638,8 +638,8 @@ the application's configuration section, e.g.: .. code-block:: ini :linenos: - [app:MyProject] - use = egg:MyProject#app + [app:main] + use = egg:MyProject pyramid.debug_templates = true With template debugging off, a :exc:`NameError` exception resulting @@ -800,7 +800,7 @@ application's configuration section, e.g.: :linenos: [app:main] - use = egg:MyProject#app + use = egg:MyProject pyramid.reload_templates = true .. index:: diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index ddbf1fb4d..8697df6a0 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -46,7 +46,7 @@ a ``urlmap`` composite. :linenos: [app:mypyramidapp] - use = egg:mypyramidapp#app + use = egg:mypyramidapp [composite:main] use = egg:Paste#urlmap -- cgit v1.2.3 From 9573ac26e7443ca9f7aa9ee17172d65c8e9774b7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Aug 2011 02:22:05 -0400 Subject: cleanups --- docs/narr/project.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9ea5f20dd..3fe0ed6a8 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -5,7 +5,7 @@ Creating a :app:`Pyramid` Project As we saw in :ref:`firstapp_chapter`, it's possible to create a :app:`Pyramid` application completely manually. However, it's usually more -convenient to use a *scaffold* to generate a basic :app:`Pyramid` +convenient to use a :term:`scaffold` to generate a basic :app:`Pyramid` :term:`project`. A project is a directory that contains at least one Python :term:`package`. @@ -20,7 +20,8 @@ distributed more easily than one which does not live within a package. a project. Each scaffold makes different configuration assumptions about what type of application you're trying to construct. -These scaffolds are rendered using the :term:`PasteDeploy` ``paster`` script. +These scaffolds are rendered using the :term:`PasteDeploy` ``paster create`` +command. .. index:: single: scaffolds @@ -441,7 +442,7 @@ The generated ``development.ini`` file looks like so: :language: ini :linenos: -This file contains several "sections" including ``[app:main]``, +This file contains several sections including ``[app:main]``, ``[server:main]`` and several other sections related to logging configuration. -- cgit v1.2.3 From 01815e030d093fb95c3051025e3a26a0a8f6b22a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Aug 2011 02:36:20 -0400 Subject: fix stray inclusion of weberror; move manifest description --- docs/narr/MyProject/setup.py | 2 +- docs/narr/project.rst | 79 +++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 42 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index a0b6fab9e..5203fc2a7 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -6,7 +6,7 @@ here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() -requires = ['pyramid', 'pyramid_debugtoolbar', 'WebError'] +requires = ['pyramid', 'pyramid_debugtoolbar'] setup(name='MyProject', version='0.0', diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 3fe0ed6a8..2bd2122c3 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -542,6 +542,37 @@ well as ``.py`` files. See http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template for more information about the syntax and usage of ``MANIFEST.in``. +Without the presence of a ``MANIFEST.in`` file or without checking your +source code into a version control repository, ``setup.py sdist`` places only +*Python source files* (files ending with a ``.py`` extension) into tarballs +generated by ``python setup.py sdist``. This means, for example, if your +project was not checked into a setuptools-compatible source control system, +and your project directory didn't contain a ``MANIFEST.in`` file that told +the ``sdist`` machinery to include ``*.pt`` files, the +``myproject/templates/mytemplate.pt`` file would not be included in the +generated tarball. + +Projects generated by Pyramid scaffolds include a default ``MANIFEST.in`` +file. The ``MANIFEST.in`` file contains declarations which tell it to +include files like ``*.pt``, ``*.css`` and ``*.js`` in the generated tarball. +If you include files with extensions other than the files named in the +project's ``MANIFEST.in`` and you don't make use of a setuptools-compatible +version control system, you'll need to edit the ``MANIFEST.in`` file and +include the statements necessary to include your new files. See +http://docs.python.org/distutils/sourcedist.html#principle for more +information about how to do this. + +You can also delete ``MANIFEST.in`` from your project and rely on a +setuptools feature which simply causes all files checked into a version +control system to be put into the generated tarball. To allow this to +happen, check all the files that you'd like to be distributed along with your +application's Python files into Subversion. After you do this, when you +rerun ``setup.py sdist``, all files checked into the version control system +will be included in the tarball. If you don't use Subversion, and instead +use a different version control system, you may need to install a setuptools +add-on such as ``setuptools-git`` or ``setuptools-hg`` for this behavior to +work properly. + .. index:: single: setup.py @@ -557,7 +588,8 @@ testing your application, packaging, and distributing your application. ``setup.py`` is the defacto 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 `_. Our generated ``setup.py`` looks like this: @@ -595,12 +627,10 @@ will be run when ``setup.py test`` is invoked. We examined ``entry_points`` in our discussion of the ``development.ini`` file; this file defines the ``main`` entry point that represents our project's application. -A more exhaustive explanation of the purpose and composition of ``setup.py`` -is available at `The Hitchhiker's Guide to Packaging -`_. Usually you only need to think -about the contents of the ``setup.py`` file when distributing your -application to other people, or when versioning your application for your own -use. For fun, you can try this command now: +Usually you only need to think about the contents of the ``setup.py`` file +when distributing your application to other people, when adding Python +package dependencies, or when versioning your application for your own use. +For fun, you can try this command now: .. code-block:: text @@ -608,40 +638,7 @@ use. For fun, you can try this command now: This will create a tarball of your application in a ``dist`` subdirectory named ``MyProject-0.1.tar.gz``. You can send this tarball to other people -who want to use your application. - -.. warning:: - - Without the presence of a ``MANIFEST.in`` file or without checking your - source code into a version control repository, ``setup.py sdist`` places - only *Python source files* (files ending with a ``.py`` extension) into - tarballs generated by ``python setup.py sdist``. This means, for example, - if your project was not checked into a setuptools-compatible source - control system, and your project directory didn't contain a ``MANIFEST.in`` - file that told the ``sdist`` machinery to include ``*.pt`` files, the - ``myproject/templates/mytemplate.pt`` file would not be included in the - generated tarball. - - Projects generated by Pyramid scaffolds include a default - ``MANIFEST.in`` file. The ``MANIFEST.in`` file contains declarations - which tell it to include files like ``*.pt``, ``*.css`` and ``*.js`` in - the generated tarball. If you include files with extensions other than - the files named in the project's ``MANIFEST.in`` and you don't make use of - a setuptools-compatible version control system, you'll need to edit the - ``MANIFEST.in`` file and include the statements necessary to include your - new files. See http://docs.python.org/distutils/sourcedist.html#principle - for more information about how to do this. - - You can also delete ``MANIFEST.in`` from your project and rely on a - setuptools feature which simply causes all files checked into a version - control system to be put into the generated tarball. To allow this to - happen, check all the files that you'd like to be distributed along with - your application's Python files into Subversion. After you do this, when - you rerun ``setup.py sdist``, all files checked into the version control - system will be included in the tarball. If you don't use Subversion, and - instead use a different version control system, you may need to install a - setuptools add-on such as ``setuptools-git`` or ``setuptools-hg`` for this - behavior to work properly. +who want to install and use your application. .. index:: single: setup.cfg -- cgit v1.2.3 From d36b566a83addddb80d221aa042b828268f185f2 Mon Sep 17 00:00:00 2001 From: Dylan Jay Date: Thu, 25 Aug 2011 13:05:52 +1000 Subject: use routes in firstapp as they are more familar to most and put hello world on the front page to make grab framework shoppers attention. --- docs/narr/firstapp.rst | 154 +++++++++++++++--------------------------------- docs/narr/helloworld.py | 12 ++++ 2 files changed, 59 insertions(+), 107 deletions(-) create mode 100644 docs/narr/helloworld.py (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 62389ec5f..447348be3 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -12,30 +12,14 @@ more detail how it works. .. _helloworld_imperative: -Hello World, Goodbye World --------------------------- +Hello World +----------- Here's one of the very simplest :app:`Pyramid` applications: -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - from pyramid.config import Configurator - from pyramid.response import Response - from paste.httpserver import serve - - def hello_world(request): - return Response('Hello world!') - - def goodbye_world(request): - return Response('Goodbye world!') - - if __name__ == '__main__': - config = Configurator() - config.add_view(hello_world) - config.add_view(goodbye_world, name='goodbye') - app = config.make_wsgi_app() - serve(app, host='0.0.0.0') When this code is inserted into a Python script named ``helloworld.py`` and executed by a Python interpreter which has the :app:`Pyramid` software @@ -46,9 +30,8 @@ installed, an HTTP server is started on TCP port 8080: $ python helloworld.py serving on 0.0.0.0:8080 view at http://127.0.0.1:8080 -When port 8080 is visited by a browser on the root URL (``/``), the server -will simply serve up the text "Hello world!" When visited by a browser on -the URL ``/goodbye``, the server will serve up the text "Goodbye world!" +When port 8080 is visited by a browser on the URL (``/hello/world``), the server +will simply serve up the text "Hello world!" Press ``Ctrl-C`` to stop the application. @@ -61,21 +44,15 @@ Imports The above ``helloworld.py`` script uses the following set of import statements: -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - - from pyramid.config import Configurator - from pyramid.response import Response - from paste.httpserver import serve + :lines: 1-2 The script imports the :class:`~pyramid.config.Configurator` class from the :mod:`pyramid.config` module. An instance of the :class:`~pyramid.config.Configurator` class is later used to configure your :app:`Pyramid` application. -The script uses the :class:`pyramid.response.Response` class later in the -script to create a :term:`response` object. - Like many other Python web frameworks, :app:`Pyramid` uses the :term:`WSGI` protocol to connect an application and a web server together. The :mod:`paste.httpserver` server is used in this example as a WSGI server for @@ -85,25 +62,18 @@ itself. View Callable Declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The above script, beneath its set of imports, defines two functions: one -named ``hello_world`` and one named ``goodbye_world``. +The above script, beneath its set of imports, defines a function +named ``hello_world``. -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: + :pyobject: hello_world - def hello_world(request): - return Response('Hello world!') - - def goodbye_world(request): - return Response('Goodbye world!') - -These functions don't do anything very difficult. Both functions accept a -single argument (``request``). The ``hello_world`` function does nothing but -return a response instance with the body ``Hello world!``. The -``goodbye_world`` function returns a response instance with the body -``Goodbye world!``. +This function doesn't do anything very difficult. The functions accepts a +single argument (``request``). The ``hello_world`` function returns a value +computed from arguments matched from the url route. -Each of these functions is known as a :term:`view callable`. A view callable +This function is known as a :term:`view callable`. A view callable accepts a single argument, ``request``. It is expected to return a :term:`response` object. A view callable doesn't need to be a function; it can be represented via another type of object, like a class or an instance, @@ -118,9 +88,7 @@ response object has all the information necessary to formulate an actual HTTP response; this object is then converted to text by the upstream :term:`WSGI` server and sent back to the requesting browser. To return a response, each view callable creates an instance of the :class:`~pyramid.response.Response` -class. In the ``hello_world`` function, the string ``'Hello world!'`` is -passed to the ``Response`` constructor as the *body* of the response. In the -``goodbye_world`` function, the string ``'Goodbye world!'`` is passed. +class. In the ``hello_world`` function, the string is passed. .. note:: As we'll see in later chapters, returning a literal :term:`response` object from a view callable is not always required; we @@ -143,26 +111,18 @@ this simple application. The application is configured using the previously defined imports and function definitions, placed within the confines of an ``if`` statement: -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - - if __name__ == '__main__': - config = Configurator() - config.add_view(hello_world) - config.add_view(goodbye_world, name='goodbye') - app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + :lines: 7-12 Let's break this down piece-by-piece. Configurator Construction ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - - if __name__ == '__main__': - config = Configurator() + :lines: 7-8 The ``if __name__ == '__main__':`` line in the code sample above represents a Python idiom: the code inside this if clause is not invoked unless the script @@ -193,44 +153,32 @@ Adding Configuration ~~~~~~~~~~~~~~~~~~~~ .. ignore-next-block -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - - config.add_view(hello_world) - config.add_view(goodbye_world, name='goodbye') - -Each of these lines calls the :meth:`pyramid.config.Configurator.add_view` -method. The ``add_view`` method of a configurator registers a :term:`view -configuration` within the :term:`application registry`. A :term:`view -configuration` represents a set of circumstances related to the + :lines: 9-10 + +First line is to call the :meth:`pyramid.config.Configurator.add_route` +which registers a :term:`route` to match any url with ``/hello/`` followed +by a string. The :meth:`pyramid.config.Configurator.add_view` method of +a configurator registers a :term:`view configuration` within the +:term:`application registry`. A :term:`view configuration` and +:term:`route configuration` represents a set of circumstances related to the :term:`request` that will cause a specific :term:`view callable` to be invoked. This "set of circumstances" is provided as one or more keyword arguments to the ``add_view`` method. Each of these keyword arguments is known as a view configuration :term:`predicate`. -The line ``config.add_view(hello_world)`` registers the ``hello_world`` -function as a view callable. The ``add_view`` method of a Configurator must -be called with a view callable object or a :term:`dotted Python name` as its +The line ``config.add_view(hello_world, route_name='hello')`` registers the +``hello_world`` function as a view callable. The ``add_view`` method +of a Configurator must be called with a view callable object or a +:term:`dotted Python name` as its first argument, so the first argument passed is the ``hello_world`` function. -This line calls ``add_view`` with a *default* value for the :term:`predicate` -argument, named ``name``. The ``name`` predicate defaults to a value -equalling the empty string (``''``). This means that we're instructing -:app:`Pyramid` to invoke the ``hello_world`` view callable when the -:term:`view name` is the empty string. We'll learn in later chapters what a -:term:`view name` is, and under which circumstances a request will have a -view name that is the empty string; in this particular application, it means -that the ``hello_world`` view callable will be invoked when the root URL -``/`` is visited by a browser. - -The line ``config.add_view(goodbye_world, name='goodbye')`` registers the -``goodbye_world`` function as a view callable. The line calls ``add_view`` -with the view callable as the first required positional argument, and a -:term:`predicate` keyword argument ``name`` with the value ``'goodbye'``. -The ``name`` argument supplied in this :term:`view configuration` implies -that only a request that has a :term:`view name` of ``goodbye`` should cause -the ``goodbye_world`` view callable to be invoked. In this particular -application, this means that the ``goodbye_world`` view callable will be -invoked when the URL ``/goodbye`` is visited by a browser. +This line calls ``add_view`` with a ``route_name`` ``predicate`` value of +``hello``. This means that we're instructing +:app:`Pyramid` to invoke the ``hello_world`` view callable if the +:term:`route` is matched is ``hello``. In :app:`Pyramid` the use of a +:term:`route` is only one of ways you can link a url to a :term:`view callable` +and is called :term:`URL Dispatch`. Each invocation of the ``add_view`` method registers a :term:`view configuration`. Each :term:`predicate` provided as a keyword argument to the @@ -240,14 +188,8 @@ predicates supplied along with a view configuration will more strictly limit the applicability of its associated view callable. When :app:`Pyramid` processes a request, the view callable with the *most specific* view configuration (the view configuration that matches the most specific set of -predicates) is always invoked. - -In this application, :app:`Pyramid` chooses the most specific view callable -based only on view :term:`predicate` applicability. The ordering of calls to -:meth:`~pyramid.config.Configurator.add_view` is never very important. We can -register ``goodbye_world`` first and ``hello_world`` second; :app:`Pyramid` -will still give us the most specific callable when a request is dispatched to -it. +predicates) is always invoked. In this application, :app:`Pyramid` chooses the most specific view callable +based only on view :term:`predicate` applicability. .. index:: single: make_wsgi_app @@ -257,10 +199,9 @@ WSGI Application Creation ~~~~~~~~~~~~~~~~~~~~~~~~~ .. ignore-next-block -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - - app = config.make_wsgi_app() + :lines: 11 After configuring views and ending configuration, the script creates a WSGI *application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` @@ -280,17 +221,16 @@ the :term:`application registry` which resulted from method calls to the configurator used to configure it. The :term:`router` consults the registry to obey the policy choices made by a single application. These policy choices were informed by method calls to the :term:`Configurator` made -earlier; in our case, the only policy choices made were implied by two calls -to its ``add_view`` method. +earlier; in our case, the only policy choices made were implied by calls +to its ``add_view`` and ``add_route`` methods. WSGI Application Serving ~~~~~~~~~~~~~~~~~~~~~~~~ .. ignore-next-block -.. code-block:: python +.. literalinclude:: helloworld.py :linenos: - - serve(app, host='0.0.0.0') + :lines: 12 Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :func:`paste.httpserver.serve` WSGI server diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py new file mode 100644 index 000000000..23bb146df --- /dev/null +++ b/docs/narr/helloworld.py @@ -0,0 +1,12 @@ +from paste.httpserver import serve +from pyramid.configuration import Configurator + +def hello_world(request): + return 'Hello %(name)s!' % request.matchdict + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_view(hello_world, route_name='hello') + app = config.make_wsgi_app() + serve(app, host='0.0.0.0') \ No newline at end of file -- cgit v1.2.3 From f7fe1d3b9b98663febad51bd6c09b5a7f7ea3e1f Mon Sep 17 00:00:00 2001 From: Dylan Jay Date: Thu, 25 Aug 2011 15:19:02 +1000 Subject: fix helloworld example --- docs/narr/helloworld.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py index 23bb146df..ce0fcf955 100644 --- a/docs/narr/helloworld.py +++ b/docs/narr/helloworld.py @@ -7,6 +7,6 @@ def hello_world(request): if __name__ == '__main__': config = Configurator() config.add_route('hello', '/hello/{name}') - config.add_view(hello_world, route_name='hello') + config.add_view(hello_world, route_name='hello', renderer='string') app = config.make_wsgi_app() serve(app, host='0.0.0.0') \ No newline at end of file -- cgit v1.2.3 From d73be153fa9544f453510524f34d55a7602e0896 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 25 Aug 2011 02:23:51 -0400 Subject: use Response; fix text --- docs/narr/firstapp.rst | 89 +++++++++++++++++-------------------------------- docs/narr/helloworld.py | 7 ++-- 2 files changed, 35 insertions(+), 61 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 447348be3..55829bef0 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -20,7 +20,6 @@ Here's one of the very simplest :app:`Pyramid` applications: .. literalinclude:: helloworld.py :linenos: - When this code is inserted into a Python script named ``helloworld.py`` and executed by a Python interpreter which has the :app:`Pyramid` software installed, an HTTP server is started on TCP port 8080: @@ -30,8 +29,8 @@ installed, an HTTP server is started on TCP port 8080: $ python helloworld.py serving on 0.0.0.0:8080 view at http://127.0.0.1:8080 -When port 8080 is visited by a browser on the URL (``/hello/world``), the server -will simply serve up the text "Hello world!" +When port 8080 is visited by a browser on the URL ``/hello/world``, the +server will simply serve up the text "Hello world!" Press ``Ctrl-C`` to stop the application. @@ -46,7 +45,7 @@ statements: .. literalinclude:: helloworld.py :linenos: - :lines: 1-2 + :lines: 1-3 The script imports the :class:`~pyramid.config.Configurator` class from the :mod:`pyramid.config` module. An instance of the @@ -59,6 +58,9 @@ protocol to connect an application and a web server together. The convenience, as the ``paste`` package is a dependency of :app:`Pyramid` itself. +The script also imports the :class:`pyramid.response.Response` class for +later use. An instance of this class will be used to create a web response. + View Callable Declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -70,8 +72,10 @@ named ``hello_world``. :pyobject: hello_world This function doesn't do anything very difficult. The functions accepts a -single argument (``request``). The ``hello_world`` function returns a value -computed from arguments matched from the url route. +single argument (``request``). The ``hello_world`` function returns an +instance of the :class:`pyramid.response.Response`. The single argument to +the class' constructor is value computed from arguments matched from the url +route. This value becomes the body of the response. This function is known as a :term:`view callable`. A view callable accepts a single argument, ``request``. It is expected to return a @@ -85,16 +89,11 @@ active :term:`WSGI` server. A view callable is required to return a :term:`response` object because a response object has all the information necessary to formulate an actual HTTP -response; this object is then converted to text by the upstream :term:`WSGI` -server and sent back to the requesting browser. To return a response, each -view callable creates an instance of the :class:`~pyramid.response.Response` -class. In the ``hello_world`` function, the string is passed. - -.. note:: As we'll see in later chapters, returning a literal - :term:`response` object from a view callable is not always required; we - can instead use a :term:`renderer` in our view configurations. If we use - a renderer, our view callable is allowed to return a value that the - renderer understands, and the renderer generates a response on our behalf. +response; this object is then converted to text by the :term:`WSGI` server +which called Pyramid and it is sent back to the requesting browser. To +return a response, each view callable creates an instance of the +:class:`~pyramid.response.Response` class. In the ``hello_world`` function, +a string is passed as the body to the response. .. index:: single: imperative configuration @@ -113,7 +112,7 @@ defined imports and function definitions, placed within the confines of an .. literalinclude:: helloworld.py :linenos: - :lines: 7-12 + :lines: 8-13 Let's break this down piece-by-piece. @@ -122,7 +121,7 @@ Configurator Construction .. literalinclude:: helloworld.py :linenos: - :lines: 7-8 + :lines: 8-9 The ``if __name__ == '__main__':`` line in the code sample above represents a Python idiom: the code inside this if clause is not invoked unless the script @@ -155,41 +154,15 @@ Adding Configuration .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 9-10 - -First line is to call the :meth:`pyramid.config.Configurator.add_route` -which registers a :term:`route` to match any url with ``/hello/`` followed -by a string. The :meth:`pyramid.config.Configurator.add_view` method of -a configurator registers a :term:`view configuration` within the -:term:`application registry`. A :term:`view configuration` and -:term:`route configuration` represents a set of circumstances related to the -:term:`request` that will cause a specific :term:`view callable` to be -invoked. This "set of circumstances" is provided as one or more keyword -arguments to the ``add_view`` method. Each of these keyword arguments is -known as a view configuration :term:`predicate`. - -The line ``config.add_view(hello_world, route_name='hello')`` registers the -``hello_world`` function as a view callable. The ``add_view`` method -of a Configurator must be called with a view callable object or a -:term:`dotted Python name` as its -first argument, so the first argument passed is the ``hello_world`` function. -This line calls ``add_view`` with a ``route_name`` ``predicate`` value of -``hello``. This means that we're instructing -:app:`Pyramid` to invoke the ``hello_world`` view callable if the -:term:`route` is matched is ``hello``. In :app:`Pyramid` the use of a -:term:`route` is only one of ways you can link a url to a :term:`view callable` -and is called :term:`URL Dispatch`. - -Each invocation of the ``add_view`` method registers a :term:`view -configuration`. Each :term:`predicate` provided as a keyword argument to the -``add_view`` method narrows the set of circumstances which would cause the -view configuration's callable to be invoked. In general, a greater number of -predicates supplied along with a view configuration will more strictly limit -the applicability of its associated view callable. When :app:`Pyramid` -processes a request, the view callable with the *most specific* view -configuration (the view configuration that matches the most specific set of -predicates) is always invoked. In this application, :app:`Pyramid` chooses the most specific view callable -based only on view :term:`predicate` applicability. + :lines: 10-11 + +First line above calls the :meth:`pyramid.config.Configurator.add_route` +method, which registers a :term:`route` to match any url path that begins +with ``/hello/`` followed by a string. + +The second line, ``config.add_view(hello_world, route_name='hello')``, +registers the ``hello_world`` function as a :term:`view callable` and makes +sure that it will be called when the ``hello`` route is matched. .. index:: single: make_wsgi_app @@ -201,7 +174,7 @@ WSGI Application Creation .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 11 + :lines: 12 After configuring views and ending configuration, the script creates a WSGI *application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` @@ -230,7 +203,7 @@ WSGI Application Serving .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 12 + :lines: 13 Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :func:`paste.httpserver.serve` WSGI server @@ -243,9 +216,9 @@ from a local system. We don't specify a TCP port number to listen on; this means we want to use the default TCP port, which is 8080. When this line is invoked, it causes the server to start listening on TCP -port 8080. It will serve requests forever, or at least until we stop it by -killing the process which runs it (usually by pressing ``Ctrl-C`` in the -terminal we used to start it). +port 8080. The server will serve requests forever, or at least until we stop +it by killing the process which runs it (usually by pressing ``Ctrl-C`` in +the terminal we used to start it). Conclusion ~~~~~~~~~~ diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py index ce0fcf955..92e16efbb 100644 --- a/docs/narr/helloworld.py +++ b/docs/narr/helloworld.py @@ -1,12 +1,13 @@ from paste.httpserver import serve from pyramid.configuration import Configurator +from pyramid.response import Response def hello_world(request): - return 'Hello %(name)s!' % request.matchdict + return Response('Hello %(name)s!' % request.matchdict) if __name__ == '__main__': config = Configurator() config.add_route('hello', '/hello/{name}') - config.add_view(hello_world, route_name='hello', renderer='string') + config.add_view(hello_world, route_name='hello') app = config.make_wsgi_app() - serve(app, host='0.0.0.0') \ No newline at end of file + serve(app, host='0.0.0.0') -- cgit v1.2.3 From 55ce9d632f828d285360c1abee9f56042243cac9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 28 Aug 2011 22:15:48 -0400 Subject: clean up inappropriate discussions of ZCML --- docs/narr/assets.rst | 3 --- docs/narr/introduction.rst | 6 +++--- docs/narr/templates.rst | 12 +++--------- 3 files changed, 6 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index c8508f1b5..93b03fbc9 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -441,9 +441,6 @@ feature, a :term:`Configurator` API exists named - Any other asset (or set of assets) addressed by code that uses the setuptools :term:`pkg_resources` API. -.. note:: The :term:`ZCML` directive named ``asset`` serves the same purpose - as the :meth:`~pyramid.config.Configurator.override_asset` method. - .. index:: single: override_asset diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 63c31d340..97f63fcfe 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -122,9 +122,9 @@ application developer may use completely imperative code to perform common framework configuration tasks such as adding a view or a route. In Zope, :term:`ZCML` is typically required for similar purposes. In :term:`Grok`, a Zope-based web framework, :term:`decorator` objects and class-level -declarations are used for this purpose. :app:`Pyramid` supports :term:`ZCML` -and decorator-based :term:`declarative configuration`, but does not require -either. See :ref:`configuration_narr` for more information. +declarations are used for this purpose. Out of the box, Pyramid supports +imperative and decorator-based configuration; :term:`ZCML` may be used via an +add-on package named ``pyramid_zcml``. Also unlike :term:`Zope` and unlike other "full-stack" frameworks such as :term:`Django`, :app:`Pyramid` makes no assumptions about which diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index d5caed4be..6412c070d 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -335,9 +335,8 @@ template renderer: function. View-configuration-relative asset specifications work only in Chameleon, not in Mako templates. -Similar renderer configuration can be done imperatively and via -:term:`ZCML`. See :ref:`views_which_use_a_renderer`. See also -:ref:`built_in_renderers`. +Similar renderer configuration can be done imperatively. See +:ref:`views_which_use_a_renderer`. See also :ref:`built_in_renderers`. Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive @@ -366,12 +365,7 @@ templates as renderers. See :ref:`available_template_system_bindings`. with renderers externally via view configuration typically return a dictionary, as above. Making assertions about results returned in a dictionary is almost always more direct and straightforward than - needing to parse HTML. Specifying a renderer from within - :term:`ZCML` (as opposed to imperatively or via a ``view_config`` - decorator, or using a template directly from within a view callable) - also makes it possible for someone to modify the template used to - render a view without needing to fork your code to do so. See - :ref:`extending_chapter` for more information. + needing to parse HTML. By default, views rendered via a template renderer return a :term:`Response` object which has a *status code* of ``200 OK``, and a *content-type* of -- cgit v1.2.3 From c0e6e69eb75ae042f0db3b98a5e064a94235837a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 29 Aug 2011 13:11:45 -0400 Subject: add match_param to the narrative docs --- docs/narr/viewconfig.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index a1b12ad2a..26cca2ad1 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -304,6 +304,25 @@ configured view. If ``request_param`` is not supplied, the view will be invoked without consideration of keys and values in the ``request.params`` dictionary. +``match_param`` + .. note:: This feature is new as of :app:`Pyramid` 1.2. + + This param may be either a single string of the format "key=value" or a + dict of key/value pairs. + + This argument ensures that the view will only be called when the + :term:`request` has key/value pairs in its :term:`matchdict` that equal + those supplied in the predicate. e.g. ``match_param="action=edit" would + require the ``action`` parameter in the :term:`matchdict` match the right + hande side of the expression (``edit``) for the view to "match" the current + request. + + If the ``match_param`` is a dict, every key/value pair must match for the + predicate to pass. + + If ``match_param`` is not supplied, the view will be invoked without + consideration of the keys and values in ``request.matchdict``. + ``containment`` This value should be a reference to a Python class or :term:`interface` that a parent object in the context resource's :term:`lineage` must provide -- cgit v1.2.3 From 6e3025d8d14dde9c442dae4c21bc76e57b452647 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 31 Aug 2011 11:20:54 -0400 Subject: wrong path for logging.config --- docs/narr/commandline.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index cef331e2d..a8459ac27 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -593,5 +593,5 @@ use the following command: .. code-block:: python - import logging - logging.fileConfig('/path/to/my/development.ini') + import logging.config + logging.config.fileConfig('/path/to/my/development.ini') -- cgit v1.2.3 From 09387f5cb04eb08b18c24a41248af0a13648286e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 1 Sep 2011 22:15:08 -0400 Subject: - Added a "Fixing HTTP vs. HTTP When Deploying Behind a Proxy" section to the "Virtual Hosting" chapter. --- docs/narr/vhosting.rst | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index 8697df6a0..086af78f7 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -139,6 +139,55 @@ the same can be achieved using ``SetEnv``: Setting a virtual root has no effect when using an application based on :term:`URL dispatch`. +Fixing HTTP vs. HTTPS When Deploying Behind a Proxy +--------------------------------------------------- + +In a configuration where you have a :app:`Pyramid` server behind an Apache or +Nginx or Squid proxy which serves your website over SSL (as ``https``) as in +the above example in :ref:`virtual_root_support`, the request will be passed +by the proxy to an `http://`` URL that will be served by :app:`Pyramid`. +Because this is true, URLs generated by :app:`Pyramid` will be generated with +``http://`` instead of ``https://``; the SSL info has been "lost" during the +proxying. + +To work around this, convert your application to use a "pipeline" instead of +a simple "app" in your PasteDeploy configuration, then add ``prefix`` +middleware to the pipeline. For example, if your ``production.ini`` file has +a ``main`` section that looks like this: + +.. code-block:: ini + + [app:main] + use = egg:MyProject + +Convert it to look like this: + +.. code-block:: ini + + [app:myapp] + use = egg:MyProject + + [pipeline:main] + pipeline = + myapp + +Then add the ``paste.prefix`` middleware with no options to the pipeline: + +.. code-block:: ini + + [app:myapp] + use = egg:MyProject + + [filter:paste_prefix] + use = egg:PasteDeploy#prefix + + [pipeline:main] + pipeline = + paste_prefix + myapp + +This will have the side effect of retaining ``https`` URLs during generation. + Further Documentation and Examples ---------------------------------- -- cgit v1.2.3 From 7c1549608daf2e3a6965320b1ef8362d8b4dd618 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Sep 2011 00:23:23 -0400 Subject: remove; too complex to document here --- docs/narr/vhosting.rst | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index 086af78f7..8697df6a0 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -139,55 +139,6 @@ the same can be achieved using ``SetEnv``: Setting a virtual root has no effect when using an application based on :term:`URL dispatch`. -Fixing HTTP vs. HTTPS When Deploying Behind a Proxy ---------------------------------------------------- - -In a configuration where you have a :app:`Pyramid` server behind an Apache or -Nginx or Squid proxy which serves your website over SSL (as ``https``) as in -the above example in :ref:`virtual_root_support`, the request will be passed -by the proxy to an `http://`` URL that will be served by :app:`Pyramid`. -Because this is true, URLs generated by :app:`Pyramid` will be generated with -``http://`` instead of ``https://``; the SSL info has been "lost" during the -proxying. - -To work around this, convert your application to use a "pipeline" instead of -a simple "app" in your PasteDeploy configuration, then add ``prefix`` -middleware to the pipeline. For example, if your ``production.ini`` file has -a ``main`` section that looks like this: - -.. code-block:: ini - - [app:main] - use = egg:MyProject - -Convert it to look like this: - -.. code-block:: ini - - [app:myapp] - use = egg:MyProject - - [pipeline:main] - pipeline = - myapp - -Then add the ``paste.prefix`` middleware with no options to the pipeline: - -.. code-block:: ini - - [app:myapp] - use = egg:MyProject - - [filter:paste_prefix] - use = egg:PasteDeploy#prefix - - [pipeline:main] - pipeline = - paste_prefix - myapp - -This will have the side effect of retaining ``https`` URLs during generation. - Further Documentation and Examples ---------------------------------- -- cgit v1.2.3 From 1feefdb0a789c89e1c4dd201a99aac6418a15b68 Mon Sep 17 00:00:00 2001 From: Charlie Choiniere Date: Sat, 3 Sep 2011 20:51:40 -0400 Subject: Updated environment documentation to include an example of accessing the settings dictionary inside an includeme function --- docs/narr/environment.rst | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index a5909e541..da93332c0 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -654,7 +654,18 @@ Here's how: dictionary with the converted version of the variable *before* passing it to the Configurator: the configurator makes a *copy* of ``settings``, it doesn't use the one you pass directly. - + +- When creating an ``includeme`` function that will be later added to your + application's configuration you may access the ``settings`` dictionary + through the instance of the :term:`Configurator` that is passed into the + function as its only argument. For Example: + + .. code-block:: python + + def includeme(config): + settings = config.registry.settings + debug_frobnosticator = settings['debug_frobnosticator'] + - In the runtime code that you need to access the new settings value, find the value in the ``registry.settings`` dictionary and use it. In :term:`view` code (or any other code that has access to the request), the @@ -662,7 +673,7 @@ Here's how: .. code-block:: python - registry = request.registry.settings + settings = request.registry.settings debug_frobnosticator = settings['debug_frobnosticator'] If you wish to use the value in code that does not have access to the -- cgit v1.2.3 From 25be339daa0448bf64b4dba03c08205b571a1cb0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 4 Sep 2011 00:04:12 -0400 Subject: remove documentation and todo mentions of zope.configuration --- docs/narr/advconfig.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 8040a465f..7b62b1a73 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -82,11 +82,8 @@ that ends something like this: self.commit() File "pyramid/pyramid/config.py", line 473, in commit self._ctx.execute_actions() - File "zope/configuration/config.py", line 600, in execute_actions - for action in resolveConflicts(self.actions): - File "zope/configuration/config.py", line 1507, in resolveConflicts - raise ConfigurationConflictError(conflicts) - zope.configuration.config.ConfigurationConflictError: + ... more code ... + pyramid.exceptions.ConfigurationConflictError: Conflicting configuration actions For: ('view', None, '', None, , None, None, None, None, None, False, None, None, None) -- cgit v1.2.3 From d0ec94cfd0a87e5c5c705b33267039eec6f0794f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 4 Sep 2011 14:52:18 -0400 Subject: Add Windows analogues to all command lines. Closes #144 --- docs/narr/install.rst | 16 +++++------ docs/narr/project.rst | 74 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 25 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index f543753ce..a1e7ce382 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -18,10 +18,10 @@ run :app:`Pyramid`. Python 2.6.6, and Python 2.7.2. :app:`Pyramid` does not run under any version of Python before 2.5, and does not yet run under Python 3.X. -:app:`Pyramid` is known to run on all popular Unix-like systems such as +:app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on Google's App Engine, :term:`PyPy` (1.5), and :term:`Jython` -(2.5.2). +known to run on Google's App Engine, :term:`PyPy` (1.5 and 1.6), and +:term:`Jython` (2.5.2). :app:`Pyramid` installation does not require the compilation of any C code, so you need only a Python interpreter that meets the @@ -204,9 +204,9 @@ into your setuptools-enabled Python interpreter, use the $ 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: +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 @@ -238,7 +238,7 @@ following: depending on the packages you've already got installed into your Python's "main" site-packages dir. -.. warning:: If you're on UNIX, *do not* use ``sudo`` to run the +.. warning:: *do not* use ``sudo`` to run the ``virtualenv`` script. It's perfectly acceptable (and desirable) to create a virtualenv as a normal user. @@ -250,7 +250,7 @@ Installing :app:`Pyramid` Into the Virtual Python Environment After you've got your ``env`` virtualenv installed, you may install :app:`Pyramid` itself using the following commands from within the -virtualenv (``env``) directory you created in the last step: +virtualenv (``env``) directory you created in the last step. .. code-block:: text diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 2bd2122c3..102078353 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -92,25 +92,38 @@ the ``virtualenv`` command. To start a :app:`Pyramid` :term:`project`, use the ``paster`` facility installed within the virtualenv. In :ref:`installing_chapter` we called the virtualenv directory ``env``; the following command assumes that our current working directory is that -directory. +directory. We'll choose the ``pyramid_starter`` scaffold for this purpose. -We'll choose the ``pyramid_starter`` scaffold for this purpose. +On UNIX: .. code-block:: text $ bin/paster create -t pyramid_starter +Or on Windows: + +.. code-block:: text + + $ Scripts\paster.exe create -t pyramid_starter + The above command uses the ``paster create`` command to create a project with the ``pyramid_starter`` scaffold. To use a different scaffold, such as -``pyramid_routesalchemy``, you'd just change the last argument. For example: +``pyramid_routesalchemy``, you'd just change the last argument. For example, +on UNIX: .. code-block:: text $ bin/paster create -t pyramid_routesalchemy +Or on Windows: + +.. code-block:: text + + $ Scripts\paster.exe create -t pyramid_routesalchemy + ``paster create`` will ask you a single question: the *name* of the project. You should use a string without spaces and with only letters in it. Here's -sample output from a run of ``paster create`` for a project we name +sample output from a run of ``paster create`` on UNIX for a project we name ``MyProject``: .. code-block:: text @@ -135,9 +148,9 @@ sample output from a run of ``paster create`` for a project we name .. note:: You may encounter an error when using ``paster create`` if a dependent Python package is not installed. This will result in a traceback - ending in ``pkg_resources.DistributionNotFound: ``. - Simply run ``bin/easy_install``, with the missing package name from the - error message to work around this issue. + ending in ``pkg_resources.DistributionNotFound: ``. Simply + run ``bin/easy_install`` (or ``Script\easy_install.exe`` on Windows), with + the missing package name from the error message to work around this issue. As a result of invoking the ``paster create`` command, a project is created in a directory named ``MyProject``. That directory is a :term:`project` @@ -175,18 +188,29 @@ command ``python setup.py develop`` The file named ``setup.py`` will be in the root of the paster-generated project directory. The ``python`` you're invoking should be the one that -lives in the ``bin`` directory of your virtual Python environment. Your -terminal's current working directory *must* be the newly created project -directory. For example: +lives in the ``bin`` (or ``Scripts`` on Windows) directory of your virtual +Python environment. Your terminal's current working directory *must* be the +newly created project directory. + +On UNIX: .. code-block:: text + $ cd MyProject $ ../bin/python setup.py develop -Elided output from a run of this command is shown below: +Or on Windows: + +.. code-block:: text + + $ cd MyProject + $ ..\Scripts\python.exe setup.py develop + +Elided output from a run of this command on UNIX is shown below: .. code-block:: text + $ cd MyProject $ ../bin/python setup.py develop ... Finished processing dependencies for MyProject==0.0 @@ -206,17 +230,25 @@ Running The Tests For Your Application To run unit tests for your application, you should invoke them using the Python interpreter from the :term:`virtualenv` you created during :ref:`installing_chapter` (the ``python`` command that lives in the ``bin`` -directory of your virtualenv): +directory of your virtualenv). + +On UNIX: .. code-block:: text $ ../bin/python setup.py test -q -Here's sample output from a test run: +Or on Windows: + +.. code-block:: text + + $ ..\Scripts\python.exe setup.py test -q + +Here's sample output from a test run on UNIX: .. code-block:: text - $ python setup.py test -q + $ ../bin/python setup.py test -q running test running egg_info writing requirements to MyProject.egg-info/requires.txt @@ -254,13 +286,21 @@ Running The Project Application Once a project is installed for development, you can run the application it represents using the ``paster serve`` command against the generated -configuration file. In our case, this file is named ``development.ini``: +configuration file. In our case, this file is named ``development.ini``. + +On UNIX: .. code-block:: text $ ../bin/paster serve development.ini -Here's sample output from a run of ``paster serve``: +On Windows: + +.. code-block:: text + + $ ..\Scripts\paster.exe serve development.ini + +Here's sample output from a run of ``paster serve`` on UNIX: .. code-block:: text @@ -279,7 +319,7 @@ restart. This typically makes development easier, as changes to Python code made within a :app:`Pyramid` application is not put into effect until the server restarts. -For example: +For example, on UNIX: .. code-block:: text -- cgit v1.2.3 From b4870b1d58f57cb20edefd4b0306615c0fc5a2e0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Sep 2011 00:19:19 -0400 Subject: readd aliases to environment tables --- docs/narr/environment.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index da93332c0..2ac094d47 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -51,7 +51,7 @@ third-party template rendering extensions. | Environment Variable Name | Config File Setting Name | +=================================+================================+ | ``PYRAMID_RELOAD_TEMPLATES`` | ``pyramid.reload_templates`` | -| | | +| | or ``reload_templates`` | | | | | | | +---------------------------------+--------------------------------+ @@ -66,7 +66,7 @@ also :ref:`overriding_assets_section`. | Environment Variable Name | Config File Setting Name | +=================================+=============================+ | ``PYRAMID_RELOAD_ASSETS`` | ``pyramid.reload_assets`` | -| | | +| | or ``reload_assets`` | | | | | | | +---------------------------------+-----------------------------+ @@ -85,7 +85,7 @@ when this value is true. See also :ref:`debug_authorization_section`. | Environment Variable Name | Config File Setting Name | +=================================+===================================+ | ``PYRAMID_DEBUG_AUTHORIZATION`` | ``pyramid.debug_authorization`` | -| | | +| | or ``debug_authorization`` | | | | | | | +---------------------------------+-----------------------------------+ @@ -100,7 +100,7 @@ when this value is true. See also :ref:`debug_notfound_section`. | Environment Variable Name | Config File Setting Name | +=================================+==============================+ | ``PYRAMID_DEBUG_NOTFOUND`` | ``pyramid.debug_notfound`` | -| | | +| | or ``debug_notfound`` | | | | | | | +---------------------------------+------------------------------+ @@ -115,7 +115,7 @@ this value is true. See also :ref:`debug_routematch_section`. | Environment Variable Name | Config File Setting Name | +=================================+================================+ | ``PYRAMID_DEBUG_ROUTEMATCH`` | ``pyramid.debug_routematch`` | -| | | +| | or ``debug_routematch`` | | | | | | | +---------------------------------+--------------------------------+ @@ -134,7 +134,7 @@ feature when this is true. See also :ref:`influencing_http_caching`. | Environment Variable Name | Config File Setting Name | +=================================+==================================+ | ``PYRAMID_PREVENT_HTTP_CACHE`` | ``pyramid.prevent_http_cache`` | -| | | +| | or ``prevent_http_cache`` | | | | | | | +---------------------------------+----------------------------------+ @@ -148,7 +148,7 @@ Turns on all ``debug*`` settings. | Environment Variable Name | Config File Setting Name | +=================================+=============================+ | ``PYRAMID_DEBUG_ALL`` | ``pyramid.debug_all`` | -| | | +| | or ``debug_all`` | | | | | | | +---------------------------------+-----------------------------+ @@ -162,7 +162,7 @@ Turns on all ``reload*`` settings. | Environment Variable Name | Config File Setting Name | +=================================+=============================+ | ``PYRAMID_RELOAD_ALL`` | ``pyramid.reload_all`` | -| | | +| | or ``reload_all`` | | | | | | | +---------------------------------+-----------------------------+ @@ -180,7 +180,7 @@ The value supplied here is used as the default locale name when a | Environment Variable Name | Config File Setting Name | +=================================+===================================+ | ``PYRAMID_DEFAULT_LOCALE_NAME`` | ``pyramid.default_locale_name`` | -| | | +| | or ``default_locale_name`` | | | | | | | +---------------------------------+-----------------------------------+ -- cgit v1.2.3 From 2b65bbb451d5b7cd87ff198cf88374dab28fd17b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Sep 2011 16:03:01 -0400 Subject: add explanation of why to use production.ini --- docs/narr/project.rst | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 102078353..10b7a5d04 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -566,6 +566,13 @@ are not automatically reloaded when changed, and turns off all debugging options. This file is appropriate to use instead of ``development.ini`` when you put your application into production. +It's important to use ``production.ini`` (and *not* ``development.ini``) to +benchmark your application and put it into production. ``development.ini`` +configures your system with a debug toolbar that helps development, but the +inclusion of this toolbar slows down page rendering times by over an order of +magnitude. The debug toolbar is also a potential security risk if you have +it configured incorrectly. + .. index:: single: MANIFEST.in -- cgit v1.2.3 From b37b97bb67eedced5c6a2e0fec718594b5d41878 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Sep 2011 17:58:34 -0400 Subject: move unrelated request cleanup to webob.rest; reorder urldispatch chapter from most-important-concept-to-least --- docs/narr/urldispatch.rst | 592 +++++++++++++++++++++------------------------- docs/narr/webob.rst | 47 ++++ 2 files changed, 320 insertions(+), 319 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 00d36cc76..0ec440f4d 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -323,43 +323,6 @@ matched. This is because the match ordering will always match ``members/{def}`` first; the route configuration with ``members/abc`` will never be evaluated. -.. index:: - single: route factory - -.. _route_factories: - -Route Factories -~~~~~~~~~~~~~~~ - -A "route" configuration declaration can mention a "factory". When that route -matches a request, and a factory is attached to a route, the :term:`root -factory` passed at startup time to the :term:`Configurator` is ignored; -instead the factory associated with the route is used to generate a -:term:`root` object. This object will usually be used as the :term:`context` -resource of the view callable ultimately found via :term:`view lookup`. - -.. code-block:: python - :linenos: - - config.add_route('abc', '/abc', - factory='myproject.resources.root_factory') - config.add_view('myproject.views.theview', route_name='abc') - -The factory can either be a Python object or a :term:`dotted Python name` (a -string) which points to such a Python object, as it is above. - -In this way, each route can use a different factory, making it possible to -supply a different :term:`context` resource object to the view related to -each particular route. - -Supplying a different resource factory for each route is useful when you're -trying to use a :app:`Pyramid` :term:`authorization policy` to provide -declarative, "context sensitive" security checks; each resource can maintain -a separate :term:`ACL`, as documented in -:ref:`using_security_with_urldispatch`. It is also useful when you wish to -combine URL dispatch with :term:`traversal` as documented within -:ref:`hybrid_chapter`. - .. index:: single: route configuration arguments @@ -384,141 +347,6 @@ neither predicates nor view configuration information. names a ``view`` and these arguments have been deprecated as of :app:`Pyramid` 1.1. -.. index:: - single: route predicates (custom) - -.. _custom_route_predicates: - -Custom Route Predicates -~~~~~~~~~~~~~~~~~~~~~~~ - -Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`~pyramid.config.Configurator.add_route` must be a callable accepting -two arguments. The first argument passed to a custom predicate is a -dictionary conventionally named ``info``. The second argument is the current -:term:`request` object. - -The ``info`` dictionary has a number of contained values: ``match`` is a -dictionary: it represents the arguments matched in the URL by the route. -``route`` is an object representing the route which was matched (see -:class:`pyramid.interfaces.IRoute` for the API of such a route object). - -``info['match']`` is useful when predicates need access to the route match. -For example: - -.. code-block:: python - :linenos: - - def any_of(segment_name, *allowed): - def predicate(info, request): - if info['match'][segment_name] in allowed: - return True - return predicate - - num_one_two_or_three = any_of('num', 'one', 'two', 'three') - - config.add_route('route_to_num', '/{num}', - custom_predicates=(num_one_two_or_three,)) - -The above ``any_of`` function generates a predicate which ensures that the -match value named ``segment_name`` is in the set of allowable values -represented by ``allowed``. We use this ``any_of`` function to generate a -predicate function named ``num_one_two_or_three``, which ensures that the -``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use -the result as a custom predicate by feeding it inside a tuple to the -``custom_predicates`` argument to -:meth:`~pyramid.config.Configurator.add_route`. - -A custom route predicate may also *modify* the ``match`` dictionary. For -instance, a predicate might do some type conversion of values: - -.. code-block:: python - :linenos: - - def integers(*segment_names): - def predicate(info, request): - match = info['match'] - for segment_name in segment_names: - try: - match[segment_name] = int(match[segment_name]) - except (TypeError, ValueError): - pass - return True - return predicate - - ymd_to_int = integers('year', 'month', 'day') - - config.add_route('ymd', '/{year}/{month}/{day}', - custom_predicates=(ymd_to_int,)) - -Note that a conversion predicate is still a predicate so it must return -``True`` or ``False``; a predicate that does *only* conversion, such as the -one we demonstrate above should unconditionally return ``True``. - -To avoid the try/except uncertainty, the route pattern can contain regular -expressions specifying requirements for that marker. For instance: - -.. code-block:: python - :linenos: - - def integers(*segment_names): - def predicate(info, request): - match = info['match'] - for segment_name in segment_names: - match[segment_name] = int(match[segment_name]) - return True - return predicate - - ymd_to_int = integers('year', 'month', 'day') - - config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', - custom_predicates=(ymd_to_int,)) - -Now the try/except is no longer needed because the route will not match at -all unless these markers match ``\d+`` which requires them to be valid digits -for an ``int`` type conversion. - -The ``match`` dictionary passed within ``info`` to each predicate attached to -a route will be the same dictionary. Therefore, when registering a custom -predicate which modifies the ``match`` dict, the code registering the -predicate should usually arrange for the predicate to be the *last* custom -predicate in the custom predicate list. Otherwise, custom predicates which -fire subsequent to the predicate which performs the ``match`` modification -will receive the *modified* match dictionary. - -.. warning:: - - It is a poor idea to rely on ordering of custom predicates to build a - conversion pipeline, where one predicate depends on the side effect of - another. For instance, it's a poor idea to register two custom - predicates, one which handles conversion of a value to an int, the next - which handles conversion of that integer to some custom object. Just do - all that in a single custom predicate. - -The ``route`` object in the ``info`` dict is an object that has two useful -attributes: ``name`` and ``pattern``. The ``name`` attribute is the route -name. The ``pattern`` attribute is the route pattern. An example of using -the route in a set of route predicates: - -.. code-block:: python - :linenos: - - def twenty_ten(info, request): - if info['route'].name in ('ymd', 'ym', 'y'): - return info['match']['year'] == '2010' - - config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) - config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) - config.add_route('ymd', '/{year}/{month}/{day}', - custom_predicates=(twenty_ten,)) - -The above predicate, when added to a number of route configurations ensures -that the year match argument is '2010' if and only if the route name is -'ymd', 'ym', or 'y'. - -See also :class:`pyramid.interfaces.IRoute` for more API documentation about -route objects. - .. index:: single: route matching @@ -732,11 +560,11 @@ request in its ``__init__``. For example: In a more complicated application, this root factory might be a class representing a :term:`SQLAlchemy` model. +See :ref:`route_factories` for more details about how to use route factories. + .. index:: single: matching the root URL single: root url (matching) - -.. index:: pair: matching; root URL Matching the Root URL @@ -907,92 +735,6 @@ The ``notfound_view`` supplied must adhere to the two-argument view callable calling convention of ``(context, request)`` (``context`` will be the exception object). -.. index:: - single: cleaning up after request - -.. _cleaning_up_after_a_request: - -Cleaning Up After a Request ---------------------------- - -Sometimes it's required that some cleanup be performed at the end of a -request when a database connection is involved. - -For example, let's say you have a ``mypackage`` :app:`Pyramid` application -package that uses SQLAlchemy, and you'd like the current SQLAlchemy database -session to be removed after each request. Put the following in the -``mypackage.__init__`` module: - -.. ignore-next-block -.. code-block:: python - :linenos: - - from mypackage.models import DBSession - - from pyramid.events import subscriber - from pyramid.events import NewRequest - - def cleanup_callback(request): - DBSession.remove() - - @subscriber(NewRequest) - def add_cleanup_callback(event): - event.request.add_finished_callback(cleanup_callback) - -Registering the ``cleanup_callback`` finished callback at the start of a -request (by causing the ``add_cleanup_callback`` to receive a -:class:`pyramid.events.NewRequest` event at the start of each request) will -cause the DBSession to be removed whenever request processing has ended. -Note that in the example above, for the :class:`pyramid.events.subscriber` -decorator to "work", the :meth:`pyramid.config.Configurator.scan` method must -be called against your ``mypackage`` package during application -initialization. - -.. note:: This is only an example. In particular, it is not necessary to - cause ``DBSession.remove`` to be called in an application generated from - any :app:`Pyramid` scaffold, because these all use the - ``repoze.tm2`` middleware. The cleanup done by ``DBSession.remove`` is - unnecessary when ``repoze.tm2`` middleware is in the WSGI pipeline. - -.. index:: - pair: URL dispatch; security - -.. _using_security_with_urldispatch: - -Using :app:`Pyramid` Security With URL Dispatch --------------------------------------------------- - -:app:`Pyramid` provides its own security framework which consults an -:term:`authorization policy` before allowing any application code to be -called. This framework operates in terms of an access control list, which is -stored as an ``__acl__`` attribute of a resource object. A common thing to -want to do is to attach an ``__acl__`` to the resource object dynamically for -declarative security purposes. You can use the ``factory`` argument that -points at a factory which attaches a custom ``__acl__`` to an object at its -creation time. - -Such a ``factory`` might look like so: - -.. code-block:: python - :linenos: - - class Article(object): - def __init__(self, request): - matchdict = request.matchdict - article = matchdict.get('article', None) - if article == '1': - self.__acl__ = [ (Allow, 'editor', 'view') ] - -If the route ``archives/{article}`` is matched, and the article number is -``1``, :app:`Pyramid` will generate an ``Article`` :term:`context` resource -with an ACL on it that allows the ``editor`` principal the ``view`` -permission. Obviously you can do more generic things than inspect the routes -match dict to see if the ``article`` argument matches a particular string; -our sample ``Article`` factory class is not very ambitious. - -.. note:: See :ref:`security_chapter` for more information about - :app:`Pyramid` security and ACLs. - .. index:: pair: debugging; route matching @@ -1031,68 +773,18 @@ You can also use the ``paster proutes`` command to see a display of all the routes configured in your application; for more information, see :ref:`displaying_application_routes`. -.. index:: - pair: route; view callable lookup details - -Route View Callable Registration and Lookup Details ---------------------------------------------------- - -When a request enters the system which matches the pattern of the route, the -usual result is simple: the view callable associated with the route is -invoked with the request that caused the invocation. - -For most usage, you needn't understand more than this; how it works is an -implementation detail. In the interest of completeness, however, we'll -explain how it *does* work in the this section. You can skip it if you're -uninterested. - -When a view is associated with a route configuration, :app:`Pyramid` ensures -that a :term:`view configuration` is registered that will always be found -when the route pattern is matched during a request. To do so: +.. _route_prefix: -- A special route-specific :term:`interface` is created at startup time for - each route configuration declaration. +Using a Route Prefix to Compose Applications +-------------------------------------------- -- When an ``add_view`` statement mentions a ``route name`` attribute, a - :term:`view configuration` is registered at startup time. This view - configuration uses a route-specific interface as a :term:`request` type. +.. note:: This feature is new as of :app:`Pyramid` 1.2. -- At runtime, when a request causes any route to match, the :term:`request` - object is decorated with the route-specific interface. - -- The fact that the request is decorated with a route-specific interface - causes the :term:`view lookup` machinery to always use the view callable - registered using that interface by the route configuration to service - requests that match the route pattern. - -As we can see from the above description, technically, URL dispatch doesn't -actually map a URL pattern directly to a view callable. Instead, URL -dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` -:term:`resource location` subsystem (i.e., :term:`URL dispatch` or -:term:`traversal`) finds a :term:`resource` object that is the -:term:`context` of a :term:`request`. Once the :term:`context` is determined, -a separate subsystem named :term:`view lookup` is then responsible for -finding and invoking a :term:`view callable` based on information available -in the context and the request. When URL dispatch is used, the resource -location and view lookup subsystems provided by :app:`Pyramid` are still -being utilized, but in a way which does not require a developer to understand -either of them in detail. - -If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back -to :term:`traversal` to handle the :term:`request`. - -.. _route_prefix: - -Using a Route Prefix to Compose Applications --------------------------------------------- - -.. note:: This feature is new as of :app:`Pyramid` 1.2. - -The :meth:`pyramid.config.Configurator.include` method allows configuration -statements to be included from separate files. See -:ref:`building_an_extensible_app` for information about this method. Using -:meth:`pyramid.config.Configurator.include` allows you to build your -application from small and potentially reusable components. +The :meth:`pyramid.config.Configurator.include` method allows configuration +statements to be included from separate files. See +:ref:`building_an_extensible_app` for information about this method. Using +:meth:`pyramid.config.Configurator.include` allows you to build your +application from small and potentially reusable components. The :meth:`pyramid.config.Configurator.include` method accepts an argument named ``route_prefix`` which can be useful to authors of URL-dispatch-based @@ -1171,6 +863,268 @@ that may be added in the future. For example: config = Configurator() config.include(users_include, route_prefix='/users') +.. index:: + single: route predicates (custom) + +.. _custom_route_predicates: + +Custom Route Predicates +----------------------- + +Each of the predicate callables fed to the ``custom_predicates`` argument of +:meth:`~pyramid.config.Configurator.add_route` must be a callable accepting +two arguments. The first argument passed to a custom predicate is a +dictionary conventionally named ``info``. The second argument is the current +:term:`request` object. + +The ``info`` dictionary has a number of contained values: ``match`` is a +dictionary: it represents the arguments matched in the URL by the route. +``route`` is an object representing the route which was matched (see +:class:`pyramid.interfaces.IRoute` for the API of such a route object). + +``info['match']`` is useful when predicates need access to the route match. +For example: + +.. code-block:: python + :linenos: + + def any_of(segment_name, *allowed): + def predicate(info, request): + if info['match'][segment_name] in allowed: + return True + return predicate + + num_one_two_or_three = any_of('num', 'one', 'two', 'three') + + config.add_route('route_to_num', '/{num}', + custom_predicates=(num_one_two_or_three,)) + +The above ``any_of`` function generates a predicate which ensures that the +match value named ``segment_name`` is in the set of allowable values +represented by ``allowed``. We use this ``any_of`` function to generate a +predicate function named ``num_one_two_or_three``, which ensures that the +``num`` segment is one of the values ``one``, ``two``, or ``three`` , and use +the result as a custom predicate by feeding it inside a tuple to the +``custom_predicates`` argument to +:meth:`~pyramid.config.Configurator.add_route`. + +A custom route predicate may also *modify* the ``match`` dictionary. For +instance, a predicate might do some type conversion of values: + +.. code-block:: python + :linenos: + + def integers(*segment_names): + def predicate(info, request): + match = info['match'] + for segment_name in segment_names: + try: + match[segment_name] = int(match[segment_name]) + except (TypeError, ValueError): + pass + return True + return predicate + + ymd_to_int = integers('year', 'month', 'day') + + config.add_route('ymd', '/{year}/{month}/{day}', + custom_predicates=(ymd_to_int,)) + +Note that a conversion predicate is still a predicate so it must return +``True`` or ``False``; a predicate that does *only* conversion, such as the +one we demonstrate above should unconditionally return ``True``. + +To avoid the try/except uncertainty, the route pattern can contain regular +expressions specifying requirements for that marker. For instance: + +.. code-block:: python + :linenos: + + def integers(*segment_names): + def predicate(info, request): + match = info['match'] + for segment_name in segment_names: + match[segment_name] = int(match[segment_name]) + return True + return predicate + + ymd_to_int = integers('year', 'month', 'day') + + config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', + custom_predicates=(ymd_to_int,)) + +Now the try/except is no longer needed because the route will not match at +all unless these markers match ``\d+`` which requires them to be valid digits +for an ``int`` type conversion. + +The ``match`` dictionary passed within ``info`` to each predicate attached to +a route will be the same dictionary. Therefore, when registering a custom +predicate which modifies the ``match`` dict, the code registering the +predicate should usually arrange for the predicate to be the *last* custom +predicate in the custom predicate list. Otherwise, custom predicates which +fire subsequent to the predicate which performs the ``match`` modification +will receive the *modified* match dictionary. + +.. warning:: + + It is a poor idea to rely on ordering of custom predicates to build a + conversion pipeline, where one predicate depends on the side effect of + another. For instance, it's a poor idea to register two custom + predicates, one which handles conversion of a value to an int, the next + which handles conversion of that integer to some custom object. Just do + all that in a single custom predicate. + +The ``route`` object in the ``info`` dict is an object that has two useful +attributes: ``name`` and ``pattern``. The ``name`` attribute is the route +name. The ``pattern`` attribute is the route pattern. An example of using +the route in a set of route predicates: + +.. code-block:: python + :linenos: + + def twenty_ten(info, request): + if info['route'].name in ('ymd', 'ym', 'y'): + return info['match']['year'] == '2010' + + config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) + config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) + config.add_route('ymd', '/{year}/{month}/{day}', + custom_predicates=(twenty_ten,)) + +The above predicate, when added to a number of route configurations ensures +that the year match argument is '2010' if and only if the route name is +'ymd', 'ym', or 'y'. + +See also :class:`pyramid.interfaces.IRoute` for more API documentation about +route objects. + +.. index:: + single: route factory + +.. _route_factories: + +Route Factories +--------------- + +Although it is not a particular common need in basic applications, a "route" +configuration declaration can mention a "factory". When that route matches a +request, and a factory is attached to a route, the :term:`root factory` +passed at startup time to the :term:`Configurator` is ignored; instead the +factory associated with the route is used to generate a :term:`root` object. +This object will usually be used as the :term:`context` resource of the view +callable ultimately found via :term:`view lookup`. + +.. code-block:: python + :linenos: + + config.add_route('abc', '/abc', + factory='myproject.resources.root_factory') + config.add_view('myproject.views.theview', route_name='abc') + +The factory can either be a Python object or a :term:`dotted Python name` (a +string) which points to such a Python object, as it is above. + +In this way, each route can use a different factory, making it possible to +supply a different :term:`context` resource object to the view related to +each particular route. + +Supplying a different resource factory for each route is useful when you're +trying to use a :app:`Pyramid` :term:`authorization policy` to provide +declarative, "context sensitive" security checks; each resource can maintain +a separate :term:`ACL`, as documented in +:ref:`using_security_with_urldispatch`. It is also useful when you wish to +combine URL dispatch with :term:`traversal` as documented within +:ref:`hybrid_chapter`. + +.. index:: + pair: URL dispatch; security + +.. _using_security_with_urldispatch: + +Using :app:`Pyramid` Security With URL Dispatch +-------------------------------------------------- + +:app:`Pyramid` provides its own security framework which consults an +:term:`authorization policy` before allowing any application code to be +called. This framework operates in terms of an access control list, which is +stored as an ``__acl__`` attribute of a resource object. A common thing to +want to do is to attach an ``__acl__`` to the resource object dynamically for +declarative security purposes. You can use the ``factory`` argument that +points at a factory which attaches a custom ``__acl__`` to an object at its +creation time. + +Such a ``factory`` might look like so: + +.. code-block:: python + :linenos: + + class Article(object): + def __init__(self, request): + matchdict = request.matchdict + article = matchdict.get('article', None) + if article == '1': + self.__acl__ = [ (Allow, 'editor', 'view') ] + +If the route ``archives/{article}`` is matched, and the article number is +``1``, :app:`Pyramid` will generate an ``Article`` :term:`context` resource +with an ACL on it that allows the ``editor`` principal the ``view`` +permission. Obviously you can do more generic things than inspect the routes +match dict to see if the ``article`` argument matches a particular string; +our sample ``Article`` factory class is not very ambitious. + +.. note:: See :ref:`security_chapter` for more information about + :app:`Pyramid` security and ACLs. + +.. index:: + pair: route; view callable lookup details + +Route View Callable Registration and Lookup Details +--------------------------------------------------- + +When a request enters the system which matches the pattern of the route, the +usual result is simple: the view callable associated with the route is +invoked with the request that caused the invocation. + +For most usage, you needn't understand more than this; how it works is an +implementation detail. In the interest of completeness, however, we'll +explain how it *does* work in the this section. You can skip it if you're +uninterested. + +When a view is associated with a route configuration, :app:`Pyramid` ensures +that a :term:`view configuration` is registered that will always be found +when the route pattern is matched during a request. To do so: + +- A special route-specific :term:`interface` is created at startup time for + each route configuration declaration. + +- When an ``add_view`` statement mentions a ``route name`` attribute, a + :term:`view configuration` is registered at startup time. This view + configuration uses a route-specific interface as a :term:`request` type. + +- At runtime, when a request causes any route to match, the :term:`request` + object is decorated with the route-specific interface. + +- The fact that the request is decorated with a route-specific interface + causes the :term:`view lookup` machinery to always use the view callable + registered using that interface by the route configuration to service + requests that match the route pattern. + +As we can see from the above description, technically, URL dispatch doesn't +actually map a URL pattern directly to a view callable. Instead, URL +dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` +:term:`resource location` subsystem (i.e., :term:`URL dispatch` or +:term:`traversal`) finds a :term:`resource` object that is the +:term:`context` of a :term:`request`. Once the :term:`context` is determined, +a separate subsystem named :term:`view lookup` is then responsible for +finding and invoking a :term:`view callable` based on information available +in the context and the request. When URL dispatch is used, the resource +location and view lookup subsystems provided by :app:`Pyramid` are still +being utilized, but in a way which does not require a developer to understand +either of them in detail. + +If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back +to :term:`traversal` to handle the :term:`request`. + References ---------- diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 106024db3..21c368350 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -310,6 +310,53 @@ Python's ``urllib2`` instead of a Javascript AJAX request: req = urllib2.Request('http://localhost:6543/', json_payload, headers) resp = urllib2.urlopen(req) +.. index:: + single: cleaning up after request + +.. _cleaning_up_after_a_request: + +Cleaning Up After a Request ++++++++++++++++++++++++++++ + +Sometimes it's required that some cleanup be performed at the end of a +request when a database connection is involved. + +For example, let's say you have a ``mypackage`` :app:`Pyramid` application +package that uses SQLAlchemy, and you'd like the current SQLAlchemy database +session to be removed after each request. Put the following in the +``mypackage.__init__`` module: + +.. ignore-next-block +.. code-block:: python + :linenos: + + from mypackage.models import DBSession + + from pyramid.events import subscriber + from pyramid.events import NewRequest + + def cleanup_callback(request): + DBSession.remove() + + @subscriber(NewRequest) + def add_cleanup_callback(event): + event.request.add_finished_callback(cleanup_callback) + +Registering the ``cleanup_callback`` finished callback at the start of a +request (by causing the ``add_cleanup_callback`` to receive a +:class:`pyramid.events.NewRequest` event at the start of each request) will +cause the DBSession to be removed whenever request processing has ended. +Note that in the example above, for the :class:`pyramid.events.subscriber` +decorator to "work", the :meth:`pyramid.config.Configurator.scan` method must +be called against your ``mypackage`` package during application +initialization. + +.. note:: This is only an example. In particular, it is not necessary to + cause ``DBSession.remove`` to be called in an application generated from + any :app:`Pyramid` scaffold, because these all use the ``pyramid_tm`` + package. The cleanup done by ``DBSession.remove`` is unnecessary when + ``pyramid_tm`` middleware is configured into the application. + More Details ++++++++++++ -- cgit v1.2.3 From bb93cbdf16ac03e354569959663d053a68685fc5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 05:56:14 -0400 Subject: add squishy whats-unique section to introduction --- docs/narr/introduction.rst | 467 ++++++++++++++++++++++++++++++++++++++++++++- docs/narr/security.rst | 2 + docs/narr/urldispatch.rst | 2 + docs/narr/viewconfig.rst | 2 + 4 files changed, 470 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 97f63fcfe..5524f698d 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -52,20 +52,481 @@ Documentation Speed :app:`Pyramid` is designed to provide noticeably fast execution for common - tasks such as templating and simple response generation. Although “hardware + tasks such as templating and simple response generation. Although "hardware is cheap", the limits of this approach become painfully evident when one finds him or herself responsible for managing a great many machines. Reliability :app:`Pyramid` is developed conservatively and tested exhaustively. Where Pyramid source code is concerned, our motto is: "If it ain’t tested, it’s - broke". Every release of Pyramid has 100% statement coverage via unit - tests. + broke". Openness As with Python, the Pyramid software is distributed under a `permissive open source license `_. +What Makes Pyramid Unique +------------------------- + +Understandably, people don't usually want to hear about squishy engineering +principles, they want to hear about concrete stuff that solves their +problems. With that in mind, what would make someone want to use Pyramid +instead of the dozens-of-odd other web frameworks available today? What +makes Pyramid unique? + +This is a hard question to answer, because there are lots of excellent +choices, and it's actually quite hard to make a wrong choice, particularly in +the Python web framework market. But one reasonable answer is this: you can +write very small applications in Pyramid without needing to know a lot. +"What?", you say, "that can't possibly be a unique feature, lots of other web +frameworks let you do that!" Well, you're right. But unlike many other +systems, you can also write very large applications in Pyramid if you learn a +little more about it. Pyramid will allow you to become productive quickly, +and will grow with you; it won't hold you back when your application is small +and it won't get in your way when your application becomes large. "Well +that's fine," you say, "lots of other frameworks let me write large apps +too." Absolutely. But other Python web frameworks don't seamlessly let you +do both. They seem to fall into two non-overlapping categories: frameworks +for "small apps" and frameworks for "big apps". The "small app" frameworks +typically sacrifice "big app" features, and vice versa. + +We don't think it's a universally reasonable suggestion to write "small apps" +in a "small framework" and "big apps" in a "big framework". You can't really +know what size every application will eventually grow to. We don't really +want to have to rewrite a previously small application in another framework +when it gets "too big". We believe the current binary distinction between +"small" and "large" frameworks is just false; one framework should be able to +be good at both if it's well-designed. Pyramid is such a framework. + +To this end, Pyramid provides a set of features, that, combined, are unique +amongst Python web frameworks. Lots of other frameworks contain some +combination of these features; Pyramid of course actually stole many of them +from those other frameworks. But Pyramid is the only one that has all of +them in one place, documented appropriately, and useful ala-carte without +necessarily paying for the entire banquet. These are detailed below. + +Single-File Applications +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can write a Pyramid application that lives entirely in one Python file, +not unlike existing Python microframeworks. This is beneficial for "one off" +prototyping, bug reproduction, and very small applications. These +applications are easy to understand because all the information about the +application lives in a single place, and you can deploy them without needing +to understand much about Python distributions and packaging. Pyramid isn't +really marketed as a "microframework", but it allows you to do almost +everything that frameworks that are marketed as "micro" offer in very similar +ways. + +Example: :ref:`firstapp_chapter`. + +Decorator-Based Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you like the idea of framework configuration statements living next to the +code it configures, so you don't have to constantly switch between files to +refer to framework configuration when adding new code, you can use Pyramid +decorators to localize the configuration. For example:: + + @view_config(route_name='fred') + def fred_view(request): + return Response('fred') + +However, unlike other systems (various "microframeworks" come to mind), using +decorators for configuration does not make your application difficult, +extend, test or reuse. The ``view_config`` decorator, for example, does not +actually *change* the input or output of the function it decorates, so +testing it is a "WYSIWYG" operation; you don't need to understand the +framework to test your own code, you just behave as if the decorator is not +there. You can also instruct Pyramid to ignore some decorators, or use +completely imperative configuration instead of decorators to add views. +Pyramid decorators are inert instead of eager: you detect and activate them +with a ``scan``. They're basically just markers. + +Example: :ref:`mapping_views_using_a_decorator_section`. + +URL Generation +~~~~~~~~~~~~~~ + +Pyramid is capable of generating URLs for resources, routes, and static +assets. Its URL generation APIs are easy to use and flexible. If you use +Pyramid's various APIs for generating URLs, you can change your configuration +around arbitrarily without fear of breaking a link on one of your web pages. + +Example: :ref:`generating_route_urls`. + +Static file serving +~~~~~~~~~~~~~~~~~~~ + +Pyramid is perfectly willing to serve static files itself. It won't make you +use some external web server to do that. You can even serve more than one +set of static files in a single Pyramid web application (e.g. ``/static`` and +``/static2``). You can also, optionally, place your files on an external web +server and ask Pyramid to help you generate URLs to those files, so you can +use Pyramid's internal fileserving while doing development, and a faster +static file server in production without changing any code. + +Example: :ref:`static_assets_section`. + +Debug Toolbar +~~~~~~~~~~~~~ + +Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to +render a project. This toolbar overlays your application in the browser, and +allows you access to framework data such as the routes configured, the last +renderings performed, the current set of packages installed, SQLAlchemy +queries run, logging data, and various other facts. When an exception +occurs, you can use its interactive debugger to poke around right in your +browser to try to determine the cause of the exception. It's handy. + +Example: :ref:`debug_toolbar`. + +Debugging settings +~~~~~~~~~~~~~~~~~~ + +Pyramid has debugging settings that allow you to print Pyramid runtime +information to the console when things aren't behaving as you're expecting. +For example, you can turn on "debug_notfound", which prints an informative +message to the console every time a URL does not match any view. You can +turn on "debug_authorization", which lets you know why a view execution was +allowed or denied by printing a message to the console. These features are +useful for those WTF moments. + +There are also a number of ``paster`` commands that allow you to introspect +the configuration of your system: ``paster proutes`` shows all configured +routes for an application in the order they'll be evaluated for matching; +``paster pviews`` shows all configured views for any given URL. These are +also WTF-crushers in some circumstances. + +Example: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. + +Class-Based and Function-Based Views +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured, unified conception of views. Views can be +functions, methods of classes, or even instances. When you add a new view, +you can choose to make it a function or a method of a class; in either case, +Pyramid treats it largely the same way. You can change your mind later, and +move code between methods of classes and functions. A collection of similar +view callables can be attached to a single class as methods, if that floats +your boat, and they can share initialization code as necessary. All kinds of +views are easy to understand and use and operate similarly. There is no +phony distinction between them; they can be used for the same purposes. + +Example: :ref:`view_config_placement`. + +Event system +~~~~~~~~~~~~ + +Pyramid emits *events* during its request processing lifecycle. You can +subscribe any number of listeners to these events. For example, to be +notified of a new request, you can subscribe to the ``NewRequest`` event. To +be notified that a template is about to be rendered, you can subscribe to the +``BeforeRender`` event, and so forth. Using an event publishing system as a +framework notification feature instead of hardcoded hook points tends to make +systems based on that framework less brittle. You can also use Pyramid's +event system to send your *own* events. For example, if you'd like to create +a system that is itself a framework, and may want to notify subscribers that +a document has just been indexed, you can create your own event type +(``DocumentIndexed`` perhaps) and send the event via Pyramid. Users of this +framework can then subscribe to your event like they'd subscribe to the +events that are normally sent by Pyramid itself. + +Example: :ref:`events_chapter` and :ref:`event_types`. + +Extensible templating +~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured API that allows for pluggability of "renderers". +Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated +as renderers. Renderer bindings for all of these templating systems already +exist for use in Pyramid. But if you'd rather use another, it's not a big +deal. Just copy the code from an existing renderer package, and plug in your +own. You'll then be able to use your templating system from within Pyramid +just as you'd use one of the "built-in" templating systems. + +Example: :ref:`templates_used_directly`. + +Speed +~~~~~ + +The Pyramid core is, as far as we can tell, at least marginally faster than +any other existing Python web framework. It has been engineered from the +ground up for speed. It only does as much work as absolutely necessary when +you ask it to get a job done. Extraneous function calls and suboptimal +algorithms in its core codepaths are avoided religiously. It is feasible to +get, for example, between 3500 and 4000 requests per second from a simple +Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI +server (mod_wsgi or gunicorn). In any case, performance statstics are +largely useless without requirements and goals, but if you need speed, +Pyramid will almost certainly never be your application's bottleneck; at +least no more than Python will be a bottleneck. + +Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the Beaker sessioning system that does exactly this. But +if you have a specialized need (perhaps you want to store your session data +in MongoDB), you can. You can even switch between implementations without +changing your application code. + +Example: :ref:`sessions_chapter`. + +No singletons +~~~~~~~~~~~~~ + +Pyramid is written in such a way that it has exactly zero "singleton" data +structures. Or, put another way, Pyramid constructs no "mutable globals". +Or put even a different way, an import of a Pyramid application needn't have +any "import time side effects". This is esoteric-sounding, but if you've +ever tried to cope with parameterizing a Django "settings.py" file for +multiple installations of the same application, or if you've ever needed to +monkey-patch some framework fixture so that it behaves properly for your use +case, or if you've ever wanted to deploy your system using an asynchronous +server, you'll end up appreciating this feature. It just won't be a problem. +You can even run multiple copies of a similar but not identically configured +Pyramid application within the same Python process. This is good for shared +hosting environments, where RAM is at a premium. + +View Predicates and Many Views Per Route +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unlike many other systems, Pyramid allows you to associate more than one view +per route. For example, you can create a route with the pattern ``/items`` +and when the route is matched, you can shuffle off the request to one view if +the request method is GET, another view if the request method is POST, etc. +A system known as "view predicates" allows for this. Request method matching +is the very most basic thing you can do with a view predicate. You can also +associate views with other request parameters such as the elements in the +query string, the Accept header, whether the request is an XHR request or +not, and lots of other things. This feature allows you to keep your +individual views "clean"; they won't need much conditional logic, so they'll +be easier to test. + +Example: :ref:`view_configuration_parameters`. + +Exception views +~~~~~~~~~~~~~~~ + +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register *exception views*. Exception views are like regular Pyramid views, +but they're only invoked when an exception "bubbles up" to Pyramid itself. +For example, you might register an exception view for the ``Exception`` +exception, which will catch *all* exceptions, and present a pretty "whoops, +this is embarrassing" page. Or you might choose to register an exception +view for only specific kinds of application-specific exceptions, such as an +exception that happens when a file is not found, or an exception that happens +when action cannot be performed because the user doesn't have permission to +do something. In the former case, you can show a pretty "Not Found" page; in +the latter case you might show a login form. + +Example: :ref:`exception_views`. + +Asset specifications +~~~~~~~~~~~~~~~~~~~~ + +Asset specifications are strings that contain both a Python package name and +a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. You can refer to a template using +an asset specification, a translation directory, and other package-bound +static resources using one. This makes a system built on Pyramid extensible, +because you don't have to rely on globals ("the static directory") or lookup +schemes ("the ordered set of template directories") to address your files. +You can move files around as necessary, and include other packages that may +not share your system's templates or static files without encountering +conflicts. + +Because asset specifications are used heavily in Pyramid, we've also provided +a way to allow users to override assets. Say you love a system that someone +else has created with Pyramid but you just need to change "that one template" +to make it all better. No need to fork the application. Just override the +asset specification for that template with your own inside a wrapper, and +you're good to go. + +Example: :ref:`asset_specifications`. + +Transaction management +~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid's :term:`scaffold` system renders projects that include a +*transaction management* system, also stolen from Zope. When you use this +transaction management system, you cease being responsible for committing +your data anymore. Instead, Pyramid takes care of committing: it commits at +the end of a request or aborts if there's an exception. Why is that a good +thing? Transaction boundaries are awfully hard to get right. If you add a +``session.commit`` call in your application logic, and your code goes on to +do other important things after that commit, and error happens in the later +code, sometimes, you're kind of screwed. Some data will have been written to +the database that probably should not have. Having a centralized commit +point saves you from needing to think about this. Also, Pyramid's +transaction management system allows you to synchronize commits between +multiple databases, and allows you to do things like conditionally send email +if a transaction commits, but otherwise keep quiet. + +Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements +anywhere in application code). + +Configuration conflict detection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When a system is small, it's reasonably easy to keep it in all in your head. +But when systems grow large, you may have hundreds or thousands of +configuration statements which add a view, add a route, and so forth. +Pyramid's configuration system keeps track of your configuration statements, +and if you accidentally add two that are identical, or Pyramid can't make +sense out of what it would mean to have both statements active at the same +time, it will complain loudly at startup time. It's not dumb though: it will +automatically resolve conflicting configuration statements on its own if you +use the configuration ``include`` system: "more local" statements are +preferred over "less local" ones. This allows you to intelligently factor +large systems into smaller ones. + +Example: :ref:`conflict_detection`. + +Configuration extensibility +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unlike other systems, Pyramid provides a structured ``include`` mechanism +that allows you compose applications from multiple Python packages. All the +configuration statements that can be performed in your "main" Pyramid +application can also be performed by included packages (including the +addition of views, routes, subscribers, and even authentication and +authorization policies). You can even extend or override an existing +application by including another application's configuration in your own, and +overriding or adding new views and routes to it. This has the potential to +allow you to compose a big application out of many other smaller ones. For +example, if you want to reuse an existing application that already has a +bunch of routes, you can just use the ``include`` statement with a +``route_prefix``; the new application will live within your application at a +URL prefix. It's not a big deal, and requires little up-front engineering +effort. + +Example: :ref:`building_an_extensible_app`. + +Flexible authentication and authorization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid includes a flexible, pluggable authentication and authorization +system. No matter where your user data is stored, or what scheme you'd like +to use to permit your users to access your data, you can use a predefined +Pyramid plugpoint to plug in your custom authentication and authorization +code. If you want to change these schemes later, you can just change it in +one place rather than everywhere in your code. It also ships with prebuilt +well-tested authentication and authorization schemes out of the box. But +what if you don't want to use Pyramid's built-in system? You don't have to. +You can just write your own bespoke security code as you would in any other +system. + +Example: :ref:`enabling_authorization_policy`. + +Built-in Internationalization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid ships with internalization-related features in its core: +localization, pluralization, and creating message catalogs from source files +and templates. Pyramid allows for a plurality of message catalog via the use +of translation domains: you can create a system that has its own translations +without conflict with other translations in other domains. + +Example: :ref:`i18n_chapter`. + +Traversal +~~~~~~~~~ + +:term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to +create a tree of resources, each of which can be addressed by one or more +URLs. Each of those resources can have one or more *views* associated with +it. Iif your data isn't naturally treelike (or you're unwilling to create a +treelike representation of your data), you aren't going to find traversal +very useful. However, traversal is absolutely fantastic for sites that need +to be arbitrarily extensible: it's a lot easier to add a node to a tree than +it is to shoehorn a route into an ordered list of other routes, or to create +another entire instance of an application to service a department and glue +code to allow disparate apps to share data. It's a great fit for sites that +naturally lend themselves to changing departmental hierarchies, such as CMS +systems and document management systems. Traversal also lends itself well to +systems that require very granular security ("Bob can edit *this* document" +as opposed to "Bob can edit documents"). + +Example: :ref:`much_ado_about_traversal_chapter`. + +HTTP Caching +~~~~~~~~~~~~ + +Pyramid provides an easy way to associate views with HTTP caching policies. +You can just tell Pyramid to configure your view with an ``http_cache`` +statement, and it will take care of the rest:: + + @view_config(http_cache=3600) # 60 minutes + def myview(request): .... + +Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to +responses generated when this view is invoked. + +See the :meth:`pyramid.config.Configurator.add_view` statement's +``http_cache`` documentation for more information. + +Tweens +~~~~~~ + +Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be +hooked by arbitrary add-ons named "tweens". The debug toolbar is a "tween", +and the ``pyramid_tm`` transaction manager is also. Tweens are more useful +than WSGI middleware in some circumstances because they run in the context of +Pyramid itself, meaning you have access to templates and other renderers, a +"real" request object, and other niceties. + +Example: :ref:`registering_tweens`. + +Testing +~~~~~~~ + +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.5, Python 2.6, Python 2.7, Jython and PyPy 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 find a lot fewer of them than do the owners of comparable +projects that don't test so exhaustively. + +Example: http://jenkins.pylonsproject.org/ + +Support +~~~~~~~ + +It's our goal that no Pyramid question go unanswered. Whether you ask a +question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're +likely to get a reasonaly prompt response. We don't tolerate "tech trolls" +or other people who seem to get their rocks off by berating fellow users in +our various offical support channels. We try to keep it well-lit and +new-user-friendly. + +Example: Visit irc://freenode.net#pyramid (the ``#pyramid`` channel on +irc.freenode.net in an IRC client) or the pylons-discuss maillist at +http://groups.google.com/group/pylons-discuss/ . + +Documentation +~~~~~~~~~~~~~ + +It's a constant struggle, but we try to maintain a balance between +completeness and new-user-friendliness in the official narrative Pyramid +documentation (concrete suggestions for improvement are always appreciated, +by the way). We 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 rest of this documentation. + .. index:: single: Pylons Project diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 8d30a76a7..5a18ca851 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -60,6 +60,8 @@ policies. .. index:: single: authorization policy +.. _enabling_authorization_policy: + Enabling an Authorization Policy -------------------------------- diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 0ec440f4d..52f6115eb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -590,6 +590,8 @@ Or provide the literal string ``/`` as the pattern: single: generating route URLs single: route URLs +.. _generating_route_urls: + Generating Route URLs --------------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 26cca2ad1..af5d7f242 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -504,6 +504,8 @@ configuration`. However, they both do the same thing. .. index:: single: view_config placement +.. _view_config_placement: + ``@view_config`` Placement ++++++++++++++++++++++++++ -- cgit v1.2.3 From 68a01e26af1a0a1ab448d4dad517001186d134b2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 06:09:43 -0400 Subject: more refs to root factory docs --- docs/narr/urldispatch.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 52f6115eb..ad9cc6033 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1030,6 +1030,19 @@ In this way, each route can use a different factory, making it possible to supply a different :term:`context` resource object to the view related to each particular route. +A factory must be a callable which accepts a request and returns an arbitrary +Python object. For example, the below class can be used as a factory: + +.. code-block:: python + :linenos: + + class Mine(object): + def __init__(self, request): + pass + +A route factory is actually conceptually identical to the :term:`root +factory` described at :ref:`the_resource_tree`. + Supplying a different resource factory for each route is useful when you're trying to use a :app:`Pyramid` :term:`authorization policy` to provide declarative, "context sensitive" security checks; each resource can maintain -- cgit v1.2.3 From d8fc16f447c1a9ac91a24bb41f56a534706dfe41 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 06:26:28 -0400 Subject: garden --- docs/narr/introduction.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 5524f698d..9c6f85680 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -65,6 +65,8 @@ Openness As with Python, the Pyramid software is distributed under a `permissive open source license `_. +.. _what_makes_pyramid_unique: + What Makes Pyramid Unique ------------------------- -- cgit v1.2.3 From 2bf587e2975063ae402f3d543fbbbf9dfff86383 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 06:52:22 -0400 Subject: typo --- docs/narr/introduction.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 9c6f85680..5f4e3c13b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -116,7 +116,7 @@ prototyping, bug reproduction, and very small applications. These applications are easy to understand because all the information about the application lives in a single place, and you can deploy them without needing to understand much about Python distributions and packaging. Pyramid isn't -really marketed as a "microframework", but it allows you to do almost +really marketed as a microframework, but it allows you to do almost everything that frameworks that are marketed as "micro" offer in very similar ways. @@ -134,16 +134,16 @@ decorators to localize the configuration. For example:: def fred_view(request): return Response('fred') -However, unlike other systems (various "microframeworks" come to mind), using -decorators for configuration does not make your application difficult, -extend, test or reuse. The ``view_config`` decorator, for example, does not -actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation; you don't need to understand the -framework to test your own code, you just behave as if the decorator is not -there. You can also instruct Pyramid to ignore some decorators, or use -completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager: you detect and activate them -with a ``scan``. They're basically just markers. +However, unlike some other systems, using decorators for Pyramid +configuration does not make your application difficult to extend, test or +reuse. The ``view_config`` decorator, for example, does not actually +*change* the input or output of the function it decorates, so testing it is a +"WYSIWYG" operation; you don't need to understand the framework to test your +own code, you just behave as if the decorator is not there. You can also +instruct Pyramid to ignore some decorators, or use completely imperative +configuration instead of decorators to add views. Pyramid decorators are +inert instead of eager: you detect and activate them with a ``scan``. +They're basically just markers. Example: :ref:`mapping_views_using_a_decorator_section`. -- cgit v1.2.3 From e088447d0fb4a908d1da07742301a3d01b48ade5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 12:24:29 -0400 Subject: add renderer section; fix wording (thanks jpenny) --- docs/narr/introduction.rst | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 5f4e3c13b..c39b7f440 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -73,8 +73,8 @@ What Makes Pyramid Unique Understandably, people don't usually want to hear about squishy engineering principles, they want to hear about concrete stuff that solves their problems. With that in mind, what would make someone want to use Pyramid -instead of the dozens-of-odd other web frameworks available today? What -makes Pyramid unique? +instead of one of the many other web frameworks available today? What makes +Pyramid unique? This is a hard question to answer, because there are lots of excellent choices, and it's actually quite hard to make a wrong choice, particularly in @@ -97,8 +97,9 @@ in a "small framework" and "big apps" in a "big framework". You can't really know what size every application will eventually grow to. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -"small" and "large" frameworks is just false; one framework should be able to -be good at both if it's well-designed. Pyramid is such a framework. +"small" and "large" frameworks is just false; a well-designed framework +should be able to be good at both. Pyramid strives to be that kind of +framework. To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some @@ -217,6 +218,19 @@ phony distinction between them; they can be used for the same purposes. Example: :ref:`view_config_placement`. +Views can return dictionaries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you use a :term:`renderer`, you don't have to return a special kind of +"webby" ``Response`` object from a view. Instead, you can return a +dictionary instead, and Pyramid will take care of converting that dictionary +to a Response using a template of your behalf. This makes the view easier +to test, because you don't have to parse HTML in your tests; just make an +assertion instead that the view returns "the right stuff" in the dictionary +it returns. + +Example: :ref:`renderers_chapter`. + Event system ~~~~~~~~~~~~ -- cgit v1.2.3 From 31dc8d526dc58bf56179d6a7417a83fefdc7f475 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 12:43:17 -0400 Subject: misspelling --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index c39b7f440..eefac9812 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -105,7 +105,7 @@ To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features; Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful ala-carte without +them in one place, documented appropriately, and useful a la carte without necessarily paying for the entire banquet. These are detailed below. Single-File Applications -- cgit v1.2.3 From 1bca77cc705622da6aa1b163917a22f35e8c01d3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 12:45:28 -0400 Subject: chronology --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index eefac9812..a672c82ad 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -372,7 +372,7 @@ Transaction management ~~~~~~~~~~~~~~~~~~~~~~ Pyramid's :term:`scaffold` system renders projects that include a -*transaction management* system, also stolen from Zope. When you use this +*transaction management* system, stolen from Zope. When you use this transaction management system, you cease being responsible for committing your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good -- cgit v1.2.3 From 397f25da241db06d8cbe4fbcfc5e65d5e7dc00ff Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 13:57:17 -0400 Subject: de-theify --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a672c82ad..d93a9c54d 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -270,7 +270,7 @@ The Pyramid core is, as far as we can tell, at least marginally faster than any other existing Python web framework. It has been engineered from the ground up for speed. It only does as much work as absolutely necessary when you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are avoided religiously. It is feasible to +algorithms in its core codepaths are studiously avoided. It is feasible to get, for example, between 3500 and 4000 requests per second from a simple Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI server (mod_wsgi or gunicorn). In any case, performance statstics are -- cgit v1.2.3 From b1d3065aad02204b2d2fe38976018bdc4ddd0c9d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 14:24:59 -0400 Subject: avoid needless generic comparison --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d93a9c54d..6e28500d1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -511,8 +511,8 @@ greater than 95% decision/condition coverage as measured by the Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy 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 find a lot fewer of them than do the owners of comparable -projects that don't test so exhaustively. +add-ons, but we find a lot fewer of them than if we didn't have a strict +testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From 5962195498f53a349b101c9c8ca19daa9c1c9972 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 14:41:10 -0400 Subject: wording --- docs/narr/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 6e28500d1..b7721f186 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -94,12 +94,12 @@ typically sacrifice "big app" features, and vice versa. We don't think it's a universally reasonable suggestion to write "small apps" in a "small framework" and "big apps" in a "big framework". You can't really -know what size every application will eventually grow to. We don't really +know to what size every application will eventually grow. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -"small" and "large" frameworks is just false; a well-designed framework -should be able to be good at both. Pyramid strives to be that kind of -framework. +frameworks for small and large applications is just false; a well-designed +framework should be able to be good at both. Pyramid strives to be that kind +of framework. To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some -- cgit v1.2.3 From bdebfb826ebee25f7f8358b89761429ca89ec249 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 15:03:25 -0400 Subject: wording --- docs/narr/introduction.rst | 103 ++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 47 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b7721f186..87617989a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -129,7 +129,12 @@ Decorator-Based Configuration If you like the idea of framework configuration statements living next to the code it configures, so you don't have to constantly switch between files to refer to framework configuration when adding new code, you can use Pyramid -decorators to localize the configuration. For example:: +decorators to localize the configuration. For example: + +.. code-block:: python + + from pyramid.view import view_config + from pyramid.response import Response @view_config(route_name='fred') def fred_view(request): @@ -137,14 +142,14 @@ decorators to localize the configuration. For example:: However, unlike some other systems, using decorators for Pyramid configuration does not make your application difficult to extend, test or -reuse. The ``view_config`` decorator, for example, does not actually -*change* the input or output of the function it decorates, so testing it is a -"WYSIWYG" operation; you don't need to understand the framework to test your -own code, you just behave as if the decorator is not there. You can also -instruct Pyramid to ignore some decorators, or use completely imperative -configuration instead of decorators to add views. Pyramid decorators are -inert instead of eager: you detect and activate them with a ``scan``. -They're basically just markers. +reuse. The :class:`~pyramid.view.view_config` decorator, for example, does +not actually *change* the input or output of the function it decorates, so +testing it is a "WYSIWYG" operation; you don't need to understand the +framework to test your own code, you just behave as if the decorator is not +there. You can also instruct Pyramid to ignore some decorators, or use +completely imperative configuration instead of decorators to add views. +Pyramid decorators are inert instead of eager: you detect and activate them +with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. @@ -206,15 +211,16 @@ Example: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid has a structured, unified conception of views. Views can be -functions, methods of classes, or even instances. When you add a new view, -you can choose to make it a function or a method of a class; in either case, -Pyramid treats it largely the same way. You can change your mind later, and -move code between methods of classes and functions. A collection of similar -view callables can be attached to a single class as methods, if that floats -your boat, and they can share initialization code as necessary. All kinds of -views are easy to understand and use and operate similarly. There is no -phony distinction between them; they can be used for the same purposes. +Pyramid has a structured, unified conception of a :term:`view callable`. +View callables can be functions, methods of classes, or even instances. When +you add a new view callable, you can choose to make it a function or a method +of a class; in either case, Pyramid treats it largely the same way. You can +change your mind later, and move code between methods of classes and +functions. A collection of similar view callables can be attached to a +single class as methods, if that floats your boat, and they can share +initialization code as necessary. All kinds of views are easy to understand +and use and operate similarly. There is no phony distinction between them; +they can be used for the same purposes. Example: :ref:`view_config_placement`. @@ -224,10 +230,11 @@ Views can return dictionaries If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a dictionary instead, and Pyramid will take care of converting that dictionary -to a Response using a template of your behalf. This makes the view easier -to test, because you don't have to parse HTML in your tests; just make an +to a Response using a template on your behalf. This makes the view easier to +test, because you don't have to parse HTML in your tests; just make an assertion instead that the view returns "the right stuff" in the dictionary -it returns. +it returns. You can write "real" unit tests instead of functionally testing +all of your views. Example: :ref:`renderers_chapter`. @@ -240,13 +247,14 @@ notified of a new request, you can subscribe to the ``NewRequest`` event. To be notified that a template is about to be rendered, you can subscribe to the ``BeforeRender`` event, and so forth. Using an event publishing system as a framework notification feature instead of hardcoded hook points tends to make -systems based on that framework less brittle. You can also use Pyramid's -event system to send your *own* events. For example, if you'd like to create -a system that is itself a framework, and may want to notify subscribers that -a document has just been indexed, you can create your own event type -(``DocumentIndexed`` perhaps) and send the event via Pyramid. Users of this -framework can then subscribe to your event like they'd subscribe to the -events that are normally sent by Pyramid itself. +systems based on that framework less brittle. + +You can also use Pyramid's event system to send your *own* events. For +example, if you'd like to create a system that is itself a framework, and may +want to notify subscribers that a document has just been indexed, you can +create your own event type (``DocumentIndexed`` perhaps) and send the event +via Pyramid. Users of this framework can then subscribe to your event like +they'd subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. @@ -258,8 +266,9 @@ Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated as renderers. Renderer bindings for all of these templating systems already exist for use in Pyramid. But if you'd rather use another, it's not a big deal. Just copy the code from an existing renderer package, and plug in your -own. You'll then be able to use your templating system from within Pyramid -just as you'd use one of the "built-in" templating systems. +favorite templating system. You'll then be able to use that templating +system from within Pyramid just as you'd use one of the "built-in" templating +systems. Example: :ref:`templates_used_directly`. @@ -270,13 +279,13 @@ The Pyramid core is, as far as we can tell, at least marginally faster than any other existing Python web framework. It has been engineered from the ground up for speed. It only does as much work as absolutely necessary when you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are studiously avoided. It is feasible to -get, for example, between 3500 and 4000 requests per second from a simple -Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI -server (mod_wsgi or gunicorn). In any case, performance statstics are -largely useless without requirements and goals, but if you need speed, -Pyramid will almost certainly never be your application's bottleneck; at -least no more than Python will be a bottleneck. +algorithms in its core codepaths are avoided. It is feasible to get, for +example, between 3500 and 4000 requests per second from a simple Pyramid view +on commodity dual-core laptop hardware and an appropriate WSGI server +(mod_wsgi or gunicorn). In any case, performance statstics are largely +useless without requirements and goals, but if you need speed, Pyramid will +almost certainly never be your application's bottleneck; at least no more +than Python will be a bottleneck. Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ @@ -287,10 +296,10 @@ Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But Pyramid also allows you to plug in your own sessioning system by creating some code that adheres to a documented interface. Currently there is a -binding package for the Beaker sessioning system that does exactly this. But -if you have a specialized need (perhaps you want to store your session data -in MongoDB), you can. You can even switch between implementations without -changing your application code. +binding package for the third-part Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. Example: :ref:`sessions_chapter`. @@ -511,8 +520,8 @@ greater than 95% decision/condition coverage as measured by the Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy 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 find a lot fewer of them than if we didn't have a strict -testing regime. +add-ons, but we've noticed we find a lot fewer of them than while working on +other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ @@ -521,10 +530,10 @@ Support It's our goal that no Pyramid question go unanswered. Whether you ask a question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're -likely to get a reasonaly prompt response. We don't tolerate "tech trolls" -or other people who seem to get their rocks off by berating fellow users in -our various offical support channels. We try to keep it well-lit and -new-user-friendly. +likely to get a reasonably prompt response. We don't tolerate "support +trolls" or other people who seem to get their rocks off by berating fellow +users in our various offical support channels. We try to keep it well-lit +and new-user-friendly. Example: Visit irc://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at -- cgit v1.2.3 From 77ef3b0d26357ba36f5577924b0bef0b3365d1a6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 15:24:22 -0400 Subject: wording --- docs/narr/introduction.rst | 80 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 87617989a..d23a1f22f 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -341,16 +341,16 @@ Exception views Exceptions happen. Rather than deal with exceptions that might present themselves to a user in production in an ad-hoc way, Pyramid allows you to -register *exception views*. Exception views are like regular Pyramid views, -but they're only invoked when an exception "bubbles up" to Pyramid itself. -For example, you might register an exception view for the ``Exception`` -exception, which will catch *all* exceptions, and present a pretty "whoops, -this is embarrassing" page. Or you might choose to register an exception -view for only specific kinds of application-specific exceptions, such as an -exception that happens when a file is not found, or an exception that happens -when action cannot be performed because the user doesn't have permission to -do something. In the former case, you can show a pretty "Not Found" page; in -the latter case you might show a login form. +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. Example: :ref:`exception_views`. @@ -385,15 +385,16 @@ Pyramid's :term:`scaffold` system renders projects that include a transaction management system, you cease being responsible for committing your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good -thing? Transaction boundaries are awfully hard to get right. If you add a -``session.commit`` call in your application logic, and your code goes on to -do other important things after that commit, and error happens in the later -code, sometimes, you're kind of screwed. Some data will have been written to -the database that probably should not have. Having a centralized commit -point saves you from needing to think about this. Also, Pyramid's -transaction management system allows you to synchronize commits between -multiple databases, and allows you to do things like conditionally send email -if a transaction commits, but otherwise keep quiet. +thing? Having a centralized place for transaction management is a great +thing. If you instead add a ``session.commit`` call in your application +logic itself, and your code goes on to do other important things after that +commit, and error happens in the later code, you can easily wind up in a bad +place. Some data will have been written to the database that probably should +not have. Having a centralized commit point saves you from needing to think +about this. Also, Pyramid's transaction management system allows you to +synchronize commits between multiple databases, and allows you to do things +like conditionally send email if a transaction commits, but otherwise keep +quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements anywhere in application code). @@ -409,29 +410,29 @@ and if you accidentally add two that are identical, or Pyramid can't make sense out of what it would mean to have both statements active at the same time, it will complain loudly at startup time. It's not dumb though: it will automatically resolve conflicting configuration statements on its own if you -use the configuration ``include`` system: "more local" statements are -preferred over "less local" ones. This allows you to intelligently factor -large systems into smaller ones. +use the configuration :meth:`~pyramid.config.Configurator.include` system: +"more local" statements are preferred over "less local" ones. This allows +you to intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. Configuration extensibility ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Unlike other systems, Pyramid provides a structured ``include`` mechanism -that allows you compose applications from multiple Python packages. All the -configuration statements that can be performed in your "main" Pyramid -application can also be performed by included packages (including the -addition of views, routes, subscribers, and even authentication and -authorization policies). You can even extend or override an existing -application by including another application's configuration in your own, and -overriding or adding new views and routes to it. This has the potential to -allow you to compose a big application out of many other smaller ones. For -example, if you want to reuse an existing application that already has a -bunch of routes, you can just use the ``include`` statement with a -``route_prefix``; the new application will live within your application at a -URL prefix. It's not a big deal, and requires little up-front engineering -effort. +Unlike other systems, Pyramid provides a structured "include" mechanism (see +:meth:`~pyramid.config.Configurator.include`) that allows you compose +applications from multiple Python packages. All the configuration statements +that can be performed in your "main" Pyramid application can also be +performed by included packages (including the addition of views, routes, +subscribers, and even authentication and authorization policies). You can +even extend or override an existing application by including another +application's configuration in your own, and overriding or adding new views +and routes to it. This has the potential to allow you to compose a big +application out of many other smaller ones. For example, if you want to +reuse an existing application that already has a bunch of routes, you can +just use the ``include`` statement with a ``route_prefix``; the new +application will live within your application at a URL prefix. It's not a +big deal, and requires little up-front engineering effort. Example: :ref:`building_an_extensible_app`. @@ -468,7 +469,7 @@ Traversal :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to create a tree of resources, each of which can be addressed by one or more URLs. Each of those resources can have one or more *views* associated with -it. Iif your data isn't naturally treelike (or you're unwilling to create a +it. If your data isn't naturally treelike (or you're unwilling to create a treelike representation of your data), you aren't going to find traversal very useful. However, traversal is absolutely fantastic for sites that need to be arbitrarily extensible: it's a lot easier to add a node to a tree than @@ -495,7 +496,7 @@ statement, and it will take care of the rest:: Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to responses generated when this view is invoked. -See the :meth:`pyramid.config.Configurator.add_view` statement's +See the :meth:`~pyramid.config.Configurator.add_view` method's ``http_cache`` documentation for more information. Tweens @@ -550,7 +551,8 @@ demonstrations of common integration scenarios, too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The rest of this documentation. +Example: The rest of this documentation and the cookbook at +https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . .. index:: single: Pylons Project -- cgit v1.2.3 From 368667432ded483434cabdf6bb46809bee73f05f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 18:31:42 -0400 Subject: add add_directive example --- docs/narr/introduction.rst | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d23a1f22f..ab76408af 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -434,6 +434,59 @@ just use the ``include`` statement with a ``route_prefix``; the new application will live within your application at a URL prefix. It's not a big deal, and requires little up-front engineering effort. +Does Pyramid's configurator allow you to do something, but you just want it a +little less verbose? Or you'd like to offer up some handy configuration +feature to other Pyramid users without requiring that we change Pyramid? You +can extend Pyramid's :term:`Configurator` with your own directives. For +example, let's say you find yourself doing this a lot: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + config = Configurator() + config.add_route('xhr_route', '/xhr/{id}') + config.add_view('my.package.GET_view', route_name='xhr_route', + xhr=True, permission='view', request_method='GET') + config.add_view('my.package.POST_view', route_name='xhr_route', + xhr=True, permission='view', request_method='POST') + config.add_view('my.package.HEAD_view', route_name='xhr_route', + xhr=True, permission='view', request_method='HEAD') + +Pretty tedious right? You can add a directive to the Pyramid configurator to +automate some of the tedium away: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def add_protected_xhr_views(config, module): + module = config.maybe_dotted(module) + for method in ('GET', 'POST', 'HEAD'): + view = getattr(module, 'xhr_%s_view' % method, None) + if view is not None: + config.add_view(view, route_name='xhr_route', xhr=True, + permission='view', request_method=method) + + config = Configurator() + config.add_directive('add_protected_xhr_views', add_protected_xhr_views) + +Once that's done, you can call the directive you've just added as a method of +the Configurator object: + +.. code-block:: python + :linenos: + + config.add_route('xhr_route', '/xhr/{id}') + config.add_protected_xhr_views('my.package') + +You can share your configuration code with others this way too by packaging +it up and calling :meth:`~pyramid.config.Configurator.add_directive` from +within a function called when another user uses the +:meth:`~pyramid.config.Configurator.include` method against your code. + Example: :ref:`building_an_extensible_app`. Flexible authentication and authorization -- cgit v1.2.3 From 6e5ab83429c3a4be37d71fe527b247f1270251a2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 18:34:28 -0400 Subject: add references --- docs/narr/introduction.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index ab76408af..1d5cc3711 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -487,7 +487,8 @@ it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the :meth:`~pyramid.config.Configurator.include` method against your code. -Example: :ref:`building_an_extensible_app`. +Examples: :ref:`building_an_extensible_app`, :ref:`including_configuration` +and :ref:`add_directive`. Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 85ac6b046b89a292e6bd383500fcb04ce6184058 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 19:18:51 -0400 Subject: add code examples --- docs/narr/introduction.rst | 132 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 1d5cc3711..a620e9505 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -224,8 +224,8 @@ they can be used for the same purposes. Example: :ref:`view_config_placement`. -Views can return dictionaries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Rendered views can return dictionaries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a @@ -236,6 +236,28 @@ assertion instead that the view returns "the right stuff" in the dictionary it returns. You can write "real" unit tests instead of functionally testing all of your views. +For example, instead of: + +.. code-block:: python + :linenos: + + from pyramid.renderers import render_to_response + + def myview(request): + return render_to_response('myapp:templates/mytemplate.pt', {'a':1}, + request=request) + +You can do this: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + @view_config(renderer='myapp:templates/mytemplate.pt') + def myview(request): + return {'a':1} + Example: :ref:`renderers_chapter`. Event system @@ -354,6 +376,112 @@ Found" page; in the latter case you might show a login form. Example: :ref:`exception_views`. +View Response Adapters +---------------------- + +A lot is made of the aesthetics of what *kind* of objects you're allowed to +return from view callables in various frameworks. Some frameworks allow +you return strings or tuples from view callables, and they make much of it. +When frameworks allow for this, code looks slightly prettier, because fewer +imports need to be done, and there is less code. For example, compare this: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + +To this: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def aview(request): + return Response("Hello world!") + +The former is "prettier", right? + +Out of the box, if you define the former view callable (the one that simply +returns a string) in Pyramid, when it is executed, Pyramid will raise an +exception. This is because "explicit is better than implicit", in most +cases, and by default, Pyramid wants you to return a :term:`Response` object +from a view callable. This is because there's usually a heck of a lot more +to a response object than just its body. But if you're the kind of person +who values such aesthetics, we have an easy way to allow for this sort of +thing: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + response.content_type = 'text/html' + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + +Do that once in your Pyramid application at startup. Now you can return +strings from any of your view callables, e.g.: + +.. code-block:: python + :linenos: + + def helloview(request): + return "Hello world!" + + def goodbyeview(request): + return "Goodbye world!" + +Oh noes! What if you want to indicate a custom content type? And a custom +status code? No fear: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def tuple_response_adapter(val): + status_int, content_type, body = val + response = Response(body) + response.content_type = content_type + response.status_int = status_int + return response + + def string_response_adapter(body): + response = Response(body) + response.content_type = 'text/html' + response.status_int = 200 + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + config.add_response_adapter(tuple_response_adapter, tuple) + +Once this is done, both of these view callables will work: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + + def anotherview(request): + return (403, 'text/plain', "Forbidden") + +Pyramid defaults to explicit behavior, because it's the most generally +useful, but provide hooks that allow you to adapt the framework to localized +aesthetic desires. + +See also :ref:`using_iresponse`. + Asset specifications ~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 970b888021e81228f38cc2d4099dfe4ca350eba9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 19:30:35 -0400 Subject: add global response section --- docs/narr/introduction.rst | 240 +++++++++++++++++++++++++-------------------- 1 file changed, 132 insertions(+), 108 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a620e9505..df1f3f954 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -260,26 +260,6 @@ You can do this: Example: :ref:`renderers_chapter`. -Event system -~~~~~~~~~~~~ - -Pyramid emits *events* during its request processing lifecycle. You can -subscribe any number of listeners to these events. For example, to be -notified of a new request, you can subscribe to the ``NewRequest`` event. To -be notified that a template is about to be rendered, you can subscribe to the -``BeforeRender`` event, and so forth. Using an event publishing system as a -framework notification feature instead of hardcoded hook points tends to make -systems based on that framework less brittle. - -You can also use Pyramid's event system to send your *own* events. For -example, if you'd like to create a system that is itself a framework, and may -want to notify subscribers that a document has just been indexed, you can -create your own event type (``DocumentIndexed`` perhaps) and send the event -via Pyramid. Users of this framework can then subscribe to your event like -they'd subscribe to the events that are normally sent by Pyramid itself. - -Example: :ref:`events_chapter` and :ref:`event_types`. - Extensible templating ~~~~~~~~~~~~~~~~~~~~~ @@ -292,98 +272,22 @@ favorite templating system. You'll then be able to use that templating system from within Pyramid just as you'd use one of the "built-in" templating systems. -Example: :ref:`templates_used_directly`. - -Speed -~~~~~ - -The Pyramid core is, as far as we can tell, at least marginally faster than -any other existing Python web framework. It has been engineered from the -ground up for speed. It only does as much work as absolutely necessary when -you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are avoided. It is feasible to get, for -example, between 3500 and 4000 requests per second from a simple Pyramid view -on commodity dual-core laptop hardware and an appropriate WSGI server -(mod_wsgi or gunicorn). In any case, performance statstics are largely -useless without requirements and goals, but if you need speed, Pyramid will -almost certainly never be your application's bottleneck; at least no more -than Python will be a bottleneck. - -Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ - -Sessions -~~~~~~~~ - -Pyramid has built-in HTTP sessioning. This allows you to associate data with -otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-part Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. - -Example: :ref:`sessions_chapter`. - -No singletons -~~~~~~~~~~~~~ - -Pyramid is written in such a way that it has exactly zero "singleton" data -structures. Or, put another way, Pyramid constructs no "mutable globals". -Or put even a different way, an import of a Pyramid application needn't have -any "import time side effects". This is esoteric-sounding, but if you've -ever tried to cope with parameterizing a Django "settings.py" file for -multiple installations of the same application, or if you've ever needed to -monkey-patch some framework fixture so that it behaves properly for your use -case, or if you've ever wanted to deploy your system using an asynchronous -server, you'll end up appreciating this feature. It just won't be a problem. -You can even run multiple copies of a similar but not identically configured -Pyramid application within the same Python process. This is good for shared -hosting environments, where RAM is at a premium. - -View Predicates and Many Views Per Route -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Unlike many other systems, Pyramid allows you to associate more than one view -per route. For example, you can create a route with the pattern ``/items`` -and when the route is matched, you can shuffle off the request to one view if -the request method is GET, another view if the request method is POST, etc. -A system known as "view predicates" allows for this. Request method matching -is the very most basic thing you can do with a view predicate. You can also -associate views with other request parameters such as the elements in the -query string, the Accept header, whether the request is an XHR request or -not, and lots of other things. This feature allows you to keep your -individual views "clean"; they won't need much conditional logic, so they'll -be easier to test. - -Example: :ref:`view_configuration_parameters`. - -Exception views -~~~~~~~~~~~~~~~ +Pyramid does not make you use a single templating system exclusively. You +can use multiple templating systems, even in the same project. -Exceptions happen. Rather than deal with exceptions that might present -themselves to a user in production in an ad-hoc way, Pyramid allows you to -register an :term:`exception view`. Exception views are like regular Pyramid -views, but they're only invoked when an exception "bubbles up" to Pyramid -itself. For example, you might register an exception view for the -:exc:`Exception` exception, which will catch *all* exceptions, and present a -pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when action cannot be performed because the user doesn't have -permission to do something. In the former case, you can show a pretty "Not -Found" page; in the latter case you might show a login form. - -Example: :ref:`exception_views`. +Example: :ref:`templates_used_directly`. View Response Adapters ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ -A lot is made of the aesthetics of what *kind* of objects you're allowed to -return from view callables in various frameworks. Some frameworks allow -you return strings or tuples from view callables, and they make much of it. -When frameworks allow for this, code looks slightly prettier, because fewer -imports need to be done, and there is less code. For example, compare this: +A lot is made of the aesthetics of what *kinds* of objects you're allowed to +return from view callables in various frameworks. In a previous section in +this document we showed you that, if you use a :term:`renderer`, you can +usually return a dictionary from a view callable instead of a full-on +:term:`Response` object. But some frameworks allow you return strings or +tuples from view callables, and they make much of it. When frameworks allow +for this, code looks slightly prettier, because fewer imports need to be +done, and there is less code. For example, compare this: .. code-block:: python :linenos: @@ -482,6 +386,126 @@ aesthetic desires. See also :ref:`using_iresponse`. +"Global" Response Object +~~~~~~~~~~~~~~~~~~~~~~~~ + +"Constructing these response objects in my view callables is such a chore! +And I'm way too lazy to register a response adapter, as per the prior +section," you say. Fine. Be that way: + +.. code-block:: python + :linenos: + + def aview(request): + response = request.response + response.body = 'Hello world!' + response.content_type = 'text/plain' + return response + +See also :ref:`request_response_attr`. + +Event system +~~~~~~~~~~~~ + +Pyramid emits *events* during its request processing lifecycle. You can +subscribe any number of listeners to these events. For example, to be +notified of a new request, you can subscribe to the ``NewRequest`` event. To +be notified that a template is about to be rendered, you can subscribe to the +``BeforeRender`` event, and so forth. Using an event publishing system as a +framework notification feature instead of hardcoded hook points tends to make +systems based on that framework less brittle. + +You can also use Pyramid's event system to send your *own* events. For +example, if you'd like to create a system that is itself a framework, and may +want to notify subscribers that a document has just been indexed, you can +create your own event type (``DocumentIndexed`` perhaps) and send the event +via Pyramid. Users of this framework can then subscribe to your event like +they'd subscribe to the events that are normally sent by Pyramid itself. + +Example: :ref:`events_chapter` and :ref:`event_types`. + +Speed +~~~~~ + +The Pyramid core is, as far as we can tell, at least marginally faster than +any other existing Python web framework. It has been engineered from the +ground up for speed. It only does as much work as absolutely necessary when +you ask it to get a job done. Extraneous function calls and suboptimal +algorithms in its core codepaths are avoided. It is feasible to get, for +example, between 3500 and 4000 requests per second from a simple Pyramid view +on commodity dual-core laptop hardware and an appropriate WSGI server +(mod_wsgi or gunicorn). In any case, performance statstics are largely +useless without requirements and goals, but if you need speed, Pyramid will +almost certainly never be your application's bottleneck; at least no more +than Python will be a bottleneck. + +Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the third-part Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. + +Example: :ref:`sessions_chapter`. + +No singletons +~~~~~~~~~~~~~ + +Pyramid is written in such a way that it has exactly zero "singleton" data +structures. Or, put another way, Pyramid constructs no "mutable globals". +Or put even a different way, an import of a Pyramid application needn't have +any "import time side effects". This is esoteric-sounding, but if you've +ever tried to cope with parameterizing a Django "settings.py" file for +multiple installations of the same application, or if you've ever needed to +monkey-patch some framework fixture so that it behaves properly for your use +case, or if you've ever wanted to deploy your system using an asynchronous +server, you'll end up appreciating this feature. It just won't be a problem. +You can even run multiple copies of a similar but not identically configured +Pyramid application within the same Python process. This is good for shared +hosting environments, where RAM is at a premium. + +View Predicates and Many Views Per Route +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unlike many other systems, Pyramid allows you to associate more than one view +per route. For example, you can create a route with the pattern ``/items`` +and when the route is matched, you can shuffle off the request to one view if +the request method is GET, another view if the request method is POST, etc. +A system known as "view predicates" allows for this. Request method matching +is the very most basic thing you can do with a view predicate. You can also +associate views with other request parameters such as the elements in the +query string, the Accept header, whether the request is an XHR request or +not, and lots of other things. This feature allows you to keep your +individual views "clean"; they won't need much conditional logic, so they'll +be easier to test. + +Example: :ref:`view_configuration_parameters`. + +Exception views +~~~~~~~~~~~~~~~ + +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. + +Example: :ref:`exception_views`. + Asset specifications ~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 2386bb2b774ee745f7923a3edec734332b38658a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 03:48:26 -0400 Subject: require, not construct --- docs/narr/introduction.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index df1f3f954..3c3c88591 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -458,12 +458,13 @@ Example: :ref:`sessions_chapter`. No singletons ~~~~~~~~~~~~~ -Pyramid is written in such a way that it has exactly zero "singleton" data -structures. Or, put another way, Pyramid constructs no "mutable globals". -Or put even a different way, an import of a Pyramid application needn't have -any "import time side effects". This is esoteric-sounding, but if you've -ever tried to cope with parameterizing a Django "settings.py" file for -multiple installations of the same application, or if you've ever needed to +Pyramid is written in such a way that it requires your application to have +exactly zero "singleton" data structures. Or, put another way, Pyramid +doesn't requires you to construct any "mutable globals". Or put even a +different way, an import of a Pyramid application needn't have any "import +time side effects". This is esoteric-sounding, but if you've ever tried to +cope with parameterizing a Django "settings.py" file for multiple +installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous server, you'll end up appreciating this feature. It just won't be a problem. -- cgit v1.2.3 From 00128a1bc824c7d79ce5595bf233669a00b57f36 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 03:56:50 -0400 Subject: wording --- docs/narr/introduction.rst | 58 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 24 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 3c3c88591..498514987 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -515,11 +515,11 @@ a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these specifications is omnipresent in Pyramid. You can refer to a template using an asset specification, a translation directory, and other package-bound static resources using one. This makes a system built on Pyramid extensible, -because you don't have to rely on globals ("the static directory") or lookup -schemes ("the ordered set of template directories") to address your files. -You can move files around as necessary, and include other packages that may -not share your system's templates or static files without encountering -conflicts. +because you don't have to rely on globals ("*the* static directory") or +lookup schemes ("*the* ordered set of template directories") to address your +files. You can move files around as necessary, and include other packages +that may not share your system's templates or static files without +encountering conflicts. Because asset specifications are used heavily in Pyramid, we've also provided a way to allow users to override assets. Say you love a system that someone @@ -539,15 +539,22 @@ transaction management system, you cease being responsible for committing your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great -thing. If you instead add a ``session.commit`` call in your application -logic itself, and your code goes on to do other important things after that -commit, and error happens in the later code, you can easily wind up in a bad -place. Some data will have been written to the database that probably should -not have. Having a centralized commit point saves you from needing to think -about this. Also, Pyramid's transaction management system allows you to -synchronize commits between multiple databases, and allows you to do things -like conditionally send email if a transaction commits, but otherwise keep -quiet. +thing. If, instead of managing your transactions in a centralized place, you +sprikle ``session.commit`` calls in your application logic itself, you can +wind up in a bad place. Wherever you manually commit data to your database, +it's likely that some of your other code is going to run *after* your commit. +If that code goes on to do other important things after that commit, and +error happens in the later code, you can easily wind up with inconsistent +data if you're not extremely careful. Some data will have been written to +the database that probably should not have. Having a centralized commit +point saves you from needing to think about this; it's great for lazy people +who also care about data integrity. Either the request completes +successfully, and all chages are committed, or it does not, and all changes +are aborted. + +Also, Pyramid's transaction management system allows you to synchronize +commits between multiple databases, and allows you to do things like +conditionally send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements anywhere in application code). @@ -576,16 +583,16 @@ Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you compose applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be -performed by included packages (including the addition of views, routes, -subscribers, and even authentication and authorization policies). You can -even extend or override an existing application by including another -application's configuration in your own, and overriding or adding new views -and routes to it. This has the potential to allow you to compose a big -application out of many other smaller ones. For example, if you want to -reuse an existing application that already has a bunch of routes, you can -just use the ``include`` statement with a ``route_prefix``; the new -application will live within your application at a URL prefix. It's not a -big deal, and requires little up-front engineering effort. +performed by included packages including the addition of views, routes, +subscribers, and even authentication and authorization policies. You can even +extend or override an existing application by including another application's +configuration in your own, and overriding or adding new views and routes to +it. This has the potential to allow you to compose a big application out of +many other smaller ones. For example, if you want to reuse an existing +application that already has a bunch of routes, you can just use the +``include`` statement with a ``route_prefix``; the new application will live +within your application at a URL prefix. It's not a big deal, and requires +little up-front engineering effort. Does Pyramid's configurator allow you to do something, but you just want it a little less verbose? Or you'd like to offer up some handy configuration @@ -635,6 +642,9 @@ the Configurator object: config.add_route('xhr_route', '/xhr/{id}') config.add_protected_xhr_views('my.package') +Your previously multiple repetitive configuration lines have now morphed into +one line. + You can share your configuration code with others this way too by packaging it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the -- cgit v1.2.3 From ab7b2447c2733e9a5ec049bb567235bae0e631f6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 05:01:43 -0400 Subject: wording/typo fixes --- docs/narr/introduction.rst | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 498514987..029aa1e07 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -206,7 +206,7 @@ routes for an application in the order they'll be evaluated for matching; ``paster pviews`` shows all configured views for any given URL. These are also WTF-crushers in some circumstances. -Example: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. +Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -512,14 +512,13 @@ Asset specifications Asset specifications are strings that contain both a Python package name and a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. You can refer to a template using -an asset specification, a translation directory, and other package-bound -static resources using one. This makes a system built on Pyramid extensible, -because you don't have to rely on globals ("*the* static directory") or -lookup schemes ("*the* ordered set of template directories") to address your -files. You can move files around as necessary, and include other packages -that may not share your system's templates or static files without -encountering conflicts. +specifications is omnipresent in Pyramid. An asset specification can refer +to a template, a translation directory, or any other package-bound static +resource. This makes a system built on Pyramid extensible, because you don't +have to rely on globals ("*the* static directory") or lookup schemes ("*the* +ordered set of template directories") to address your files. You can move +files around as necessary, and include other packages that may not share your +system's templates or static files without encountering conflicts. Because asset specifications are used heavily in Pyramid, we've also provided a way to allow users to override assets. Say you love a system that someone @@ -528,7 +527,7 @@ to make it all better. No need to fork the application. Just override the asset specification for that template with your own inside a wrapper, and you're good to go. -Example: :ref:`asset_specifications`. +Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. Transaction management ~~~~~~~~~~~~~~~~~~~~~~ @@ -586,7 +585,7 @@ that can be performed in your "main" Pyramid application can also be performed by included packages including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's -configuration in your own, and overriding or adding new views and routes to +configuration in your own, overriding or adding new views and routes to it. This has the potential to allow you to compose a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the -- cgit v1.2.3 From fdae55901a72a0894274847da8811779cdfdd1cd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 05:02:25 -0400 Subject: wording/typo fixes --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 029aa1e07..267234b6a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -737,8 +737,8 @@ greater than 95% decision/condition coverage as measured by the Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy 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 fewer of them than while working on -other projects that don't have a good testing regime. +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 e7085bb4fcbd1bec75dc13724b8e399879c69290 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 05:03:08 -0400 Subject: wording/typo fixes --- docs/narr/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 267234b6a..d404ef08c 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -285,9 +285,9 @@ return from view callables in various frameworks. In a previous section in this document we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on :term:`Response` object. But some frameworks allow you return strings or -tuples from view callables, and they make much of it. When frameworks allow -for this, code looks slightly prettier, because fewer imports need to be -done, and there is less code. For example, compare this: +tuples from view callables. When frameworks allow for this, code looks +slightly prettier, because fewer imports need to be done, and there is less +code. For example, compare this: .. code-block:: python :linenos: -- cgit v1.2.3 From 5b0496ee16cc1c43344870eda41f48e3851667f4 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 8 Sep 2011 10:56:24 -0500 Subject: garden --- docs/narr/introduction.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d404ef08c..49c6ce521 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -211,7 +211,7 @@ Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid has a structured, unified conception of a :term:`view callable`. +Pyramid has a structured, unified concept of a :term:`view callable`. View callables can be functions, methods of classes, or even instances. When you add a new view callable, you can choose to make it a function or a method of a class; in either case, Pyramid treats it largely the same way. You can @@ -448,7 +448,7 @@ Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But Pyramid also allows you to plug in your own sessioning system by creating some code that adheres to a documented interface. Currently there is a -binding package for the third-part Beaker sessioning system that does exactly +binding package for the third-party Beaker sessioning system that does exactly this. But if you have a specialized need (perhaps you want to store your session data in MongoDB), you can. You can even switch between implementations without changing your application code. @@ -460,8 +460,8 @@ No singletons Pyramid is written in such a way that it requires your application to have exactly zero "singleton" data structures. Or, put another way, Pyramid -doesn't requires you to construct any "mutable globals". Or put even a -different way, an import of a Pyramid application needn't have any "import +doesn't require you to construct any "mutable globals". Or put even a +different way, an import of a Pyramid application needn't have any "import- time side effects". This is esoteric-sounding, but if you've ever tried to cope with parameterizing a Django "settings.py" file for multiple installations of the same application, or if you've ever needed to @@ -501,7 +501,7 @@ itself. For example, you might register an exception view for the pretty "well, this is embarrassing" page. Or you might choose to register an exception view for only specific kinds of application-specific exceptions, such as an exception that happens when a file is not found, or an exception -that happens when action cannot be performed because the user doesn't have +that happens when an action cannot be performed because the user doesn't have permission to do something. In the former case, you can show a pretty "Not Found" page; in the latter case you might show a login form. @@ -539,10 +539,10 @@ your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great thing. If, instead of managing your transactions in a centralized place, you -sprikle ``session.commit`` calls in your application logic itself, you can +sprinkle ``session.commit`` calls in your application logic itself, you can wind up in a bad place. Wherever you manually commit data to your database, it's likely that some of your other code is going to run *after* your commit. -If that code goes on to do other important things after that commit, and +If that code goes on to do other important things after that commit, and an error happens in the later code, you can easily wind up with inconsistent data if you're not extremely careful. Some data will have been written to the database that probably should not have. Having a centralized commit @@ -561,7 +561,7 @@ anywhere in application code). Configuration conflict detection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a system is small, it's reasonably easy to keep it in all in your head. +When a system is small, it's reasonably easy to keep it all in your head. But when systems grow large, you may have hundreds or thousands of configuration statements which add a view, add a route, and so forth. Pyramid's configuration system keeps track of your configuration statements, @@ -641,8 +641,7 @@ the Configurator object: config.add_route('xhr_route', '/xhr/{id}') config.add_protected_xhr_views('my.package') -Your previously multiple repetitive configuration lines have now morphed into -one line. +Your previously repetitive configuration lines have now morphed into one line. You can share your configuration code with others this way too by packaging it up and calling :meth:`~pyramid.config.Configurator.add_directive` from -- cgit v1.2.3 From a3b2b7437d52bd5b0d72ac6616b601e8a3a2d659 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 8 Sep 2011 10:58:15 -0500 Subject: p.configuration was deprecated --- docs/narr/helloworld.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py index 92e16efbb..5f121d48d 100644 --- a/docs/narr/helloworld.py +++ b/docs/narr/helloworld.py @@ -1,5 +1,5 @@ from paste.httpserver import serve -from pyramid.configuration import Configurator +from pyramid.config import Configurator from pyramid.response import Response def hello_world(request): -- cgit v1.2.3 From fed66efe5347858eaf78e0fcb75c77eabf01efab Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Sep 2011 12:38:52 -0700 Subject: Replaced "the the" with "the" under Minimalism --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 49c6ce521..bba3594fe 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -40,7 +40,7 @@ Simplicity understand to a minimum. Minimalism - :app:`Pyramid` tries to solve only the the fundamental problems of creating + :app:`Pyramid` tries to solve only the fundamental problems of creating a web application: the mapping of URLs to code, templating, security and serving static assets. We consider these to be the core activities that are common to nearly all web applications. -- cgit v1.2.3 From 41cb3afe29320abb4e20a951863c0ae4a64eba67 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 17:59:53 -0400 Subject: typo --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index bba3594fe..25511d12a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -434,7 +434,7 @@ you ask it to get a job done. Extraneous function calls and suboptimal algorithms in its core codepaths are avoided. It is feasible to get, for example, between 3500 and 4000 requests per second from a simple Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI server -(mod_wsgi or gunicorn). In any case, performance statstics are largely +(mod_wsgi or gunicorn). In any case, performance statistics are largely useless without requirements and goals, but if you need speed, Pyramid will almost certainly never be your application's bottleneck; at least no more than Python will be a bottleneck. -- cgit v1.2.3 From d10aeb228f58be6beff35266fea0bc7be006aab9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 03:37:11 -0400 Subject: feedback from david cramer --- docs/narr/introduction.rst | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 25511d12a..b691d5a7c 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -258,6 +258,14 @@ You can do this: def myview(request): return {'a':1} +When this view callable is called by Pyramid, the ``{'a':1}`` dictionary will +be rendered to a response on your behalf. The string passed as ``renderer=`` +above is an :term:`asset specification`. It is in the form +``packagename:directoryname/filename.ext``. In this case, it names the +``mytemplate.pt`` file in the ``templates`` directory within the ``myapp`` +Python package. Asset specifications are omnipresent in Pyramid: see +:ref:`intro_asset_specs` for more information. + Example: :ref:`renderers_chapter`. Extensible templating @@ -507,6 +515,8 @@ Found" page; in the latter case you might show a login form. Example: :ref:`exception_views`. +.. _intro_asset_specs: + Asset specifications ~~~~~~~~~~~~~~~~~~~~ @@ -597,7 +607,10 @@ Does Pyramid's configurator allow you to do something, but you just want it a little less verbose? Or you'd like to offer up some handy configuration feature to other Pyramid users without requiring that we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own directives. For -example, let's say you find yourself doing this a lot: +example, let's say you find yourself calling +:meth:`pyramid.config.Configurator.add_view` repetitvely. Usually you can +take the boring away by using existing shortcuts, but let's say that this is +a case such a way that no existing shortcut works to take the boring away: .. code-block:: python :linenos: -- cgit v1.2.3 From a7238e374de68557aeed47c416cb94538615dcf8 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 9 Sep 2011 02:42:16 -0500 Subject: garden --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b691d5a7c..b24c95c67 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -608,7 +608,7 @@ little less verbose? Or you'd like to offer up some handy configuration feature to other Pyramid users without requiring that we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own directives. For example, let's say you find yourself calling -:meth:`pyramid.config.Configurator.add_view` repetitvely. Usually you can +:meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can take the boring away by using existing shortcuts, but let's say that this is a case such a way that no existing shortcut works to take the boring away: -- cgit v1.2.3 From 214125fa966026f979981312356832cd0a52983a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 04:04:27 -0400 Subject: garden --- docs/narr/introduction.rst | 168 ++++++++++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 54 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b24c95c67..62374ff54 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -208,6 +208,17 @@ also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. +Add-ons +~~~~~~~~ + +Pyramid has an extensive set of add-ons held to the same quality standards as +the Pyramid core itself. Add-ons are packages which provide functionality +that the Pyramid core doesn't. Add-on packages already exist which let you +easily send email, let you use the Jinja2 templating system, let you use +XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. + +Examples: https://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation + Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -222,7 +233,39 @@ initialization code as necessary. All kinds of views are easy to understand and use and operate similarly. There is no phony distinction between them; they can be used for the same purposes. -Example: :ref:`view_config_placement`. +Here's a view callable defined as a function: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + @view_config(route_name='aview') + def aview(request): + return Response('one') + +Here's a few views defined as methods of a class instead: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + class AView(object): + def __init__(self, request): + self.request = request + + @view_config(route_name='view_one') + def view_one(request): + return Response('one') + + @view_config(route_name='view_two') + def view_two(request): + return Response('two') + +See also :ref:`view_config_placement`. Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -603,66 +646,20 @@ application that already has a bunch of routes, you can just use the within your application at a URL prefix. It's not a big deal, and requires little up-front engineering effort. -Does Pyramid's configurator allow you to do something, but you just want it a -little less verbose? Or you'd like to offer up some handy configuration -feature to other Pyramid users without requiring that we change Pyramid? You -can extend Pyramid's :term:`Configurator` with your own directives. For -example, let's say you find yourself calling -:meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can -take the boring away by using existing shortcuts, but let's say that this is -a case such a way that no existing shortcut works to take the boring away: +For example: .. code-block:: python :linenos: from pyramid.config import Configurator - config = Configurator() - config.add_route('xhr_route', '/xhr/{id}') - config.add_view('my.package.GET_view', route_name='xhr_route', - xhr=True, permission='view', request_method='GET') - config.add_view('my.package.POST_view', route_name='xhr_route', - xhr=True, permission='view', request_method='POST') - config.add_view('my.package.HEAD_view', route_name='xhr_route', - xhr=True, permission='view', request_method='HEAD') - -Pretty tedious right? You can add a directive to the Pyramid configurator to -automate some of the tedium away: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def add_protected_xhr_views(config, module): - module = config.maybe_dotted(module) - for method in ('GET', 'POST', 'HEAD'): - view = getattr(module, 'xhr_%s_view' % method, None) - if view is not None: - config.add_view(view, route_name='xhr_route', xhr=True, - permission='view', request_method=method) - - config = Configurator() - config.add_directive('add_protected_xhr_views', add_protected_xhr_views) - -Once that's done, you can call the directive you've just added as a method of -the Configurator object: - -.. code-block:: python - :linenos: - - config.add_route('xhr_route', '/xhr/{id}') - config.add_protected_xhr_views('my.package') - -Your previously repetitive configuration lines have now morphed into one line. - -You can share your configuration code with others this way too by packaging -it up and calling :meth:`~pyramid.config.Configurator.add_directive` from -within a function called when another user uses the -:meth:`~pyramid.config.Configurator.include` method against your code. + if __name__ == '__main__': + config = Configurator() + config.include('pyramid_jinja2') + config.include('pyramid_exclog') + config.include('some.other.guys.package', route_prefix='/someotherguy') -Examples: :ref:`building_an_extensible_app`, :ref:`including_configuration` -and :ref:`add_directive`. +See also :ref:`including_configuration` and :ref:`building_an_extensible_app` Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -739,6 +736,69 @@ Pyramid itself, meaning you have access to templates and other renderers, a Example: :ref:`registering_tweens`. +Automating repetitive configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Does Pyramid's configurator allow you to do something, but you're a little +adventurous and just want it a little less verbose? Or you'd like to offer +up some handy configuration feature to other Pyramid users without requiring +that we change Pyramid? You can extend Pyramid's :term:`Configurator` with +your own directives. For example, let's say you find yourself calling +:meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can +take the boring away by using existing shortcuts, but let's say that this is +a case such a way that no existing shortcut works to take the boring away: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + config = Configurator() + config.add_route('xhr_route', '/xhr/{id}') + config.add_view('my.package.GET_view', route_name='xhr_route', + xhr=True, permission='view', request_method='GET') + config.add_view('my.package.POST_view', route_name='xhr_route', + xhr=True, permission='view', request_method='POST') + config.add_view('my.package.HEAD_view', route_name='xhr_route', + xhr=True, permission='view', request_method='HEAD') + +Pretty tedious right? You can add a directive to the Pyramid configurator to +automate some of the tedium away: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def add_protected_xhr_views(config, module): + module = config.maybe_dotted(module) + for method in ('GET', 'POST', 'HEAD'): + view = getattr(module, 'xhr_%s_view' % method, None) + if view is not None: + config.add_view(view, route_name='xhr_route', xhr=True, + permission='view', request_method=method) + + config = Configurator() + config.add_directive('add_protected_xhr_views', add_protected_xhr_views) + +Once that's done, you can call the directive you've just added as a method of +the Configurator object: + +.. code-block:: python + :linenos: + + config.add_route('xhr_route', '/xhr/{id}') + config.add_protected_xhr_views('my.package') + +Your previously repetitive configuration lines have now morphed into one line. + +You can share your configuration code with others this way too by packaging +it up and calling :meth:`~pyramid.config.Configurator.add_directive` from +within a function called when another user uses the +:meth:`~pyramid.config.Configurator.include` method against your code. + +See also :ref:`add_directive`. + Testing ~~~~~~~ -- cgit v1.2.3 From d3aae87e4e167ab8ff7a0c54fee4197d9a8b8763 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 04:13:31 -0400 Subject: garden --- docs/narr/introduction.rst | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 62374ff54..8a7c724a1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -108,22 +108,24 @@ from those other frameworks. But Pyramid is the only one that has all of them in one place, documented appropriately, and useful a la carte without necessarily paying for the entire banquet. These are detailed below. -Single-File Applications +Single-file applications ~~~~~~~~~~~~~~~~~~~~~~~~ You can write a Pyramid application that lives entirely in one Python file, -not unlike existing Python microframeworks. This is beneficial for "one off" +not unlike existing Python microframeworks. This is beneficial for one-off prototyping, bug reproduction, and very small applications. These applications are easy to understand because all the information about the application lives in a single place, and you can deploy them without needing to understand much about Python distributions and packaging. Pyramid isn't really marketed as a microframework, but it allows you to do almost -everything that frameworks that are marketed as "micro" offer in very similar +everything that frameworks that are marketed as micro offer in very similar ways. -Example: :ref:`firstapp_chapter`. +.. literalinclude:: helloworld.py -Decorator-Based Configuration +See also :ref:`firstapp_chapter`. + +Decorator-based configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you like the idea of framework configuration statements living next to the @@ -153,7 +155,7 @@ with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. -URL Generation +URL generation ~~~~~~~~~~~~~~ Pyramid is capable of generating URLs for resources, routes, and static @@ -219,7 +221,7 @@ XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. Examples: https://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation -Class-Based and Function-Based Views +Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pyramid has a structured, unified concept of a :term:`view callable`. @@ -328,7 +330,7 @@ can use multiple templating systems, even in the same project. Example: :ref:`templates_used_directly`. -View Response Adapters +View response adapters ~~~~~~~~~~~~~~~~~~~~~~ A lot is made of the aesthetics of what *kinds* of objects you're allowed to @@ -437,7 +439,7 @@ aesthetic desires. See also :ref:`using_iresponse`. -"Global" Response Object +"Global" response object ~~~~~~~~~~~~~~~~~~~~~~~~ "Constructing these response objects in my view callables is such a chore! @@ -523,7 +525,7 @@ You can even run multiple copies of a similar but not identically configured Pyramid application within the same Python process. This is good for shared hosting environments, where RAM is at a premium. -View Predicates and Many Views Per Route +View predicates and many views per route ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike many other systems, Pyramid allows you to associate more than one view @@ -677,7 +679,7 @@ system. Example: :ref:`enabling_authorization_policy`. -Built-in Internationalization +Built-in internationalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pyramid ships with internalization-related features in its core: @@ -708,7 +710,7 @@ as opposed to "Bob can edit documents"). Example: :ref:`much_ado_about_traversal_chapter`. -HTTP Caching +HTTP caching ~~~~~~~~~~~~ Pyramid provides an easy way to associate views with HTTP caching policies. -- cgit v1.2.3 From 82dcba5bf8d6d024f42ded1565d30c314b8e8b4b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 04:20:46 -0400 Subject: reorder --- docs/narr/introduction.rst | 448 ++++++++++++++++++++++----------------------- 1 file changed, 224 insertions(+), 224 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8a7c724a1..8694556b2 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -269,6 +269,47 @@ Here's a few views defined as methods of a class instead: See also :ref:`view_config_placement`. +.. _intro_asset_specs: + +Asset specifications +~~~~~~~~~~~~~~~~~~~~ + +Asset specifications are strings that contain both a Python package name and +a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. An asset specification can refer +to a template, a translation directory, or any other package-bound static +resource. This makes a system built on Pyramid extensible, because you don't +have to rely on globals ("*the* static directory") or lookup schemes ("*the* +ordered set of template directories") to address your files. You can move +files around as necessary, and include other packages that may not share your +system's templates or static files without encountering conflicts. + +Because asset specifications are used heavily in Pyramid, we've also provided +a way to allow users to override assets. Say you love a system that someone +else has created with Pyramid but you just need to change "that one template" +to make it all better. No need to fork the application. Just override the +asset specification for that template with your own inside a wrapper, and +you're good to go. + +Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. + +Extensible templating +~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured API that allows for pluggability of "renderers". +Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated +as renderers. Renderer bindings for all of these templating systems already +exist for use in Pyramid. But if you'd rather use another, it's not a big +deal. Just copy the code from an existing renderer package, and plug in your +favorite templating system. You'll then be able to use that templating +system from within Pyramid just as you'd use one of the "built-in" templating +systems. + +Pyramid does not make you use a single templating system exclusively. You +can use multiple templating systems, even in the same project. + +Example: :ref:`templates_used_directly`. + Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -313,150 +354,6 @@ Python package. Asset specifications are omnipresent in Pyramid: see Example: :ref:`renderers_chapter`. -Extensible templating -~~~~~~~~~~~~~~~~~~~~~ - -Pyramid has a structured API that allows for pluggability of "renderers". -Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated -as renderers. Renderer bindings for all of these templating systems already -exist for use in Pyramid. But if you'd rather use another, it's not a big -deal. Just copy the code from an existing renderer package, and plug in your -favorite templating system. You'll then be able to use that templating -system from within Pyramid just as you'd use one of the "built-in" templating -systems. - -Pyramid does not make you use a single templating system exclusively. You -can use multiple templating systems, even in the same project. - -Example: :ref:`templates_used_directly`. - -View response adapters -~~~~~~~~~~~~~~~~~~~~~~ - -A lot is made of the aesthetics of what *kinds* of objects you're allowed to -return from view callables in various frameworks. In a previous section in -this document we showed you that, if you use a :term:`renderer`, you can -usually return a dictionary from a view callable instead of a full-on -:term:`Response` object. But some frameworks allow you return strings or -tuples from view callables. When frameworks allow for this, code looks -slightly prettier, because fewer imports need to be done, and there is less -code. For example, compare this: - -.. code-block:: python - :linenos: - - def aview(request): - return "Hello world!" - -To this: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - - def aview(request): - return Response("Hello world!") - -The former is "prettier", right? - -Out of the box, if you define the former view callable (the one that simply -returns a string) in Pyramid, when it is executed, Pyramid will raise an -exception. This is because "explicit is better than implicit", in most -cases, and by default, Pyramid wants you to return a :term:`Response` object -from a view callable. This is because there's usually a heck of a lot more -to a response object than just its body. But if you're the kind of person -who values such aesthetics, we have an easy way to allow for this sort of -thing: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - from pyramid.response import Response - - def string_response_adapter(s): - response = Response(s) - response.content_type = 'text/html' - return response - - if __name__ == '__main__': - config = Configurator() - config.add_response_adapter(string_response_adapter, basestring) - -Do that once in your Pyramid application at startup. Now you can return -strings from any of your view callables, e.g.: - -.. code-block:: python - :linenos: - - def helloview(request): - return "Hello world!" - - def goodbyeview(request): - return "Goodbye world!" - -Oh noes! What if you want to indicate a custom content type? And a custom -status code? No fear: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def tuple_response_adapter(val): - status_int, content_type, body = val - response = Response(body) - response.content_type = content_type - response.status_int = status_int - return response - - def string_response_adapter(body): - response = Response(body) - response.content_type = 'text/html' - response.status_int = 200 - return response - - if __name__ == '__main__': - config = Configurator() - config.add_response_adapter(string_response_adapter, basestring) - config.add_response_adapter(tuple_response_adapter, tuple) - -Once this is done, both of these view callables will work: - -.. code-block:: python - :linenos: - - def aview(request): - return "Hello world!" - - def anotherview(request): - return (403, 'text/plain', "Forbidden") - -Pyramid defaults to explicit behavior, because it's the most generally -useful, but provide hooks that allow you to adapt the framework to localized -aesthetic desires. - -See also :ref:`using_iresponse`. - -"Global" response object -~~~~~~~~~~~~~~~~~~~~~~~~ - -"Constructing these response objects in my view callables is such a chore! -And I'm way too lazy to register a response adapter, as per the prior -section," you say. Fine. Be that way: - -.. code-block:: python - :linenos: - - def aview(request): - response = request.response - response.body = 'Hello world!' - response.content_type = 'text/plain' - return response - -See also :ref:`request_response_attr`. - Event system ~~~~~~~~~~~~ @@ -477,6 +374,47 @@ they'd subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. +Built-in internationalization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid ships with internalization-related features in its core: +localization, pluralization, and creating message catalogs from source files +and templates. Pyramid allows for a plurality of message catalog via the use +of translation domains: you can create a system that has its own translations +without conflict with other translations in other domains. + +Example: :ref:`i18n_chapter`. + +HTTP caching +~~~~~~~~~~~~ + +Pyramid provides an easy way to associate views with HTTP caching policies. +You can just tell Pyramid to configure your view with an ``http_cache`` +statement, and it will take care of the rest:: + + @view_config(http_cache=3600) # 60 minutes + def myview(request): .... + +Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to +responses generated when this view is invoked. + +See the :meth:`~pyramid.config.Configurator.add_view` method's +``http_cache`` documentation for more information. + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the third-party Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. + +Example: :ref:`sessions_chapter`. + Speed ~~~~~ @@ -494,19 +432,23 @@ than Python will be a bottleneck. Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ -Sessions -~~~~~~~~ +Exception views +~~~~~~~~~~~~~~~ -Pyramid has built-in HTTP sessioning. This allows you to associate data with -otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-party Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when an action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. -Example: :ref:`sessions_chapter`. +Example: :ref:`exception_views`. No singletons ~~~~~~~~~~~~~ @@ -542,48 +484,6 @@ be easier to test. Example: :ref:`view_configuration_parameters`. -Exception views -~~~~~~~~~~~~~~~ - -Exceptions happen. Rather than deal with exceptions that might present -themselves to a user in production in an ad-hoc way, Pyramid allows you to -register an :term:`exception view`. Exception views are like regular Pyramid -views, but they're only invoked when an exception "bubbles up" to Pyramid -itself. For example, you might register an exception view for the -:exc:`Exception` exception, which will catch *all* exceptions, and present a -pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when an action cannot be performed because the user doesn't have -permission to do something. In the former case, you can show a pretty "Not -Found" page; in the latter case you might show a login form. - -Example: :ref:`exception_views`. - -.. _intro_asset_specs: - -Asset specifications -~~~~~~~~~~~~~~~~~~~~ - -Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. An asset specification can refer -to a template, a translation directory, or any other package-bound static -resource. This makes a system built on Pyramid extensible, because you don't -have to rely on globals ("*the* static directory") or lookup schemes ("*the* -ordered set of template directories") to address your files. You can move -files around as necessary, and include other packages that may not share your -system's templates or static files without encountering conflicts. - -Because asset specifications are used heavily in Pyramid, we've also provided -a way to allow users to override assets. Say you love a system that someone -else has created with Pyramid but you just need to change "that one template" -to make it all better. No need to fork the application. Just override the -asset specification for that template with your own inside a wrapper, and -you're good to go. - -Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. - Transaction management ~~~~~~~~~~~~~~~~~~~~~~ @@ -679,17 +579,6 @@ system. Example: :ref:`enabling_authorization_policy`. -Built-in internationalization -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pyramid ships with internalization-related features in its core: -localization, pluralization, and creating message catalogs from source files -and templates. Pyramid allows for a plurality of message catalog via the use -of translation domains: you can create a system that has its own translations -without conflict with other translations in other domains. - -Example: :ref:`i18n_chapter`. - Traversal ~~~~~~~~~ @@ -710,22 +599,6 @@ as opposed to "Bob can edit documents"). Example: :ref:`much_ado_about_traversal_chapter`. -HTTP caching -~~~~~~~~~~~~ - -Pyramid provides an easy way to associate views with HTTP caching policies. -You can just tell Pyramid to configure your view with an ``http_cache`` -statement, and it will take care of the rest:: - - @view_config(http_cache=3600) # 60 minutes - def myview(request): .... - -Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to -responses generated when this view is invoked. - -See the :meth:`~pyramid.config.Configurator.add_view` method's -``http_cache`` documentation for more information. - Tweens ~~~~~~ @@ -738,6 +611,133 @@ Pyramid itself, meaning you have access to templates and other renderers, a Example: :ref:`registering_tweens`. +View response adapters +~~~~~~~~~~~~~~~~~~~~~~ + +A lot is made of the aesthetics of what *kinds* of objects you're allowed to +return from view callables in various frameworks. In a previous section in +this document we showed you that, if you use a :term:`renderer`, you can +usually return a dictionary from a view callable instead of a full-on +:term:`Response` object. But some frameworks allow you return strings or +tuples from view callables. When frameworks allow for this, code looks +slightly prettier, because fewer imports need to be done, and there is less +code. For example, compare this: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + +To this: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def aview(request): + return Response("Hello world!") + +The former is "prettier", right? + +Out of the box, if you define the former view callable (the one that simply +returns a string) in Pyramid, when it is executed, Pyramid will raise an +exception. This is because "explicit is better than implicit", in most +cases, and by default, Pyramid wants you to return a :term:`Response` object +from a view callable. This is because there's usually a heck of a lot more +to a response object than just its body. But if you're the kind of person +who values such aesthetics, we have an easy way to allow for this sort of +thing: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + response.content_type = 'text/html' + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + +Do that once in your Pyramid application at startup. Now you can return +strings from any of your view callables, e.g.: + +.. code-block:: python + :linenos: + + def helloview(request): + return "Hello world!" + + def goodbyeview(request): + return "Goodbye world!" + +Oh noes! What if you want to indicate a custom content type? And a custom +status code? No fear: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def tuple_response_adapter(val): + status_int, content_type, body = val + response = Response(body) + response.content_type = content_type + response.status_int = status_int + return response + + def string_response_adapter(body): + response = Response(body) + response.content_type = 'text/html' + response.status_int = 200 + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + config.add_response_adapter(tuple_response_adapter, tuple) + +Once this is done, both of these view callables will work: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + + def anotherview(request): + return (403, 'text/plain', "Forbidden") + +Pyramid defaults to explicit behavior, because it's the most generally +useful, but provide hooks that allow you to adapt the framework to localized +aesthetic desires. + +See also :ref:`using_iresponse`. + +"Global" response object +~~~~~~~~~~~~~~~~~~~~~~~~ + +"Constructing these response objects in my view callables is such a chore! +And I'm way too lazy to register a response adapter, as per the prior +section," you say. Fine. Be that way: + +.. code-block:: python + :linenos: + + def aview(request): + response = request.response + response.body = 'Hello world!' + response.content_type = 'text/plain' + return response + +See also :ref:`request_response_attr`. + Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 814455d4475046a24cd11a30805a5db8d4e4ed13 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:09:23 -0700 Subject: Insert missing "to". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..63f142124 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -618,7 +618,7 @@ A lot is made of the aesthetics of what *kinds* of objects you're allowed to return from view callables in various frameworks. In a previous section in this document we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on -:term:`Response` object. But some frameworks allow you return strings or +:term:`Response` object. But some frameworks allow you to return strings or tuples from view callables. When frameworks allow for this, code looks slightly prettier, because fewer imports need to be done, and there is less code. For example, compare this: -- cgit v1.2.3 From 7047d24edf7ade4e442d1e79dea33492f2a4ba45 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:16:04 -0700 Subject: Corrected verb to agree with singular subject "Pyramid". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..ed0f322b6 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -715,7 +715,7 @@ Once this is done, both of these view callables will work: return (403, 'text/plain', "Forbidden") Pyramid defaults to explicit behavior, because it's the most generally -useful, but provide hooks that allow you to adapt the framework to localized +useful, but provides hooks that allow you to adapt the framework to localized aesthetic desires. See also :ref:`using_iresponse`. -- cgit v1.2.3 From 3970b06caa0e51fadc9525c7f4ac83b733fd19be Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:23:49 -0700 Subject: Removed line break in hyphenation of "import-time" which rendered as "import- time". --- docs/narr/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..b2fb95c42 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -456,9 +456,9 @@ No singletons Pyramid is written in such a way that it requires your application to have exactly zero "singleton" data structures. Or, put another way, Pyramid doesn't require you to construct any "mutable globals". Or put even a -different way, an import of a Pyramid application needn't have any "import- -time side effects". This is esoteric-sounding, but if you've ever tried to -cope with parameterizing a Django "settings.py" file for multiple +different way, an import of a Pyramid application needn't have any +"import-time side effects". This is esoteric-sounding, but if you've ever +tried to cope with parameterizing a Django "settings.py" file for multiple installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous -- cgit v1.2.3 From 157d3256acf633bb21cfd09e542c639672c2c579 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:30:48 -0700 Subject: Correct spelling of "chages" to "changes". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..6bf2665ee 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -503,7 +503,7 @@ data if you're not extremely careful. Some data will have been written to the database that probably should not have. Having a centralized commit point saves you from needing to think about this; it's great for lazy people who also care about data integrity. Either the request completes -successfully, and all chages are committed, or it does not, and all changes +successfully, and all changes are committed, or it does not, and all changes are aborted. Also, Pyramid's transaction management system allows you to synchronize -- cgit v1.2.3 From efc17af3c788809db4fc50cd7c585f6545534933 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:32:52 -0700 Subject: Insert missing "to". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..ef7615079 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -534,7 +534,7 @@ Configuration extensibility ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike other systems, Pyramid provides a structured "include" mechanism (see -:meth:`~pyramid.config.Configurator.include`) that allows you compose +:meth:`~pyramid.config.Configurator.include`) that allows you to compose applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be performed by included packages including the addition of views, routes, -- cgit v1.2.3 From 0e5e1bc169b137c03f9112925a10c2185c414292 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:39:23 -0700 Subject: "internalization-related" s/b "internationalization-related" --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..633b48d36 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -377,7 +377,7 @@ Example: :ref:`events_chapter` and :ref:`event_types`. Built-in internationalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid ships with internalization-related features in its core: +Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files and templates. Pyramid allows for a plurality of message catalog via the use of translation domains: you can create a system that has its own translations -- cgit v1.2.3 From acf9ff6b8816afa4e0ce57b6301911fe343d4fb4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:42:38 -0700 Subject: "CMS systems" is redundant, so spelled out acronym. --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..8cd6daba8 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -592,8 +592,8 @@ to be arbitrarily extensible: it's a lot easier to add a node to a tree than it is to shoehorn a route into an ordered list of other routes, or to create another entire instance of an application to service a department and glue code to allow disparate apps to share data. It's a great fit for sites that -naturally lend themselves to changing departmental hierarchies, such as CMS -systems and document management systems. Traversal also lends itself well to +naturally lend themselves to changing departmental hierarchies, such as +content management systems and document management systems. Traversal also lends itself well to systems that require very granular security ("Bob can edit *this* document" as opposed to "Bob can edit documents"). -- cgit v1.2.3 From 649ddf33537cd2a3ea2b1efc140cc74a16a81b10 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 12 Sep 2011 12:58:43 -0400 Subject: document replacement marker composition --- docs/narr/urldispatch.rst | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ad9cc6033..a6e46515f 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -138,11 +138,22 @@ replacement marker does not need to be preceded by a ``/`` character. A replacement marker is in the format ``{name}``, where this means "accept any characters up to the next slash character and use this as the ``name`` -:term:`matchdict` value." A matchdict is the dictionary representing the -dynamic parts extracted from a URL based on the routing pattern. It is -available as ``request.matchdict``. For example, the following pattern -defines one literal segment (``foo``) and two replacement markers (``baz``, -and ``bar``): +:term:`matchdict` value." + +A replacement marker in a pattern must begin with an uppercase or lowercase +ASCII letter or an underscore, and can be composed only of uppercase or +lowercase ASCII letters, underscores, and numbers. For example: ``a``, +``a_b``, ``_b``, and ``b9`` are all valid replacement marker names, but +``0a`` is not. + +.. note:: A replacement marker could not start with an underscore until + Pyramid 1.2. Previous versions required that the replacement marker start + with an uppercase or lowercase letter. + +A matchdict is the dictionary representing the dynamic parts extracted from a +URL based on the routing pattern. It is available as ``request.matchdict``. +For example, the following pattern defines one literal segment (``foo``) and +two replacement markers (``baz``, and ``bar``): .. code-block:: text -- cgit v1.2.3 From 8fd6ba03e313b910acd60c10cb689382840febc0 Mon Sep 17 00:00:00 2001 From: Douglas Cerna Date: Fri, 23 Sep 2011 02:39:36 -0600 Subject: Edited docs/narr/resources.rst via GitHub --- docs/narr/resources.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 9335906a0..b8dc6d857 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -229,7 +229,7 @@ this: .. code-block:: python :linenos: - url = request.resource_url(resource, request) + url = request.resource_url(resource) The ``request`` in the above example is an instance of a :app:`Pyramid` :term:`request` object. -- cgit v1.2.3 From 012b9762cd0b114b6afbf2d6356554b51706804a Mon Sep 17 00:00:00 2001 From: michr Date: Fri, 23 Sep 2011 18:48:28 -0700 Subject: fixed up all the warning dealing ..note and ..warn added a hide toc for glossary to prevent warnings --- docs/narr/assets.rst | 8 ++++++-- docs/narr/hooks.rst | 16 ++++++++++++---- docs/narr/i18n.rst | 8 ++++++-- docs/narr/install.rst | 4 +++- docs/narr/logging.rst | 4 +++- docs/narr/muchadoabouttraversal.rst | 4 +++- docs/narr/project.rst | 4 +++- docs/narr/resources.rst | 4 +++- docs/narr/templates.rst | 4 +++- docs/narr/urldispatch.rst | 12 +++++++++--- 10 files changed, 51 insertions(+), 17 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 93b03fbc9..cd76f7b60 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -102,7 +102,9 @@ directory on a filesystem to an application user's browser. Use the mechanism makes a directory of static files available at a name relative to the application root URL, e.g. ``/static`` or as an external URL. -.. note:: :meth:`~pyramid.config.Configurator.add_static_view` cannot serve a +.. note:: + + :meth:`~pyramid.config.Configurator.add_static_view` cannot serve a single file, nor can it serve a directory of static files directly relative to the root URL of a :app:`Pyramid` application. For these features, see :ref:`advanced_static`. @@ -312,7 +314,9 @@ instance of this class is actually used by the :meth:`~pyramid.config.Configurator.add_static_view` configuration method, so its behavior is almost exactly the same once it's configured. -.. warning:: The following example *will not work* for applications that use +.. warning:: + + The following example *will not work* for applications that use :term:`traversal`, it will only work if you use :term:`URL dispatch` exclusively. The root-relative route we'll be registering will always be matched before traversal takes place, subverting any views registered via diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4afc0506b..3ab82ecf7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -55,7 +55,9 @@ Here's some sample code that implements a minimal NotFound view callable: def notfound_view(request): return HTTPNotFound() -.. note:: When a NotFound view callable is invoked, it is passed a +.. note:: + + When a NotFound view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will be an instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the not found view to be called. The value of @@ -64,7 +66,9 @@ Here's some sample code that implements a minimal NotFound view callable: ``pyramid.debug_notfound`` environment setting is true than it is when it is false. -.. warning:: When a NotFound view callable accepts an argument list as +.. warning:: + + When a NotFound view callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` passed as the first argument to the view callable will be the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception instance. If @@ -121,7 +125,9 @@ Here's some sample code that implements a minimal forbidden view: def forbidden_view(request): return Response('forbidden') -.. note:: When a forbidden view callable is invoked, it is passed a +.. note:: + + When a forbidden view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will be an instance of the :exc:`~pyramid.httpexceptions.HTTPForbidden` exception that caused the forbidden view to be called. The value of @@ -1100,7 +1106,9 @@ in the ``pyramid.tweens`` list will be used as the producer of the effective declared directly "below" it, ad infinitum. The "main" Pyramid request handler is implicit, and always "at the bottom". -.. note:: Pyramid's own :term:`exception view` handling logic is implemented +.. note:: + + Pyramid's own :term:`exception view` handling logic is implemented as a tween factory function: :func:`pyramid.tweens.excview_tween_factory`. If Pyramid exception view handling is desired, and tween factories are specified via the ``pyramid.tweens`` configuration setting, the diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index aef9b59ab..bac86e982 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -518,7 +518,9 @@ negotiator is registered. def aview(request): locale = get_localizer(request) -.. note:: If you need to create a localizer for a locale use the +.. note:: + + If you need to create a localizer for a locale use the :func:`pyramid.i18n.make_localizer` function. .. index:: @@ -555,7 +557,9 @@ represented by the request. The translation returned from its ``domain`` attribute of the provided translation string as well as the locale of the localizer. -.. note:: If you're using :term:`Chameleon` templates, you don't need +.. note:: + + If you're using :term:`Chameleon` templates, you don't need to pre-translate translation strings this way. See :ref:`chameleon_translation_strings`. diff --git a/docs/narr/install.rst b/docs/narr/install.rst index a1e7ce382..e1b5eb208 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -229,7 +229,9 @@ following: New python executable in env/bin/python Installing setuptools.............done. -.. warning:: Using ``--no-site-packages`` when generating your +.. warning:: + + Using ``--no-site-packages`` when generating your virtualenv is *very important*. This flag provides the necessary isolation for running the set of packages required by :app:`Pyramid`. If you do not specify ``--no-site-packages``, diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 8abcba3c7..3e39151a3 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -7,7 +7,9 @@ Logging :mod:`logging` module. This chapter describes how to configure logging and how to send log messages to loggers that you've configured. -.. warning:: This chapter assumes you've used a :term:`scaffold` to create a +.. warning:: + + This chapter assumes you've used a :term:`scaffold` to create a project which contains ``development.ini`` and ``production.ini`` files which help configure logging. All of the scaffolds which ship along with :app:`Pyramid` do this. If you're not using a scaffold, or if you've used diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 6ad33c1ce..a948e57cc 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -313,6 +313,8 @@ don't require it, great: stick with :term:`URL dispatch`. But if you're using :app:`Pyramid` and you ever find that you *do* need to support one of these use cases, you'll be glad you have traversal in your toolkit. -.. note:: It is even possible to mix and match :term:`traversal` with +.. note:: + + It is even possible to mix and match :term:`traversal` with :term:`URL dispatch` in the same :app:`Pyramid` application. See the :ref:`hybrid_chapter` chapter for details. diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 10b7a5d04..345672204 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -64,7 +64,9 @@ The included scaffolds are these: URL mapping via :term:`traversal` and persistence via :term:`SQLAlchemy` -.. note:: At this time, each of these scaffolds uses the :term:`Chameleon` +.. note:: + + At this time, each of these scaffolds uses the :term:`Chameleon` templating system, which is incompatible with Jython. To use scaffolds to build applications which will run on Jython, you can try the ``pyramid_jinja2_starter`` scaffold which ships as part of the diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index b8dc6d857..256f69fc3 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -160,7 +160,9 @@ resource in the resource tree, you will eventually come to the root resource, just like if you keep executing the ``cd ..`` filesystem command, eventually you will reach the filesystem root directory. -.. warning:: If your root resource has a ``__name__`` argument that is not +.. warning:: + + If your root resource has a ``__name__`` argument that is not ``None`` or the empty string, URLs returned by the :func:`~pyramid.request.Request.resource_url` function and paths generated by the :func:`~pyramid.traversal.resource_path` and diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 6412c070d..052843a23 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -46,7 +46,9 @@ within the body of a view callable like so: {'foo':1, 'bar':2}, request=request) -.. warning:: Earlier iterations of this documentation +.. warning:: + + Earlier iterations of this documentation (pre-version-1.3) encouraged the application developer to use ZPT-specific APIs such as :func:`pyramid.chameleon_zpt.render_template_to_response` and diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a6e46515f..9d5229c70 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -353,7 +353,9 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. -.. warning:: Some arguments are view-configuration related arguments, such as +.. warning:: + + Some arguments are view-configuration related arguments, such as ``view_renderer``. These only have an effect when the route configuration names a ``view`` and these arguments have been deprecated as of :app:`Pyramid` 1.1. @@ -646,7 +648,9 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. -.. note:: the ``static`` argument to +.. note:: + + the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` is new as of :app:`Pyramid` 1.1. @@ -1098,7 +1102,9 @@ permission. Obviously you can do more generic things than inspect the routes match dict to see if the ``article`` argument matches a particular string; our sample ``Article`` factory class is not very ambitious. -.. note:: See :ref:`security_chapter` for more information about +.. note:: + + See :ref:`security_chapter` for more information about :app:`Pyramid` security and ACLs. .. index:: -- cgit v1.2.3 From 52346bed8c07002f4b720b8b0889952dc1e02959 Mon Sep 17 00:00:00 2001 From: michr Date: Fri, 23 Sep 2011 19:54:35 -0700 Subject: add documenteation for the __text__ attribute for a predicate --- docs/narr/urldispatch.rst | 79 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 19 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 9d5229c70..2fcbce507 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -190,7 +190,7 @@ at the end of the segment represented by ``{name}.html`` (it only contains To capture both segments, two replacement markers can be used: .. code-block:: text - + foo/{name}.{ext} The literal path ``/foo/biz.html`` will match the above route pattern, and @@ -256,10 +256,10 @@ The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text - foo/1/2/ -> + foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()} - foo/abc/def/a/b/c -> + foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle':(u'a', u'b', u'c')} Note that when a ``*stararg`` remainder match is matched, the value put into @@ -288,7 +288,7 @@ split by segment. Changing the regular expression used to match a marker can also capture the remainder of the URL, for example: .. code-block:: text - + foo/{baz}/{bar}{fizzle:.*} The above pattern will match these URLs, generating the following matchdicts: @@ -699,10 +699,10 @@ route with an appended slash. .. warning:: - You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original - request. + You **should not** rely on this mechanism to redirect ``POST`` requests. + The redirect of the slash-appending not found view will turn a ``POST`` + request into a ``GET``, losing any ``POST`` data in the original + request. To configure the slash-appending not found view in your application, change the application's startup configuration, adding the following stanza: @@ -710,7 +710,7 @@ the application's startup configuration, adding the following stanza: .. code-block:: python :linenos: - config.add_view('pyramid.view.append_slash_notfound_view', + config.add_view('pyramid.view.append_slash_notfound_view', context='pyramid.httpexceptions.HTTPNotFound') See :ref:`view_module` and :ref:`changing_the_notfound_view` for more @@ -772,7 +772,7 @@ which you started the application from. For example: :linenos: [chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \ - bin/paster serve development.ini + bin/paster serve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ @@ -813,7 +813,7 @@ will have their pattern prefixed with the value of ``route_prefix``. This can be used to help mount a set of routes at a different location than the included callable's author intended while still maintaining the same route names. For example: - + .. code-block:: python :linenos: @@ -821,7 +821,7 @@ names. For example: def users_include(config): config.add_route('show_users', '/show') - + def main(global_config, **settings): config = Configurator() config.include(users_include, route_prefix='/users') @@ -844,7 +844,7 @@ will be prepended with the first: def timing_include(config): config.add_route('show_times', /times') - + def users_include(config): config.add_route('show_users', '/show') config.include(timing_include, route_prefix='/timing') @@ -871,7 +871,7 @@ that may be added in the future. For example: def timing_include(config): config.add_route('timing.show_times', /times') - + def users_include(config): config.add_route('users.show_users', '/show') config.include(timing_include, route_prefix='/timing') @@ -913,7 +913,7 @@ For example: num_one_two_or_three = any_of('num', 'one', 'two', 'three') - config.add_route('route_to_num', '/{num}', + config.add_route('route_to_num', '/{num}', custom_predicates=(num_one_two_or_three,)) The above ``any_of`` function generates a predicate which ensures that the @@ -944,7 +944,7 @@ instance, a predicate might do some type conversion of values: ymd_to_int = integers('year', 'month', 'day') - config.add_route('ymd', '/{year}/{month}/{day}', + config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(ymd_to_int,)) Note that a conversion predicate is still a predicate so it must return @@ -967,7 +967,7 @@ expressions specifying requirements for that marker. For instance: ymd_to_int = integers('year', 'month', 'day') - config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', + config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', custom_predicates=(ymd_to_int,)) Now the try/except is no longer needed because the route will not match at @@ -1005,13 +1005,54 @@ the route in a set of route predicates: config.add_route('y', '/{year}', custom_predicates=(twenty_ten,)) config.add_route('ym', '/{year}/{month}', custom_predicates=(twenty_ten,)) - config.add_route('ymd', '/{year}/{month}/{day}', + config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(twenty_ten,)) The above predicate, when added to a number of route configurations ensures that the year match argument is '2010' if and only if the route name is 'ymd', 'ym', or 'y'. +You can also caption the predicates by setting the ``__text__`` attribute. This +will help you with the ``paster pviews`` command (see +:ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. + +If a predicate is a class just add __text__ property in a standard manner. + +.. code-block:: python + :linenos: + + class DummyCustomPredicate1(object): + def __init__(self): + self.__text__ = 'my custom class predicate' + + class DummyCustomPredicate2(object): + __text__ = 'my custom class predicate' + +If a predicate is a method you'll need to assign it after method declaration +(see `PEP 232 `_) + +.. code-block:: python + :linenos: + + def custom_predicate(): + pass + custom_predicate.__text__ = 'my custom method predicate' + +If a predicate is a classmethod using @classmethod will not work, but you can +still easily do it by wrapping it in classmethod call. + +.. code-block:: python + :linenos: + + def classmethod_predicate(): + pass + classmethod_predicate.__text__ = 'my classmethod predicate' + classmethod_predicate = classmethod(classmethod_predicate) + +Same will work with staticmethod, just use ``staticmethod`` instead of +``classmethod``. + + See also :class:`pyramid.interfaces.IRoute` for more API documentation about route objects. @@ -1034,7 +1075,7 @@ callable ultimately found via :term:`view lookup`. .. code-block:: python :linenos: - config.add_route('abc', '/abc', + config.add_route('abc', '/abc', factory='myproject.resources.root_factory') config.add_view('myproject.views.theview', route_name='abc') -- cgit v1.2.3 From 7a66b778592422e32d121cf96313204c2ba23b44 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 27 Sep 2011 00:11:58 -0400 Subject: typo --- 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 3ab82ecf7..7db1eca73 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -863,8 +863,8 @@ Pyramid request handling function or another tween. ``registry`` will be the Pyramid :term:`application registry` represented by this Configurator. A tween factory must return a tween when it is called. -A tween is a callable which accepts a :term:`request` object and returns a -two-tuple a :term:`response` object. +A tween is a callable which accepts a :term:`request` object and returns +a :term:`response` object. Here's an example of a tween factory: -- cgit v1.2.3 From c8b363e547635e92a78c5718e9f17a5e8f55dc7f Mon Sep 17 00:00:00 2001 From: michr Date: Thu, 29 Sep 2011 02:03:33 -0700 Subject: avoid warning for latexindex, foreword by putting them in a hidden toc from now on complie docs strictly, turning warnings to errors exclude unnecssary static js files when compiling ePub --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 823c1ea13..8f0533997 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -826,7 +826,7 @@ trolls" or other people who seem to get their rocks off by berating fellow users in our various offical support channels. We try to keep it well-lit and new-user-friendly. -Example: Visit irc://freenode.net#pyramid (the ``#pyramid`` channel on +Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at http://groups.google.com/group/pylons-discuss/ . -- cgit v1.2.3 From b1e795e320a505f9ed737a5f1466261508cfc33b Mon Sep 17 00:00:00 2001 From: Casey Duncan Date: Sat, 1 Oct 2011 15:03:48 -0600 Subject: Fix incorrect import in static view example --- 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 cd76f7b60..4f80d33c7 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -335,7 +335,7 @@ your application root as below. .. code-block:: python :linenos: - from pyramid.static import static + from pyramid.static import static_view static_view = static_view('/path/to/static/dir', use_subpath=True) .. note:: For better cross-system flexibility, use an :term:`asset -- cgit v1.2.3 From 0078b214ca0d64a631674a95b002dfd82e2ba963 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 4 Oct 2011 15:16:36 -0500 Subject: Fixed the translogger example and link. --- docs/narr/logging.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 3e39151a3..9625723ba 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -297,7 +297,7 @@ Request Logging with Paste's TransLogger ---------------------------------------- Paste provides the `TransLogger -`_ middleware for logging +`_ middleware for logging requests using the `Apache Combined Log Format `_. TransLogger combined with a FileHandler can be used to create an ``access.log`` file similar to @@ -323,7 +323,7 @@ To this: use = egg:MyProject [filter:translogger] - paste.filter_app_factory = egg:Paste#translogger + use = egg:Paste#translogger setup_console_handler = False [pipeline:main] -- cgit v1.2.3 From cfb2b5596b8ef366aeef3bce5b61eafc7a2f175d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 6 Oct 2011 03:05:29 -0400 Subject: remove all reference to the paster command-line utility --- docs/narr/MyProject/setup.py | 1 - docs/narr/commandline.rst | 70 +++++++-------- docs/narr/hooks.rst | 9 +- docs/narr/introduction.rst | 10 +-- docs/narr/logging.rst | 8 +- docs/narr/paste.rst | 45 +++++----- docs/narr/project.rst | 200 ++++++++++++++++++------------------------- docs/narr/security.rst | 2 +- docs/narr/startup.rst | 41 +++++---- docs/narr/templates.rst | 4 +- docs/narr/urldispatch.rst | 10 +-- 11 files changed, 179 insertions(+), 221 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index 5203fc2a7..74879f65d 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -32,6 +32,5 @@ setup(name='MyProject', [paste.app_factory] main = myproject:main """, - paster_plugins=['pyramid'], ) diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index a8459ac27..0dc41e919 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -9,7 +9,7 @@ chapter. .. index:: pair: matching views; printing - single: paster pviews + single: pviews .. _displaying_matching_views: @@ -18,9 +18,9 @@ Displaying Matching Views for a Given URL 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 ``paster pviews`` command in a terminal window to +yourself. You can use the ``pviews`` command in a terminal window to print a summary of matching routes and views for a given URL in your -application. The ``paster pviews`` command accepts two arguments. The first +application. The ``pviews`` command accepts two arguments. The first argument to ``pviews`` is the path to your application's ``.ini`` file and section name inside the ``.ini`` file which points to your application. This should be of the format ``config_file#section_name``. The second argument is @@ -32,7 +32,7 @@ Here is an example for a simple view configuration using :term:`traversal`: .. code-block:: text :linenos: - $ ../bin/paster pviews development.ini#tutorial /FrontPage + $ ../bin/pviews development.ini#tutorial /FrontPage URL = /FrontPage @@ -56,7 +56,7 @@ A more complex configuration might generate something like this: .. code-block:: text :linenos: - $ ../bin/paster pviews development.ini#shootout /about + $ ../bin/pviews development.ini#shootout /about URL = /about @@ -103,14 +103,13 @@ displayed first, followed by any views that are associated with that route. As you can see from the second matching route output, a route can be associated with more than one view. -For a URL that doesn't match any views, ``paster pviews`` will simply print -out a *Not found* message. +For a URL that doesn't match any views, ``pviews`` will simply print out a +*Not found* message. .. index:: single: interactive shell single: IPython - single: paster pshell single: pshell .. _interactive_shell: @@ -121,7 +120,7 @@ The Interactive Shell 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 "for real". To do so, use the ``paster pshell`` command. +application runs "for real". To do so, use the ``pshell`` command. The argument to ``pshell`` follows the format ``config_file#section_name`` where ``config_file`` is the path to your application's ``.ini`` file and @@ -145,7 +144,7 @@ name ``MyProject`` as a section name: .. code-block:: text - chrism@thinko env26]$ bin/paster pshell starter/development.ini#MyProject + chrism@thinko env26]$ bin/pshell starter/development.ini#MyProject Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -180,7 +179,7 @@ hash after the filename: .. code-block:: text - chrism@thinko env26]$ bin/paster pshell starter/development.ini + chrism@thinko env26]$ bin/pshell starter/development.ini Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). @@ -243,7 +242,7 @@ exposed, and the request is configured to generate urls from the host .. code-block:: text - chrism@thinko env26]$ bin/paster pshell starter/development.ini + chrism@thinko env26]$ bin/pshell starter/development.ini Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -273,22 +272,20 @@ IPython ~~~~~~~ If you have `IPython `_ installed in -the interpreter you use to invoke the ``paster`` command, the ``pshell`` -command will use an IPython interactive shell instead of a standard Python -interpreter shell. If you don't want this to happen, even if you have -IPython installed, you can pass the ``--disable-ipython`` flag to the -``pshell`` command to use a standard Python interpreter shell -unconditionally. +the interpreter you use to invoke the ``pshell`` command, ``pshell`` will use +an IPython interactive shell instead of a standard Python interpreter shell. +If you don't want this to happen, even if you have IPython installed, you can +pass the ``--disable-ipython`` flag to the ``pshell`` command to use a +standard Python interpreter shell unconditionally. .. code-block:: text - [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ + [chrism@vitaminf shellenv]$ ../bin/pshell --disable-ipython \ development.ini#MyProject .. index:: pair: routes; printing - single: paster proutes single: proutes .. _displaying_application_routes: @@ -296,11 +293,11 @@ unconditionally. Displaying All Application Routes --------------------------------- -You can use the ``paster proutes`` command in a terminal window to print a -summary of routes related to your application. Much like the ``paster -pshell`` command (see :ref:`interactive_shell`), the ``paster proutes`` -command accepts one argument with the format ``config_file#section_name``. -The ``config_file`` is the path to your application's ``.ini`` file, and +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 the format ``config_file#section_name``. The +``config_file`` is the path to your application's ``.ini`` file, and ``section_name`` is the ``app`` section name inside the ``.ini`` file which points to your application. By default, the ``section_name`` is ``main`` and can be omitted. @@ -310,7 +307,7 @@ For example: .. code-block:: text :linenos: - [chrism@thinko MyProject]$ ../bin/paster proutes development.ini#MyProject + [chrism@thinko MyProject]$ ../bin/proutes development.ini#MyProject Name Pattern View ---- ------- ---- home / @@ -319,19 +316,18 @@ For example: static/ static/*subpath catchall /*subpath -``paster proutes`` generates a table. The table has three columns: a Name +``proutes`` generates a table. The table has three columns: a Name column, a Pattern column, and a View column. The items listed in the Name column are route names, the items listed in the Pattern column are route patterns, and the items listed in the View column are representations of the view callable that will be invoked when a request matches the associated route pattern. The view column may show ``None`` if no associated view callable could be found. If no routes are configured within your -application, nothing will be printed to the console when ``paster proutes`` +application, nothing will be printed to the console when ``proutes`` is executed. .. index:: pair: tweens; printing - single: paster ptweens single: ptweens .. _displaying_tweens: @@ -344,17 +340,17 @@ 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 calls to :meth:`pyramid.config.Configurator.add_tween`) and the explicit tween ordering (specified by the ``pyramid.tweens`` configuration -setting) orderings using the ``paster ptweens`` command. Tween factories +setting) orderings using the ``ptweens`` command. Tween factories will show up represented by their standard Python dotted name in the -``paster ptweens`` output. +``ptweens`` output. -For example, here's the ``paster pwteens`` command run against a system +For example, here's the ``pwteens`` command run against a system configured without any explicit tweens: .. code-block:: text :linenos: - [chrism@thinko pyramid]$ paster ptweens development.ini + [chrism@thinko pyramid]$ ptweens development.ini "pyramid.tweens" config value NOT set (implicitly ordered tweens used) Implicit Tween Chain @@ -366,13 +362,13 @@ configured without any explicit tweens: 1 pyramid.tweens.excview_tween_factory excview - - MAIN -Here's the ``paster pwteens`` command run against a system configured *with* +Here's the ``pwteens`` command run against a system configured *with* explicit tweens defined in its ``development.ini`` file: .. code-block:: text :linenos: - [chrism@thinko pyramid]$ paster ptweens development.ini + [chrism@thinko pyramid]$ ptweens development.ini "pyramid.tweens" config value set (explicitly ordered tweens used) Explicit Tween Chain (used) @@ -395,8 +391,8 @@ explicit tweens defined in its ``development.ini`` file: - - MAIN Here's the application configuration section of the ``development.ini`` used -by the above ``paster ptweens`` command which reprorts that the explicit -tween chain is used: +by the above ``ptweens`` command which reports that the explicit tween chain +is used: .. code-block:: text :linenos: diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 7db1eca73..3c6799afb 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -727,7 +727,7 @@ A user might make use of these framework components like so: from pyramid.response import Response from pyramid.config import Configurator import pyramid_handlers - from paste.httpserver import serve + from wsgiref.simple_server import make_server class MyController(BaseController): def index(self, id): @@ -738,7 +738,8 @@ A user might make use of these framework components like so: config.include(pyramid_handlers) config.add_handler('one', '/{id}', MyController, action='index') config.add_handler('two', '/{action}/{id}', MyController) - serve(config.make_wsgi_app()) + server.make_server('0.0.0.0', 8080, config.make_wsgi_app()) + server.serve_forever() The :meth:`pyramid.config.Configurator.set_view_mapper` method can be used to set a *default* view mapper (overriding the superdefault view mapper used by @@ -1012,7 +1013,7 @@ Effectively, ``under`` means "closer to the main Pyramid application than", For example, the following call to :meth:`~pyramid.config.Configurator.add_tween` will attempt to place the tween factory represented by ``myapp.tween_factory`` directly 'above' (in -``paster ptweens`` order) the main Pyramid request handler. +``ptweens`` order) the main Pyramid request handler. .. code-block:: python :linenos: @@ -1136,6 +1137,6 @@ time. Displaying Tween Ordering ~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``paster ptweens`` command-line utility can be used to report the current +The ``ptweens`` command-line utility can be used to report the current implict and explicit tween chains used by an application. See :ref:`displaying_tweens`. diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 823c1ea13..e30a23a9a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -202,11 +202,11 @@ turn on "debug_authorization", which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. -There are also a number of ``paster`` commands that allow you to introspect -the configuration of your system: ``paster proutes`` shows all configured -routes for an application in the order they'll be evaluated for matching; -``paster pviews`` shows all configured views for any given URL. These are -also WTF-crushers in some circumstances. +There are also a number of commands that you can invoke within a Pyramid +environment that allow you to introspect the configuration of your system: +``proutes`` shows all configured routes for an application in the order +they'll be evaluated for matching; ``pviews`` shows all configured views for +any given URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 3e39151a3..b18fefae0 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -32,13 +32,13 @@ format used as the Python `logging module's Configuration file format `_. The application-related and logging-related sections in the configuration file can coexist peacefully, and the logging-related sections in the file are used -from when you run ``paster serve``. +from when you run ``pserve``. -The ``paster serve`` command calls the `logging.fileConfig function +The ``pserve`` command calls the `logging.fileConfig function `_ using the specified ini file if it contains a ``[loggers]`` section (all of the scaffold-generated ``.ini`` files do). ``logging.fileConfig`` reads the -logging configuration from the ini file upon which ``paster serve`` was +logging configuration from the ini file upon which ``pserve`` was invoked. Default logging configuration is provided in both the default @@ -89,7 +89,7 @@ project. For instance, if you do: .. code-block:: text :linenos: - paster create -t pyramid_starter MyApp + pcreate -s starter MyApp The logging configuration will literally be: diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index 39ae4f373..5c7d4c3fb 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -1,26 +1,25 @@ .. _paste_chapter: -Paste -===== +PasteDeploy Configuration Files +=============================== Packages generated via a :term:`scaffold` make use of a system created by Ian -Bicking named :term:`Paste`. Paste provides the following features: - -- A way to declare :term:`WSGI` application configuration in an ``.ini`` file - (PasteDeploy). - -- A :term:`WSGI` server runner (``paster serve``) which can accept - PasteDeploy ``.ini`` file values as input. - -- A mechanism for rendering scaffolds into projects (``paster create``). - -Paste is not a particularly integral part of Pyramid. It's more or less used -directly only in projects created from scaffolds. It's possible to create a -Pyramid application which does not use Paste at all. We show a Pyramid -application that doesn't use Paste in :ref:`firstapp_chapter`. However, all -Pyramid scaffolds use the system, to provide new developers with a -standardized way of starting, stopping, and setting deployment values. This -chapter is not a replacement for documentation about Paste or PasteDeploy; it +Bicking named :term:`PasteDeploy`. PasteDeploy defines a way to declare +:term:`WSGI` application configuration in an ``.ini`` file. + +Pyramid uses this configuration file format in input to its :term:`WSGI` +server runner ``pserve``, as well as other commands such as ``pviews``, +``pshell``, ``proutes``, and ``ptweens``. + +PasteDeploy is not a particularly integral part of Pyramid. It's possible to +create a Pyramid application which does not use PasteDeploy at all. We show +a Pyramid application that doesn't use PasteDeploy in +:ref:`firstapp_chapter`. However, all Pyramid scaffolds render PasteDeploy +configuration files, to provide new developers with a standardized way of +setting deployment values, and to provide new users with a standardized way +of starting, stopping, and debugging an application. + +This chapter is not a replacement for documentation about PasteDeploy; it only contextualizes the use of Paste within Pyramid. For detailed documentation, see http://pythonpaste.org. @@ -29,7 +28,7 @@ PasteDeploy :term:`PasteDeploy` is the system that Pyramid uses to allow :term:`deployment settings` to be spelled using an ``.ini`` configuration -file format. It also allows the ``paster serve`` command to work. Its +file format. It also allows the ``pserve`` command to work. Its configuration format provides a convenient place to define application :term:`deployment settings` and WSGI server settings, and its server runner allows you to stop and start a Pyramid application easily. @@ -82,9 +81,9 @@ factory in the ``MyProject`` project which has the entry point named ``main`` where the entry point refers to a ``main`` function in the ``mypackage`` module". Indeed, if you open up the ``__init__.py`` module generated within any scaffold-generated package, you'll see a ``main`` function. This is the -function called by :term:`PasteDeploy` when the ``paster serve`` command is -invoked against our application. It accepts a global configuration object -and *returns* an instance of our application. +function called by :term:`PasteDeploy` when the ``pserve`` command is invoked +against our application. It accepts a global configuration object and +*returns* an instance of our application. ``[DEFAULTS]`` Section of a PasteDeploy ``.ini`` File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 345672204..c961b4143 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -20,15 +20,15 @@ distributed more easily than one which does not live within a package. a project. Each scaffold makes different configuration assumptions about what type of application you're trying to construct. -These scaffolds are rendered using the :term:`PasteDeploy` ``paster create`` -command. +These scaffolds are rendered using the ``pcreate`` command that is installed +as part of Pyramid. .. index:: single: scaffolds - single: pyramid_starter scaffold - single: pyramid_zodb scaffold - single: pyramid_alchemy scaffold - single: pyramid_routesalchemy scaffold + single: starter scaffold + single: zodb scaffold + single: alchemy scaffold + single: routesalchemy scaffold .. _additional_paster_scaffolds: @@ -44,36 +44,24 @@ each other on a number of axes: - the mechanism they use to map URLs to code (:term:`traversal` or :term:`URL dispatch`). -- whether or not the ``pyramid_beaker`` library is relied upon as the - sessioning implementation (as opposed to no sessioning or default - sessioning). - The included scaffolds are these: -``pyramid_starter`` +``starter`` URL mapping via :term:`traversal` and no persistence mechanism. -``pyramid_zodb`` +``zodb`` URL mapping via :term:`traversal` and persistence via :term:`ZODB`. -``pyramid_routesalchemy`` +``routesalchemy`` URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` -``pyramid_alchemy`` +``alchemy`` URL mapping via :term:`traversal` and persistence via :term:`SQLAlchemy` .. note:: - At this time, each of these scaffolds uses the :term:`Chameleon` - templating system, which is incompatible with Jython. To use scaffolds to - build applications which will run on Jython, you can try the - ``pyramid_jinja2_starter`` scaffold which ships as part of the - :term:`pyramid_jinja2` package. You can also just use any above scaffold - and replace the Chameleon template it includes with a :term:`Mako` - analogue. - Rather than use any of the above scaffolds, Pylons 1 users may feel more comfortable installing the :term:`Akhet` development environment, which provides a scaffold named ``akhet``. This scaffold configures a Pyramid @@ -91,85 +79,64 @@ Creating the Project In :ref:`installing_chapter`, you created a virtual Python environment via the ``virtualenv`` command. To start a :app:`Pyramid` :term:`project`, use -the ``paster`` facility installed within the virtualenv. In +the ``pcreate`` command installed within the virtualenv. In :ref:`installing_chapter` we called the virtualenv directory ``env``; the following command assumes that our current working directory is that -directory. We'll choose the ``pyramid_starter`` scaffold for this purpose. +directory. We'll choose the ``starter`` scaffold for this purpose. On UNIX: .. code-block:: text - $ bin/paster create -t pyramid_starter + $ bin/pcreate -s starter MyProject Or on Windows: .. code-block:: text - $ Scripts\paster.exe create -t pyramid_starter + $ Scripts\pcreate -s starter MyProject -The above command uses the ``paster create`` command to create a project with -the ``pyramid_starter`` scaffold. To use a different scaffold, such as -``pyramid_routesalchemy``, you'd just change the last argument. For example, +The above command uses the ``pcreate`` command to create a project with the +``starter`` scaffold. To use a different scaffold, such as +``routesalchemy``, you'd just change the ``-s`` argument value. For example, on UNIX: .. code-block:: text - $ bin/paster create -t pyramid_routesalchemy + $ bin/pcreate -s routesalchemy MyProject Or on Windows: .. code-block:: text - $ Scripts\paster.exe create -t pyramid_routesalchemy + $ Scripts\pcreate routesalchemy MyProject -``paster create`` will ask you a single question: the *name* of the project. -You should use a string without spaces and with only letters in it. Here's -sample output from a run of ``paster create`` on UNIX for a project we name +Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: .. code-block:: text - $ bin/paster create -t pyramid_starter - Selected and implied templates: - pyramid#pyramid_starter pyramid starter project - - Enter project name: MyProject - Variables: - egg: MyProject - package: myproject - project: MyProject + $ bin/pcreate -s starter MyProject Creating template pyramid Creating directory ./MyProject # ... more output ... Running /Users/chrism/projects/pyramid/bin/python setup.py egg_info -.. note:: You can skip the interrogative question about a project - name during ``paster create`` by adding the project name to the - command line, e.g. ``paster create -t pyramid_starter MyProject``. - -.. note:: You may encounter an error when using ``paster create`` if a - dependent Python package is not installed. This will result in a traceback - ending in ``pkg_resources.DistributionNotFound: ``. Simply - run ``bin/easy_install`` (or ``Script\easy_install.exe`` on Windows), with - the missing package name from the error message to work around this issue. - -As a result of invoking the ``paster create`` command, a project is created -in a directory named ``MyProject``. That directory is a :term:`project` +As a result of invoking the ``pcreate`` command, a project is created in a +directory named ``MyProject``. That directory is a :term:`project` directory. The ``setup.py`` file in that directory can be used to distribute your application, or install your application for deployment or development. -A :term:`PasteDeploy` ``.ini`` file named ``development.ini`` will be created -in the project directory. You will use this ``.ini`` file to configure a -server, to run your application, and to debug your application. It sports -configuration that enables an interactive debugger and settings optimized for -development. +A ``.ini`` file named ``development.ini`` will be created in the project +directory. You will use this ``.ini`` file to configure a server, to run +your application, and to debug your application. It sports configuration +that enables an interactive debugger and settings optimized for development. -Another :term:`PasteDeploy` ``.ini`` file named ``production.ini`` will also -be created in the project directory. It sports configuration that disables -any interactive debugger (to prevent inappropriate access and disclosure), -and turns off a number of debugging settings. You can use this file to put -your application into production. +Another ``.ini`` file named ``production.ini`` will also be created in the +project directory. It sports configuration that disables any interactive +debugger (to prevent inappropriate access and disclosure), and turns off a +number of debugging settings. You can use this file to put your application +into production. The ``MyProject`` project directory contains an additional subdirectory named ``myproject`` (note the case difference) representing a Python @@ -188,7 +155,7 @@ newly created project directory and use the Python interpreter from the :term:`virtualenv` you created during :ref:`installing_chapter` to invoke the command ``python setup.py develop`` -The file named ``setup.py`` will be in the root of the paster-generated +The file named ``setup.py`` will be in the root of the pcreate-generated project directory. The ``python`` you're invoking should be the one that lives in the ``bin`` (or ``Scripts`` on Windows) directory of your virtual Python environment. Your terminal's current working directory *must* be the @@ -219,8 +186,8 @@ Elided output from a run of this command on UNIX is shown below: This will install a :term:`distribution` representing your project into the interpreter's library set so it can be found by ``import`` statements and by -:term:`PasteDeploy` commands such as ``paster serve``, ``paster pshell``, -``paster proutes`` and ``paster pviews``. +other console scripts such as ``pserve``, ``pshell``, ``proutes`` and +``pviews``. .. index:: single: running tests @@ -273,13 +240,13 @@ Here's sample output from a test run on UNIX: output to a stream of dots. If you don't pass ``-q``, you'll see more verbose test result output (which normally isn't very useful). -The tests themselves are found in the ``tests.py`` module in your ``paster -create`` -generated project. Within a project generated by the -``pyramid_starter`` scaffold, a single sample test exists. +The tests themselves are found in the ``tests.py`` module in your ``pcreate`` +generated project. Within a project generated by the ``starter`` scaffold, a +single sample test exists. .. index:: single: running an application - single: paster serve + single: pserve single: reload single: startup @@ -287,26 +254,26 @@ Running The Project Application ------------------------------- Once a project is installed for development, you can run the application it -represents using the ``paster serve`` command against the generated -configuration file. In our case, this file is named ``development.ini``. +represents using the ``pserve`` command against the generated configuration +file. In our case, this file is named ``development.ini``. On UNIX: .. code-block:: text - $ ../bin/paster serve development.ini + $ ../bin/pserve development.ini On Windows: .. code-block:: text - $ ..\Scripts\paster.exe serve development.ini + $ ..\Scripts\pserve development.ini -Here's sample output from a run of ``paster serve`` on UNIX: +Here's sample output from a run of ``pserve`` on UNIX: .. code-block:: text - $ ../bin/paster serve development.ini + $ ../bin/pserve development.ini Starting server in PID 16601. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 @@ -314,18 +281,17 @@ By default, :app:`Pyramid` applications generated from a scaffold will listen on TCP port 6543. You can shut down a server started this way by pressing ``Ctrl-C``. -During development, it's often useful to run ``paster serve`` using its -``--reload`` option. When ``--reload`` is passed to ``paster serve``, -changes to any Python module your project uses will cause the server to -restart. This typically makes development easier, as changes to Python code -made within a :app:`Pyramid` application is not put into effect until the -server restarts. +During development, it's often useful to run ``pserve`` using its +``--reload`` option. When ``--reload`` is passed to ``pserve``, changes to +any Python module your project uses will cause the server to restart. This +typically makes development easier, as changes to Python code made within a +:app:`Pyramid` application is not put into effect until the server restarts. For example, on UNIX: .. code-block:: text - $ ../bin/paster serve development.ini --reload + $ ../bin/pserve development.ini --reload Starting subprocess with file monitor Starting server in PID 16601. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 @@ -341,14 +307,14 @@ configuration file settings that influence startup and runtime behavior, see Viewing the Application ----------------------- -Once your application is running via ``paster serve``, you may visit +Once your application is running via ``pserve``, you may visit ``http://localhost:6543/`` in your browser. You will see something in your browser like what is displayed in the following image: .. image:: project.png -This is the page shown by default when you visit an unmodified ``paster -create`` -generated ``pyramid_starter`` application in a browser. +This is the page shown by default when you visit an unmodified ``pcreate`` +generated ``starter`` application in a browser. .. index:: single: debug toolbar @@ -403,13 +369,12 @@ Then restart the application to see that the toolbar has been turned off. The Project Structure --------------------- -The ``pyramid_starter`` scaffold generated a :term:`project` (named -``MyProject``), which contains a Python :term:`package`. The package is -*also* named ``myproject``, but it's lowercased; the scaffold -generates a project which contains a package that shares its name except for -case. +The ``starter`` scaffold generated a :term:`project` (named ``MyProject``), +which contains a Python :term:`package`. The package is *also* named +``myproject``, but it's lowercased; the scaffold generates a project which +contains a package that shares its name except for case. -All :app:`Pyramid` ``paster`` -generated projects share a similar structure. +All :app:`Pyramid` ``pcreate`` -generated projects share a similar structure. The ``MyProject`` project we've generated has the following directory structure: @@ -475,8 +440,8 @@ describe, run, and test your application. ~~~~~~~~~~~~~~~~~~~ The ``development.ini`` file is a :term:`PasteDeploy` configuration file. -Its purpose is to specify an application to run when you invoke ``paster -serve``, as well as the deployment settings provided to that application. +Its purpose is to specify an application to run when you invoke ``pserve``, +as well as the deployment settings provided to that application. The generated ``development.ini`` file looks like so: @@ -529,9 +494,9 @@ or influencing runtime behavior of a :app:`Pyramid` application. See :ref:`environment_chapter` for more information about these settings. The name ``main`` in ``[app:main]`` signifies that this is the default -application run by ``paster serve`` when it is invoked against this -configuration file. The name ``main`` is a convention used by PasteDeploy -signifying that it is the default application. +application run by ``pserve`` when it is invoked against this configuration +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 @@ -544,7 +509,7 @@ and ``# End logging configuration`` represent Python's standard library between these two markers are passed to the `logging module's config file configuration engine `_ when the -``paster serve`` or ``paster pshell`` commands are executed. The default +``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`. @@ -762,7 +727,7 @@ also informs Python that the directory which contains it is a *package*. #. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the - :term:`PasteDeploy` framework as a result of running ``paster serve``. + :term:`PasteDeploy` framework as a result of running ``pserve``. Within this function, application configuration is performed. @@ -922,10 +887,10 @@ way you see fit. For example, the configuration method named :meth:`~pyramid.config.Configurator.add_view` requires you to pass a :term:`dotted Python name` or a direct object reference as the class or -function to be used as a view. By default, the ``pyramid_starter`` scaffold -would have you add view functions to the ``views.py`` module in your -package. However, you might be more comfortable creating a ``views`` -*directory*, and adding a single file for each view. +function to be used as a view. By default, the ``starter`` scaffold would +have you add view functions to the ``views.py`` module in your package. +However, you might be more comfortable creating a ``views`` *directory*, and +adding a single file for each view. If your project package name was ``myproject`` and you wanted to arrange all your views in a Python subpackage within the ``myproject`` :term:`package` @@ -980,33 +945,32 @@ Using the Interactive Shell It is possible to use a Python interpreter prompt loaded with a similar configuration as would be loaded if you were running your Pyramid application -via ``paster serve``. This can be a useful debugging tool. See +via ``pserve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. Using an Alternate WSGI Server ------------------------------ The code generated by a :app:`Pyramid` scaffold assumes that you will be -using the ``paster serve`` command to start your application while you do -development. However, ``paster serve`` is by no means the only way to start -up and serve a :app:`Pyramid` application. As we saw in -:ref:`firstapp_chapter`, ``paster serve`` needn't be invoked at all to run a -:app:`Pyramid` application. The use of ``paster serve`` to run a -:app:`Pyramid` application is purely conventional based on the output of its -scaffold. +using the ``pserve`` command to start your application while you do +development. However, ``pserve`` is by no means the only way to start up and +serve a :app:`Pyramid` application. As we saw in :ref:`firstapp_chapter`, +``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. +The use of ``pserve`` to run a :app:`Pyramid` application is purely +conventional based on the output of its scaffold. Any :term:`WSGI` server is capable of running a :app:`Pyramid` application. -Some WSGI servers don't require the :term:`PasteDeploy` framework's ``paster -serve`` command to do server process management at all. Each :term:`WSGI` +Some WSGI servers don't require the :term:`PasteDeploy` framework's +``pserve`` command to do server process management at all. Each :term:`WSGI` server has its own documentation about how it creates a process to run an application, and there are many of them, so we cannot provide the details for each here. But the concepts are largely the same, whatever server you happen to use. -One popular production alternative to a ``paster``-invoked server is +One popular production alternative to a ``pserve``-invoked server is :term:`mod_wsgi`. You can also use :term:`mod_wsgi` to serve your :app:`Pyramid` application using the Apache web server rather than any -"pure-Python" server that is started as a result of ``paster serve``. See +"pure-Python" server that is started as a result of ``pserve``. See :ref:`modwsgi_tutorial` for details. However, it is usually easier to -*develop* an application using a ``paster serve`` -invoked webserver, as +*develop* an application using a ``pserve`` -invoked webserver, as exception and debugging output will be sent to the console. diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 5a18ca851..1ad35b961 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -512,7 +512,7 @@ example: .. code-block:: text - $ PYRAMID_DEBUG_AUTHORIZATION=1 bin/paster serve myproject.ini + $ PYRAMID_DEBUG_AUTHORIZATION=1 bin/pserve myproject.ini When any authorization takes place during a top-level view rendering, a message will be logged to the console (to stderr) about what ACE in diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index c66264655..f4ebef154 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -8,12 +8,12 @@ you'll see something much like this show up on the console: .. code-block:: text - $ paster serve myproject/MyProject.ini + $ pserve myproject/MyProject.ini Starting server in PID 16601. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 This chapter explains what happens between the time you press the "Return" -key on your keyboard after typing ``paster serve myproject/MyProject.ini`` +key on your keyboard after typing ``pserve myproject/MyProject.ini`` and the time the line ``serving on 0.0.0.0:6543 ...`` is output to your console. @@ -24,22 +24,21 @@ The Startup Process ------------------- The easiest and best-documented way to start and serve a :app:`Pyramid` -application is to use the ``paster serve`` command against a +application is to use the ``pserve`` command against a :term:`PasteDeploy` ``.ini`` file. This uses the ``.ini`` file to infer settings and starts a server listening on a port. For the purposes of this discussion, we'll assume that you are using this command to run your :app:`Pyramid` application. Here's a high-level time-ordered overview of what happens when you press -``return`` after running ``paster serve development.ini``. +``return`` after running ``pserve development.ini``. -#. The :term:`PasteDeploy` ``paster`` command is invoked under your shell - with the arguments ``serve`` and ``development.ini``. As a result, the - :term:`PasteDeploy` framework recognizes that it is meant to begin to run - and serve an application using the information contained within the - ``development.ini`` file. +#. The ``pserve`` command is invoked under your shell with the argument + ``development.ini``. As a result, Pyramid recognizes that it is meant to + begin to run and serve an application using the information contained + within the ``development.ini`` file. -#. The PasteDeploy framework finds a section named either ``[app:main]``, +#. The framework finds a section named either ``[app:main]``, ``[pipeline:main]``, or ``[composite:main]`` in the ``.ini`` file. This section represents the configuration of a :term:`WSGI` application that will be served. If you're using a simple application (e.g. @@ -48,16 +47,16 @@ Here's a high-level time-ordered overview of what happens when you press configuration. If, instead of a simple application, you're using a WSGI :term:`pipeline` (e.g. a ``[pipeline:main]`` section), the application named on the "last" element will refer to your :app:`Pyramid` application. - If instead of a simple application or a pipeline, you're using a Paste + If instead of a simple application or a pipeline, you're using a "composite" (e.g. ``[composite:main]``), refer to the documentation for that particular composite to understand how to make it refer to your :app:`Pyramid` application. In most cases, a Pyramid application built from a scaffold will have a single ``[app:main]`` section in it, and this will be the application served. -#. The PasteDeploy framework finds all :mod:`logging` related configuration - in the ``.ini`` file and uses it to configure the Python standard library - logging system for this application. +#. The framework finds all :mod:`logging` related configuration in the + ``.ini`` file and uses it to configure the Python standard library logging + system for this application. #. The application's *constructor* (named by the entry point reference or dotted Python name on the ``use=`` line of the section representing your @@ -82,7 +81,7 @@ Here's a high-level time-ordered overview of what happens when you press key/value pairs received by this function in ``**settings`` will be composed of all the key/value pairs that are present in the ``[app:main]`` section (except for the ``use=`` setting) when this function is called by - the :term:`PasteDeploy` framework when you run ``paster serve``. + when you run ``pserve``. Our generated ``development.ini`` file looks like so: @@ -110,7 +109,7 @@ Here's a high-level time-ordered overview of what happens when you press The ``settings`` dictionary contains all the options in the ``[app:main]`` section of our .ini file except the ``use`` option (which is internal to - Paste) such as ``pyramid.reload_templates``, + PasteDeploy) such as ``pyramid.reload_templates``, ``pyramid.debug_authorization``, etc. #. The ``main`` function then calls various methods on the instance of the @@ -130,12 +129,12 @@ Here's a high-level time-ordered overview of what happens when you press #. Assuming there were no errors, the ``main`` function in ``myproject`` returns the router instance created by - :meth:`pyramid.config.Configurator.make_wsgi_app` back to PasteDeploy. As - far as PasteDeploy is concerned, it is "just another WSGI application". + :meth:`pyramid.config.Configurator.make_wsgi_app` back to ``pserve``. As + far as ``pserve`` is concerned, it is "just another WSGI application". -#. PasteDeploy starts the WSGI *server* defined within the ``[server:main]`` - section. In our case, this is the ``Paste#http`` server (``use = - egg:Paste#http``), and it will listen on all interfaces (``host = +#. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` + section. In our case, this is the ``egg:pyramid#wsgiref`` server (``use = + egg:pyramid#wsgiref``), 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 diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 052843a23..fb9dd56c2 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -625,7 +625,7 @@ variable set to ``1``, For example: .. code-block:: text - $ PYRAMID_DEBUG_TEMPLATES=1 bin/paster serve myproject.ini + $ PYRAMID_DEBUG_TEMPLATES=1 bin/pserve myproject.ini To use a setting in the application ``.ini`` file for the same purpose, set the ``pyramid.debug_templates`` key to ``true`` within @@ -786,7 +786,7 @@ variable set to ``1``, For example: .. code-block:: text - $ PYRAMID_RELOAD_TEMPLATES=1 bin/paster serve myproject.ini + $ PYRAMID_RELOAD_TEMPLATES=1 bin/pserve myproject.ini To use a setting in the application ``.ini`` file for the same purpose, set the ``pyramid.reload_templates`` key to ``true`` within the diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2fcbce507..9ceb20f21 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -390,7 +390,7 @@ lookup` subsystem takes over to find the most reasonable view callable for the matched route. Most often, there's only one view that will match (a view configured with a ``route_name`` argument matching the matched route). To gain a better understanding of how routes and views are associated in a real -application, you can use the ``paster pviews`` command, as documented in +application, you can use the ``pviews`` command, as documented in :ref:`displaying_matching_views`. If no route matches after all route patterns are exhausted, :app:`Pyramid` @@ -772,7 +772,7 @@ which you started the application from. For example: :linenos: [chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \ - bin/paster serve development.ini + bin/pserve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ @@ -786,7 +786,7 @@ which you started the application from. For example: See :ref:`environment_chapter` for more information about how, and where to set these values. -You can also use the ``paster proutes`` command to see a display of all the +You can also use the ``proutes`` command to see a display of all the routes configured in your application; for more information, see :ref:`displaying_application_routes`. @@ -1012,8 +1012,8 @@ The above predicate, when added to a number of route configurations ensures that the year match argument is '2010' if and only if the route name is 'ymd', 'ym', or 'y'. -You can also caption the predicates by setting the ``__text__`` attribute. This -will help you with the ``paster pviews`` command (see +You can also caption the predicates by setting the ``__text__`` +attribute. This will help you with the ``pviews`` command (see :ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. If a predicate is a class just add __text__ property in a standard manner. -- cgit v1.2.3 From f8869cb0664506204b22aa791003a6d5f8ded58c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 6 Oct 2011 03:22:35 -0400 Subject: remove stray references to Paste --- docs/narr/MyProject/development.ini | 2 +- docs/narr/MyProject/production.ini | 2 +- docs/narr/environment.rst | 4 ++-- docs/narr/firstapp.rst | 2 +- docs/narr/helloworld.py | 6 ++++-- docs/narr/i18n.rst | 16 ++++++++-------- docs/narr/install.rst | 9 ++++----- docs/narr/paste.rst | 18 +++++++++--------- docs/narr/project.rst | 5 +++-- docs/narr/vhosting.rst | 10 +++++----- docs/narr/zca.rst | 13 ++++++------- 11 files changed, 44 insertions(+), 43 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index e93266bab..3a4758c44 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -10,7 +10,7 @@ pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar [server:main] -use = egg:Paste#http +use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 83bce1ef2..9d025715d 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -9,7 +9,7 @@ pyramid.debug_templates = false pyramid.default_locale_name = en [server:main] -use = egg:Paste#http +use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 2ac094d47..8206e0bcb 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -344,8 +344,8 @@ sequence can take several different forms. Each value in the sequence should be a :term:`dotted Python name`. -Paste Configuration vs. Plain-Python Configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +PasteDeploy Configuration vs. Plain-Python Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Using the following ``pyramid.tweens`` setting in the PasteDeploy ``.ini`` file in your application: diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 55829bef0..45d65402c 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -209,7 +209,7 @@ Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :func:`paste.httpserver.serve` WSGI server runner, passing it the ``app`` object (a :term:`router`) as the application we wish to serve. We also pass in an argument ``host=='0.0.0.0'``, meaning -"listen on all TCP interfaces." By default, the Paste HTTP server listens +"listen on all TCP interfaces." By default, the HTTP server listens only on the ``127.0.0.1`` interface, which is problematic if you're running the server on a remote system and you wish to access it with a web browser from a local system. We don't specify a TCP port number to listen on; this diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py index 5f121d48d..93a403a13 100644 --- a/docs/narr/helloworld.py +++ b/docs/narr/helloworld.py @@ -1,4 +1,4 @@ -from paste.httpserver import serve +from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response @@ -10,4 +10,6 @@ if __name__ == '__main__': config.add_route('hello', '/hello/{name}') config.add_view(hello_world, route_name='hello') app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080) + server.serve_forever() + diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index bac86e982..c2ecba9bb 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -365,10 +365,10 @@ be performed to localize your application. By default, the translation domain is the :term:`project` name of your :app:`Pyramid` application. -To change the translation domain of the extracted messages in your -project, edit the ``setup.cfg`` file of your application, The default -``setup.cfg`` file of a Paster-generated :app:`Pyramid` application -has stanzas in it that look something like the following: +To change the translation domain of the extracted messages in your project, +edit the ``setup.cfg`` file of your application, The default ``setup.cfg`` +file of a ``pcreate`` -generated :app:`Pyramid` application has stanzas in it +that look something like the following: .. code-block:: ini :linenos: @@ -785,7 +785,7 @@ time: config = Configurator(settings={'pyramid.default_locale_name':'de'}) You may alternately supply a ``pyramid.default_locale_name`` via an -application's Paster ``.ini`` file: +application's ``.ini`` file: .. code-block:: ini :linenos: @@ -797,8 +797,8 @@ application's Paster ``.ini`` file: pyramid.debug_notfound = false pyramid.default_locale_name = de -If this value is not supplied via the Configurator constructor or via -a Paste config file, it will default to ``en``. +If this value is not supplied via the Configurator constructor or via a +config file, it will default to ``en``. If this setting is supplied within the :app:`Pyramid` application ``.ini`` file, it will be available as a settings key: @@ -845,7 +845,7 @@ You can set up a system to allow a deployer to select available languages based on convention by using the :mod:`pyramid.settings` mechanism: -Allow a deployer to modify your application's PasteDeploy .ini file: +Allow a deployer to modify your application's ``.ini`` file: .. code-block:: ini :linenos: diff --git a/docs/narr/install.rst b/docs/narr/install.rst index e1b5eb208..66bcea706 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -347,10 +347,9 @@ Jython; use it instead. What Gets Installed ------------------- -When you ``easy_install`` :app:`Pyramid`, various Zope libraries, -various Chameleon libraries, WebOb, Paste, PasteScript, and -PasteDeploy libraries are installed. +When you ``easy_install`` :app:`Pyramid`, various other 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. +Additionally, as chronicled in :ref:`project_narr`, scaffolds will be +registered, which make it easy to start a new :app:`Pyramid` project. diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index 5c7d4c3fb..cf8f96c8a 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -20,7 +20,7 @@ setting deployment values, and to provide new users with a standardized way of starting, stopping, and debugging an application. This chapter is not a replacement for documentation about PasteDeploy; it -only contextualizes the use of Paste within Pyramid. For detailed +only contextualizes the use of PasteDeploy within Pyramid. For detailed documentation, see http://pythonpaste.org. PasteDeploy @@ -76,14 +76,14 @@ The ``egg:`` prefix in ``egg:MyProject`` indicates that this is an entry point *URI* specifier, where the "scheme" is "egg". An "egg" is created when you run ``setup.py install`` or ``setup.py develop`` within your project. -In English, this entry point can thus be referred to as a "Paste application -factory in the ``MyProject`` project which has the entry point named ``main`` -where the entry point refers to a ``main`` function in the ``mypackage`` -module". Indeed, if you open up the ``__init__.py`` module generated within -any scaffold-generated package, you'll see a ``main`` function. This is the -function called by :term:`PasteDeploy` when the ``pserve`` command is invoked -against our application. It accepts a global configuration object and -*returns* an instance of our application. +In English, this entry point can thus be referred to as a "PasteDeploy +application factory in the ``MyProject`` project which has the entry point +named ``main`` where the entry point refers to a ``main`` function in the +``mypackage`` module". Indeed, if you open up the ``__init__.py`` module +generated within any scaffold-generated package, you'll see a ``main`` +function. This is the function called by :term:`PasteDeploy` when the +``pserve`` command is invoked against our application. It accepts a global +configuration object and *returns* an instance of our application. ``[DEFAULTS]`` Section of a PasteDeploy ``.ini`` File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index c961b4143..4f96448af 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -683,7 +683,8 @@ The ``myproject`` :term:`package` lives inside the ``MyProject`` #. An ``__init__.py`` file signifies that this is a Python :term:`package`. It also contains code that helps users run the application, including a - ``main`` function which is used as a Paste entry point. + ``main`` function which is used as a entry point for commands such as + ``pserve``, ``pshell``, ``pviews``, and others. #. A ``resources.py`` module, which contains :term:`resource` code. @@ -750,7 +751,7 @@ also informs Python that the directory which contains it is a *package*. directory of the ``mypackage`` package). Line 12 returns a :term:`WSGI` application to the caller of the function - (Paste). + (Pyramid's pserve). .. index:: single: views.py diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index 8697df6a0..d37518052 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -25,11 +25,11 @@ can host a :app:`Pyramid` application as a "subset" of some other site (e.g. under ``http://example.com/mypyramidapplication/`` as opposed to under ``http://example.com/``). -If you use a "pure Python" environment, this functionality is provided -by Paste's `urlmap `_ -"composite" WSGI application. Alternately, you can use -:term:`mod_wsgi` to serve your application, which handles this virtual -hosting translation for you "under the hood". +If you use a "pure Python" environment, this functionality can be provided by +Paste's `urlmap `_ "composite" +WSGI application. Alternately, you can use :term:`mod_wsgi` to serve your +application, which handles this virtual hosting translation for you "under +the hood". If you use the ``urlmap`` composite application "in front" of a :app:`Pyramid` application or if you use :term:`mod_wsgi` to serve diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index 96aac6a80..f7707ea29 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -61,14 +61,13 @@ Using the ZCA Global API in a :app:`Pyramid` Application effectively making it impossible to run more than one Zope application in a single process. -However, for ease of deployment, it's often useful to be able to run -more than a single application per process. For example, use of a -:term:`Paste` "composite" allows you to run separate individual WSGI +However, for ease of deployment, it's often useful to be able to run more +than a single application per process. For example, use of a +:term:`PasteDeploy` "composite" allows you to run separate individual WSGI applications in the same process, each answering requests for some URL -prefix. This makes it possible to run, for example, a TurboGears -application at ``/turbogears`` and a :app:`Pyramid` application at -``/pyramid``, both served up using the same :term:`WSGI` server -within a single Python process. +prefix. This makes it possible to run, for example, a TurboGears application +at ``/turbogears`` and a :app:`Pyramid` application at ``/pyramid``, both +served up using the same :term:`WSGI` server within a single Python process. Most production Zope applications are relatively large, making it impractical due to memory constraints to run more than one Zope -- cgit v1.2.3 From d7afdd514faa804e93f5bb8d2bb0b330c7b4c4b0 Mon Sep 17 00:00:00 2001 From: Wayne Tong Date: Wed, 12 Oct 2011 13:08:52 +0200 Subject: Edited docs/narr/urldispatch.rst via GitHub --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 9ceb20f21..c2414965c 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -65,7 +65,7 @@ example: config.add_view(myview, route_name='myroute') When a :term:`view callable` added to the configuration by way of -:meth:`~pyramid.config.Configurator.add_view` bcomes associated with a route +:meth:`~pyramid.config.Configurator.add_view` becomes associated with a route via its ``route_name`` predicate, that view callable will always be found and invoked when the associated route pattern matches during a request. -- cgit v1.2.3 From c1265329e28bc513a2304fd451e727d9bc95f7ba Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 14 Oct 2011 14:39:15 -0500 Subject: fixed translationstring docs, default is not the first argument --- docs/narr/i18n.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index c2ecba9bb..631654d32 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -149,7 +149,7 @@ generated by using it. For example: from pyramid.i18n import TranslationStringFactory _ = TranslationStringFactory('pyramid') - ts = _('Add ${number}', msgid='add-number', mapping={'number':1}) + ts = _('add-number', default='Add ${number}', mapping={'number':1}) .. note:: We assigned the translation string factory to the name ``_``. This is a convention which will be supported by translation @@ -170,7 +170,7 @@ to: :linenos: from pyramid.i18n import TranslationString as _ - ts = _('Add ${number}', msgid='add-number', mapping={'number':1}, + ts = _('add-number', default='Add ${number}', mapping={'number':1}, domain='pyramid') You can set up your own translation string factory much like the one @@ -185,7 +185,7 @@ do something like this: from pyramid.i18n import TranslationStringFactory _ = TranslationStringFactory('form') - ts = _('Add ${number}', msgid='add-number', mapping={'number':1}) + ts = _('add-number', default='Add ${number}', mapping={'number':1}) Creating a unique domain for your application via a translation string factory is best practice. Using your own unique translation domain -- cgit v1.2.3 From f01fc7ce0cb03f093b1ab4d32b774d685df85b57 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 17 Oct 2011 21:44:05 -0400 Subject: fix note rendering --- docs/narr/project.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4f96448af..8fa4fbe9f 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -62,11 +62,12 @@ The included scaffolds are these: .. note:: -Rather than use any of the above scaffolds, Pylons 1 users may feel more -comfortable installing the :term:`Akhet` development environment, which -provides a scaffold named ``akhet``. This scaffold configures a Pyramid -application in a "Pylons-esque" way, including the use of a :term:`view -handler` to map URLs to code (a handler is much like a Pylons "controller"). + Rather than use any of the above scaffolds, Pylons 1 users may feel more + comfortable installing the :term:`Akhet` development environment, which + provides a scaffold named ``akhet``. This scaffold configures a Pyramid + application in a "Pylons-esque" way, including the use of a :term:`view + handler` to map URLs to code (a handler is much like a Pylons + "controller"). .. index:: single: creating a project -- cgit v1.2.3 From d7ac00322fe7669d02d38b8f9fa02fa66e268fbc Mon Sep 17 00:00:00 2001 From: Cypha Date: Sun, 23 Oct 2011 04:12:12 -0400 Subject: updated Dive Into Python link --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 05e851fde..7ee432fa7 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -52,7 +52,7 @@ The suggested mechanism for unit and integration testing of a :app:`Pyramid` application is the Python :mod:`unittest` module. Although this module is named :mod:`unittest`, it is actually capable of driving both unit and integration tests. A good :mod:`unittest` tutorial is available within `Dive -Into Python `_ by Mark +Into Python `_ by Mark Pilgrim. :app:`Pyramid` provides a number of facilities that make unit, integration, -- cgit v1.2.3 From 777ca3c6feac4179b1ecec9cd50fd15ca8dbe6bb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 24 Oct 2011 00:05:14 -0500 Subject: garden --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index c2414965c..35613ea1b 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -101,7 +101,7 @@ that references ``myroute`` as a ``route_name`` parameter: def myview(request): return Response('OK') -THe above combination of ``add_route`` and ``scan`` is completely equivalent +The above combination of ``add_route`` and ``scan`` is completely equivalent to using the previous combination of ``add_route`` and ``add_view``. .. index:: -- cgit v1.2.3 From 2217d19853a5c389dd809983f69fb31e6e7c9c4b Mon Sep 17 00:00:00 2001 From: Cypha Date: Mon, 24 Oct 2011 04:39:04 -0400 Subject: clarified [DEFAULT] as an optional section in .ini --- docs/narr/startup.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index f4ebef154..0d5acfa47 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -76,12 +76,12 @@ Here's a high-level time-ordered overview of what happens when you press Note that the constructor function accepts a ``global_config`` argument, which is a dictionary of key/value pairs mentioned in the ``[DEFAULT]`` - section of an ``.ini`` file. It also accepts a ``**settings`` argument, - which collects another set of arbitrary key/value pairs. The arbitrary - key/value pairs received by this function in ``**settings`` will be - composed of all the key/value pairs that are present in the ``[app:main]`` - section (except for the ``use=`` setting) when this function is called by - when you run ``pserve``. + section of an ``.ini`` file (if ``[DEFAULT]`` is present). It also accepts + a ``**settings`` argument, which collects another set of arbitrary + key/value pairs. The arbitrary key/value pairs received by this function + in ``**settings`` will be composed of all the key/value pairs that are + present in the ``[app:main]`` section (except for the ``use=`` setting) + when this function is called by when you run ``pserve``. Our generated ``development.ini`` file looks like so: -- cgit v1.2.3 From 88bc1225e5f515e53a6f9d8413441581df191aca Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 24 Oct 2011 03:42:42 -0500 Subject: garden --- docs/narr/muchadoabouttraversal.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index a948e57cc..4a249ed0d 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,7 +4,9 @@ Much Ado About Traversal ======================== -.. note:: This chapter was adapted, with permission, from a blog post by `Rob +.. note:: + + This chapter was adapted, with permission, from a blog post by `Rob Miller `_, originally published at http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ . -- cgit v1.2.3 From e980bac6aa7715c11b8a618c7486fe9331251103 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 24 Oct 2011 09:42:02 -0500 Subject: garden --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 631654d32..c5e6a9062 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -249,7 +249,7 @@ GNU gettext uses three types of files in the translation framework, The tools for working with :term:`gettext` translation files related to a :app:`Pyramid` application is :term:`Babel` and :term:`Lingua`. Lingua is a -Balel extension that provides support for scraping i18n references out of +Babel extension that provides support for scraping i18n references out of Python and Chameleon files. .. index:: -- cgit v1.2.3 From 62912fda287f613c4a7180c55a31b349e01e6aa8 Mon Sep 17 00:00:00 2001 From: Cypha Date: Tue, 25 Oct 2011 02:45:58 -0400 Subject: updated [DEFAULT] to link to the relevant section --- docs/narr/startup.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 0d5acfa47..971d12b45 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -76,8 +76,10 @@ Here's a high-level time-ordered overview of what happens when you press Note that the constructor function accepts a ``global_config`` argument, which is a dictionary of key/value pairs mentioned in the ``[DEFAULT]`` - section of an ``.ini`` file (if ``[DEFAULT]`` is present). It also accepts - a ``**settings`` argument, which collects another set of arbitrary + section of an ``.ini`` file (if `[DEFAULT] + `__ is present). It also + accepts a ``**settings`` argument, which collects another set of arbitrary key/value pairs. The arbitrary key/value pairs received by this function in ``**settings`` will be composed of all the key/value pairs that are present in the ``[app:main]`` section (except for the ``use=`` setting) -- cgit v1.2.3 From 8912639e65535a7a6842c48d2773daef1a98aec7 Mon Sep 17 00:00:00 2001 From: alexander-travov Date: Wed, 26 Oct 2011 02:20:42 +0400 Subject: Removing some minor misprints in documentation. --- docs/narr/firstapp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 45d65402c..ccc2b8b18 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -134,7 +134,7 @@ Using the ``if`` clause is necessary -- or at least best practice -- because code in a Python ``.py`` file may be eventually imported via the Python ``import`` statement by another ``.py`` file. ``.py`` files that are imported by other ``.py`` files are referred to as *modules*. By using the -``if __name__ == 'main':`` idiom, the script above is indicating that it does +``if __name__ == '__main__':`` idiom, the script above is indicating that it does not want the code within the ``if`` statement to execute if this module is imported from another; the code within the ``if`` block should only be run during a direct script execution. @@ -208,7 +208,7 @@ WSGI Application Serving Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :func:`paste.httpserver.serve` WSGI server runner, passing it the ``app`` object (a :term:`router`) as the application -we wish to serve. We also pass in an argument ``host=='0.0.0.0'``, meaning +we wish to serve. We also pass in an argument ``host='0.0.0.0'``, meaning "listen on all TCP interfaces." By default, the HTTP server listens only on the ``127.0.0.1`` interface, which is problematic if you're running the server on a remote system and you wish to access it with a web browser -- cgit v1.2.3 From 8595a7757b9347597e5664cc2c631f494825103e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 12 Nov 2011 20:05:48 -0500 Subject: make myproject project relocatable (as per Ken's changes) --- docs/narr/MyProject/myproject/__init__.py | 8 ++--- docs/narr/MyProject/myproject/tests.py | 2 +- docs/narr/MyProject/myproject/views.py | 4 +++ docs/narr/project.rst | 53 ++++++++++++++++--------------- 4 files changed, 35 insertions(+), 32 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py index 04e219e36..ddcdd7162 100644 --- a/docs/narr/MyProject/myproject/__init__.py +++ b/docs/narr/MyProject/myproject/__init__.py @@ -1,12 +1,10 @@ from pyramid.config import Configurator -from myproject.resources import Root +from .resources import Root def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(root_factory=Root, settings=settings) - config.add_view('myproject.views.my_view', - context='myproject.resources.Root', - renderer='myproject:templates/mytemplate.pt') - config.add_static_view('static', 'myproject:static') + config.add_static_view('static', 'static', cache_max_age=3600) + config.scan() return config.make_wsgi_app() diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py index 5fa710278..a32165471 100644 --- a/docs/narr/MyProject/myproject/tests.py +++ b/docs/narr/MyProject/myproject/tests.py @@ -10,7 +10,7 @@ class ViewTests(unittest.TestCase): testing.tearDown() def test_my_view(self): - from myproject.views import my_view + from .views import my_view request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'MyProject') diff --git a/docs/narr/MyProject/myproject/views.py b/docs/narr/MyProject/myproject/views.py index c43b34460..5b5d230f2 100644 --- a/docs/narr/MyProject/myproject/views.py +++ b/docs/narr/MyProject/myproject/views.py @@ -1,2 +1,6 @@ +from pyramid.view import view_config +from .resources import Root + +@view_config(context=Root, renderer='templates/mytemplate.pt') def my_view(request): return {'project':'MyProject'} diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 8fa4fbe9f..fe015d72f 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -727,31 +727,22 @@ also informs Python that the directory which contains it is a *package*. #. Line 2 imports the ``Root`` class from :mod:`myproject.resources` that we use later. -#. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 4-10 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. Within this function, application configuration is performed. - Lines 8-10 register a "default view" (a view that has no ``name`` - attribute). It is registered so that it will be found when the - :term:`context` of the request is an instance of the - :class:`myproject.resources.Root` class. The first argument to - ``add_view`` points at a Python function that does all the work for this - view, also known as a :term:`view callable`, via a :term:`dotted Python - name`. The view declaration also names a ``renderer``, which in this case - is a template that will be used to render the result of the view callable. - This particular view declaration points at - ``myproject:templates/mytemplate.pt``, which is a :term:`asset - specification` that specifies the ``mytemplate.pt`` file within the - ``templates`` directory of the ``myproject`` package. The template file - it actually points to is a :term:`Chameleon` ZPT template file. - - Line 11 registers a static view, which will serve up the files from the + Line 7 creates an instance of a :term:`Configurator`. + + Line 8 registers a static view, which will serve up the files from the ``mypackage:static`` :term:`asset specification` (the ``static`` directory of the ``mypackage`` package). - Line 12 returns a :term:`WSGI` application to the caller of the function + Line 9 calls ``config.scan()``, which picks up view registrations declared + elsewhere in the package (in this case, in the ``view.py`` module). + + Line 10 returns a :term:`WSGI` application to the caller of the function (Pyramid's pserve). .. index:: @@ -769,10 +760,20 @@ and which returns a :term:`response`. :language: python :linenos: -This bit of code was registered as the view callable within ``__init__.py`` -(via ``add_view``). ``add_view`` said that the default URL for instances -that are of the class :class:`myproject.resources.Root` should run this -:func:`myproject.views.my_view` function. +Lines 4-6 define and register a :term:`view callable` named ``my_view``. The +function named ``my_view`` is decorated with a ``view_config`` decorator +(which is processed by the ``config.scan()`` line in our ``__init__.py``). +The view_config decorator asserts that this view be found when the +:term:`context` of the request is an instance of the +:class:`myproject.resources.Root` class. The view_config decorator also +names a ``renderer``, which in this case is a template that will be used to +render the result of the view callable. This particular view declaration +points at ``templates/mytemplate.pt``, which is a :term:`asset specification` +that specifies the ``mytemplate.pt`` file within the ``templates`` directory +of the ``myproject`` package. The asset specification could have also been +specified as ``myproject:templates/mytemplate.pt``; the leading package name +and colon is optional. The template file it actually points to is a +:term:`Chameleon` ZPT template file. This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` @@ -839,11 +840,11 @@ template. It includes CSS and images. ``templates/mytemplate.pt`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The single :term:`Chameleon` template that exists in the project. Its contents -are too long to show here, but it displays a default page when rendered. It -is referenced by the call to ``add_view`` as the ``renderer`` attribute in -the ``__init__`` file. See :ref:`views_which_use_a_renderer` for more -information about renderers. +The single :term:`Chameleon` template that exists in the project. Its +contents are too long to show here, but it displays a default page when +rendered. It is referenced by the call to ``@view_config`` as the +``renderer`` of the ``my_view`` view callable in the ``views.py`` file. See +:ref:`views_which_use_a_renderer` for more information about renderers. Templates are accessed and used by view configurations and sometimes by view functions themselves. See :ref:`templates_used_directly` and -- cgit v1.2.3 From 818f8cab1dff781bbacf94cbabb4bec3825e081e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 12 Nov 2011 20:41:29 -0500 Subject: - The ``alchemy`` scaffold has been removed. - The ``routesalchemy`` scaffold has been renamed ``alchemy``. --- docs/narr/project.rst | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index fe015d72f..4c528ab58 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -28,7 +28,6 @@ as part of Pyramid. single: starter scaffold single: zodb scaffold single: alchemy scaffold - single: routesalchemy scaffold .. _additional_paster_scaffolds: @@ -52,12 +51,8 @@ The included scaffolds are these: ``zodb`` URL mapping via :term:`traversal` and persistence via :term:`ZODB`. -``routesalchemy`` - URL mapping via :term:`URL dispatch` and persistence via - :term:`SQLAlchemy` - ``alchemy`` - URL mapping via :term:`traversal` and persistence via + URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` .. note:: @@ -99,18 +94,18 @@ Or on Windows: The above command uses the ``pcreate`` command to create a project with the ``starter`` scaffold. To use a different scaffold, such as -``routesalchemy``, you'd just change the ``-s`` argument value. For example, +``alchemy``, you'd just change the ``-s`` argument value. For example, on UNIX: .. code-block:: text - $ bin/pcreate -s routesalchemy MyProject + $ bin/pcreate -s alchemy MyProject Or on Windows: .. code-block:: text - $ Scripts\pcreate routesalchemy MyProject + $ Scripts\pcreate alchemy MyProject Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: -- cgit v1.2.3 From 56f1d2ea13f93b46161d12112e75125efee2120b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 21 Nov 2011 12:03:47 -0500 Subject: de-jythonify --- docs/narr/install.rst | 30 +++++------------------------- docs/narr/introduction.rst | 10 +++++----- docs/narr/templates.rst | 8 -------- 3 files changed, 10 insertions(+), 38 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 66bcea706..3de4d6e27 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -9,19 +9,18 @@ Installing :app:`Pyramid` Before You Install ------------------ -You will need `Python `_ version 2.5 or better to +You will need `Python `_ version 2.6 or better to run :app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.5.5, - Python 2.6.6, and Python 2.7.2. :app:`Pyramid` does not run under any - version of Python before 2.5, and does not yet run under Python 3.X. + As of this writing, :app:`Pyramid` has been tested under Python 2.6.6, + Python 2.7.2, and Python 3.2. :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, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on Google's App Engine, :term:`PyPy` (1.5 and 1.6), and -:term:`Jython` (2.5.2). +known to run on Google's App Engine, and :term:`PyPy` (1.6+). :app:`Pyramid` installation does not require the compilation of any C code, so you need only a Python interpreter that meets the @@ -325,25 +324,6 @@ Installing :app:`Pyramid` on Google App Engine :ref:`appengine_tutorial` documents the steps required to install a :app:`Pyramid` application on Google App Engine. -.. index:: - single: installing on Jython - -Installing :app:`Pyramid` on Jython --------------------------------------- - -:app:`Pyramid` is known to work under :term:`Jython` version 2.5.1. -Install :term:`Jython`, and then follow the installation steps for -:app:`Pyramid` on your platform described in one of the sections -entitled :ref:`installing_unix` or :ref:`installing_windows` above, -replacing the ``python`` command with ``jython`` as necessary. The -steps are exactly the same except you should use the ``jython`` -command name instead of the ``python`` command name. - -One caveat exists to using :app:`Pyramid` under Jython: the :term:`Chameleon` -templating engine does not work on Jython. However, the :term:`Mako` -templating system, which is also included with Pyramid, does work under -Jython; use it instead. - What Gets Installed ------------------- diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 547f88ef3..2387db6a7 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -808,11 +808,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.5, Python 2.6, Python 2.7, Jython and PyPy 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.2 and PyPy 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/ diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index fb9dd56c2..11318d9eb 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -403,14 +403,6 @@ The language definition documentation for Chameleon ZPT-style templates is available from `the Chameleon website `_. -.. warning:: - - :term:`Chameleon` only works on :term:`CPython` platforms and - :term:`Google App Engine`. On :term:`Jython` and other non-CPython - platforms, you should use Mako (see :ref:`mako_templates`) or - ``pyramid_jinja2`` instead. See - :ref:`available_template_system_bindings`. - Given a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory in your application named ``templates``, you can render the template as a :term:`renderer` like so: -- cgit v1.2.3 From f1013bebcdd013cd1cb47cf7585c0eaa34ec3b75 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Camguilhem Date: Sat, 19 Nov 2011 16:09:41 +0100 Subject: add bpython support for pshell --- docs/narr/commandline.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 0dc41e919..dc2b75ed6 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -111,6 +111,7 @@ For a URL that doesn't match any views, ``pviews`` will simply print out a single: interactive shell single: IPython single: pshell + single: bpython .. _interactive_shell: @@ -284,6 +285,19 @@ standard Python interpreter shell unconditionally. development.ini#MyProject +bpython +~~~~~~~ + +If you have `bpython `_ installed in +the interpreter you use to invoke the ``pshell`` command, ``pshell`` will use +a bpython interactive shell instead of a standard Python if you pass the ``-b`` +or ``--enable-bpython`` flag to the ``pshell`` command. + +.. code-block:: text + + [chrism@vitaminf shellenv]$ ../bin/pshell --enable-bpython \ + development.ini#MyProject + .. index:: pair: routes; printing single: proutes -- cgit v1.2.3 From 2cf5d280866e8936b0fee0952c89ebde164337ee Mon Sep 17 00:00:00 2001 From: Jean-Philippe Camguilhem Date: Tue, 22 Nov 2011 00:20:07 +0100 Subject: add bpython support to pshell with raydeo remarks and design --- docs/narr/commandline.rst | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index dc2b75ed6..0f0e17ca6 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -268,34 +268,22 @@ exposed, and the request is configured to generate urls from the host .. index:: single: IPython + single: bpython -IPython -~~~~~~~ - -If you have `IPython `_ installed in -the interpreter you use to invoke the ``pshell`` command, ``pshell`` will use -an IPython interactive shell instead of a standard Python interpreter shell. -If you don't want this to happen, even if you have IPython installed, you can -pass the ``--disable-ipython`` flag to the ``pshell`` command to use a -standard Python interpreter shell unconditionally. - -.. code-block:: text - - [chrism@vitaminf shellenv]$ ../bin/pshell --disable-ipython \ - development.ini#MyProject - - -bpython -~~~~~~~ +IPython or bpython +~~~~~~~~~~~~~~~~~~ -If you have `bpython `_ installed in -the interpreter you use to invoke the ``pshell`` command, ``pshell`` will use -a bpython interactive shell instead of a standard Python if you pass the ``-b`` -or ``--enable-bpython`` flag to the ``pshell`` command. +If you have `IPython `_ or +`bpython `_ or both installed in +the interpreter you use to invoke the ``pshell`` command, ``pshell`` will +autodiscover them and use the first respectively found in this order : +IPython, bpython, standard Python interpreter. However you could +specifically invoke one of your choice with the ``-p choice`` or +``--python-shell choice`` option. .. code-block:: text - [chrism@vitaminf shellenv]$ ../bin/pshell --enable-bpython \ + [chrism@vitaminf shellenv]$ ../bin/pshell -p ipython | bpython | python \ development.ini#MyProject .. index:: -- cgit v1.2.3 From 3bfb4068c2e17a282b53d1b7f14f653f128cced4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 26 Nov 2011 12:30:39 -0500 Subject: fix to match starter package --- docs/narr/MyProject/myproject/static/pylons.css | 15 +++-- .../MyProject/myproject/templates/mytemplate.pt | 76 +++++++--------------- 2 files changed, 31 insertions(+), 60 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/static/pylons.css b/docs/narr/MyProject/myproject/static/pylons.css index 33b21ac1a..c54499ddd 100644 --- a/docs/narr/MyProject/myproject/static/pylons.css +++ b/docs/narr/MyProject/myproject/static/pylons.css @@ -23,7 +23,7 @@ h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;} a{color:#1b61d6;text-decoration:none;} a:hover{color:#e88f00;text-decoration:underline;} body h1, @@ -31,19 +31,20 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} #wrap{min-height:100%;} #header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} #header{background:#000000;top:0;font-size:14px;} #footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} .header,.footer{width:750px;margin-right:auto;margin-left:auto;} .wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#000000;height:230px; -background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} #bottom{color:#222;background-color:#ffffff;} -.top,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} .top{padding-top:40px;} +.top-small{padding-top:10px;} #middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} .app-welcome{margin-top:25px;} .app-name{color:#000000;font-weight:bold;} @@ -58,7 +59,7 @@ ul.links li{list-style-type:none;font-size:14px;} form{border-style:none;} fieldset{border-style:none;} input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{width:205px;} +input[type=text],input[type=password]{width:205px;} input[type=submit]{background-color:#ddd;font-weight:bold;} /*Opera Fix*/ body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 97f1e1aa3..ab698123e 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -1,42 +1,29 @@ - - + + The Pyramid Web Application Development Framework - - - + + + +
    -
    - pyramid -
    +
    pyramid

    - Welcome to ${project}, - an application generated by
    + Welcome to ${project}, an application generated by
    the Pyramid web application development framework.

    @@ -45,62 +32,45 @@
    -- cgit v1.2.3 From 35ad08ba9c66b900fe0c537516b390a92cb2a8cd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 29 Nov 2011 08:31:33 -0500 Subject: move register method from IIntrospector back to IIntrospectable; provide better conflict reporting and a more useful ActionInfo object --- docs/narr/advconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 7b62b1a73..a6db5f58e 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -87,8 +87,8 @@ that ends something like this: Conflicting configuration actions For: ('view', None, '', None, , None, None, None, None, None, False, None, None, None) - ('app.py', 14, '', 'config.add_view(hello_world)') - ('app.py', 17, '', 'config.add_view(hello_world)') + Line 14 of file app.py in : 'config.add_view(hello_world)' + Line 17 of file app.py in : 'config.add_view(hello_world)' This traceback is trying to tell us: -- cgit v1.2.3 From 56bfd68215d656cb5039bc842b030b5ab447a7f7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 29 Nov 2011 08:33:24 -0500 Subject: get repr right --- docs/narr/advconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index a6db5f58e..4d4f82197 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -88,7 +88,7 @@ that ends something like this: For: ('view', None, '', None, , None, None, None, None, None, False, None, None, None) Line 14 of file app.py in : 'config.add_view(hello_world)' - Line 17 of file app.py in : 'config.add_view(hello_world)' + Line 17 of file app.py in : 'config.add_view(goodbye_world)' This traceback is trying to tell us: -- cgit v1.2.3 From 9f341ea78cfae3a33ef250acee49fa9709a7d7fe Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 29 Nov 2011 08:37:49 -0500 Subject: add note about allowing extension via custom directives --- docs/narr/advconfig.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 4d4f82197..3b6f7669a 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -13,6 +13,8 @@ also, by default, performs configuration in two separate phases. This allows you to ignore relative configuration statement ordering in some circumstances. +Pyramid also allows you to extend its Configurator with custom directives. + .. index:: pair: configuration; conflict detection -- cgit v1.2.3 From 97b888f8f2b01df8b37cbeab229e171324012c0f Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Tue, 29 Nov 2011 22:21:43 +0100 Subject: Fix helloworld example. It got broken in f8869cb0664506204b22aa791003a6d5f8ded58c when moving from Paste to wsgiref. --- docs/narr/helloworld.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py index 93a403a13..7c26c8cdc 100644 --- a/docs/narr/helloworld.py +++ b/docs/narr/helloworld.py @@ -10,6 +10,6 @@ if __name__ == '__main__': config.add_route('hello', '/hello/{name}') config.add_view(hello_world, route_name='hello') app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8080) + server = make_server('0.0.0.0', 8080, app) server.serve_forever() -- cgit v1.2.3 From f75a3f07b0a5699f99b89d93b4e3a66beea21ac1 Mon Sep 17 00:00:00 2001 From: Chris Davies Date: Thu, 1 Dec 2011 01:57:41 -0500 Subject: https://docs.pylonsproject.org to http://docs.pylonsproject.org as readthedocs.org doesn't support https --- docs/narr/introduction.rst | 4 ++-- docs/narr/logging.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 2387db6a7..7c6ad00f3 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -219,7 +219,7 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: https://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation +Examples: http://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -842,7 +842,7 @@ official narrative docs. In any case, the Pyramid documentation is comprehensive. Example: The rest of this documentation and the cookbook at -https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . +http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . .. index:: single: Pylons Project diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 5377d0c66..f9f72270f 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -291,7 +291,7 @@ Logging Exceptions To log (or email) exceptions generated by your :app:`Pyramid` application, use the :term:`pyramid_exclog` package. Details about its configuration are in its `documentation -`_. +`_. Request Logging with Paste's TransLogger ---------------------------------------- -- cgit v1.2.3 From 5999a8c3ae406902987989cf7c48d3c08b6638cf Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 1 Dec 2011 22:26:50 -0800 Subject: Attempt to correct grammar in this paragraph. Uncertain whether it is both technically and grammatically correct now. Please verify. --- docs/narr/firstapp.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index ccc2b8b18..2c8e346b1 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -71,11 +71,11 @@ named ``hello_world``. :linenos: :pyobject: hello_world -This function doesn't do anything very difficult. The functions accepts a +This function doesn't do anything very difficult. The function accepts a single argument (``request``). The ``hello_world`` function returns an -instance of the :class:`pyramid.response.Response`. The single argument to -the class' constructor is value computed from arguments matched from the url -route. This value becomes the body of the response. +instance of the :class:`pyramid.response.Response` class. The single +argument to the class' constructor value is computed from arguments +matched from the url route. This value becomes the body of the response. This function is known as a :term:`view callable`. A view callable accepts a single argument, ``request``. It is expected to return a -- cgit v1.2.3 From f0a1b9b491bab0ac90be6765ddf56a0696d4f863 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 2 Dec 2011 09:44:21 -0600 Subject: Attempted to clean this up further. --- docs/narr/firstapp.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 2c8e346b1..c082f616b 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -71,11 +71,10 @@ named ``hello_world``. :linenos: :pyobject: hello_world -This function doesn't do anything very difficult. The function accepts a -single argument (``request``). The ``hello_world`` function returns an +The function accepts a single argument (``request``) and it returns an instance of the :class:`pyramid.response.Response` class. The single -argument to the class' constructor value is computed from arguments -matched from the url route. This value becomes the body of the response. +argument to the class' constructor is a string computed from parameters +matched from the URL. This value becomes the body of the response. This function is known as a :term:`view callable`. A view callable accepts a single argument, ``request``. It is expected to return a @@ -157,7 +156,7 @@ Adding Configuration :lines: 10-11 First line above calls the :meth:`pyramid.config.Configurator.add_route` -method, which registers a :term:`route` to match any url path that begins +method, which registers a :term:`route` to match any URL path that begins with ``/hello/`` followed by a string. The second line, ``config.add_view(hello_world, route_name='hello')``, -- cgit v1.2.3 From c4503bf117e43f780c269e64edbde71fc3d6d72b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 01:56:17 -0500 Subject: break out 'extending config' into exconfig and add stuff about the action method; move startup and router chapters to earlier in toc --- docs/narr/advconfig.rst | 77 +---------------- docs/narr/extconfig.rst | 219 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+), 75 deletions(-) create mode 100644 docs/narr/extconfig.rst (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 3b6f7669a..3a7bf2805 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -13,8 +13,6 @@ also, by default, performs configuration in two separate phases. This allows you to ignore relative configuration statement ordering in some circumstances. -Pyramid also allows you to extend its Configurator with custom directives. - .. index:: pair: configuration; conflict detection @@ -117,6 +115,8 @@ Conflict detection happens for any kind of configuration: imperative configuration or configuration that results from the execution of a :term:`scan`. +.. _manually_resolving_conflicts: + Manually Resolving Conflicts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -399,76 +399,3 @@ constraints: the routes they imply require relative ordering. Such ordering constraints are not absolved by two-phase configuration. Routes are still added in configuration execution order. -.. index:: - single: add_directive - pair: configurator; adding directives - -.. _add_directive: - -Adding Methods to the Configurator via ``add_directive`` --------------------------------------------------------- - -Framework extension writers can add arbitrary methods to a -:term:`Configurator` by using the -:meth:`pyramid.config.Configurator.add_directive` method of the configurator. -This makes it possible to extend a Pyramid configurator in arbitrary ways, -and allows it to perform application-specific tasks more succinctly. - -The :meth:`~pyramid.config.Configurator.add_directive` method accepts two -positional arguments: a method name and a callable object. The callable -object is usually a function that takes the configurator instance as its -first argument and accepts other arbitrary positional and keyword arguments. -For example: - -.. code-block:: python - :linenos: - - from pyramid.events import NewRequest - from pyramid.config import Configurator - - def add_newrequest_subscriber(config, subscriber): - config.add_subscriber(subscriber, NewRequest). - - if __name__ == '__main__': - config = Configurator() - config.add_directive('add_newrequest_subscriber', - add_newrequest_subscriber) - -Once :meth:`~pyramid.config.Configurator.add_directive` is called, a user can -then call the method by its given name as if it were a built-in method of the -Configurator: - -.. code-block:: python - :linenos: - - def mysubscriber(event): - print event.request - - config.add_newrequest_subscriber(mysubscriber) - -A call to :meth:`~pyramid.config.Configurator.add_directive` is often -"hidden" within an ``includeme`` function within a "frameworky" package meant -to be included as per :ref:`including_configuration` via -:meth:`~pyramid.config.Configurator.include`. For example, if you put this -code in a package named ``pyramid_subscriberhelpers``: - -.. code-block:: python - :linenos: - - def includeme(config) - config.add_directive('add_newrequest_subscriber', - add_newrequest_subscriber) - -The user of the add-on package ``pyramid_subscriberhelpers`` would then be -able to install it and subsequently do: - -.. code-block:: python - :linenos: - - def mysubscriber(event): - print event.request - - from pyramid.config import Configurator - config = Configurator() - config.include('pyramid_subscriberhelpers') - config.add_newrequest_subscriber(mysubscriber) diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst new file mode 100644 index 000000000..4a0db85de --- /dev/null +++ b/docs/narr/extconfig.rst @@ -0,0 +1,219 @@ +.. index:: + single: extending configuration + +.. _extconfig_narr: + +Extending Pyramid Configuration +=============================== + +Pyramid allows you to extend its Configurator with custom directives. These +directives can add an :term:`action`, participate in :term:`conflict +resolution`, and can provide some number of :term:`introspectable` objects. + +.. index:: + single: add_directive + pair: configurator; adding directives + +.. _add_directive: + +Adding Methods to the Configurator via ``add_directive`` +-------------------------------------------------------- + +Framework extension writers can add arbitrary methods to a +:term:`Configurator` by using the +:meth:`pyramid.config.Configurator.add_directive` method of the configurator. +Using :meth:`~pyramid.config.Configurator.add_directive` makes it possible to +extend a Pyramid configurator in arbitrary ways, and allows it to perform +application-specific tasks more succinctly. + +The :meth:`~pyramid.config.Configurator.add_directive` method accepts two +positional arguments: a method name and a callable object. The callable +object is usually a function that takes the configurator instance as its +first argument and accepts other arbitrary positional and keyword arguments. +For example: + +.. code-block:: python + :linenos: + + from pyramid.events import NewRequest + from pyramid.config import Configurator + + def add_newrequest_subscriber(config, subscriber): + config.add_subscriber(subscriber, NewRequest). + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_newrequest_subscriber', + add_newrequest_subscriber) + +Once :meth:`~pyramid.config.Configurator.add_directive` is called, a user can +then call the added directive by its given name as if it were a built-in +method of the Configurator: + +.. code-block:: python + :linenos: + + def mysubscriber(event): + print event.request + + config.add_newrequest_subscriber(mysubscriber) + +A call to :meth:`~pyramid.config.Configurator.add_directive` is often +"hidden" within an ``includeme`` function within a "frameworky" package meant +to be included as per :ref:`including_configuration` via +:meth:`~pyramid.config.Configurator.include`. For example, if you put this +code in a package named ``pyramid_subscriberhelpers``: + +.. code-block:: python + :linenos: + + def includeme(config) + config.add_directive('add_newrequest_subscriber', + add_newrequest_subscriber) + +The user of the add-on package ``pyramid_subscriberhelpers`` would then be +able to install it and subsequently do: + +.. code-block:: python + :linenos: + + def mysubscriber(event): + print event.request + + from pyramid.config import Configurator + config = Configurator() + config.include('pyramid_subscriberhelpers') + config.add_newrequest_subscriber(mysubscriber) + +Using ``config.action`` in a Directive +-------------------------------------- + +If a custom directive can't do its work exclusively in terms of existing +configurator methods (such as +:meth:`pyramid.config.Configurator.add_subscriber`, as above), the directive +may need to make use of the :meth:`pyramid.config.Configurator.action` +method. This method adds an entry to the list of "actions" that Pyramid will +attempt to process when :meth:`pyramid.config.Configurator.commit` is called. +An action is simply a dictionary that includes a :term:`discriminator`, +possibly a callback function, and possibly other metadata used by Pyramid's +action system. + +Here's an example directive which uses the "action" method: + +.. code-block:: python + :linenos: + + def add_jammyjam(config, jammyjam): + def register(): + config.registry.jammyjam = jammyjam + config.action('jammyjam', register) + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_jammyjam', add_jammyjam) + +Fancy, but what does it do? The action method accepts a number of arguments. +In the above directive named ``add_jammyjam``, we call +:meth:`~pyramid.config.Configurator.action` with two arguments: the string +``jammyjam`` is passed as the first argument, ``discriminator`` and the +closure function named ``register`` is passed as the second argument, +named ``callable``. + +When the :meth:`~pyramid.config.Configurator.action` method is called, it +appends an action to the list of pending configuration actions. All pending +actions with the same discriminator value are potentially in conflict with +one another (see :ref:`conflict_detection`). When the +:meth:`~pyramid.config.Configurator.commit` method of the Configurator is +called (either explicitly or as the result of calling +:meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are +potentially automatically resolved as per +:ref:`automatic_conflict_resolution`. If a conflict cannot be automatically +resolved, a ConfigurationConflictError is raised and application startup is +prevented. + +In our above example, therefore, if a consumer of our ``add_jammyjam`` +directive did this: + +.. code-block:: python + :linenos: + + config.add_jammyjam('first') + config.add_jammyjam('second') + +When the action list was committed, the user's application would not start, +because the discriminators of the actions generated by the two calls are in +direct conflict. Automatic conflict resolution cannot resolve the conflict, +and the user provided no intermediate +:meth:`pyramid.config.Configurator.commit` call between the calls to +``add_jammyjam`` to ensure that the successive calls did not conflict with +each other. This is the purpose of the discriminator argument to the action +method: it's used to indicate a uniqueness constraint for an action. Two +actions with the same discriminator will conflict unless the conflict is +automatically or manually resolved. A discriminator can be any hashable +object, but it is generally a string or a tuple. + +But let's imagine that a consumer of ``add_jammyjam`` used it in such a way +that no configuration conflicts are generated. + +.. code-block:: python + :linenos: + + config.add_jammyjam('first') + +What happens then? When the ``add_jammyjam`` method is called, an action is +appended to the pending actions list. When the pending configuration actions +are processed during :meth:`~pyramid.config.Configurator.commit`, and no +conflicts occur, the *callable* provided as the second argument to the +:meth:`~pyramid.config.Configurator.action` method within ``add_jammyjam`` is +called with no arguments. The callable in ``add_jammyjam`` is the +``register`` closure function. It simply sets the value +``config.registry.jammyjam`` to whatever the user passed in as the +``jammyjam`` argument to the ``add_jammyjam`` function. Therefore, the +result of the user's call to our directive will set the ``jammyjam`` +attribute of the registry to the string ``first``. A callable is used by a +directive to defer the result of a user's call to a directive until conflict +detection has had a chance to do its job. + +Other arguments exist to the :meth:`~pyramid.config.Configurator.action` +method, including ``args``, ``kw``, ``order``, and ``introspectables``. + +``args`` and ``kw`` exist as values, which, if passed, will be used as +arguments to the ``callable`` function when it is called back. For example +our directive might use them like so: + +.. code-block:: python + :linenos: + + def add_jammyjam(config, jammyjam): + def register(*arg, **kw): + config.registry.jammyjam_args = arg + config.registry.jammyjam_kw = kw + config.registry.jammyjam = jammyjam + config.action('jammyjam', register, args=('one',), kw={'two':'two'}) + +In the above example, when this directive is used to generate an action, and +that action is committed, ``config.registry.jammyjam_args`` will be set to +``('one',)`` and ``config.registry.jammyjam_kw`` will be set to +``{'two':'two'}``. ``args`` and ``kw`` are honestly not very useful when +your ``callable`` is a closure function, because you already usually have +access to every local in the directive without needing them to be passed +back. They can be useful, however, if you don't use a closure as a callable. + +``order`` is a crude order control mechanism. ``order`` defaults to the +integer ``0``; it can be set to any other integer. All actions that share an +order will be called before other actions that share a higher order. This +makes it possible to write a directive with callable logic that relies on the +execution of the callable of another directive being done first. For +example, Pyramid's :meth:`pyramid.config.Configurator.add_view` directive +registers an action with a higher order than the +:meth:`pyramid.config.Configurator.add_route` method. Due to this, the +``add_view`` method's callable can assume that, if a ``route_name`` was +passed to it, that a route by this name was already registered by +``add_route``, and if such a route has not already been registered, it's a +configuration error (a view that names a nonexistent route via its +``route_name`` parameter will never be called). + +``introspectables`` is a sequence of :term:`introspectable` objects. Using +``introspectables`` allows you to plug into Pyramid's configuration +introspection system. + -- cgit v1.2.3 From efd490e1c5bc17da49700f2d4572e64d0a3c0c9a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 01:58:49 -0500 Subject: reword --- docs/narr/extconfig.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 4a0db85de..4468e95b4 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -115,9 +115,9 @@ Here's an example directive which uses the "action" method: Fancy, but what does it do? The action method accepts a number of arguments. In the above directive named ``add_jammyjam``, we call :meth:`~pyramid.config.Configurator.action` with two arguments: the string -``jammyjam`` is passed as the first argument, ``discriminator`` and the -closure function named ``register`` is passed as the second argument, -named ``callable``. +``jammyjam`` is passed as the first argument named ``discriminator``, and the +closure function named ``register`` is passed as the second argument named +``callable``. When the :meth:`~pyramid.config.Configurator.action` method is called, it appends an action to the list of pending configuration actions. All pending -- cgit v1.2.3 From 1c4631864bcb7eb4b81a72fb305f72edc86f56ed Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 02:02:16 -0500 Subject: wording --- docs/narr/extconfig.rst | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 4468e95b4..570d20ec7 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -140,17 +140,22 @@ directive did this: config.add_jammyjam('first') config.add_jammyjam('second') -When the action list was committed, the user's application would not start, -because the discriminators of the actions generated by the two calls are in -direct conflict. Automatic conflict resolution cannot resolve the conflict, -and the user provided no intermediate +When the action list was committed resulting from the set of calls above, our +user's application would not start, because the discriminators of the actions +generated by the two calls are in direct conflict. Automatic conflict +resolution cannot resolve the conflict (because no ``config.include`` is +involved), and the user provided no intermediate :meth:`pyramid.config.Configurator.commit` call between the calls to ``add_jammyjam`` to ensure that the successive calls did not conflict with -each other. This is the purpose of the discriminator argument to the action +each other. + +This demonstrates the purpose of the discriminator argument to the action method: it's used to indicate a uniqueness constraint for an action. Two actions with the same discriminator will conflict unless the conflict is automatically or manually resolved. A discriminator can be any hashable -object, but it is generally a string or a tuple. +object, but it is generally a string or a tuple. *You use a discriminator to +declaratively ensure that the user doesn't provide ambiguous configuration +statements.* But let's imagine that a consumer of ``add_jammyjam`` used it in such a way that no configuration conflicts are generated. @@ -160,7 +165,7 @@ that no configuration conflicts are generated. config.add_jammyjam('first') -What happens then? When the ``add_jammyjam`` method is called, an action is +What happens now? When the ``add_jammyjam`` method is called, an action is appended to the pending actions list. When the pending configuration actions are processed during :meth:`~pyramid.config.Configurator.commit`, and no conflicts occur, the *callable* provided as the second argument to the @@ -170,9 +175,9 @@ called with no arguments. The callable in ``add_jammyjam`` is the ``config.registry.jammyjam`` to whatever the user passed in as the ``jammyjam`` argument to the ``add_jammyjam`` function. Therefore, the result of the user's call to our directive will set the ``jammyjam`` -attribute of the registry to the string ``first``. A callable is used by a -directive to defer the result of a user's call to a directive until conflict -detection has had a chance to do its job. +attribute of the registry to the string ``first``. *A callable is used by a +directive to defer the result of a user's call to the directive until +conflict detection has had a chance to do its job*. Other arguments exist to the :meth:`~pyramid.config.Configurator.action` method, including ``args``, ``kw``, ``order``, and ``introspectables``. -- cgit v1.2.3 From 8015a9f1e05526a4990997f58aab19a5f06b1737 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 02:03:06 -0500 Subject: wording --- docs/narr/extconfig.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 570d20ec7..edc120e39 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -6,9 +6,10 @@ Extending Pyramid Configuration =============================== -Pyramid allows you to extend its Configurator with custom directives. These -directives can add an :term:`action`, participate in :term:`conflict -resolution`, and can provide some number of :term:`introspectable` objects. +Pyramid allows you to extend its Configurator with custom directives. Custom +directives can use other directives, they can add a custom :term:`action`, +they can participate in :term:`conflict resolution`, and they can provide +some number of :term:`introspectable` objects. .. index:: single: add_directive -- cgit v1.2.3 From 6ab90035628ab282ba4e5433f5b9549c98a6df13 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 02:34:39 -0500 Subject: add blather about introspectables --- docs/narr/extconfig.rst | 140 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 137 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index edc120e39..ac8b83baa 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -219,7 +219,141 @@ passed to it, that a route by this name was already registered by configuration error (a view that names a nonexistent route via its ``route_name`` parameter will never be called). -``introspectables`` is a sequence of :term:`introspectable` objects. Using -``introspectables`` allows you to plug into Pyramid's configuration -introspection system. +``introspectables`` is a sequence of :term:`introspectable` objects. You can +pass a sequence of introspectables to the +:meth:`~pyramid.config.Configurator.action` method, which allows you to +augment Pyramid's configuration introspection system. + +.. _introspection: + +Configuration Introspection +--------------------------- + +.. warning:: + + The introspection subsystem is new in Pyramid 1.3. + +Pyramid provides a configuration introspection system that can be used by +debugging tools to provide visibility into the configuration of a running +application. + +All built-in Pyramid directives (such as +:meth:`pyramid.config.Configurator.add_view` and +:meth:`pyramid.config.Configurator.add_route`) register a set of +introspectables when called. For example, when you register a view via +``add_view``, the directive registers at least one introspectable: an +introspectable about the view registration itself, providing human-consumable +values for the arguments it was passed. You can later use the introspection +query system to determine whether a particular view uses a renderer, or +whether a particular view is limited to a particular request method, or which +routes a particular view is registered against. The Pyramid "debug toolbar" +makes use of the introspection system in various ways to display information +to Pyramid developers. + +Introspection values are set when a sequence of :term:`introspectable` +objects is passed to the :meth:`~pyramid.config.Configurator.action` method. +Here's an example of a directive which uses introspectables: + +.. code-block:: python + :linenos: + + def add_jammyjam(config, value): + def register(): + config.registry.jammyjam = value + intr = config.introspectable(category_name='jammyjams', + discriminator='jammyjam', + title='a jammyjam', + type_name=None) + intr['value'] = value + config.action('jammyjam', register, introspectables=(intr,)) + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_jammyjam', add_jammyjam) + +If you notice, the above directive uses the ``introspectable`` attribute of a +Configurator (:attr:`pyramid.config.Configurator.introspectable`) to create +an introspectable object. The introspectable object's constructor requires +at least four arguments: the ``category_name``, the ``discriminator``, the +``title``, and the ``type_name``. + +The ``category_name`` is a string representing the logical category for this +introspectable. Usually the category_name is a pluralization of the type of +object being added via the action. + +The ``discriminator`` is a value unique **within the category** (unlike the +action discriminator, which must be unique within the entire set of actions). +It is typically a string or tuple representing the values unique to this +introspectable within the category. It is used to generate links and as part +of a relationship-forming target for other introspectables. + +The ``title`` is a human-consumable string that can be used by introspection +system frontends to show a friendly summary of this introspectable. + +The ``type_name`` is a value that can be used to subtype this introspectable +within its category for for sorting and presentation purposes. It can be any +value. + +An introspectable is also dictionary-like. It can contain any set of +key/value pairs, typically related to the arguments passed to its related +directive. While the category_name, discriminator, title and type_name are +*metadata* about the introspectable, the values provided as key/value pairs +are the actual data provided by the introspectable. In the above example, we +set the ``value`` key to the value of the ``value`` argument passed to the +directive. + +Our directive above mutates the introspectable, and passes it in to the +``action`` method as the first element of a tuple as the value of the +``introspectable`` keyword argument. This associates this introspectable +with the action. Introspection tools will then display this introspectable +in their index. + +Introspectable Relationships +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Two introspectables may have relationships between each other. + +.. code-block:: python + :linenos: + + def add_jammyjam(config, value, template): + def register(): + config.registry.jammyjam = (value, template) + intr = config.introspectable(category_name='jammyjams', + discriminator='jammyjam', + title='a jammyjam', + type_name=None) + intr['value'] = value + tmpl_intr = config.introspectable(category_name='jammyjam templates', + discriminator=template, + title=template, + type_name=None) + tmpl_intr['value'] = template + intr.relate('jammyjam templates', template) + config.action('jammyjam', register, introspectables=(intr, tmpl_intr)) + + if __name__ == '__main__': + config = Configurator() + config.add_directive('add_jammyjam', add_jammyjam) + +In the above example, the ``add_jammyjam`` directive registers *two* +introspectables. The first is related to the ``value`` passed to the +directive; the second is related to the ``template`` passed to the directive. +If you believe a concept within a directive is important enough to have its +own introspectable, you can cause the same directive to register more than +one introspectable, registering one introspectable for the "main idea" and +another for a related concept. + +The call to ``intr.relate`` above +(:meth:`pyramid.interfaces.IIntrospectable.relate`) is passed two arguments: +a category name and a directive. The example above effectively indicates +that the directive wishes to form a relationship between the ``intr`` +introspectable and the ``tmpl_intr`` introspectable; the arguments passed to +``relate`` are the category name and discriminator of the ``tmpl_intr`` +introspectable. + +Introspectable relationships will show up in frontend system renderings of +introspection values. For example, if a view registration names a route +name, the introspectable related to the view callable will show a reference +to the route it relates to and vice versa. -- cgit v1.2.3 From 9d97b654057e621c4928fe597053d54aa5f63a8c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 03:00:15 -0500 Subject: add skeleton for using introspection chapter --- docs/narr/introspector.rst | 89 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 docs/narr/introspector.rst (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst new file mode 100644 index 000000000..3cbafa010 --- /dev/null +++ b/docs/narr/introspector.rst @@ -0,0 +1,89 @@ +.. index:: + single: introspection + single: introspector + +.. _using_introspection: + +Pyramid Configuration Introspection +=================================== + +When Pyramid starts up, each call to a :term:`configuration directive` causes +one or more :term:`introspectable` objects to be registered with an +:term:`introspector`. This introspector can be queried by application code +to obtain information about the configuration of the running application. +This feature is useful for debug toolbars, command-line scripts which show +some aspect of configuration, and for runtime reporting of startup-time +configuration settings. + +Using the Introspector +---------------------- + +Here's an example of using Pyramid's introspector: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + + @view_config(route_name='foo') + @view_config(route_name='bar') + def route_accepts(request): + introspector = request.registry.introspector + route_name = request.matched_route.name + route_intr = introspector.get('routes', route_name) + return Response(str(route_intr['accept'])) + +This view will return a response that contains the "accept" argument provided +to the ``add_route`` method of the route which matched when the view was +called. It used the :meth:`pyramid.interfaces.IIntrospector.get` method to +return an introspectable in the category ``routes`` with a +:term:`discriminator` equal to the matched route name. It then used the +returned introspectable to obtain an "accept" value. + +The introspector has a number of other query-related methods: see +:class:`pyramid.interfaces.IIntrospector` for more information. The +introspectable returned by the query methods of the introspector has methods +and attributes described by :class:`pyramid.interfaces.IIntrospectable`. + +Concrete Introspection Categories +--------------------------------- + +This is a list of concrete introspection categories provided by Pyramid. + +``subscribers`` + +``response adapters`` + +``asset overrides`` + +``root factories`` + +``session factory`` + +``request factory`` + +``locale negotiator`` + +``translation directories`` + +``renderer factories`` + +``routes`` + +``authentication policy`` + +``authorization policy`` + +``default permission`` + +``tweens (implicit)`` + +``views`` + +``templates`` + +``permissions`` + +``view mapper`` + -- cgit v1.2.3 From 5224059f71d0ad592a611c196a3af7cbd1dc828f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 16:24:34 -0500 Subject: add more content to the introspectables narr chapter; adjust introspection registrations while doing so --- docs/narr/extconfig.rst | 13 +- docs/narr/introspector.rst | 425 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 411 insertions(+), 27 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index ac8b83baa..856654377 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -336,7 +336,7 @@ Two introspectables may have relationships between each other. config = Configurator() config.add_directive('add_jammyjam', add_jammyjam) -In the above example, the ``add_jammyjam`` directive registers *two* +In the above example, the ``add_jammyjam`` directive registers two introspectables. The first is related to the ``value`` passed to the directive; the second is related to the ``template`` passed to the directive. If you believe a concept within a directive is important enough to have its @@ -352,8 +352,15 @@ introspectable and the ``tmpl_intr`` introspectable; the arguments passed to ``relate`` are the category name and discriminator of the ``tmpl_intr`` introspectable. +Relationships need not be made between two introspectables created by the +same directive. Instead, a relationship can be formed between an +introspectable created in one directive and another introspectable created in +another by calling ``relate`` on either side with the other directive's +category name and discriminator. An error will be raised at configuration +commit time if you attempt to relate an introspectable with another +nonexistent introspectable, however. + Introspectable relationships will show up in frontend system renderings of introspection values. For example, if a view registration names a route name, the introspectable related to the view callable will show a reference -to the route it relates to and vice versa. - +to the route to which it relates to and vice versa. diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 3cbafa010..8adfde7d1 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -9,16 +9,17 @@ Pyramid Configuration Introspection When Pyramid starts up, each call to a :term:`configuration directive` causes one or more :term:`introspectable` objects to be registered with an -:term:`introspector`. This introspector can be queried by application code -to obtain information about the configuration of the running application. -This feature is useful for debug toolbars, command-line scripts which show -some aspect of configuration, and for runtime reporting of startup-time +:term:`introspector`. The introspector can be queried by application code to +obtain information about the configuration of the running application. This +feature is useful for debug toolbars, command-line scripts which show some +aspect of configuration, and for runtime reporting of startup-time configuration settings. Using the Introspector ---------------------- -Here's an example of using Pyramid's introspector: +Here's an example of using Pyramid's introspector from within a view +callable: .. code-block:: python :linenos: @@ -26,64 +27,440 @@ Here's an example of using Pyramid's introspector: from pyramid.view import view_config from pyramid.response import Response - @view_config(route_name='foo') @view_config(route_name='bar') def route_accepts(request): introspector = request.registry.introspector route_name = request.matched_route.name route_intr = introspector.get('routes', route_name) - return Response(str(route_intr['accept'])) + return Response(str(route_intr['pattern'])) -This view will return a response that contains the "accept" argument provided -to the ``add_route`` method of the route which matched when the view was -called. It used the :meth:`pyramid.interfaces.IIntrospector.get` method to -return an introspectable in the category ``routes`` with a -:term:`discriminator` equal to the matched route name. It then used the -returned introspectable to obtain an "accept" value. +This view will return a response that contains the "pattern" argument +provided to the ``add_route`` method of the route which matched when the view +was called. It uses the :meth:`pyramid.interfaces.IIntrospector.get` method +to return an introspectable in the category ``routes`` with a +:term:`discriminator` equal to the matched route name. It then uses the +returned introspectable to obtain an "pattern" value. -The introspector has a number of other query-related methods: see -:class:`pyramid.interfaces.IIntrospector` for more information. The -introspectable returned by the query methods of the introspector has methods -and attributes described by :class:`pyramid.interfaces.IIntrospectable`. +The introspectable returned by the query methods of the introspector has +methods and attributes described by +:class:`pyramid.interfaces.IIntrospectable`. In particular, the +:meth:`~pyramid.interfaces.IIntrospector.get`, +:meth:`~pyramid.interfaces.IIntrospector.get_category`, +:meth:`~pyramid.interfaces.IIntrospector.categories`, +:meth:`~pyramid.interfaces.IIntrospector.categorized`, and +:meth:`~pyramid.interfaces.IIntrospector.related` methods of an introspector +can be used to query for introspectables. -Concrete Introspection Categories ---------------------------------- +Introspectable Objects +---------------------- + +Introspectable objects are returned from query methods of an introspector. +Each introspectable object implements the attributes and methods the +documented at :class:`pyramid.interfaces.IIntrospectable`. + +The important attributes shared by all introspectables are the following: + +``title`` + + A human-readable text title describing the introspectable + +``category_name`` + + A text category name describing the introspection category to which this + introspectable belongs. It is often a plural if there are expected to be + more than one introspectable registered within the category. + +``discriminator`` + + A hashable object representing the unique value of this introspectable + within its category. + +``discriminator_hash`` -This is a list of concrete introspection categories provided by Pyramid. + The integer hash of the discriminator (useful for using in HTML links). + +``type_name`` + + The text name of a subtype within this introspectable's category. If there + is only one type name in this introspectable's category, this value will + often be a singular version of the category name but it can be an arbitrary + value. + +Besides having the attributes described above, an introspectable is a +dictionary-like object. An introspectable can be queried for data values via +its ``__getitem__``, ``get``, ``keys``, ``values``, or ``items`` methods. +For example: + +.. code-block:: python + :linenos: + + route_intr = introspector.get('routes', 'edit_user') + pattern = route_intr['pattern'] + +Pyramid Introspection Categories +-------------------------------- + +The list of concrete introspection categories provided by built-in Pyramid +configuration directives follows. Add-on packages may supply other +introspectables in categories not described here. ``subscribers`` + Each introspectable in the ``subscribers`` category represents a call to + :meth:`pryamid.config.Configurator.add_subscriber` (or the decorator + equivalent); each will have the following data. + + ``subscriber`` + + The subscriber callable object (the resolution of the ``subscriber`` + argument passed to ``add_susbcriber``). + + ``interfaces`` + + A sequence of interfaces (or classes) that are subscribed to (the + resolution of the ``ifaces`` argument passed to ``add_subscriber``). + ``response adapters`` -``asset overrides`` + Each introspectable in the ``response adapters`` category represents a call + to :meth:`pyramid.config.Configurator.add_response_adapter` (or a decorator + equivalent); each will have the following data. + + ``adapter`` + + The adapter object (the resolved ``adapter`` argument to + ``add_response_adapter``). + + ``type`` + + The resolved ``type_or_iface`` argument passed to + ``add_response_adapter``. ``root factories`` + XXX ``default root factory`` category? + + Each introspectable in the ``root factories`` category represents a call to + :meth:`pyramid.config.Configurator.set_root_factory` (or the Configurator + constructor equivalent) *or* a ``factory`` argument passed to + :meth:`pyramid.config.Configurator.add_route`; each will have the following + data. + + ``factory`` + + The factory object (the resolved ``factory`` argument to + ``set_root_factory``). + + ``route_name`` + + The name of the route which will use this factory. If this is the + *default* root factory (if it's registered during a call to + ``set_root_factory``), this value will be ``None``. + ``session factory`` + Only one introspectable will exist in the ``session factory`` category. It + represents a call to :meth:`pyramid.config.Configurator.set_session_factory` + (or the Configurator constructor equivalent); it will have the following + data. + + ``factory`` + + The factory object (the resolved ``factory`` argument to + ``set_session_factory``). + ``request factory`` + Only one introspectable will exist in the ``request factory`` category. It + represents a call to :meth:`pyramid.config.Configurator.set_request_factory` + (or the Configurator constructor equivalent); it will have the following + data. + + ``factory`` + + The factory object (the resolved ``factory`` argument to + ``set_request_factory``). + ``locale negotiator`` -``translation directories`` + Only one introspectable will exist in the ``locale negotiator`` category. + It represents a call to + :meth:`pyramid.config.Configurator.set_locale_negotiator` (or the + Configurator constructor equivalent); it will have the following data. + + ``negotiator`` + + The factory object (the resolved ``negotiator`` argument to + ``set_locale_negotiator``). ``renderer factories`` + Each introspectable in the ``renderer factories`` category represents a + call to :meth:`pyramid.config.Configurator.add_renderer` (or the + Configurator constructor equivalent); each will have the following data. + + ``name`` + + The name of the renderer (the value of the ``name`` argument to + ``add_renderer``). + + ``factory`` + + The factory object (the resolved ``factory`` argument to + ``add_renderer``). + +``renderer globals factory`` + + There will be one and only one introspectable in the ``renderer globals + factory`` category. It represents a call to + :meth:`pyramid.config.Configurator.set_renderer_globals_factory`; it will + have the following data. + + ``factory`` + + The factory object (the resolved ``factory`` argument to + ``set_renderer_globals_factory``). + ``routes`` + Each introspectable in the ``routes`` category represents a call to + :meth:`pyramid.config.Configurator.add_route`; each will have the following + data. + + ``name`` + + The ``name`` argument passed to ``add_route``. + + ``pattern`` + + The ``pattern`` argument passed to ``add_route``. + + ``factory`` + + The (resolved) ``factory`` argument passed to ``add_route``. + + ``xhr`` + + The ``xhr`` argument passed to ``add_route``. + + ``request_method`` + + The ``request_method`` argument passed to ``add_route``. + + ``request_methods`` + + A sequence of request method names implied by the ``request_method`` + argument passed to ``add_route``. + + ``path_info`` + + The ``path_info`` argument passed to ``add_route``. + + ``request_param`` + + The ``request_param`` argument passed to ``add_route``. + + ``header`` + + The ``header`` argument passed to ``add_route``. + + ``accept`` + + The ``accept`` argument passed to ``add_route``. + + ``traverse`` + + The ``traverse`` argument passed to ``add_route``. + + ``custom_predicates`` + + The ``custom_predicates`` argument passed to ``add_route``. + + ``pregenerator`` + + The ``pregenerator`` argument passed to ``add_route``. + + ``pregenerator`` + + The ``static`` argument passed to ``add_route``. + + ``pregenerator`` + + The ``use_global_views`` argument passed to ``add_route``. + + ``object`` + + The :class:`pyramid.interfaces.IRoute` object that is used to perform + matching and generation for this route. + ``authentication policy`` + There will be one and only one introspectable in the ``authentication + policy`` category. It represents a call to the + :meth:`pyramid.config.Configurator.set_authentication_policy` method (or + its Configurator constructor equivalent); it will have the following data. + + ``policy`` + + The policy object (the resolved ``policy`` argument to + ``set_authentication_policy``). + ``authorization policy`` + There will be one and only one introspectable in the ``authorization + policy`` category. It represents a call to the + :meth:`pyramid.config.Configurator.set_authorization_policy` method (or its + Configurator constructor equivalent); it will have the following data. + + ``policy`` + + The policy object (the resolved ``policy`` argument to + ``set_authorization_policy``). + ``default permission`` -``tweens (implicit)`` + There will be one and only one introspectable in the ``default permission`` + category. It represents a call to the + :meth:`pyramid.config.Configurator.set_default_permission` method (or its + Configurator constructor equivalent); it will have the following data. + + ``value`` + + The permission name passed to ``set_default_permission``. ``views`` -``templates`` + Each introspectable in the ``views`` category represents a call to + :meth:`pyramid.config.Configurator.add_view`; each will have the following + data. + + ``name`` + + The ``name`` argument passed to ``add_view``. + + ``context`` + + The (resolved) ``context`` argument passed to ``add_view``. + + ``containment`` + + The (resolved) ``containment`` argument passed to ``add_view``. + + ``request_param`` + + The ``request_param`` argument passed to ``add_view``. + + ``request_methods`` + + A sequence of request method names implied by the ``request_method`` + argument passed to ``add_view``. + + ``route_name`` + + The ``route_name`` argument passed to ``add_view``. + + ``attr`` + + The ``attr`` argument passed to ``add_view``. + + ``xhr`` + + The ``xhr`` argument passed to ``add_view``. + + ``accept`` + + The ``accept`` argument passed to ``add_view``. + + ``header`` + + The ``header`` argument passed to ``add_view``. + + ``path_info`` + + The ``path_info`` argument passed to ``add_view``. + + ``match_param`` + + The ``match_param`` argument passed to ``add_view``. + + ``callable`` + + The (resolved) ``view`` argument passed to ``add_view``. Represents the + "raw" view callable. + + ``derived_callable`` + + The view callable derived from the ``view`` argument passed to + ``add_view``. Represents the view callable which Pyramid itself calls + (wrapped in security and other wrappers). + + ``mapper`` + + The (resolved) ``mapper`` argument passed to ``add_view``. + + ``decorator`` + + The (resolved) ``decorator`` argument passed to ``add_view``. ``permissions`` + Each introspectable in the ``permissions`` category represents a call to + :meth:`pyramid.config.Configurator.add_view` that has an explicit + ``permission`` argument to *or* a call to + :meth:`pyramid.config.Configurator.set_default_permission`; each will have + the following data. + + ``value`` + + The permission name passed to ``add_view`` or ``set_default_permission``. + +``templates`` + + Each introspectable in the ``templates`` category represents a call to + :meth:`pyramid.config.Configurator.add_view` that has a ``renderer`` + argument which points to a template; each will have the following data. + + ``name`` + + The renderer's name (a string). + + ``type`` + + The renderer's type (a string). + + ``renderer`` + + The :class:`pyramid.interfaces.IRendererInfo` object which represents + this template's renderer. + ``view mapper`` + XXX default view mapper category? + + Each introspectable in the ``permissions`` category represents a call to + :meth:`pyramid.config.Configurator.add_view` that has an explicit + ``mapper`` argument to *or* a call to + :meth:`pyramid.config.Configurator.set_view_mapper`; each will have + the following data. + + ``mapper`` + + The (resolved) ``mapper`` argument passed to ``add_view`` or + ``set_view_mapper``. + +``asset overrides`` + + XXX + +``translation directories`` + + XXX + +``tweens (implicit)`` + + XXX + +``tweens (explicit)`` + + XXX + -- cgit v1.2.3 From 58c01ff8863971f81db59d437d49fd9e97b59e5c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 19:37:38 -0500 Subject: flesh out categories more --- docs/narr/introspector.rst | 80 ++++++++++++++++++++++++++++++++++++------ docs/narr/tb_introspector.png | Bin 0 -> 46164 bytes 2 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 docs/narr/tb_introspector.png (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 8adfde7d1..ac0859164 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -15,6 +15,10 @@ feature is useful for debug toolbars, command-line scripts which show some aspect of configuration, and for runtime reporting of startup-time configuration settings. +.. warning:: + + Introspection is new in Pyramid 1.3. + Using the Introspector ---------------------- @@ -86,6 +90,12 @@ The important attributes shared by all introspectables are the following: often be a singular version of the category name but it can be an arbitrary value. +``action_info`` + + An object describing the directive call site which caused this + introspectable to be registered; contains attributes described in + :class:`pyramid.interfaces.IActionInfo`. + Besides having the attributes described above, an introspectable is a dictionary-like object. An introspectable can be queried for data values via its ``__getitem__``, ``get``, ``keys``, ``values``, or ``items`` methods. @@ -107,7 +117,7 @@ introspectables in categories not described here. ``subscribers`` Each introspectable in the ``subscribers`` category represents a call to - :meth:`pryamid.config.Configurator.add_subscriber` (or the decorator + :meth:`pyramid.config.Configurator.add_subscriber` (or the decorator equivalent); each will have the following data. ``subscriber`` @@ -138,8 +148,6 @@ introspectables in categories not described here. ``root factories`` - XXX ``default root factory`` category? - Each introspectable in the ``root factories`` category represents a call to :meth:`pyramid.config.Configurator.set_root_factory` (or the Configurator constructor equivalent) *or* a ``factory`` argument passed to @@ -435,8 +443,6 @@ introspectables in categories not described here. ``view mapper`` - XXX default view mapper category? - Each introspectable in the ``permissions`` category represents a call to :meth:`pyramid.config.Configurator.add_view` that has an explicit ``mapper`` argument to *or* a call to @@ -450,17 +456,69 @@ introspectables in categories not described here. ``asset overrides`` - XXX + Each introspectable in the ``asset overrides`` category represents a call + to :meth:`pyramid.config.Configurator.override_asset`; each will have the + following data. + + ``to_override`` + + The ``to_override`` argument (an asset spec) passed to + ``override_asset``. + + ``override_with`` + + The ``override_with`` argument (an asset spec) passed to + ``override_asset``. ``translation directories`` - XXX + Each introspectable in the ``asset overrides`` category represents an + individual element in a ``specs`` argument passed to to + :meth:`pyramid.config.Configurator.add_translation_dirs`; each will have + the following data. + + ``directory`` + + The absolute path of the translation directory. + + ``spec`` + + The asset specification passed to ``add_translation_dirs``. + +``tweens`` + + Each introspectable in the ``tweens`` category represents a call to + :meth:`pyramid.config.Configurator.add_tween`; each will have the following + data. + + ``name`` + + The dotted name to the tween factory as a string (passed as + the ``tween_factory`` argument to ``add_tween``). + + ``factory`` + + The (resolved) tween factory object. + + ``type`` + + ``implict`` or ``explicit`` as a string. + + ``under`` + + The ``under`` argument passed to ``add_tween`` (a string). + + ``over`` + + The ``over`` argument passed to ``add_tween`` (a string). -``tweens (implicit)`` +Toolbar Introspection +--------------------- - XXX +The Pyramid debug toolbar (part of the ``pyramid_debugtoolbar`` package) +provides a canned view of all registered introspectables and their +relationships. It looks something like this: -``tweens (explicit)`` +.. image:: tb_introspector.png - XXX diff --git a/docs/narr/tb_introspector.png b/docs/narr/tb_introspector.png new file mode 100644 index 000000000..231a094f7 Binary files /dev/null and b/docs/narr/tb_introspector.png differ -- cgit v1.2.3 From b40fb8b26fe37102b076cd2310ea7a3fe8b79311 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 21:04:24 -0500 Subject: add a noop introspector (allow introspection to be turned off) --- docs/narr/introspector.rst | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index ac0859164..71b41773c 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -512,8 +512,8 @@ introspectables in categories not described here. The ``over`` argument passed to ``add_tween`` (a string). -Toolbar Introspection ---------------------- +Introspection in the Toolbar +---------------------------- The Pyramid debug toolbar (part of the ``pyramid_debugtoolbar`` package) provides a canned view of all registered introspectables and their @@ -521,4 +521,20 @@ relationships. It looks something like this: .. image:: tb_introspector.png +Disabling Introspection +----------------------- +You can disable Pyramid introspection by passing the object +:attr:`pyramid.registry.noop_introspector` to the :term:`Configurator` +constructor in your application setup: + +.. code-block:: python + + from pyramid.config import Configurator + from pyramid.registry import noop_introspector + config = Configurator(..., introspector=noop_introspector) + +When the noop introspector is active, all introspectables generated by the +framework are thrown away. A noop introspector behaves just like a "real" +introspector, but the methods of a noop introspector do nothing and return +null values. -- cgit v1.2.3 From d8e504cb1d486b9cd1caea7437ff212f92ed4fdb Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 21:25:43 -0500 Subject: make add_route generate the right request methods introspection value --- docs/narr/introspector.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 71b41773c..1285a4cf1 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -258,7 +258,8 @@ introspectables in categories not described here. ``request_methods`` A sequence of request method names implied by the ``request_method`` - argument passed to ``add_route``. + argument passed to ``add_route`` or the value ``None`` if a + ``request_method`` argument was not supplied. ``path_info`` @@ -361,7 +362,8 @@ introspectables in categories not described here. ``request_methods`` A sequence of request method names implied by the ``request_method`` - argument passed to ``add_view``. + argument passed to ``add_view`` or the value ``None`` if a + ``request_method`` argument was not supplied. ``route_name`` -- cgit v1.2.3 From fc3e425e64420fc05dc4fa1ebf83951934a2f005 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 3 Dec 2011 21:29:25 -0500 Subject: wording --- docs/narr/introspector.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 1285a4cf1..cfc6144dd 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -536,7 +536,7 @@ constructor in your application setup: from pyramid.registry import noop_introspector config = Configurator(..., introspector=noop_introspector) -When the noop introspector is active, all introspectables generated by the -framework are thrown away. A noop introspector behaves just like a "real" -introspector, but the methods of a noop introspector do nothing and return -null values. +When the noop introspector is active, all introspectables generated by +configuration directives are thrown away. A noop introspector behaves just +like a "real" introspector, but the methods of a noop introspector do nothing +and return null values. -- cgit v1.2.3 From 8fe02156794c2cac0cbc6961332f9d8bebc1cb90 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Dec 2011 00:12:38 -0500 Subject: the starter scaffold now uses url dispatch; add a minimal section about using another WSGI server; random docs fixes --- docs/narr/MyProject/README.txt | 3 - docs/narr/MyProject/development.ini | 2 +- docs/narr/MyProject/myproject/__init__.py | 4 +- docs/narr/MyProject/myproject/resources.py | 3 - .../MyProject/myproject/static/pyramid-small.png | Bin 0 -> 7044 bytes docs/narr/MyProject/myproject/tests.py | 2 - docs/narr/MyProject/myproject/views.py | 3 +- docs/narr/MyProject/production.ini | 4 +- docs/narr/extconfig.rst | 4 +- docs/narr/project.rst | 162 ++++++++------------- 10 files changed, 67 insertions(+), 120 deletions(-) delete mode 100644 docs/narr/MyProject/myproject/resources.py create mode 100644 docs/narr/MyProject/myproject/static/pyramid-small.png (limited to 'docs/narr') diff --git a/docs/narr/MyProject/README.txt b/docs/narr/MyProject/README.txt index 5e10949fc..c28d0d94a 100644 --- a/docs/narr/MyProject/README.txt +++ b/docs/narr/MyProject/README.txt @@ -1,4 +1 @@ MyProject README - - - diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 3a4758c44..d61da580f 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -41,6 +41,6 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s # End logging configuration diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py index ddcdd7162..31b02cf02 100644 --- a/docs/narr/MyProject/myproject/__init__.py +++ b/docs/narr/MyProject/myproject/__init__.py @@ -1,10 +1,10 @@ from pyramid.config import Configurator -from .resources import Root def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ - config = Configurator(root_factory=Root, settings=settings) + config = Configurator(settings=settings) config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') config.scan() return config.make_wsgi_app() diff --git a/docs/narr/MyProject/myproject/resources.py b/docs/narr/MyProject/myproject/resources.py deleted file mode 100644 index 3d811895c..000000000 --- a/docs/narr/MyProject/myproject/resources.py +++ /dev/null @@ -1,3 +0,0 @@ -class Root(object): - def __init__(self, request): - self.request = request diff --git a/docs/narr/MyProject/myproject/static/pyramid-small.png b/docs/narr/MyProject/myproject/static/pyramid-small.png new file mode 100644 index 000000000..a5bc0ade7 Binary files /dev/null and b/docs/narr/MyProject/myproject/static/pyramid-small.png differ diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py index a32165471..d8b764041 100644 --- a/docs/narr/MyProject/myproject/tests.py +++ b/docs/narr/MyProject/myproject/tests.py @@ -14,5 +14,3 @@ class ViewTests(unittest.TestCase): request = testing.DummyRequest() info = my_view(request) self.assertEqual(info['project'], 'MyProject') - - diff --git a/docs/narr/MyProject/myproject/views.py b/docs/narr/MyProject/myproject/views.py index 5b5d230f2..f571a5976 100644 --- a/docs/narr/MyProject/myproject/views.py +++ b/docs/narr/MyProject/myproject/views.py @@ -1,6 +1,5 @@ from pyramid.view import view_config -from .resources import Root -@view_config(context=Root, renderer='templates/mytemplate.pt') +@view_config(route_name='home', renderer='templates/mytemplate.pt') def my_view(request): return {'project':'MyProject'} diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 9d025715d..97050e8fe 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -25,11 +25,11 @@ keys = console keys = generic [logger_root] -level = INFO +level = WARN handlers = console [logger_myproject] -level = INFO +level = WARN handlers = qualname = myproject diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 856654377..a57c78105 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -226,8 +226,8 @@ augment Pyramid's configuration introspection system. .. _introspection: -Configuration Introspection ---------------------------- +Adding Configuration Introspection +---------------------------------- .. warning:: diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4c528ab58..478e92b7e 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -46,24 +46,17 @@ each other on a number of axes: The included scaffolds are these: ``starter`` - URL mapping via :term:`traversal` and no persistence mechanism. + URL mapping via :term:`URL dispatch` and no persistence mechanism. ``zodb`` - URL mapping via :term:`traversal` and persistence via :term:`ZODB`. + URL mapping via :term:`traversal` and persistence via :term:`ZODB`. *Note + that, as of this writing, this scaffold will not run under Python 3, only + under Python 2.* ``alchemy`` URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` -.. note:: - - Rather than use any of the above scaffolds, Pylons 1 users may feel more - comfortable installing the :term:`Akhet` development environment, which - provides a scaffold named ``akhet``. This scaffold configures a Pyramid - application in a "Pylons-esque" way, including the use of a :term:`view - handler` to map URLs to code (a handler is much like a Pylons - "controller"). - .. index:: single: creating a project single: project @@ -382,7 +375,6 @@ structure: |-- MANIFEST.in |-- myproject | |-- __init__.py - | |-- resources.py | |-- static | | |-- favicon.ico | | |-- logo.png @@ -682,8 +674,6 @@ The ``myproject`` :term:`package` lives inside the ``MyProject`` ``main`` function which is used as a entry point for commands such as ``pserve``, ``pshell``, ``pviews``, and others. -#. A ``resources.py`` module, which contains :term:`resource` code. - #. A ``templates`` directory, which contains :term:`Chameleon` (or other types of) templates. @@ -719,23 +709,23 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Line 2 imports the ``Root`` class from :mod:`myproject.resources` that we - use later. - -#. Lines 4-10 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 3-16 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. Within this function, application configuration is performed. - Line 7 creates an instance of a :term:`Configurator`. + Line 6 creates an instance of a :term:`Configurator`. - Line 8 registers a static view, which will serve up the files from the + Line 7 registers a static view, which will serve up the files from the ``mypackage:static`` :term:`asset specification` (the ``static`` directory of the ``mypackage`` package). + Line 8 adds a :term:`route` to the configuration. This route is later + used by a view in the ``views`` module. + Line 9 calls ``config.scan()``, which picks up view registrations declared - elsewhere in the package (in this case, in the ``view.py`` module). + elsewhere in the package (in this case, in the ``views.py`` module). Line 10 returns a :term:`WSGI` application to the caller of the function (Pyramid's pserve). @@ -755,20 +745,22 @@ and which returns a :term:`response`. :language: python :linenos: -Lines 4-6 define and register a :term:`view callable` named ``my_view``. The +Lines 3-5 define and register a :term:`view callable` named ``my_view``. The function named ``my_view`` is decorated with a ``view_config`` decorator (which is processed by the ``config.scan()`` line in our ``__init__.py``). -The view_config decorator asserts that this view be found when the -:term:`context` of the request is an instance of the -:class:`myproject.resources.Root` class. The view_config decorator also -names a ``renderer``, which in this case is a template that will be used to -render the result of the view callable. This particular view declaration -points at ``templates/mytemplate.pt``, which is a :term:`asset specification` -that specifies the ``mytemplate.pt`` file within the ``templates`` directory -of the ``myproject`` package. The asset specification could have also been -specified as ``myproject:templates/mytemplate.pt``; the leading package name -and colon is optional. The template file it actually points to is a -:term:`Chameleon` ZPT template file. +The view_config decorator asserts that this view be found when a +:term:`route` named ``home`` is matched. In our case, because our +``__init__.py`` maps the route named ``home`` to the URL pattern ``/``, this +route will match when a visitor visits the root URL. The view_config +decorator also names a ``renderer``, which in this case is a template that +will be used to render the result of the view callable. This particular view +declaration points at ``templates/mytemplate.pt``, which is a :term:`asset +specification` that specifies the ``mytemplate.pt`` file within the +``templates`` directory of the ``myproject`` package. The asset +specification could have also been specified as +``myproject:templates/mytemplate.pt``; the leading package name and colon is +optional. The template file it actually points to is a :term:`Chameleon` ZPT +template file. This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` @@ -778,8 +770,7 @@ This view returns a dictionary. When this view is invoked, a :term:`renderer` converts the dictionary returned by the view into HTML, and returns the result as the :term:`response`. This view is configured to invoke a renderer which uses a :term:`Chameleon` ZPT template -(``mypackage:templates/my_template.pt``, as specified in the ``__init__.py`` -file call to ``add_view``). +(``templates/my_template.pt``). See :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. @@ -794,35 +785,6 @@ renderers, and templates relate and cooperate. set your project's ``pyramid.reload_templates`` to ``false`` to increase the speed at which templates may be rendered. -.. index:: - single: resources.py - -.. _resourcespy_project_section: - -``resources.py`` -~~~~~~~~~~~~~~~~ - -The ``resources.py`` module provides the :term:`resource` data and behavior -for our application. Resources are objects which exist to provide site -structure in applications which use :term:`traversal` to map URLs to code. -We write a class named ``Root`` that provides the behavior for the root -resource. - -.. literalinclude:: MyProject/myproject/resources.py - :language: python - :linenos: - -#. Lines 1-3 define the Root class. The Root class is a "root resource - factory" function that will be called by the :app:`Pyramid` *Router* for - each request when it wants to find the root of the resource tree. - -In a "real" application, the Root object would likely not be such a simple -object. Instead, it might be an object that could access some persistent -data store, such as a database. :app:`Pyramid` doesn't make any assumption -about which sort of data storage you'll want to use, so the sample -application uses an instance of :class:`myproject.resources.Root` to -represent the root. - .. index:: single: static directory @@ -904,39 +866,12 @@ named ``views`` instead of within a single ``views.py`` file, you might: can be empty, this just tells Python that the ``views`` directory is a *package*. -Then change the __init__.py of your myproject project (*not* the -``__init__.py`` you just created in the ``views`` directory, the one in its -parent directory). For example, from something like: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.my_view', - renderer='myproject:templates/mytemplate.pt') - -To this: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.blog.my_view', - renderer='myproject:templates/mytemplate.pt') - -You can then continue to add files to the ``views`` directory, and refer to -view classes or functions within those files via the dotted name passed as -the first argument to ``add_view``. For example, if you added a file named -``anothermodule.py`` to the ``views`` subdirectory, and added a view callable -named ``my_view`` to it: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.anothermodule.my_view', - renderer='myproject:templates/anothertemplate.pt') - -This pattern can be used to rearrage code referred to by any Pyramid API -argument which accepts a :term:`dotted Python name` or direct object -reference. +You can then continue to add view callable functions to the ``blog.py`` +module, but you can also add other ``.py`` files which contain view callable +functions to the ``views`` directory. As long as you use the +``@view_config`` directive to register views in conjuction with +``config.scan()`` they will be picked up automatically when the application +is restarted. Using the Interactive Shell --------------------------- @@ -949,13 +884,34 @@ via ``pserve``. This can be a useful debugging tool. See Using an Alternate WSGI Server ------------------------------ -The code generated by a :app:`Pyramid` scaffold assumes that you will be +The code generated by :app:`Pyramid` scaffolding assumes that you will be using the ``pserve`` command to start your application while you do -development. However, ``pserve`` is by no means the only way to start up and -serve a :app:`Pyramid` application. As we saw in :ref:`firstapp_chapter`, -``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. -The use of ``pserve`` to run a :app:`Pyramid` application is purely -conventional based on the output of its scaffold. +development. The default rendering of Pyramid scaffolding uses the *wsgiref* +WSGI server, which is a server that is ill-suited for production usage: its +main feature is that it works on all platforms and all systems, making it a +good choice as a default server from the perspective of Pyramid's developers. + +To use a server more suitable for production, you have a number of choices. +Replace the ``use = egg:pyramid#wsgref`` line in your ``production.ini`` with +one of the following. + +``use = egg:Paste#http`` + + ``paste.httpserver`` is Windows, UNIX, and Python 2 compatible. You'll + need to ``easy_install Paste`` into your Pyramid virtualenv for this server + to work. + +``use = egg:pyramid#cherrypy`` + + The ``CherryPy`` WSGI server is Windows, UNIX, Python 2, and Python 3 + compatible. You'll need to ``easy_install CherryPy`` into your Pyramid + virtualenv for this server to work. + +``pserve`` is by no means the only way to start up and serve a :app:`Pyramid` +application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be +invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to +run a :app:`Pyramid` application is purely conventional based on the output +of its scaffold. Any :term:`WSGI` server is capable of running a :app:`Pyramid` application. Some WSGI servers don't require the :term:`PasteDeploy` framework's -- cgit v1.2.3 From d83b3943474d2eb01b0fd8c1be31c50553fd4384 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Dec 2011 01:41:04 -0500 Subject: add whatsnew-1.3; garden --- docs/narr/commandline.rst | 2 ++ docs/narr/project.rst | 2 ++ 2 files changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 0f0e17ca6..66ef46671 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -270,6 +270,8 @@ exposed, and the request is configured to generate urls from the host single: IPython single: bpython +.. _ipython_or_bpython: + IPython or bpython ~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 478e92b7e..af8714573 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -881,6 +881,8 @@ configuration as would be loaded if you were running your Pyramid application via ``pserve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. +.. _alternate_wsgi_server: + Using an Alternate WSGI Server ------------------------------ -- cgit v1.2.3 From 9197920a850cf80600fdf51a7235a364e253f621 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Dec 2011 01:04:23 -0800 Subject: grammar correction --- docs/narr/introspector.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index cfc6144dd..83f05bc2f 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -43,7 +43,7 @@ provided to the ``add_route`` method of the route which matched when the view was called. It uses the :meth:`pyramid.interfaces.IIntrospector.get` method to return an introspectable in the category ``routes`` with a :term:`discriminator` equal to the matched route name. It then uses the -returned introspectable to obtain an "pattern" value. +returned introspectable to obtain a "pattern" value. The introspectable returned by the query methods of the introspector has methods and attributes described by -- cgit v1.2.3 From 51e3ae1d6023f1acc0788b44d6f87b8c2ac03f48 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Dec 2011 01:59:18 -0800 Subject: grammar --- docs/narr/introspector.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 83f05bc2f..3e42c42f6 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -59,7 +59,7 @@ Introspectable Objects ---------------------- Introspectable objects are returned from query methods of an introspector. -Each introspectable object implements the attributes and methods the +Each introspectable object implements the attributes and methods documented at :class:`pyramid.interfaces.IIntrospectable`. The important attributes shared by all introspectables are the following: -- cgit v1.2.3 From 4a88195676733fb32e01893eb9de0f5e3fd2b7ff Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Dec 2011 02:35:07 -0800 Subject: too many pregenerator? --- docs/narr/introspector.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 3e42c42f6..6bdca645c 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -289,11 +289,11 @@ introspectables in categories not described here. The ``pregenerator`` argument passed to ``add_route``. - ``pregenerator`` + ``static`` The ``static`` argument passed to ``add_route``. - ``pregenerator`` + ``use_global_views`` The ``use_global_views`` argument passed to ``add_route``. -- cgit v1.2.3 From 773948a42423cc7185f36b8473576b4fcae1bcee Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 04:33:28 -0500 Subject: add static views introspection category --- docs/narr/introspector.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 6bdca645c..11d779854 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -514,6 +514,21 @@ introspectables in categories not described here. The ``over`` argument passed to ``add_tween`` (a string). +``static views`` + + Each introspectable in the ``static views`` category represents a call to + :meth:`pyramid.config.Configurator.add_static_view`; each will have the + following data. + + ``name`` + + The ``name`` argument provided to ``add_static_view``. + + ``spec`` + + A normalized version of the ``spec`` argument provided to + ``add_static_view``. + Introspection in the Toolbar ---------------------------- -- cgit v1.2.3 From dca45cea4e3d968b89dc62234f3d8d8392614da6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 04:36:39 -0500 Subject: fix bare python mentions --- docs/narr/extending.rst | 4 ++-- docs/narr/i18n.rst | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index 9c96248f2..c464203f0 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -200,8 +200,8 @@ like this: overridden elements, such as templates and static assets as necessary. - Install the new package into the same Python environment as the original - application (e.g. ``python setup.py develop`` or ``python setup.py - install``). + application (e.g. ``$myvenv/bin/python setup.py develop`` or + ``$myvenv/bin/python setup.py install``). - Change the ``main`` function in the new package's ``__init__.py`` to include the original :app:`Pyramid` application's configuration functions via diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index c5e6a9062..e261f9a11 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -347,7 +347,7 @@ extract the messages: $ cd /place/where/myapplication/setup.py/lives $ mkdir -p myapplication/locale - $ python setup.py extract_messages + $ $myvenv/bin/python setup.py extract_messages The message catalog ``.pot`` template will end up in: @@ -439,7 +439,7 @@ init_catalog`` command: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ python setup.py init_catalog -l es + $ $myvenv/bin/python setup.py init_catalog -l es By default, the message catalog ``.po`` file will end up in: @@ -471,7 +471,7 @@ Then use the ``setup.py update_catalog`` command. .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ python setup.py update_catalog + $ $myvenv/bin/python setup.py update_catalog .. index:: pair: compiling; message catalog @@ -487,7 +487,7 @@ translations, compile ``.po`` files to ``.mo`` files: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ python setup.py compile_catalog + $ $myvenv/bin/python setup.py compile_catalog This will create a ``.mo`` file for each ``.po`` file in your application. As long as the :term:`translation directory` in which -- cgit v1.2.3 From 47388a2de919f09bb7d4bbc557ca07597d2d04f1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 04:51:30 -0500 Subject: use a better image for toolbar introspection demo; fix typos --- docs/narr/extconfig.rst | 10 ++++------ docs/narr/tb_introspector.png | Bin 46164 -> 95962 bytes 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index a57c78105..5fc71bec5 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -40,7 +40,7 @@ For example: from pyramid.config import Configurator def add_newrequest_subscriber(config, subscriber): - config.add_subscriber(subscriber, NewRequest). + config.add_subscriber(subscriber, NewRequest) if __name__ == '__main__': config = Configurator() @@ -68,7 +68,7 @@ code in a package named ``pyramid_subscriberhelpers``: .. code-block:: python :linenos: - def includeme(config) + def includeme(config): config.add_directive('add_newrequest_subscriber', add_newrequest_subscriber) @@ -129,14 +129,13 @@ called (either explicitly or as the result of calling :meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are potentially automatically resolved as per :ref:`automatic_conflict_resolution`. If a conflict cannot be automatically -resolved, a ConfigurationConflictError is raised and application startup is -prevented. +resolved, a :exc:`ConfigurationConflictError` is raised and application +startup is prevented. In our above example, therefore, if a consumer of our ``add_jammyjam`` directive did this: .. code-block:: python - :linenos: config.add_jammyjam('first') config.add_jammyjam('second') @@ -162,7 +161,6 @@ But let's imagine that a consumer of ``add_jammyjam`` used it in such a way that no configuration conflicts are generated. .. code-block:: python - :linenos: config.add_jammyjam('first') diff --git a/docs/narr/tb_introspector.png b/docs/narr/tb_introspector.png index 231a094f7..4ae406a86 100644 Binary files a/docs/narr/tb_introspector.png and b/docs/narr/tb_introspector.png differ -- cgit v1.2.3 From 7bf4e11335893a95aabbda035c35804b59e037f5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 04:52:55 -0500 Subject: note, not warning --- docs/narr/extconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 5fc71bec5..5e7fe2753 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -227,7 +227,7 @@ augment Pyramid's configuration introspection system. Adding Configuration Introspection ---------------------------------- -.. warning:: +.. note:: The introspection subsystem is new in Pyramid 1.3. -- cgit v1.2.3 From ca602b62bcd5ab07abe2139565f62fecd8e3218c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 13:17:50 -0500 Subject: fix template links --- docs/narr/MyProject/myproject/templates/mytemplate.pt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index ab698123e..d20fc7efb 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -44,22 +44,22 @@ Pylons Website
  • - Narrative Documentation + Narrative Documentation
  • - API Documentation + API Documentation
  • - Tutorials + Tutorials
  • - Change History + Change History
  • - Sample Applications + Sample Applications
  • - Support and Development + Support and Development
  • IRC Channel -- cgit v1.2.3 From 4250b64e8dd4406c3eab818bb873581823715dc2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Dec 2011 14:28:59 -0500 Subject: fix links again --- docs/narr/MyProject/myproject/templates/mytemplate.pt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index d20fc7efb..0bfac946e 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -47,13 +47,13 @@ Narrative Documentation
  • - API Documentation + API Documentation
  • Tutorials
  • - Change History + Change History
  • Sample Applications -- cgit v1.2.3 From d3ce2b6187977608ff0c460ae47aebd04b216679 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 10 Dec 2011 22:39:47 -0500 Subject: update startup chapter against new scaffolding --- docs/narr/logging.rst | 2 ++ docs/narr/startup.rst | 38 ++++++++++++++++++-------------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index f9f72270f..044655c1f 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -16,6 +16,8 @@ how to send log messages to loggers that you've configured. a third-party scaffold which does not create these files, the configuration information in this chapter will not be applicable. +.. _logging_config: + Logging Configuration --------------------- diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 971d12b45..a7fc5d33c 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -24,11 +24,11 @@ The Startup Process ------------------- The easiest and best-documented way to start and serve a :app:`Pyramid` -application is to use the ``pserve`` command against a -:term:`PasteDeploy` ``.ini`` file. This uses the ``.ini`` file to infer -settings and starts a server listening on a port. For the purposes of this -discussion, we'll assume that you are using this command to run your -:app:`Pyramid` application. +application is to use the ``pserve`` command against a :term:`PasteDeploy` +``.ini`` file. This uses the ``.ini`` file to infer settings and starts a +server listening on a port. For the purposes of this discussion, we'll +assume that you are using this command to run your :app:`Pyramid` +application. Here's a high-level time-ordered overview of what happens when you press ``return`` after running ``pserve development.ini``. @@ -56,11 +56,12 @@ Here's a high-level time-ordered overview of what happens when you press #. The framework finds all :mod:`logging` related configuration in the ``.ini`` file and uses it to configure the Python standard library logging - system for this application. + system for this application. See :ref:`logging_config` for more + information. -#. The application's *constructor* (named by the entry point reference or +#. The application's *constructor* named by the entry point reference or dotted Python name on the ``use=`` line of the section representing your - :app:`Pyramid` application) is passed the key/value parameters mentioned + :app:`Pyramid` application is passed the key/value parameters mentioned within the section in which it's defined. The constructor is meant to return a :term:`router` instance, which is a :term:`WSGI` application. @@ -77,13 +78,13 @@ Here's a high-level time-ordered overview of what happens when you press Note that the constructor function accepts a ``global_config`` argument, which is a dictionary of key/value pairs mentioned in the ``[DEFAULT]`` section of an ``.ini`` file (if `[DEFAULT] - `__ is present). It also - accepts a ``**settings`` argument, which collects another set of arbitrary - key/value pairs. The arbitrary key/value pairs received by this function - in ``**settings`` will be composed of all the key/value pairs that are - present in the ``[app:main]`` section (except for the ``use=`` setting) - when this function is called by when you run ``pserve``. + `__ + is present). It also accepts a ``**settings`` argument, which collects + another set of arbitrary key/value pairs. The arbitrary key/value pairs + received by this function in ``**settings`` will be composed of all the + key/value pairs that are present in the ``[app:main]`` section (except for + the ``use=`` setting) when this function is called by when you run + ``pserve``. Our generated ``development.ini`` file looks like so: @@ -97,7 +98,8 @@ Here's a high-level time-ordered overview of what happens when you press 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'}``. + 'pyramid.default_locale_name':'en'}``. See :ref:`environment_chapter` for + the meanings of these keys. #. The ``main`` function first constructs a :class:`~pyramid.config.Configurator` instance, passing a root resource @@ -105,10 +107,6 @@ Here's a high-level time-ordered overview of what happens when you press ``settings`` dictionary captured via the ``**settings`` kwarg as its ``settings`` argument. - The root resource factory is invoked on every request to retrieve the - application's root resource. It is not called during startup, only when a - request is handled. - The ``settings`` dictionary contains all the options in the ``[app:main]`` section of our .ini file except the ``use`` option (which is internal to PasteDeploy) such as ``pyramid.reload_templates``, -- cgit v1.2.3 From 99520ee274400c246ab073f598dff32acc256fa9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 10 Dec 2011 22:50:58 -0500 Subject: update router document --- docs/narr/router.rst | 141 ++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 76 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index d08261b17..b78362066 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -9,74 +9,67 @@ Request Processing ================== -Once a :app:`Pyramid` application is up and running, it is ready to -accept requests and return responses. +Once a :app:`Pyramid` application is up and running, it is ready to accept +requests and return responses. What happens from the time a :term:`WSGI` +request enters a :app:`Pyramid` application through to the point that +:app:`Pyramid` hands off a response back to WSGI for upstream processing? -What happens from the time a :term:`WSGI` request enters a -:app:`Pyramid` application through to the point that -:app:`Pyramid` hands off a response back to WSGI for upstream -processing? +#. A user initiates a request from his browser to the hostname and port + number of the WSGI server used by the :app:`Pyramid` application. -#. A user initiates a request from his browser to the hostname and - port number of the WSGI server used by the :app:`Pyramid` - application. - -#. The WSGI server used by the :app:`Pyramid` application passes - the WSGI environment to the ``__call__`` method of the - :app:`Pyramid` :term:`router` object. +#. The WSGI server used by the :app:`Pyramid` application passes the WSGI + environment to the ``__call__`` method of the :app:`Pyramid` + :term:`router` object. #. A :term:`request` object is created based on the WSGI environment. -#. The :term:`application registry` and the :term:`request` object - created in the last step are pushed on to the :term:`thread local` - stack that :app:`Pyramid` uses to allow the functions named +#. The :term:`application registry` and the :term:`request` object created in + the last step are pushed on to the :term:`thread local` stack that + :app:`Pyramid` uses to allow the functions named :func:`~pyramid.threadlocal.get_current_request` and :func:`~pyramid.threadlocal.get_current_registry` to work. #. A :class:`~pyramid.events.NewRequest` :term:`event` is sent to any subscribers. -#. If any :term:`route` has been defined within application - configuration, the :app:`Pyramid` :term:`router` calls a - :term:`URL dispatch` "route mapper." The job of the mapper is to - examine the request to determine whether any user-defined - :term:`route` matches the current WSGI environment. The - :term:`router` passes the request as an argument to the mapper. - -#. If any route matches, the request is mutated; a ``matchdict`` and - ``matched_route`` attributes are added to the request object; the - former contains a dictionary representing the matched dynamic - elements of the request's ``PATH_INFO`` value, 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: if the :term:`route configuration` which - matched has an associated a ``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 :app:`Pyramid` router calls a "traverser" function with the - root object and the request. The traverser function attempts to - traverse the root object (using any existing ``__getitem__`` on the - root object and subobjects) to find a :term:`context`. If the root - object has no ``__getitem__`` method, the root itself is assumed to - be the context. The exact traversal algorithm is described in - :ref:`traversal_chapter`. The traverser function returns a - dictionary, which contains a :term:`context` and a :term:`view - name` as well as other ancillary information. - -#. The request is decorated with various names returned from the - traverser (such as ``context``, ``view_name``, and so forth), so - they can be accessed via e.g. ``request.context`` within - :term:`view` code. - -#. A :class:`~pyramid.events.ContextFound` :term:`event` is - sent to any subscribers. +#. If any :term:`route` has been defined within application configuration, + the :app:`Pyramid` :term:`router` calls a :term:`URL dispatch` "route + mapper." The job of the mapper is to examine the request to determine + whether any user-defined :term:`route` matches the current WSGI + environment. The :term:`router` passes the request as an argument to the + mapper. + +#. If any route matches, the route mapper adds attributes to the request: + ``matchdict`` and ``matched_route`` attributes are added to the request + object. The former contains a dictionary representing the matched dynamic + elements of the request's ``PATH_INFO`` value, 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: if the :term:`route configuration` which matched has an + associated a ``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 :app:`Pyramid` router calls a "traverser" function with the root + object and the request. The traverser function attempts to traverse the + root object (using any existing ``__getitem__`` on the root object and + subobjects) to find a :term:`context`. If the root object has no + ``__getitem__`` method, the root itself is assumed to be the context. The + exact traversal algorithm is described in :ref:`traversal_chapter`. The + traverser function returns a dictionary, which contains a :term:`context` + and a :term:`view name` as well as other ancillary information. + +#. The request is decorated with various names returned from the traverser + (such as ``context``, ``view_name``, and so forth), so they can be + accessed via e.g. ``request.context`` within :term:`view` code. + +#. A :class:`~pyramid.events.ContextFound` :term:`event` is sent to any + subscribers. #. :app:`Pyramid` looks up a :term:`view` callable using the context, the request, and the view name. If a view callable doesn't exist for this @@ -86,20 +79,17 @@ processing? :class:`~pyramid.httpexceptions.HTTPNotFound` exception, which is meant to be caught by a surrounding :term:`exception view`. -#. If a view callable was found, :app:`Pyramid` attempts to call - the view function. - -#. If an :term:`authorization policy` is in use, and the view was protected - by a :term:`permission`, :app:`Pyramid` passes the context, the request, - and the view_name to a function which determines whether the view being - asked for can be executed by the requesting user, based on credential - information in the request and security information attached to the - context. If it returns ``True``, :app:`Pyramid` calls the view callable - to obtain a response. If it returns ``False``, it raises a - :class:`~pyramid.httpexceptions.HTTPForbidden` exception, which is meant - to be called by a surrounding :term:`exception view`. - -#. If any exception was raised within a :term:`root factory`, by +#. If a view callable was found, :app:`Pyramid` attempts to call it. If an + :term:`authorization policy` is in use, and the view configuration is + protected by a :term:`permission`, :app:`Pyramid` determines whether the + view callable being asked for can be executed by the requesting user based + on credential information in the request and security information attached + to the context. If the view execution is allowed, :app:`Pyramid` calls + the view callable to obtain a response. If view execution is forbidden, + :app:`Pyramid` raises a :class:`~pyramid.httpexceptions.HTTPForbidden` + exception. + +#. If any exception is raised within a :term:`root factory`, by :term:`traversal`, by a :term:`view callable` or by :app:`Pyramid` itself (such as when it raises :class:`~pyramid.httpexceptions.HTTPNotFound` or :class:`~pyramid.httpexceptions.HTTPForbidden`), the router catches the @@ -128,9 +118,8 @@ processing? .. image:: router.png -This is a very high-level overview that leaves out various details. -For more detail about subsystems invoked by the :app:`Pyramid` router -such as traversal, URL dispatch, views, and event processing, see -:ref:`urldispatch_chapter`, :ref:`views_chapter`, and -:ref:`events_chapter`. +This is a very high-level overview that leaves out various details. For more +detail about subsystems invoked by the :app:`Pyramid` router such as +traversal, URL dispatch, views, and event processing, see +:ref:`urldispatch_chapter`, :ref:`views_chapter`, and :ref:`events_chapter`. -- cgit v1.2.3 From 4375cf2bad3535ce896e95fcf1e388e33f2e8ecf Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 03:41:03 -0500 Subject: Flesh out new view_defaults feature and add docs, change notes, and add to whatsnew. --- docs/narr/viewconfig.rst | 181 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index af5d7f242..03000629c 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -621,6 +621,7 @@ against the ``amethod`` method could be spelled equivalently as the below: def amethod(self): return Response('hello') + .. index:: single: add_view @@ -657,6 +658,186 @@ When you use only :meth:`~pyramid.config.Configurator.add_view` to add view configurations, you don't need to issue a :term:`scan` in order for the view configuration to take effect. +.. index:: + single: view_defaults class decorator + +.. _view_defaults: + +``@view_defaults`` Class Decorator +---------------------------------- + +.. note:: + + This feature is new in Pyramid 1.3. + +If you use a class as a view, you can use the +:class:`pyramid.view.view_defaults` class decorator on the class to provide +defaults to the view configuration information used by every ``@view_config`` +decorator that decorates a method of that class. + +For instance, if you've got a class that has methods that represent "REST +actions", all which are mapped to the same route, but different request +methods, instead of this: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + + class RESTView(object): + def __init__(self, request): + self.request = request + + @view_config(route_name='rest', request_method='GET') + def get(self): + return Response('get') + + @view_config(route_name='rest', request_method='POST') + def post(self): + return Response('post') + + @view_config(route_name='rest', request_method='DELETE') + def delete(self): + return Response('delete') + +You can do this: + +.. code-block:: python + :linenos: + + from pyramid.view import view_defaults + from pyramid.view import view_config + from pyramid.response import Response + + @view_defaults(route_name='rest') + class RESTView(object): + def __init__(self, request): + self.request = request + + @view_config(request_method='GET') + def get(self): + return Response('get') + + @view_config(request_method='POST') + def post(self): + return Response('post') + + @view_config(request_method='DELETE') + def delete(self): + return Response('delete') + +In the above example, we were able to take the ``route_name='rest'`` argument +out of the call to each individual ``@view_config`` statement, because we +used a ``@view_defaults`` class decorator to provide the argument as a +default to each view method it possessed. + +Arguments passed to ``@view_config`` will override any default passed to +``@view_defaults``. + +The ``view_defaults`` class decorator can also provide defaults to the +:meth:`pyramid.config.Configurator.add_view` directive when a decorated class +is passed to that directive as its ``view`` argument. For example, instead +of this: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.config import Configurator + + class RESTView(object): + def __init__(self, request): + self.request = request + + def get(self): + return Response('get') + + def post(self): + return Response('post') + + def delete(self): + return Response('delete') + + if __name__ == '__main__': + config = Configurator() + config.add_route('rest', '/rest') + config.add_view( + RESTView, route_name='rest', attr='get', request_method='GET') + config.add_view( + RESTView, route_name='rest', attr='post', request_method='POST') + config.add_view( + RESTView, route_name='rest', attr='delete', request_method='DELETE') + +To reduce the amount of repetion in the ``config.add_view`` statements, we +can move the ``route_name='rest'`` argument to a ``@view_default`` class +decorator on the RESTView class: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + from pyramid.config import Configurator + + @view_defaults(route_name='rest') + class RESTView(object): + def __init__(self, request): + self.request = request + + def get(self): + return Response('get') + + def post(self): + return Response('post') + + def delete(self): + return Response('delete') + + if __name__ == '__main__': + config = Configurator() + config.add_route('rest', '/rest') + config.add_view(RESTView, attr='get', request_method='GET') + config.add_view(RESTView, attr='post', request_method='POST') + config.add_view(RESTView, attr='delete', request_method='DELETE') + +:class:`pyramid.view.view_defaults` accepts the same set of arguments that +:class:`pyramid.view.view_config` does, and they have the same meaning. Each +argument passed to ``view_defaults`` provides a default for the view +configurations of methods of the class it's decorating. + +Normal Python inheritance rules apply to defaults added via +``view_defaults``. For example: + +.. code-block:: python + :linenos: + + @view_defaults(route_name='rest') + class Foo(object): + pass + + class Bar(Foo): + pass + +The ``Bar`` class above will inherit its view defaults from the arguments +passed to the ``view_defaults`` decorator of the ``Foo`` class. To prevent +this from happening, use a ``view_defaults`` decorator without any arguments +on the subclass: + +.. code-block:: python + :linenos: + + @view_defaults(route_name='rest') + class Foo(object): + pass + + @view_defaults() + class Bar(Foo): + pass + +The ``view_defaults`` decorator only works as a class decorator; using it +against a function or a method will produce nonsensical results. + .. index:: single: view security pair: security; view -- cgit v1.2.3 From bfd4b39b3467681ad34b1dda74acd20294e81a86 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 09:10:10 -0500 Subject: - Changed scaffolding machinery around a bit to make it easier for people who want to have extension scaffolds that can work across Pyramid 1.0.X, 1.1.X, 1.2.X and 1.3.X. See the new "Creating Pyramid Scaffolds" chapter in the narrative documentation for more info. - Added an API docs chapter for ``pyramid.scaffolds``. - Added a narrative docs chapter named "Creating Pyramid Scaffolds". - The ``template_renderer`` method of ``pyramid.scaffolds.PyramidScaffold`` was renamed to ``render_template``. If you were overriding it, you're a bad person, because it wasn't an API before now. But we're nice so we're letting you know. --- docs/narr/scaffolding.rst | 171 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 docs/narr/scaffolding.rst (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst new file mode 100644 index 000000000..fda0632f8 --- /dev/null +++ b/docs/narr/scaffolding.rst @@ -0,0 +1,171 @@ +.. _scaffolding_chapter: + +Creating Pyramid Scaffolds +========================== + +You can extend Pyramid by creating a :term:`scaffold` template. A scaffold +template is useful if you'd like to distribute a customizable configuration +of Pyramid to other users. Once you've created a scaffold, and someone has +installed the distribution that houses the scaffold, they can use the +``pcreate`` script to create a custom version of your scaffold's template. +Pyramid itself uses scaffolds to allow people to bootstrap new projects. For +example, ``pcreate -s alchemy MyStuff`` causes Pyramid to render the +``alchemy`` scaffold template to the ``MyStuff`` directory. + +Basics +------ + +A scaffold template is just a bunch of source files and directories on disk. +A small definition class points at this directory; it is in turn pointed at +by a :term:`setuptools` "entry point" which registers the scaffold so it can +be 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 the sake of 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 +distribution's package directory, and create a file within that directory +named ``__init__.py`` with something like the following: + +.. code-block:: python + :linenos: + + # CoolExtension/coolextension/scaffolds/__init__.py + + from pyramid.scaffolds import PyramidTemplate + + class CoolExtensionTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool extension' + +Once this is done, within the ``scaffolds`` directory, create a template +directory. Our example used a template directory named +``coolextension_scaffold``. + +As you create files and directories within the template directory, note that: + +- Files which have a name which are suffixed with the value ``_tmpl`` will be + rendered, and replacing any instance of the literal string ``{{var}}`` with + the string value of the variable named ``var`` provided to the scaffold. + +- Files and directories with filenames that contain the string ``+var+`` will + have that string replaced with the value of the ``var`` variable provided + to the scaffold. + +Otherwise, files and directories which live in the template directory will be +copied directly without modification to the ``pcreate`` output location. + +The variables provided by the default ``PyramidTemplate`` include ``project`` +(the project name provided by the user as an argument to ``pcreate``), +``package`` (a lowercasing and normalizing of the project name provided by +the user), ``random_string`` (a long random string), and ``package_logger`` +(the name of the package's logger). + +See Pyramid's "scaffolds" package +(https://github.com/Pylons/pyramid/tree/master/pyramid/scaffolds) for +concrete examples of scaffold directories (``zodb``, ``alchemy``, and +``starter``, for example). + +After you've created the template directory, add the following to the +``entry_points`` value of your distribution's ``setup.py``: + + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + +For example:: + + def setup( + ..., + entry_points = """\ + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + """ + ) + +Run your distribution's ``setup.py develop`` or ``setup.py install`` +command. After that, you should be able to see your scaffolding template +listed when you run ``pcreate -l``. It will be named ``coolextension`` +because that's the name we gave it in the entry point setup. Running +``pcreate -s coolextension MyStuff`` will then render your scaffold to an +output directory named ``MyStuff``. + +See the module documentation for :mod:`pyramid.scaffolds` for information +about the API of the :class:`pyramid.scaffolds.PyramidScaffold` class and +related classes. You can override methods of this class to get special +behavior. + +Supporting Older Pyramid Versions +--------------------------------- + +Because different versions of Pyramid handled scaffolding differently, if you +want to have extension scaffolds that can work across Pyramid 1.0.X, 1.1.X, +1.2.X and 1.3.X, you'll need to use something like this bit of horror while +defining your scaffold template: + +.. code-block:: python + :linenos: + + try: # pyramid 1.0.X + # "pyramid.paster_templates" doesn't exist past 1.0.X + from pyramid.paster_templates import PyramidTemplate + from pyramid.paster_templates import paste_script_template_renderer + except ImportError: + try: # pyramid 1.1.X, 1.2.X + # trying to import "paste_script_template_renderer" fails on 1.3.X + from pyramid.scaffolds import paste_script_template_renderer + from pyramid.scaffolds import PyramidTemplate + except ImportError: # pyramid >=1.3a2 + paste_script_template_renderer = None + from pyramid.scaffolds import PyramidTemplate + + class CoolExtensionTemplateTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool extension' + template_renderer = staticmethod(paste_script_template_renderer) + +And then in the setup.py of the package that contains your scaffold, define +the template as a target of both ``paste.paster_create_template`` (for +``paster create``) and ``pyramid.scaffold`` (for ``pcreate``):: + + [paste.paster_create_template] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + +Doing this hideousness will allow your scaffold to work as a ``paster +create`` target (under 1.0, 1.1, or 1.2) or as a ``pcreate`` target (under +1.3). If an invoker tries to run ``paster create`` against a scaffold +defined this way under 1.3, an error is raised instructing them to use +``pcreate`` instead. + +If you want only to support Pyramid 1.3 only, it's much cleaner, and the API +is stable: + +.. code-block:: python + :linenos: + + from pyramid.scaffolds import PyramidTemplate + + class CoolExtensionTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool_extension' + +You only need to specify a ``paste.paster_create_template`` entry point +target in your ``setup.py`` if you want your scaffold to be consumable by +users of Pyramid 1.0, 1.1, or 1.2. To support only 1.3, specifying only the +``pyramid.scaffold`` entry point is good enough. If you want to support both +``paster create`` and ``pcreate`` (meaning you want to support Pyramid 1.2 +and some older version), you'll need to define both. + +Examples +-------- + +Existing third-party distributions which house scaffolding are available via +:term:`PyPI`. The ``pyramid_jqm``, ``pyramid_zcml`` and ``pyramid_jinja2`` +packages house scaffolds. You can install and examine these packages to see +how they work in the quest to develop your own scaffolding. -- cgit v1.2.3 From 351777c2f870ba4fb3ba2a81e6b413d3bf50da72 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 21:03:36 -0500 Subject: fix for 1.0 --- docs/narr/scaffolding.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index fda0632f8..214ddfdfa 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -112,8 +112,8 @@ defining your scaffold template: try: # pyramid 1.0.X # "pyramid.paster_templates" doesn't exist past 1.0.X - from pyramid.paster_templates import PyramidTemplate - from pyramid.paster_templates import paste_script_template_renderer + from pyramid.paster import PyramidTemplate + from pyramid.paster import paste_script_template_renderer except ImportError: try: # pyramid 1.1.X, 1.2.X # trying to import "paste_script_template_renderer" fails on 1.3.X -- cgit v1.2.3 From 604b812a4361a63ed93f3135be3a800d5592b2a1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 22:22:44 -0500 Subject: avoid warning under 1.2 --- docs/narr/scaffolding.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 214ddfdfa..3e7b102fd 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -111,9 +111,9 @@ defining your scaffold template: :linenos: try: # pyramid 1.0.X - # "pyramid.paster_templates" doesn't exist past 1.0.X - from pyramid.paster import PyramidTemplate + # "pyramid.paster.paste_script..." doesn't exist past 1.0.X from pyramid.paster import paste_script_template_renderer + from pyramid.paster import PyramidTemplate except ImportError: try: # pyramid 1.1.X, 1.2.X # trying to import "paste_script_template_renderer" fails on 1.3.X -- cgit v1.2.3 From c8061ee1d797cb666e1d45e19765ede565d21915 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 17:29:01 -0500 Subject: finish prequest feature --- docs/narr/commandline.rst | 65 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 66ef46671..b9aa2c8c3 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -121,7 +121,8 @@ The Interactive Shell 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 "for real". To do so, use the ``pshell`` command. +application runs "for real". To do so, use the ``pshell`` command line +utility. The argument to ``pshell`` follows the format ``config_file#section_name`` where ``config_file`` is the path to your application's ``.ini`` file and @@ -311,7 +312,7 @@ For example: .. code-block:: text :linenos: - [chrism@thinko MyProject]$ ../bin/proutes development.ini#MyProject + [chrism@thinko MyProject]$ ../bin/proutes development.ini Name Pattern View ---- ------- ---- home / @@ -354,7 +355,7 @@ configured without any explicit tweens: .. code-block:: text :linenos: - [chrism@thinko pyramid]$ ptweens development.ini + [chrism@thinko pyramid]$ myenv/bin/ptweens development.ini "pyramid.tweens" config value NOT set (implicitly ordered tweens used) Implicit Tween Chain @@ -416,6 +417,64 @@ is used: See :ref:`registering_tweens` for more information about tweens. +.. index:: + single: invoking a request + single: prequest + +.. _invoking_a_request: + +Invoking a Request +------------------ + +You can use the ``prequest`` command-line utility to send a request to your +application and see the response body without starting a server. + +There are two required arguments to ``prequest``: + +- The config file/section: follows the format ``config_file#section_name`` + where ``config_file`` is the path to your application's ``.ini`` file and + ``section_name`` is the ``app`` section name inside the ``.ini`` file. The + ``section_name`` is optional, it defaults to ``main``. For example: + ``development.ini``. + +- The path: this should be the non-url-quoted path element of the URL to the + resource you'd like to be rendered on the server. For example, ``/``. + +For example:: + + $ bin/prequest development.ini / + +This will print the body of the response to the console on which it was +invoked. + +Several options are supported by ``prequest``. These should precede any +config file name or URL. + +``prequest`` has a ``-d`` (aka ``--display-headers``) option which prints the +status and headers returned by the server before the output:: + + $ bin/prequest -d development.ini / + +This will print the status, then the headers, then the body of the response +to the console. + +You can add request header values by using the ``--header`` option:: + + $ bin/prequest --header=Host=example.com development.ini / + +Headers are added to the WSGI environment by converting them to their +CGI/WSGI equivalents (e.g. ``Host=example.com`` will insert the ``HTTP_HOST`` +header variable as the value ``example.com``). Multiple ``--header`` options +can be supplied. The special header value ``content-type`` sets the +``CONTENT_TYPE`` in the WSGI environment. + +By default, ``prequest`` sends a ``GET`` request. You can change this by +using the ``-m`` (aka ``--method``) option. ``GET``, ``HEAD``, ``POST`` and +``DELETE`` are currently supported. When you use ``POST``, the standard +input of the ``prequest`` process is used as the ``POST`` body:: + + $ bin/prequest -mPOST development.ini / < somefile + .. _writing_a_script: Writing a Script -- cgit v1.2.3 From 02d7451d4e6a3fafdda8ebbb65e19d4333bb9c33 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 21:25:43 -0500 Subject: fix import --- 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 3c6799afb..a1ed6c7ff 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -119,7 +119,7 @@ Here's some sample code that implements a minimal forbidden view: .. code-block:: python :linenos: - from pyramid.views import view_config + from pyramid.view import view_config from pyramid.response import Response def forbidden_view(request): -- cgit v1.2.3 From 61838b76639d6dcf9facd549841a2ed0d07ea012 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 21:35:23 -0500 Subject: - Added a section named "Making Your Script into a Console Script" in the "Command-Line Pyramid" chapter. --- docs/narr/commandline.rst | 231 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index b9aa2c8c3..dc3cff8ac 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -654,3 +654,234 @@ use the following command: import logging.config logging.config.fileConfig('/path/to/my/development.ini') + +.. index:: + single: console script + +.. _making_a_console_script: + +Making Your Script into a Console Script +---------------------------------------- + +A "console script" is :term:`setuptools` terminology for a script that gets +installed into the ``bin`` directory of a Python :term:`virtualenv` (or +"base" Python environment) when a :term:`distribution` which houses that +script is installed. Because it's installed into the ``bin`` directory of a +virtualenv when the distribution is installed, it's a convenient way to +package and distribute functionality that you can call from the command-line. +It's often more convenient to create a console script than it is to create a +``.py`` script and instruct people to call it with "the right Python +interpreter": because it generates a file that lives in ``bin``, when it's +invoked, it will always use "the right" Python environment, which means it +will always be invoked in an environment where all the libraries it needs +(such as Pyramid) are available. + +In general, you can make your script into a console script by doing the +following: + +- Use an existing distribution (such as one you've already created via + ``pcreate``) or create a new distribution that possesses at least one + package or module. It should, within any module within the distribution, + house a callable (usually a function) that takes no arguments and which + runs any of the code you wish to run. + +- Add a ``[console_scripts]`` section to the ``entry_points`` argument of the + 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. + +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 pretend you have a distribution with a package in it named +``myproject``. Within this package, we'll pretend you've added a +``scripts.py`` module which contains the following code: + +.. code-block:: python + :linenos: + + # myproject.scripts module + + import optparse + import sys + import textwrap + + from pyramid.paster import bootstrap + + def settings_show(): + description = """\ + Print the deployment settings for a Pyramid application. Example: + 'psettings deployment.ini' + """ + usage = "usage: %prog config_uri" + parser = optparse.OptionParser( + usage=usage, + description=textwrap.dedent(description) + ) + parser.add_option( + '-o', '--omit', + dest='omit', + metavar='PREFIX', + type='string', + action='append', + help=("Omit settings which start with PREFIX (you can use this " + "option multiple times)") + ) + + options, args = parser.parse_args(sys.argv[1:]) + if not len(args) >= 1: + print('You must provide at least one argument') + return 2 + config_uri = args[0] + omit = options.omit + if omit is None: + omit = [] + env = bootstrap(config_uri) + settings, closer = env['registry'].settings, env['closer'] + try: + for k, v in settings.items(): + if any([k.startswith(x) for x in omit]): + continue + print('%-40s %-20s' % (k, v)) + finally: + closer() + +This script uses the Python ``optparse`` module to allow us to make sense out +of extra arguments passed to the script. It uses the +:func:`pyramid.paster.bootstrap` function to get information about the the +application defined by a config file, and prints the deployment settings +defined in that config file. + +After adding this script to the package, you'll need to tell your +distribution's ``setup.py`` about its existence. Within your distribution's +top-level directory your ``setup.py`` file will look something like this: + +.. code-block:: python + :linenos: + + import os + + from setuptools import setup, find_packages + + here = os.path.abspath(os.path.dirname(__file__)) + README = open(os.path.join(here, 'README.txt')).read() + CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + + requires = ['pyramid', 'pyramid_debugtoolbar'] + + 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", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="wiggystatic", + entry_points = """\ + [paste.app_factory] + main = wiggystatic:main + """, + ) + +We're going to change the setup.py file to add an ``[console_scripts]`` +section with in the ``entry_points`` string. Within this section, you should +specify a ``scriptname = dotted.path.to:yourfunction`` line. For example:: + + [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 +``settings_show`` above indicates that ``myproject.scripts`` is a Python +module, and ``settings_show`` is the function in that module which contains +the code you'd like to run as the result of someone invoking the +``show_settings`` script from their command line. + +The result will be something like: + +.. code-block:: python + :linenos: + + import os + + from setuptools import setup, find_packages + + here = os.path.abspath(os.path.dirname(__file__)) + README = open(os.path.join(here, 'README.txt')).read() + CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + + requires = ['pyramid', 'pyramid_debugtoolbar'] + + 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", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="wiggystatic", + entry_points = """\ + [paste.app_factory] + main = wiggystatic:main + [console_scripts] + show_settings = myproject.scripts:settings_show + """, + ) + +Once you've done this, invoking ``$somevirtualenv/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``:: + + [chrism@thinko somevenv]$ bin/show_settings development.ini \ + --omit=pyramid \ + --omit=debugtoolbar + debug_routematch False + debug_templates True + reload_templates True + mako.directories [] + debug_notfound False + default_locale_name en + reload_resources False + debug_authorization False + reload_assets False + prevent_http_cache False + +Pyramid's ``pserve``, ``pcreate``, ``pshell``, ``prequest``, ``ptweens`` and +other ``p*`` scripts are implemented as console scripts. When you invoke one +of those, you are using a console script. -- cgit v1.2.3 From 04cd4bea0457d7beeab2d2b3a1873f1e619650e8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 22:00:01 -0500 Subject: undo cutnpaste mistakes --- docs/narr/commandline.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index dc3cff8ac..b42a7ae9e 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -793,10 +793,10 @@ top-level directory your ``setup.py`` file will look something like this: zip_safe=False, install_requires=requires, tests_require=requires, - test_suite="wiggystatic", + test_suite="myproject", entry_points = """\ [paste.app_factory] - main = wiggystatic:main + main = myproject:main """, ) @@ -848,10 +848,10 @@ The result will be something like: zip_safe=False, install_requires=requires, tests_require=requires, - test_suite="wiggystatic", + test_suite="myproject", entry_points = """\ [paste.app_factory] - main = wiggystatic:main + main = myproject:main [console_scripts] show_settings = myproject.scripts:settings_show """, -- cgit v1.2.3 From 9003a8bba654f98933b98dacac67760cff73e1c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Dec 2011 04:35:05 -0500 Subject: - Removed the "Running Pyramid on Google App Engine" tutorial from the main docs. It survives on in the Cookbook (http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/gae.html). Rationale: it provides the correct info for the Python 2.5 version of GAE only, and this version of Pyramid does not support Python 2.5. --- docs/narr/install.rst | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 3de4d6e27..172cfd6d3 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -20,7 +20,7 @@ run :app:`Pyramid`. :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on Google's App Engine, and :term:`PyPy` (1.6+). +known to run on :term:`PyPy` (1.6+). :app:`Pyramid` installation does not require the compilation of any C code, so you need only a Python interpreter that meets the @@ -315,15 +315,6 @@ Installing :app:`Pyramid` on a Windows System c:\env> Scripts\easy_install pyramid -.. index:: - single: installing on Google App Engine - -Installing :app:`Pyramid` on Google App Engine -------------------------------------------------- - -:ref:`appengine_tutorial` documents the steps required to install a -:app:`Pyramid` application on Google App Engine. - What Gets Installed ------------------- -- cgit v1.2.3 From 10f1b5c35072c5499f3504dc261fb3c67a90c70d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Dec 2011 04:54:09 -0500 Subject: stamp out paste.httpserver usage --- docs/narr/advconfig.rst | 20 ++++++++++++-------- docs/narr/configuration.rst | 11 ++++++----- docs/narr/firstapp.rst | 24 +++++++++++++----------- docs/narr/hooks.rst | 5 +++-- 4 files changed, 34 insertions(+), 26 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 3a7bf2805..5f2175d2a 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -27,7 +27,7 @@ configured imperatively: .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response @@ -38,7 +38,8 @@ configured imperatively: config = Configurator() config.add_view(hello_world) app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() When you start this application, all will be OK. However, what happens if we try to add another view to the configuration with the same set of @@ -47,7 +48,7 @@ try to add another view to the configuration with the same set of .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response @@ -66,7 +67,8 @@ try to add another view to the configuration with the same set of config.add_view(goodbye_world, name='hello') app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() The application now has two conflicting view configuration statements. When we try to start it again, it won't start. Instead, we'll receive a traceback @@ -170,7 +172,7 @@ application that generates conflicts: .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response @@ -189,7 +191,8 @@ application that generates conflicts: config.add_view(goodbye_world, name='hello') app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() We can prevent the two ``add_view`` calls from conflicting by issuing a call to :meth:`~pyramid.config.Configurator.commit` between them: @@ -197,7 +200,7 @@ to :meth:`~pyramid.config.Configurator.commit` between them: .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response @@ -218,7 +221,8 @@ to :meth:`~pyramid.config.Configurator.commit` between them: config.add_view(goodbye_world, name='hello') app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() In the above example we've issued a call to :meth:`~pyramid.config.Configurator.commit` between the two ``add_view`` diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 597d48b09..37122e382 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -36,7 +36,7 @@ applications, configured imperatively: .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response @@ -46,8 +46,8 @@ applications, configured imperatively: if __name__ == '__main__': config = Configurator() config.add_view(hello_world) - app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() We won't talk much about what this application does yet. Just note that the "configuration' statements take place underneath the ``if __name__ == @@ -105,7 +105,7 @@ in a package and its subpackages. For example: .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.response import Response from pyramid.view import view_config @@ -118,7 +118,8 @@ in a package and its subpackages. For example: config = Configurator() config.scan() app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() The scanning machinery imports each module and subpackage in a package or module recursively, looking for special attributes attached to objects diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index c082f616b..922b0ea82 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -54,9 +54,8 @@ The script imports the :class:`~pyramid.config.Configurator` class from the Like many other Python web frameworks, :app:`Pyramid` uses the :term:`WSGI` protocol to connect an application and a web server together. The -:mod:`paste.httpserver` server is used in this example as a WSGI server for -convenience, as the ``paste`` package is a dependency of :app:`Pyramid` -itself. +:mod:`wsgiref` server is used in this example as a WSGI server for +convenience, as it is shipped within the Python standard library. The script also imports the :class:`pyramid.response.Response` class for later use. An instance of this class will be used to create a web response. @@ -205,14 +204,17 @@ WSGI Application Serving :lines: 13 Finally, we actually serve the application to requestors by starting up a -WSGI server. We happen to use the :func:`paste.httpserver.serve` WSGI server -runner, passing it the ``app`` object (a :term:`router`) as the application -we wish to serve. We also pass in an argument ``host='0.0.0.0'``, meaning -"listen on all TCP interfaces." By default, the HTTP server listens -only on the ``127.0.0.1`` interface, which is problematic if you're running -the server on a remote system and you wish to access it with a web browser -from a local system. We don't specify a TCP port number to listen on; this -means we want to use the default TCP port, which is 8080. +WSGI server. We happen to use the :mod:`wsgiref` ``make_server`` server +maker for this purpose. We pass in as the first argument ``'0.0.0.0'``, +which means "listen on all TCP interfaces." By default, the HTTP server +listens only on the ``127.0.0.1`` interface, which is problematic if you're +running the server on a remote system and you wish to access it with a web +browser from a local system. We also specify a TCP port number to listen on, +which is 8080, passing it as the second argument. The final argument ios , +passing it the ``app`` object (a :term:`router`), which is the the +application we wish to serve. Finally, we call the server's +``serve_forever`` method, which starts the main loop in which it will wait +for requests from the outside world. When this line is invoked, it causes the server to start listening on TCP port 8080. The server will serve requests forever, or at least until we stop diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a1ed6c7ff..fd6544416 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -812,7 +812,7 @@ performed, enabling you to set up the utility in advance: .. code-block:: python :linenos: - from paste.httpserver import serve + from wsgiref.simple_server import make_server from pyramid.config import Configurator from mypackage.interfaces import IMyUtility @@ -831,7 +831,8 @@ performed, enabling you to set up the utility in advance: config.registry.registerUtility(UtilityImplementation()) config.scan() app = config.make_wsgi_app() - serve(app, host='0.0.0.0') + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() For full details, please read the `Venusian documentation `_. -- cgit v1.2.3 From 0cc7a31f6fab611a151335c5f1590d0f9e7b7d98 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Dec 2011 04:57:40 -0500 Subject: have output description match reality --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index af8714573..39f6faace 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -283,7 +283,7 @@ For example, on UNIX: $ ../bin/pserve development.ini --reload Starting subprocess with file monitor Starting server in PID 16601. - serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 + Starting HTTP server on http://0.0.0.0:6543 For more detailed information about the startup process, see :ref:`startup_chapter`. For more information about environment variables and -- cgit v1.2.3 From ef9767780ff176aef063ca669bb729e6be15c7c3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Dec 2011 05:00:05 -0500 Subject: justify wsgiref usage --- docs/narr/project.rst | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 39f6faace..0c12d97e6 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -909,6 +909,13 @@ one of the following. compatible. You'll need to ``easy_install CherryPy`` into your Pyramid virtualenv for this server to work. +The servers described above are typically both faster and more secure than +the default WSGI server used by Pyramid. Pyramid does not depend on either +because Paste doesn't run on Python 3 (and Pyramid must) and the CherryPy +server is not distributed separately from the CherryPy web framework (and it +would be an awkward dependency to have a web framework rely on another web +framework for just its server component). + ``pserve`` is by no means the only way to start up and serve a :app:`Pyramid` application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to -- cgit v1.2.3 From 253df134a73613574e6c895b1edde4d3bb441253 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 17 Dec 2011 00:43:16 -0500 Subject: whitespace --- docs/narr/paste.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index cf8f96c8a..86b047aec 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -17,7 +17,7 @@ a Pyramid application that doesn't use PasteDeploy in :ref:`firstapp_chapter`. However, all Pyramid scaffolds render PasteDeploy configuration files, to provide new developers with a standardized way of setting deployment values, and to provide new users with a standardized way -of starting, stopping, and debugging an application. +of starting, stopping, and debugging an application. This chapter is not a replacement for documentation about PasteDeploy; it only contextualizes the use of PasteDeploy within Pyramid. For detailed -- cgit v1.2.3 From c469f2f89685dfcfe5d34a412979c807e3c35c88 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 21 Dec 2011 00:42:58 -0800 Subject: Split long run-on sentence into two. Attempt to make it more understandable, not sure of technical correctness. --- docs/narr/commandline.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index b42a7ae9e..a1fcf12f5 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -670,9 +670,9 @@ script is installed. Because it's installed into the ``bin`` directory of a virtualenv when the distribution is installed, it's a convenient way to package and distribute functionality that you can call from the command-line. It's often more convenient to create a console script than it is to create a -``.py`` script and instruct people to call it with "the right Python -interpreter": because it generates a file that lives in ``bin``, when it's -invoked, it will always use "the right" Python environment, which means it +``.py`` script and instruct people to call it with the "right" Python +interpreter. A console script generates a file that lives in ``bin``, and when it's +invoked it will always use the "right" Python environment, which means it will always be invoked in an environment where all the libraries it needs (such as Pyramid) are available. -- cgit v1.2.3 From 030d10697cc52a5c26d19818140616a485f63428 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 2 Jan 2012 20:41:44 -0500 Subject: - Use the ``waitress`` WSGI server instead of ``wsgiref`` in scaffolding. --- docs/narr/MyProject/development.ini | 2 +- docs/narr/MyProject/production.ini | 2 +- docs/narr/project.rst | 32 +++++--------------------------- docs/narr/startup.rst | 4 ++-- 4 files changed, 9 insertions(+), 31 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index d61da580f..2ccedb27b 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -10,7 +10,7 @@ pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar [server:main] -use = egg:pyramid#wsgiref +use = egg:waitress#main host = 0.0.0.0 port = 6543 diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 97050e8fe..43ea1d140 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -9,7 +9,7 @@ pyramid.debug_templates = false pyramid.default_locale_name = en [server:main] -use = egg:pyramid#wsgiref +use = egg:waitress#main host = 0.0.0.0 port = 6543 diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 0c12d97e6..896b65249 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -888,33 +888,11 @@ Using an Alternate WSGI Server The code generated by :app:`Pyramid` scaffolding assumes that you will be using the ``pserve`` command to start your application while you do -development. The default rendering of Pyramid scaffolding uses the *wsgiref* -WSGI server, which is a server that is ill-suited for production usage: its -main feature is that it works on all platforms and all systems, making it a -good choice as a default server from the perspective of Pyramid's developers. - -To use a server more suitable for production, you have a number of choices. -Replace the ``use = egg:pyramid#wsgref`` line in your ``production.ini`` with -one of the following. - -``use = egg:Paste#http`` - - ``paste.httpserver`` is Windows, UNIX, and Python 2 compatible. You'll - need to ``easy_install Paste`` into your Pyramid virtualenv for this server - to work. - -``use = egg:pyramid#cherrypy`` - - The ``CherryPy`` WSGI server is Windows, UNIX, Python 2, and Python 3 - compatible. You'll need to ``easy_install CherryPy`` into your Pyramid - virtualenv for this server to work. - -The servers described above are typically both faster and more secure than -the default WSGI server used by Pyramid. Pyramid does not depend on either -because Paste doesn't run on Python 3 (and Pyramid must) and the CherryPy -server is not distributed separately from the CherryPy web framework (and it -would be an awkward dependency to have a web framework rely on another web -framework for just its server component). +development. The default rendering of Pyramid scaffolding uses the +*waitress* WSGI server, which is a server that is suited for production +usage. It's not very fast, or very featureful: its main feature is that it +works on all platforms and all systems, making it a good choice as a default +server from the perspective of Pyramid's developers. ``pserve`` is by no means the only way to start up and serve a :app:`Pyramid` application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index a7fc5d33c..78b119687 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -133,8 +133,8 @@ Here's a high-level time-ordered overview of what happens when you press far as ``pserve`` is concerned, it is "just another WSGI application". #. ``pserve`` starts the WSGI *server* defined within the ``[server:main]`` - section. In our case, this is the ``egg:pyramid#wsgiref`` server (``use = - egg:pyramid#wsgiref``), and it will listen on all interfaces (``host = + 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 -- cgit v1.2.3 From 22c2200bf69ca49a0bfbe0e0a0241e87b9143737 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 2 Jan 2012 20:42:56 -0500 Subject: have sample scaffold depend on waitress --- docs/narr/MyProject/setup.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index 74879f65d..b119a954b 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -6,7 +6,11 @@ here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() -requires = ['pyramid', 'pyramid_debugtoolbar'] +requires = [ + 'pyramid', + 'pyramid_debugtoolbar', + 'waitress', + ] setup(name='MyProject', version='0.0', -- cgit v1.2.3 From a511b1423334f855e996bb06714b36aa86f861e9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 5 Jan 2012 02:41:32 -0500 Subject: fix urldispatch matching and generation to cope with various inputs --- docs/narr/urldispatch.rst | 87 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 35613ea1b..7e485f8ae 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -235,7 +235,7 @@ When matching the following URL: .. code-block:: text - foo/La%20Pe%C3%B1a + http://example.com/foo/La%20Pe%C3%B1a The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): @@ -243,6 +243,50 @@ The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): {'bar':u'La Pe\xf1a'} +Literal strings in the path segment should represent the *decoded* value of +the ``PATH_INFO`` provided to Pyramid. You don't want to use a URL-encoded +value or a bytestring representing the literal's UTF-8 in the pattern. For +example, rather than this: + +.. code-block:: text + + /Foo%20Bar/{baz} + +You'll want to use something like this: + +.. code-block:: text + + /Foo Bar/{baz} + +For patterns that contain "high-order" characters in its literals, you'll +want to use a Unicode value as the pattern as opposed to any URL-encoded or +UTF-8-encoded value. For example, you might be tempted to use a bytestring +pattern like this: + +.. code-block:: text + + /La Pe\xc3\xb1a/{x} + +But that probably won't match as you expect it to. You'll want to use a +Unicode value as the pattern instead rather than raw bytestring escapes. You +can use a high-order Unicode value as the pattern by using `Python source +file encoding `_ plus the "real" +character in the Unicode pattern in the source, like so: + +.. code-block:: text + + /La Peña/{x} + +Or you can ignore source file encoding and use equivalent Unicode escape +characters in the pattern. + +.. code-block:: text + + /La Pe\xf1a/{x} + +Dynamic segment names cannot contain high-order characters, so this applies +only to literals in the pattern. + If the pattern has a ``*`` in it, the name which follows it is considered a "remainder match". A remainder match *must* come at the end of the pattern. Unlike segment replacement markers, it does not need to be preceded by a @@ -612,7 +656,6 @@ Use the :meth:`pyramid.request.Request.route_url` method to generate URLs based on route patterns. For example, if you've configured a route with the ``name`` "foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. -.. ignore-next-block .. code-block:: python :linenos: @@ -620,7 +663,45 @@ based on route patterns. For example, if you've configured a route with the This would return something like the string ``http://example.com/1/2/3`` (at least if the current protocol and hostname implied ``http://example.com``). -See the :meth:`~pyramid.request.Request.route_url` API documentation for more + +To get only the *path* of a route, use the +:meth:`pyramid.request.Request.route_path` API instead of +:meth:`~pyramid.request.Request.route_url`. + +.. code-block:: python + + url = request.route_path('foo', a='1', b='2', c='3') + +This will return the string ``/1/2/3`` rather than a full URL. + +Note that URLs and paths generated by ``route_path`` and ``route_url`` are +always URL-quoted string types (which contain no non-ASCII characters). +Therefore, if you've added a route like so: + +.. code-block:: python + + config.add_route('la', u'/La Peña/{city}') + +And you later generate a URL using ``route_path`` or ``route_url`` like so: + +.. code-block:: python + + url = request.route_path('la', city=u'Québec') + +You will wind up with the path encoded to UTF-8 and URL quoted like so: + +.. code-block:: python + + /La%20Pe%C3%B1a/Qu%C3%A9bec + +.. note:: + + Generating URL-quoted URLs and paths is new as of Pyramid 1.3 (and Pyramid + 1.2 after 1.2.6). Previous versions generated unquoted URLs and paths + (which was broken). + +See the :meth:`~pyramid.request.Request.route_url` and +:meth:`~pyramid.request.Request.route_path` API documentation for more information. .. index:: -- cgit v1.2.3 From 64497edc64a153815c54b254bf64a46ac21a6ac7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Jan 2012 03:46:18 -0600 Subject: Fixed a couple docs bugs reported by davidfung. --- docs/narr/configuration.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 37122e382..cd3dab099 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -46,6 +46,7 @@ applications, configured imperatively: if __name__ == '__main__': config = Configurator() config.add_view(hello_world) + app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever() @@ -106,6 +107,7 @@ in a package and its subpackages. For example: :linenos: from wsgiref.simple_server import make_server + from pyramid.config import Configurator from pyramid.response import Response from pyramid.view import view_config -- cgit v1.2.3 From e3dadfd5865f58a2f816e558e8dbc636dd037197 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 5 Jan 2012 05:55:31 -0500 Subject: bring docs up to date with code --- docs/narr/urldispatch.rst | 59 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 7e485f8ae..6d9dfdd92 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -267,11 +267,12 @@ pattern like this: /La Pe\xc3\xb1a/{x} -But that probably won't match as you expect it to. You'll want to use a -Unicode value as the pattern instead rather than raw bytestring escapes. You -can use a high-order Unicode value as the pattern by using `Python source -file encoding `_ plus the "real" -character in the Unicode pattern in the source, like so: +But this will either cause an error at startup time or it won't match +properly. You'll want to use a Unicode value as the pattern instead rather +than raw bytestring escapes. You can use a high-order Unicode value as the +pattern by using `Python source file encoding +`_ plus the "real" character in the +Unicode pattern in the source, like so: .. code-block:: text @@ -664,7 +665,7 @@ based on route patterns. For example, if you've configured a route with the This would return something like the string ``http://example.com/1/2/3`` (at least if the current protocol and hostname implied ``http://example.com``). -To get only the *path* of a route, use the +To generate only the *path* portion of a URL from a route, use the :meth:`pyramid.request.Request.route_path` API instead of :meth:`~pyramid.request.Request.route_url`. @@ -674,8 +675,14 @@ To get only the *path* of a route, use the This will return the string ``/1/2/3`` rather than a full URL. +Replacement values passed to ``route_url`` or ``route_path`` must be Unicode +or bytestrings encoded in UTF-8. One exception to this rule exists: if +you're trying to replace a "remainder" match value (a ``*stararg`` +replacement value), the value may be a tuple containing Unicode strings or +UTF-8 strings. + Note that URLs and paths generated by ``route_path`` and ``route_url`` are -always URL-quoted string types (which contain no non-ASCII characters). +always URL-quoted string types (they contain no non-ASCII characters). Therefore, if you've added a route like so: .. code-block:: python @@ -690,19 +697,41 @@ And you later generate a URL using ``route_path`` or ``route_url`` like so: You will wind up with the path encoded to UTF-8 and URL quoted like so: -.. code-block:: python +.. code-block:: text /La%20Pe%C3%B1a/Qu%C3%A9bec -.. note:: +If you have a ``*stararg`` remainder dynamic part of your route pattern: + +.. code-block:: python + + config.add_route('abc', 'a/b/c/*foo') + +And you later generate a URL using ``route_path`` or ``route_url`` using a +*string* as the replacement value: + +.. code-block:: python + + url = request.route_path('abc', foo=u'Québec/biz') - Generating URL-quoted URLs and paths is new as of Pyramid 1.3 (and Pyramid - 1.2 after 1.2.6). Previous versions generated unquoted URLs and paths - (which was broken). +The value you pass will be URL-quoted except for embedded slashes in the +result: + +.. code-block:: text + + /a/b/c/Qu%C3%A9bec/biz + +You can get a similar result by passing a tuple composed of path elements: + +.. code-block:: python + + url = request.route_path('abc', foo=(u'Québec', u'biz')) + +Each value in the tuple will be url-quoted and joined by slashes in this case: + +.. code-block:: text -See the :meth:`~pyramid.request.Request.route_url` and -:meth:`~pyramid.request.Request.route_path` API documentation for more -information. + /a/b/c/Qu%C3%A9bec/biz .. index:: single: static routes -- cgit v1.2.3 From b63a4605608eca76c1b0afac194e189a9220995d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:28:07 -0500 Subject: fix output expectations for wsgiref, add indication that a virtualenv should be used to run helloworld --- docs/narr/firstapp.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 922b0ea82..0d1c9e3c7 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -22,13 +22,21 @@ Here's one of the very simplest :app:`Pyramid` applications: When this code is inserted into a Python script named ``helloworld.py`` and executed by a Python interpreter which has the :app:`Pyramid` software -installed, an HTTP server is started on TCP port 8080: +installed, an HTTP server is started on TCP port 8080. + +On UNIX: + +.. code-block:: text + + $ /path/to/your/virtualenv/bin/python helloworld.py + +On Windows: .. code-block:: text - $ python helloworld.py - serving on 0.0.0.0:8080 view at http://127.0.0.1:8080 + C:\> \path\to\your\virtualenv\Scripts\python helloworld.py +This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the server will simply serve up the text "Hello world!" -- cgit v1.2.3 From 7c33c92fb8a85fde5227773c53c812f6cc75891d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:28:46 -0500 Subject: fix Windows break sequence --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 0d1c9e3c7..562fc18c2 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -40,7 +40,7 @@ This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the server will simply serve up the text "Hello world!" -Press ``Ctrl-C`` to stop the application. +Press ``Ctrl-C`` (or ``Ctrl-Break`` on Windows) to stop the application. Now that we have a rudimentary understanding of what the application does, let's examine it piece-by-piece. -- cgit v1.2.3 From 612f18fc76c2bf96435d38a8a6804e2c49b5587f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:29:49 -0500 Subject: fix Windows break sequence --- docs/narr/firstapp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 562fc18c2..5e6ce54e0 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -226,8 +226,8 @@ for requests from the outside world. When this line is invoked, it causes the server to start listening on TCP port 8080. The server will serve requests forever, or at least until we stop -it by killing the process which runs it (usually by pressing ``Ctrl-C`` in -the terminal we used to start it). +it by killing the process which runs it (usually by pressing ``Ctrl-C`` +or ``Ctrl-Break`` in the terminal we used to start it). Conclusion ~~~~~~~~~~ -- cgit v1.2.3 From 08e5df4288e11957349cf91b863238aea7d8edf1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:33:41 -0500 Subject: guess we have to be drooly here --- docs/narr/firstapp.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 5e6ce54e0..f9439e6cb 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -38,7 +38,9 @@ On Windows: This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the -server will simply serve up the text "Hello world!" +server will simply serve up the text "Hello world!". If your application is +running on your local system, using ``http://localhost:8080/hello/world`` +in a browser will show this result. Press ``Ctrl-C`` (or ``Ctrl-Break`` on Windows) to stop the application. -- cgit v1.2.3 From 6c78bb95850d0ded75b7415b3a639598cb895a74 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:36:43 -0500 Subject: typos --- docs/narr/firstapp.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index f9439e6cb..0565ee7ea 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -220,11 +220,10 @@ which means "listen on all TCP interfaces." By default, the HTTP server listens only on the ``127.0.0.1`` interface, which is problematic if you're running the server on a remote system and you wish to access it with a web browser from a local system. We also specify a TCP port number to listen on, -which is 8080, passing it as the second argument. The final argument ios , -passing it the ``app`` object (a :term:`router`), which is the the -application we wish to serve. Finally, we call the server's -``serve_forever`` method, which starts the main loop in which it will wait -for requests from the outside world. +which is 8080, passing it as the second argument. The final argument is the +``app`` object (a :term:`router`), which is the the application we wish to +serve. Finally, we call the server's ``serve_forever`` method, which starts +the main loop in which it will wait for requests from the outside world. When this line is invoked, it causes the server to start listening on TCP port 8080. The server will serve requests forever, or at least until we stop -- cgit v1.2.3 From b95a5e23b2db563d069d5ab1e40663bf1c26cc20 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:47:35 -0500 Subject: ugh --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 0565ee7ea..8511647ac 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -34,7 +34,7 @@ On Windows: .. code-block:: text - C:\> \path\to\your\virtualenv\Scripts\python helloworld.py + C:\> \path\to\your\virtualenv\Scripts\python.exe helloworld.py This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the -- cgit v1.2.3 From b20d68703af695c80e7844e8aae61ccf31cedaaa Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 16 Jan 2012 04:59:21 -0500 Subject: explain logging --- docs/narr/firstapp.rst | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 8511647ac..1ca188d7e 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -42,6 +42,12 @@ server will simply serve up the text "Hello world!". If your application is running on your local system, using ``http://localhost:8080/hello/world`` in a browser will show this result. +Each time you visit a URL served by the application in a browser, a logging +line will be emitted to the console displaying the hostname, the date, the +request method and path, and some additional information. This output is +done by the wsgiref server we've used to serve this application. It logs an +"access log" in Apache combined logging format to the console. + Press ``Ctrl-C`` (or ``Ctrl-Break`` on Windows) to stop the application. Now that we have a rudimentary understanding of what the application does, -- cgit v1.2.3 From c3a36b9b11b9414caabff957e07d4baa2d3367ad Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 18 Jan 2012 16:38:36 -0500 Subject: untangle some docs about using alternate wsgi servers (divide into 2 sections, one about pserve, the other about waitress vs. others) --- docs/narr/project.rst | 71 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 27 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 896b65249..5696b0b73 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -881,37 +881,54 @@ configuration as would be loaded if you were running your Pyramid application via ``pserve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. -.. _alternate_wsgi_server: +What Is This ``pserve`` Thing +----------------------------- -Using an Alternate WSGI Server ------------------------------- - -The code generated by :app:`Pyramid` scaffolding assumes that you will be +The code generated by an :app:`Pyramid` scaffold assumes that you will be using the ``pserve`` command to start your application while you do -development. The default rendering of Pyramid scaffolding uses the -*waitress* WSGI server, which is a server that is suited for production -usage. It's not very fast, or very featureful: its main feature is that it -works on all platforms and all systems, making it a good choice as a default -server from the perspective of Pyramid's developers. +development. ``pserve`` is a command that reads a :term:`PasteDeploy` +``.ini`` file (e.g. ``development.ini``) and configures a server to serve a +Pyramid application based on the data in the file. ``pserve`` is by no means the only way to start up and serve a :app:`Pyramid` application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to run a :app:`Pyramid` application is purely conventional based on the output -of its scaffold. - -Any :term:`WSGI` server is capable of running a :app:`Pyramid` application. -Some WSGI servers don't require the :term:`PasteDeploy` framework's -``pserve`` command to do server process management at all. Each :term:`WSGI` -server has its own documentation about how it creates a process to run an -application, and there are many of them, so we cannot provide the details for -each here. But the concepts are largely the same, whatever server you happen -to use. - -One popular production alternative to a ``pserve``-invoked server is -:term:`mod_wsgi`. You can also use :term:`mod_wsgi` to serve your -:app:`Pyramid` application using the Apache web server rather than any -"pure-Python" server that is started as a result of ``pserve``. See -:ref:`modwsgi_tutorial` for details. However, it is usually easier to -*develop* an application using a ``pserve`` -invoked webserver, as -exception and debugging output will be sent to the console. +of its scaffolding. But we strongly recommend using while developing your +application, because many other convenience introspection commands (such as +``pviews``, ``prequest``, ``proutes`` and others) are also implemented in +terms of configuration availaibility of this ``.ini`` file format. It also +configures Pyramid logging and provides the ``--reload`` switch for +convenient restarting of the server when code changes. + +.. _alternate_wsgi_server: + +Using an Alternate WSGI Server +------------------------------ + +Pyramid scaffolds generate projects which use the :term:`Waitress` WSGI +server. Waitress is a server that is suited for development and light +production usage. It's not the fastest nor the most featureful WSGI server. +Instead, its main feature is that it works on all platforms that Pyramid +needs to run on, making it a good choice as a default server from the +perspective of Pyramid's developers. + +Any WSGI server is capable of running a :app:`Pyramid` application. But we +suggest you stick with the default server for development, and that you wait +to investigate other server options until you're ready to deploy your +application to production. Unless for some reason you need to develop on a +non-local system, investigating alternate server options is usually a +distraction until you're ready to deploy. But we recommend developing using +the default configuration on a local system that you have complete control +over; it will provide the best development experience. + +One popular production alternative to the default Waitress server is +:term:`mod_wsgi`. You can use mod_wsgi to serve your :app:`Pyramid` +application using the Apache web server rather than any "pure-Python" server +like Waitress. It is fast and featureful. See :ref:`modwsgi_tutorial` for +details. + +Another good production alternative is :term:`Green Unicorn` (aka +``gunicorn``). It's faster than Waitress and slightly easier to configure +than mod_wsgi, although it depends, in its default configuration, on having a +buffering HTTP proxy in front of it. -- cgit v1.2.3 From f23becf9eb5cbe134701d3f57d91ddc253ffcb54 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 19 Jan 2012 03:53:03 -0500 Subject: Fixes #400 (although sports was an intentional verb, maybe not the best one to use in a place where some folks wont have english as a first language) --- 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 5696b0b73..eb8867c6b 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -118,11 +118,11 @@ your application, or install your application for deployment or development. A ``.ini`` file named ``development.ini`` will be created in the project directory. You will use this ``.ini`` file to configure a server, to run -your application, and to debug your application. It sports configuration +your application, and to debug your application. It contains configuration that enables an interactive debugger and settings optimized for development. Another ``.ini`` file named ``production.ini`` will also be created in the -project directory. It sports configuration that disables any interactive +project directory. It contains configuration that disables any interactive debugger (to prevent inappropriate access and disclosure), and turns off a number of debugging settings. You can use this file to put your application into production. -- cgit v1.2.3 From 3bee9e93b3bbfb330127a89dfe99434375a04637 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 19 Jan 2012 04:06:25 -0500 Subject: fixes #398 .. mention only method-based authN configuration, remove indications of constructor value --- docs/narr/security.rst | 69 +++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 38 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 1ad35b961..07ec0f21e 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -73,16 +73,15 @@ to enable an authorization policy. Enabling an Authorization Policy Imperatively ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Passing an ``authorization_policy`` argument to the constructor of the -:class:`~pyramid.config.Configurator` class enables an -authorization policy. +Use the :meth:`~pyramid.config.Configurator.set_authorization_policy` method +of the :class:`~pyramid.config.Configurator` to enable an authorization +policy. -You must also enable an :term:`authentication policy` in order to -enable the authorization policy. This is because authorization, in -general, depends upon authentication. Use the -``authentication_policy`` argument to the -:class:`~pyramid.config.Configurator` class during -application setup to specify an authentication policy. +You must also enable an :term:`authentication policy` in order to enable the +authorization policy. This is because authorization, in general, depends +upon authentication. Use the +:meth:`~pyramid.config.Configurator.set_authentication_policy` and method +during application setup to specify the authentication policy. For example: @@ -95,13 +94,14 @@ For example: from pyramid.authorization import ACLAuthorizationPolicy authentication_policy = AuthTktAuthenticationPolicy('seekrit') authorization_policy = ACLAuthorizationPolicy() - config = Configurator(authentication_policy=authentication_policy, - authorization_policy=authorization_policy) + config = Configurator() + config.set_authentication_policy(authentication_policy) + config.set_authorization_policy(authorization_policy) .. note:: the ``authentication_policy`` and ``authorization_policy`` - arguments may also be passed to the Configurator as :term:`dotted - Python name` values, each representing the dotted name path to a - suitable implementation global defined at Python module scope. + arguments may also be passed to their respective methods mentioned above + as :term:`dotted Python name` values, each representing the dotted name + path to a suitable implementation global defined at Python module scope. The above configuration enables a policy which compares the value of an "auth ticket" cookie passed in the request's environment which contains a reference @@ -110,9 +110,9 @@ to a single :term:`principal` against the principals present in any :term:`view`. While it is possible to mix and match different authentication and -authorization policies, it is an error to pass an authentication -policy without the authorization policy or vice versa to a -:term:`Configurator` constructor. +authorization policies, it is an error to configure a Pyramid application +with an authentication policy but without the authorization policy or vice +versa. If you do this, you'll receive an error at application startup time. See also the :mod:`pyramid.authorization` and :mod:`pyramid.authentication` modules for alternate implementations @@ -188,13 +188,8 @@ In support of making it easier to configure applications which are the permission string to all view registrations which don't otherwise name a ``permission`` argument. -These APIs are in support of configuring a default permission for an -application: - -- The ``default_permission`` constructor argument to the - :mod:`~pyramid.config.Configurator` constructor. - -- The :meth:`pyramid.config.Configurator.set_default_permission` method. +The :meth:`pyramid.config.Configurator.set_default_permission` method +supports configuring a default permission for an application. When a default permission is registered: @@ -605,8 +600,8 @@ that implements the following interface: current user on subsequent requests. """ After you do so, you can pass an instance of such a class into the -:class:`~pyramid.config.Configurator` class at configuration -time as ``authentication_policy`` to use it. +:class:`~pyramid.config.Configurator.set_authentication_policy` method +configuration time to use it. .. index:: single: authorization policy (creating) @@ -616,18 +611,16 @@ time as ``authentication_policy`` to use it. Creating Your Own Authorization Policy -------------------------------------- -An authorization policy is a policy that allows or denies access after -a user has been authenticated. By default, :app:`Pyramid` will use -the :class:`pyramid.authorization.ACLAuthorizationPolicy` if an -authentication policy is activated and an authorization policy isn't -otherwise specified. +An authorization policy is a policy that allows or denies access after a user +has been authenticated. Most :app:`Pyramid` applications will use the +default :class:`pyramid.authorization.ACLAuthorizationPolicy`. -In some cases, it's useful to be able to use a different +However, in some cases, it's useful to be able to use a different authorization policy than the default -:class:`~pyramid.authorization.ACLAuthorizationPolicy`. For -example, it might be desirable to construct an alternate authorization -policy which allows the application to use an authorization mechanism -that does not involve :term:`ACL` objects. +:class:`~pyramid.authorization.ACLAuthorizationPolicy`. For example, it +might be desirable to construct an alternate authorization policy which +allows the application to use an authorization mechanism that does not +involve :term:`ACL` objects. :app:`Pyramid` ships with only a single default authorization policy, so you'll need to create your own if you'd like to use a @@ -655,5 +648,5 @@ following interface: used.""" After you do so, you can pass an instance of such a class into the -:class:`~pyramid.config.Configurator` class at configuration -time as ``authorization_policy`` to use it. +:class:`~pyramid.config.Configurator.set_authorization_policy` method at +configuration time to use it. -- cgit v1.2.3 From 3c1affd62c7674e3cacd494f02db3ea91975149e Mon Sep 17 00:00:00 2001 From: davidjb Date: Wed, 25 Jan 2012 11:43:01 +1000 Subject: Minor change - remove duplicated word --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index a3fd61098..fa34cca61 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -233,7 +233,7 @@ provided within :mod:`pyramid.httpexceptions`. How Pyramid Uses HTTP Exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -HTTP exceptions are meant to be used directly by application application +HTTP exceptions are meant to be used directly by application developers. However, Pyramid itself will raise two HTTP exceptions at various points during normal operations: :exc:`pyramid.httpexceptions.HTTPNotFound` and -- cgit v1.2.3 From 7eefb69a6b2dd8a4a68430f60bbd1ef34c1a98d3 Mon Sep 17 00:00:00 2001 From: davidjb Date: Wed, 25 Jan 2012 11:48:31 +1000 Subject: Minor fix - change attribute to be prevent_auto rather than preserve_auto --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 03000629c..d1188eaec 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -926,7 +926,7 @@ there's a ``should_cache`` GET or POST variable: return response Note that the ``http_cache`` machinery will overwrite or add to caching -headers you set within the view itself unless you use ``preserve_auto``. +headers you set within the view itself unless you use ``prevent_auto``. You can also turn of the effect of ``http_cache`` entirely for the duration of a Pyramid application lifetime. To do so, set the -- cgit v1.2.3 From d3988b59c7f515d317dedc4e031cc19f19e8bd25 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 28 Jan 2012 03:58:36 -0500 Subject: fix bad numbering --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index eb8867c6b..ea0045ca7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -709,7 +709,7 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Lines 3-16 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 3-10 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. -- cgit v1.2.3 From 73d3a8ebde31f14f538e3fe63e85c3985fb4f9f3 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 14:20:08 -0500 Subject: clarify that there's no technical restriction on the value of request_method --- docs/narr/viewconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index d1188eaec..763c0e131 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -280,8 +280,8 @@ configured view. *This is an advanced feature, not often used by "civilians"*. ``request_method`` - This value can be one of the strings ``GET``, ``POST``, ``PUT``, - ``DELETE``, or ``HEAD`` representing an HTTP ``REQUEST_METHOD``. A view + This value can be a string (typically ``"GET"``, ``"POST"``, ``"PUT"``, + ``"DELETE"``, or ``"HEAD"``) representing an HTTP ``REQUEST_METHOD``. A view declaration with this argument ensures that the view will only be called when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the WSGI environment) string matches the supplied value. -- cgit v1.2.3 From ada151234b6533f3f46ceedada45ad210cbaed99 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 16:45:00 -0500 Subject: incorrect use of 'whom' --- docs/narr/muchadoabouttraversal.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 4a249ed0d..4ce8cacfe 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -15,7 +15,7 @@ Traversal is an alternative to :term:`URL dispatch` which allows .. note:: - Ex-Zope users whom are already familiar with traversal and view lookup + Ex-Zope users who are already familiar with traversal and view lookup conceptually may want to skip directly to the :ref:`traversal_chapter` chapter, which discusses technical details. This chapter is mostly aimed at people who have previous :term:`Pylons` experience or experience in -- cgit v1.2.3 From 97b64d3b736f6abf0d78126c75d5e56e774bd234 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 17:34:51 -0500 Subject: Hello world with traversal, linked from various places; plus some 'what this chapter is for' notes on the other traversal chapters. Hope this helps. --- docs/narr/hellotraversal.py | 22 ++++++++++++++ docs/narr/hellotraversal.rst | 69 ++++++++++++++++++++++++++++++++++++++++++++ docs/narr/introduction.rst | 2 +- docs/narr/traversal.rst | 7 +++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 docs/narr/hellotraversal.py create mode 100644 docs/narr/hellotraversal.rst (limited to 'docs/narr') diff --git a/docs/narr/hellotraversal.py b/docs/narr/hellotraversal.py new file mode 100644 index 000000000..1ef7525e6 --- /dev/null +++ b/docs/narr/hellotraversal.py @@ -0,0 +1,22 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response + +class Resource(dict): + pass + +def get_root(request): + return Resource({'a': Resource({'b': Resource({'c': Resource()})})}) + +def hello_world_of_resources(context, request): + output = "Here's a resource and its children: %s" % context + return Response(output) + +if __name__ == '__main__': + config = Configurator(root_factory=get_root) + config.add_view(hello_world_of_resources, context=Resource) + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() + + diff --git a/docs/narr/hellotraversal.rst b/docs/narr/hellotraversal.rst new file mode 100644 index 000000000..142c24f54 --- /dev/null +++ b/docs/narr/hellotraversal.rst @@ -0,0 +1,69 @@ +.. _hello_traversal_chapter: + +Hello Traversal World +====================== + + +.. index:: + single: traversal quick example + +Traversal is an alternative to URL dispatch which allows Pyramid +applications to map URLs to code. + +If code speaks louder than words, maybe this will help. Here is a +single-file Pyramid application that uses traversal: + +.. literalinclude:: hellotraversal.py + :linenos: + +You may notice that this application is intentionally very similar to +the "hello world" app from :doc:`firstapp`. + +On lines 5-6, we create a trivial :term:`resource` class that's just a +dictionary subclass. + +On lines 8-9, we hard-code a :term:`resource tree` in our :term:`root +factory` function. + +On lines 11-13 we define a single :term:`view callable` that can +display a single instance of our Resource class, passed as the +``context`` argument. + +The rest of the file sets up and serves our pyramid WSGI app. Line 18 +is where our view gets configured for use whenever the traversal ends +with an instance of our Resource class. + +Interestingly, there are no URLs explicitly configured in this +application. Instead, the URL space is defined entirely by the keys in +the resource tree. + +Example requests +---------------- + +If this example is running on http://localhost:8080, and the user +browses to http://localhost:8080/a/b, Pyramid will call +``get_root(request)`` to get the root resource, then traverse the tree +from there by key; starting from the root, it will find the child with +key ``"a"``, then its child with key ``"b"``; then use that as the +``context`` argument for calling ``hello_world_of_resources``. + +Or, if the user browses to http://localhost:8080/ , Pyramid will +stop at the root - the outermost Resource instance, in this case - and +use that as the ``context`` argument to the same view. + +Or, if the user browses to a key that doesn't exist in this resource +tree, like http://localhost:8080/xyz or +http://localhost:8080/a/b/c/d, the traversal will end by raising a +KeyError, and Pyramid will turn that into a 404 HTTP response. + +A more complicated application could have many types of resources, +with different view callables defined for each type, and even multiple +views for each type. + +See Also +--------- + +Full technical details may be found in :doc:`traversal`. + +For more about *why* you might use traversal, see :doc:`muchadoabouttraversal`. + diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7c6ad00f3..92955aafd 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -597,7 +597,7 @@ content management systems and document management systems. Traversal also lend systems that require very granular security ("Bob can edit *this* document" as opposed to "Bob can edit documents"). -Example: :ref:`much_ado_about_traversal_chapter`. +Example: :ref:`hello_traversal_chapter` and :ref:`much_ado_about_traversal_chapter`. Tweens ~~~~~~ diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index ef875c8f0..8c5d950c1 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -3,6 +3,13 @@ Traversal ========= +This chapter explains the technical details of how traversal works in +Pyramid. + +For a quick example, see :doc:`hellotraversal`. + +For more about *why* you might use traversal, see :doc:`muchadoabouttraversal`. + A :term:`traversal` uses the URL (Universal Resource Locator) to find a :term:`resource` located in a :term:`resource tree`, which is a set of nested dictionary-like objects. Traversal is done by using each segment -- cgit v1.2.3 From 3f8e72a2412866ca937d5e95679813c00367ed0a Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 17:40:22 -0500 Subject: another 'what is this chapter' note --- docs/narr/muchadoabouttraversal.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 4ce8cacfe..40d498391 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,6 +4,8 @@ Much Ado About Traversal ======================== +(Or, why you should care about it) + .. note:: This chapter was adapted, with permission, from a blog post by `Rob -- cgit v1.2.3 From d01ae960c9e278bd361e2517e0fef7173549f642 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 5 Feb 2012 23:56:29 -0500 Subject: fix extra paren --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 6d9dfdd92..dfa4e629d 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -341,7 +341,7 @@ The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()} - foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c')} + foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c'} This occurs because the default regular expression for a marker is ``[^/]+`` which will match everything up to the first ``/``, while ``{fizzle:.*}`` will -- cgit v1.2.3 From 9399c12f561a74cdba7a5758c78173083625e6a9 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 6 Feb 2012 10:37:14 -0600 Subject: fix #424 --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ea0045ca7..d69f0cf13 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -98,7 +98,7 @@ Or on Windows: .. code-block:: text - $ Scripts\pcreate alchemy MyProject + $ Scripts\pcreate -s alchemy MyProject Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: -- cgit v1.2.3 From 02c12a9e2ff804e825fdb22c28e1d16e14ac6c1f Mon Sep 17 00:00:00 2001 From: Jens Rantil Date: Tue, 7 Feb 2012 16:01:51 +0100 Subject: Minor documentation fix. Correcting a noun; 'a' => 'an', since __call__ starts with a consonant. --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index fa34cca61..dbc702de8 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -30,7 +30,7 @@ View Callables View callables are, at the risk of sounding obvious, callable Python objects. Specifically, view callables can be functions, classes, or instances -that implement an ``__call__`` method (making the instance callable). +that implement a ``__call__`` method (making the instance callable). View callables must, at a minimum, accept a single argument named ``request``. This argument represents a :app:`Pyramid` :term:`Request` -- cgit v1.2.3 From 1ceae4adac7c050e955778c71b3680edb9a3cb8c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 7 Feb 2012 10:06:52 -0600 Subject: bug in url dispatch docs --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index dfa4e629d..a7bf74786 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -340,7 +340,7 @@ The above pattern will match these URLs, generating the following matchdicts: .. code-block:: text - foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()} + foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':u''} foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c'} This occurs because the default regular expression for a marker is ``[^/]+`` -- cgit v1.2.3 From ad3c25bac043e9d14ce8ffe1b03ae6d0e92b3b0e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 11 Feb 2012 13:52:20 -0600 Subject: Updated the scripting example for more url control. --- docs/narr/commandline.rst | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index a1fcf12f5..95927cfca 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -606,19 +606,21 @@ Assuming that you have a route configured in your application like so: config.add_route('verify', '/verify/{code}') You need to inform the Pyramid environment that the WSGI application is -handling requests from a certain base. For example, we want to mount our -application at `example.com/prefix` and the generated URLs should use HTTPS. -This can be done by mutating the request object: +handling requests from a certain base. For example, we want to simulate +mounting our application at `https://example.com/prefix`, to ensure that +the generated URLs are correct for our deployment. This can be done by +either mutating the resulting request object, or more simply by constructing +the desired request and passing it into :func:`~pyramid.paster.bootstrap`: .. code-block:: python from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini#another') - env['request'].host = 'example.com' - env['request'].scheme = 'https' - env['request'].script_name = '/prefix' + from pyramid.request import Request + + request = Request.blank('/', base_url='https://example.com/prefix') + env = bootstrap('/path/to/my/development.ini#another', request=request) print env['request'].application_url - # will print 'https://example.com/prefix/another/url' + # will print 'https://example.com/prefix' Now you can readily use Pyramid's APIs for generating URLs: @@ -630,8 +632,8 @@ Now you can readily use Pyramid's APIs for generating URLs: Cleanup ~~~~~~~ -When your scripting logic finishes, it's good manners (but not required) to -call the ``closer`` callback: +When your scripting logic finishes, it's good manners to call the ``closer`` +callback: .. code-block:: python -- cgit v1.2.3 From 9bdb099a5f5cb9f70c1bc60c2e2f58d6bc6f5c28 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 14 Feb 2012 06:59:28 -0500 Subject: add note about debugtoolbar.hosts --- docs/narr/project.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index d69f0cf13..66643af73 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -322,6 +322,22 @@ image again. .. image:: project-debug.png +If you don't see the debug toolbar image on the right hand top of the page, +it means you're browsing from a system that does not have debugging access. +By default, for security reasons, only a browser originating from +``localhost`` (``127.0.0.1``) can see the debug toolbar. To allow your +browser on a remote system to access the server, add the a line within the +``[app:main]`` section of the ``development.ini`` file in the form +``debugtoolbar.hosts = X.X.X.X``. For example, if your Pyramid application +is running on a remote system, and you're browsing from a host with the IP +address ``192.168.1.1``, you'd add something like this to enable the toolbar +when your system contacts Pyramid: + +.. code-block:: ini + + [app:main] + debugtoolbar.hosts = 192.168.1.1 + For more information about what the debug toolbar allows you to do, see `the documentation for pyramid_debugtoolbar `_. -- cgit v1.2.3 From 72bb7174bb4a4c4547828ab20d3b174b35200e47 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 14 Feb 2012 07:00:39 -0500 Subject: denote other settings --- docs/narr/project.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 66643af73..d626667ca 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -336,6 +336,7 @@ when your system contacts Pyramid: .. code-block:: ini [app:main] + # .. other settings ... debugtoolbar.hosts = 192.168.1.1 For more information about what the debug toolbar allows you to do, see `the -- cgit v1.2.3 From 2f35a1e938b7f4e9ad182f1ead415632769345d6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 14 Feb 2012 07:10:43 -0500 Subject: use the newer url --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index d626667ca..4566a4fb8 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -341,7 +341,7 @@ when your system contacts Pyramid: For more information about what the debug toolbar allows you to do, see `the documentation for pyramid_debugtoolbar -`_. +`_. The debug toolbar will not be shown (and all debugging will be turned off) when you use the ``production.ini`` file instead of the ``development.ini`` -- cgit v1.2.3 From 2e7f0cfb4c5f0a4804e0c44cdf181c2ee35b020a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Feb 2012 16:18:06 -0500 Subject: remove unused imports --- docs/narr/renderers.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index ed391f4fe..67354a1ed 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -156,7 +156,6 @@ dictionary: .. code-block:: python :linenos: - from pyramid.response import Response from pyramid.view import view_config @view_config(renderer='string') @@ -193,7 +192,6 @@ render the returned dictionary to a JSON serialization: .. code-block:: python :linenos: - from pyramid.response import Response from pyramid.view import view_config @view_config(renderer='json') -- cgit v1.2.3 From 1ca5b34f17ea889f705c1120a5b8878bff16ec63 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Feb 2012 16:23:59 -0500 Subject: - Replace all mentions of zope.interface.implements with zope.interface.implementer. --- docs/narr/hooks.rst | 15 ++++++++------- docs/narr/resources.rst | 10 +++++----- docs/narr/traversal.rst | 9 +++++---- 3 files changed, 18 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index fd6544416..350b5734d 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -606,24 +606,24 @@ adapter to the more complex IResponse interface: If you want to implement your own Response object instead of using the :class:`pyramid.response.Response` object in any capacity at all, you'll have to make sure the object implements every attribute and method outlined in -:class:`pyramid.interfaces.IResponse` and you'll have to ensure that it's -marked up with ``zope.interface.implements(IResponse)``: +:class:`pyramid.interfaces.IResponse` and you'll have to ensure that it uses +``zope.interface.implementer(IResponse)`` as a class decoratoror. .. code-block:: python :linenos: from pyramid.interfaces import IResponse - from zope.interface import implements + from zope.interface import implementer + @implementer(IResponse) class MyResponse(object): - implements(IResponse) # ... an implementation of every method and attribute # documented in IResponse should follow ... When an alternate response object implementation is returned by a view callable, if that object asserts that it implements :class:`~pyramid.interfaces.IResponse` (via -``zope.interface.implements(IResponse)``) , an adapter needn't be registered +``zope.interface.implementer(IResponse)``) , an adapter needn't be registered for the object; Pyramid will use it directly. An IResponse adapter for ``webob.Response`` (as opposed to @@ -812,14 +812,15 @@ performed, enabling you to set up the utility in advance: .. code-block:: python :linenos: + from zope.interface import implementer + from wsgiref.simple_server import make_server from pyramid.config import Configurator from mypackage.interfaces import IMyUtility + @implementer(IMyUtility) class UtilityImplementation: - implements(IMyUtility) - def __init__(self): self.registrations = {} diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 256f69fc3..83734be9f 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -540,14 +540,14 @@ declares that the blog entry implements an :term:`interface`. :linenos: import datetime - from zope.interface import implements + from zope.interface import implementer from zope.interface import Interface class IBlogEntry(Interface): pass + @implementer(IBlogEntry) class BlogEntry(object): - implements(IBlogEntry) def __init__(self, title, body, author): self.title = title self.body = body @@ -556,15 +556,15 @@ declares that the blog entry implements an :term:`interface`. This resource consists of two things: the class which defines the resource constructor as the class ``BlogEntry``, and an :term:`interface` attached to -the class via an ``implements`` statement at class scope using the -``IBlogEntry`` interface as its sole argument. +the class via an ``implementer`` class decorator using the ``IBlogEntry`` +interface as its sole argument. The interface object used must be an instance of a class that inherits from :class:`zope.interface.Interface`. A resource class may implement zero or more interfaces. You specify that a resource implements an interface by using the -:func:`zope.interface.implements` function at class scope. The above +:func:`zope.interface.implementer` function as a class decorator. The above ``BlogEntry`` resource implements the ``IBlogEntry`` interface. You can also specify that a particular resource *instance* provides an diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index 8c5d950c1..8e7f93a1b 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -488,20 +488,21 @@ you must create an interface and mark up your resource classes or instances with interface declarations that refer to this interface. To attach an interface to a resource *class*, you define the interface and -use the :func:`zope.interface.implements` function to associate the interface -with the class. +use the :func:`zope.interface.implementer` class decorator to associate the +interface with the class. .. code-block:: python :linenos: from zope.interface import Interface - from zope.interface import implements + from zope.interface import implementer class IHello(Interface): """ A marker interface """ + @implementer(IHello) class Hello(object): - implements(IHello) + pass To attach an interface to a resource *instance*, you define the interface and use the :func:`zope.interface.alsoProvides` function to associate the -- cgit v1.2.3 From 748aad47f90136b151be13f477ed6af1caed0493 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Feb 2012 19:09:08 -0500 Subject: - Add ``pyramid.config.Configurator.set_traverser`` API method. See the Hooks narrative documentation section entitled "Changing the Traverser" for more information. This is not a new feature, it just provides an API for adding a traverser without needing to use the ZCA API. --- docs/narr/hooks.rst | 14 ++++++-------- docs/narr/introspector.rst | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 350b5734d..076f9fa5c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -406,11 +406,10 @@ via configuration. .. code-block:: python :linenos: - from pyramid.interfaces import ITraverser - from zope.interface import Interface + from pyramid.config import Configurator from myapp.traversal import Traverser - - config.registry.registerAdapter(Traverser, (Interface,), ITraverser) + config = Configurator() + config.set_traverser(Traverser) In the example above, ``myapp.traversal.Traverser`` is assumed to be a class that implements the following interface: @@ -456,12 +455,11 @@ used. Otherwise, the default traverser would be used. For example: .. code-block:: python :linenos: - from pyramid.interfaces import ITraverser - from zope.interface import Interface from myapp.traversal import Traverser from myapp.resources import MyRoot - - config.registry.registerAdapter(Traverser, (MyRoot,), ITraverser) + from pyramid.config import Configurator + config = Configurator() + config.set_traverser(Traverser, MyRoot) If the above stanza was added to a Pyramid ``__init__.py`` file's ``main`` function, :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 11d779854..08cc430f6 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -529,6 +529,21 @@ introspectables in categories not described here. A normalized version of the ``spec`` argument provided to ``add_static_view``. +``traversers`` + + Each introspectable in the ``traversers`` category represents a call to + :meth:`pyramid.config.Configurator.add_traverser`; each will have the + following data. + + ``iface`` + + The (resolved) interface or class object that represents the return value + of a root factory that this traverser will be used for. + + ``factory`` + + The (resolved) traverser class. + Introspection in the Toolbar ---------------------------- -- cgit v1.2.3 From 4786cae2e7a053b01091b5e185102f9c26885b08 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Feb 2012 19:32:46 -0500 Subject: - The system value ``r`` is now supplied to renderers as an alias for ``request``. This means that you can now, for example, in a template, do ``r.route_url(...)`` instead of ``request.route_url(...)``. Fixes #413. --- docs/narr/renderers.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 67354a1ed..1622f1f29 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -333,15 +333,15 @@ dictionary, an error will be raised. Before passing keywords to the template, the keyword arguments derived from the dictionary returned by the view are augmented. The callable object -- -whatever object was used to define the view -- will be automatically -inserted into the set of keyword arguments passed to the template as the -``view`` keyword. If the view callable was a class, the ``view`` keyword -will be an instance of that class. Also inserted into the keywords passed to -the template are ``renderer_name`` (the string used in the ``renderer`` -attribute of the directive), ``renderer_info`` (an object containing -renderer-related information), ``context`` (the context resource of the view -used to render the template), and ``request`` (the request passed to the view -used to render the template). +whatever object was used to define the view -- will be automatically inserted +into the set of keyword arguments passed to the template as the ``view`` +keyword. If the view callable was a class, the ``view`` keyword will be an +instance of that class. Also inserted into the keywords passed to the +template are ``renderer_name`` (the string used in the ``renderer`` attribute +of the directive), ``renderer_info`` (an object containing renderer-related +information), ``context`` (the context resource of the view used to render +the template), and ``request`` (the request passed to the view used to render +the template). ``request`` is also available as ``r`` in Pyramid 1.3+. Here's an example view configuration which uses a Chameleon ZPT renderer: -- cgit v1.2.3 From b2ea4c88b8b3bc9ed657160d8a888780d6c41844 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Feb 2012 22:06:30 -0500 Subject: Use req instead of r for #413. It's more likely that somebody is already passing something named r, and a template may depend on its existence or nonexistence to conditionalize rendering a bit of html. --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 1622f1f29..1f1b1943b 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -341,7 +341,7 @@ template are ``renderer_name`` (the string used in the ``renderer`` attribute of the directive), ``renderer_info`` (an object containing renderer-related information), ``context`` (the context resource of the view used to render the template), and ``request`` (the request passed to the view used to render -the template). ``request`` is also available as ``r`` in Pyramid 1.3+. +the template). ``request`` is also available as ``req`` in Pyramid 1.3+. Here's an example view configuration which uses a Chameleon ZPT renderer: -- cgit v1.2.3 From c51896756eeffc7e8c50ad71300ec355ae47465a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 17 Feb 2012 01:08:42 -0500 Subject: Features -------- - Add ``pyramid.config.Configurator.add_resource_url_adapter`` API method. See the Hooks narrative documentation section entitled "Changing How pyramid.request.Request.resource_url Generates a URL" for more information. This is not a new feature, it just provides an API for adding a resource url adapter without needing to use the ZCA API. - A new interface was added: ``pyramid.interfaces.IResourceURL``. An adapter implementing its interface can be used to override resource URL generation when ``request.resource_url`` is called. This interface replaces the now-deprecated ``pyramid.interfaces.IContextURL`` interface. - The dictionary passed to a resource's ``__resource_url__`` method (see "Overriding Resource URL Generation" in the "Resources" chapter) now contains an ``app_url`` key, representing the application URL generated during ``request.resource_url``. It represents a potentially customized URL prefix, containing potentially custom scheme, host and port information passed by the user to ``request.resource_url``. It should be used instead of ``request.application_url`` where necessary. - The ``request.resource_url`` API now accepts these arguments: ``app_url``, ``scheme``, ``host``, and ``port``. The app_url argument can be used to replace the URL prefix wholesale during url generation. The ``scheme``, ``host``, and ``port`` arguments can be used to replace the respective default values of ``request.application_url`` partially. - A new API named ``request.resource_path`` now exists. It works like ``request.resource_url`` but produces a relative URL rather than an absolute one. - The ``request.route_url`` API now accepts these arguments: ``_app_url``, ``_scheme``, ``_host``, and ``_port``. The ``_app_url`` argument can be used to replace the URL prefix wholesale during url generation. The ``_scheme``, ``_host``, and ``_port`` arguments can be used to replace the respective default values of ``request.application_url`` partially. Backwards Incompatibilities --------------------------- - The ``pyramid.interfaces.IContextURL`` interface has been deprecated. People have been instructed to use this to register a resource url adapter in the "Hooks" chapter to use to influence ``request.resource_url`` URL generation for resources found via custom traversers since Pyramid 1.0. The interface still exists and registering such an adapter still works, but this interface will be removed from the software after a few major Pyramid releases. You should replace it with an equivalent ``pyramid.interfaces.IResourceURL`` adapter, registered using the new ``pyramid.config.Configurator.add_resource_url_adapter`` API. A deprecation warning is now emitted when a ``pyramid.interfaces.IContextURL`` adapter is found when ``request.resource_url`` is called. Misc ---- - Change ``set_traverser`` API name to ``add_traverser``. Ref #438. --- docs/narr/hooks.rst | 59 +++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 076f9fa5c..2c4310080 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -479,58 +479,55 @@ When you add a traverser as described in :ref:`changing_the_traverser`, it's often convenient to continue to use the :meth:`pyramid.request.Request.resource_url` API. However, since the way traversal is done will have been modified, the URLs it generates by default -may be incorrect. +may be incorrect when used against resources derived from your custom +traverser. If you've added a traverser, you can change how :meth:`~pyramid.request.Request.resource_url` generates a URL for a specific -type of resource by adding a registerAdapter call for -:class:`pyramid.interfaces.IContextURL` to your application: +type of resource by adding a call to +:meth:`pyramid.config.add_resource_url_adapter`. + +For example: .. code-block:: python :linenos: - from pyramid.interfaces import ITraverser - from zope.interface import Interface - from myapp.traversal import URLGenerator + from myapp.traversal import ResourceURLAdapter from myapp.resources import MyRoot - config.registry.registerAdapter(URLGenerator, (MyRoot, Interface), - IContextURL) + config.add_resource_url_adapter(ResourceURLAdapter, resource_iface=MyRoot) -In the above example, the ``myapp.traversal.URLGenerator`` class will be used -to provide services to :meth:`~pyramid.request.Request.resource_url` any time -the :term:`context` passed to ``resource_url`` is of class -``myapp.resources.MyRoot``. The second argument in the ``(MyRoot, -Interface)`` tuple represents the type of interface that must be possessed by -the :term:`request` (in this case, any interface, represented by -``zope.interface.Interface``). +In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will +be used to provide services to :meth:`~pyramid.request.Request.resource_url` +any time the :term:`resource` passed to ``resource_url`` is of the class +``myapp.resources.MyRoot``. The ``resource_iface`` argument ``MyRoot`` +represents the type of interface that must be possessed by the resource for +this resource url factory to be found. If the ``resource_iface`` argument is +omitted, this resource url adapter will be used for *all* resources. -The API that must be implemented by a class that provides -:class:`~pyramid.interfaces.IContextURL` is as follows: +The API that must be implemented by your a class that provides +:class:`~pyramid.interfaces.IResourceURL` is as follows: .. code-block:: python :linenos: - from zope.interface import Interface - - class IContextURL(Interface): - """ An adapter which deals with URLs related to a context. + class MyResourceURL(object): + """ An adapter which provides the virtual and physical paths of a + resource """ - def __init__(self, context, request): - """ Accept the context and request """ - - def virtual_root(self): - """ Return the virtual root object related to a request and the - current context""" - - def __call__(self): - """ Return a URL that points to the context """ + def __init__(self, resource, request): + """ Accept the resource and request and set self.physical_path and + self.virtual_path""" + self.virtual_path = some_function_of(resource, request) + self.physical_path = some_other_function_of(resource, request) The default context URL generator is available for perusal as the class -:class:`pyramid.traversal.TraversalContextURL` in the `traversal module +:class:`pyramid.traversal.ResourceURL` in the `traversal module `_ of the :term:`Pylons` GitHub Pyramid repository. +See :meth:`pyramid.config.add_resource_url_adapter` for more information. + .. index:: single: IResponse single: special view responses -- cgit v1.2.3 From 0a6a26ca36f6aff7d03b438eef57f6b8d17123e9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 17 Feb 2012 08:55:45 -0500 Subject: docs fixes --- docs/narr/resources.rst | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 83734be9f..a24c44f29 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -303,13 +303,22 @@ The ``__resource_url__`` hook is passed two arguments: ``request`` and two keys: ``physical_path`` - The "physical path" computed for the resource, as defined by - ``pyramid.traversal.resource_path(resource)``. + A string representing the "physical path" computed for the resource, as + defined by ``pyramid.traversal.resource_path(resource)``. It will begin + and end with a slash. ``virtual_path`` - The "virtual path" computed for the resource, as defined by - :ref:`virtual_root_support`. This will be identical to the physical path - if virtual rooting is not enabled. + A string representing the "virtual path" computed for the resource, as + defined by :ref:`virtual_root_support`. This will be identical to the + physical path if virtual rooting is not enabled. It will begin and end + with a slash. + +``app_url`` + A string representing the application URL generated during + ``request.resource_url``. It will not end with a slash. It represents a + potentially customized URL prefix, containing potentially custom scheme, + host and port information passed by the user to ``request.resource_url``. + It should be preferred over use of ``request.application_url``. The ``__resource_url__`` method of a resource should return a string representing a URL. If it cannot override the default, it should return @@ -322,16 +331,16 @@ Here's an example ``__resource_url__`` method. class Resource(object): def __resource_url__(self, request, info): - return request.application_url + info['virtual_path'] + return info['app_url'] + info['virtual_path'] The above example actually just generates and returns the default URL, which -would have been what was returned anyway, but your code can perform arbitrary -logic as necessary. For example, your code may wish to override the hostname -or port number of the generated URL. +would have been what was generated by the default ``resource_url`` machinery, +but your code can perform arbitrary logic as necessary. For example, your +code may wish to override the hostname or port number of the generated URL. Note that the URL generated by ``__resource_url__`` should be fully qualified, should end in a slash, and should not contain any query string or -anchor elements (only path elements) to work best with +anchor elements (only path elements) to work with :meth:`~pyramid.request.Request.resource_url`. .. index:: -- cgit v1.2.3 From ee9769d5a23bc346911c00b482865360babf9f36 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 08:17:32 -0500 Subject: minor wording fixes --- docs/narr/hooks.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2c4310080..a782b9ec6 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -145,10 +145,10 @@ Here's some sample code that implements a minimal forbidden view: Changing the Request Factory ---------------------------- -Whenever :app:`Pyramid` handles a :term:`WSGI` request, it creates a -:term:`request` object based on the WSGI environment it has been passed. By -default, an instance of the :class:`pyramid.request.Request` class is created -to represent the request object. +Whenever :app:`Pyramid` handles a request from a :term:`WSGI` server, it +creates a :term:`request` object based on the WSGI environment it has been +passed. By default, an instance of the :class:`pyramid.request.Request` +class is created to represent the request object. The class (aka "factory") that :app:`Pyramid` uses to create a request object instance can be changed by passing a ``request_factory`` argument to the @@ -236,11 +236,11 @@ Adding Renderer Globals (Deprecated) is documented in :ref:`beforerender_event`. Whenever :app:`Pyramid` handles a request to perform a rendering (after a -view with a ``renderer=`` configuration attribute is invoked, or when any -of the methods beginning with ``render`` within the :mod:`pyramid.renderers` +view with a ``renderer=`` configuration attribute is invoked, or when any of +the methods beginning with ``render`` within the :mod:`pyramid.renderers` module are called), *renderer globals* can be injected into the *system* values sent to the renderer. By default, no renderer globals are injected, -and the "bare" system values (such as ``request``, ``context``, and +and the "bare" system values (such as ``request``, ``context``, ``view``, and ``renderer_name``) are the only values present in the system dictionary passed to every renderer. @@ -447,7 +447,7 @@ that implements the following interface: More than one traversal algorithm can be active at the same time. For instance, if your :term:`root factory` returns more than one type of object -conditionally, you could claim that an alternate traverser adapter is ``for`` +conditionally, you could claim that an alternate traverser adapter is "for" only one particular class or interface. When the root factory returned an object that implemented that class or interface, a custom traverser would be used. Otherwise, the default traverser would be used. For example: -- cgit v1.2.3 From 20ecd354ab99eb0dec5617115f4288ec9262270c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 08:26:26 -0500 Subject: expand --- docs/narr/advconfig.rst | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 5f2175d2a..0060ef65c 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -122,9 +122,10 @@ configuration or configuration that results from the execution of a Manually Resolving Conflicts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There are a number of ways to manually resolve conflicts: the "right" way, by -strategically using :meth:`pyramid.config.Configurator.commit`, or by using -an "autocommitting" configurator. +There are a number of ways to manually resolve conflicts: by changing +registrations to not conflict, by strategically using +:meth:`pyramid.config.Configurator.commit`, or by using an "autocommitting" +configurator. The Right Thing +++++++++++++++ @@ -294,9 +295,18 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.add_route`, :meth:`~pyramid.config.Configurator.add_renderer`, :meth:`~pyramid.config.Configurator.set_request_factory`, +:meth:`~pyramid.config.Configurator.set_session_factory`, +:meth:`~pyramid.config.Configurator.set_request_property`, +:meth:`~pyramid.config.Configurator.set_root_factory`, +:meth:`~pyramid.config.Configurator.set_view_mapper`, +:meth:`~pyramid.config.Configurator.set_authentication_policy`, +:meth:`~pyramid.config.Configurator.set_authorization_policy`, :meth:`~pyramid.config.Configurator.set_renderer_globals_factory`, -:meth:`~pyramid.config.Configurator.set_locale_negotiator` and -:meth:`~pyramid.config.Configurator.set_default_permission`. +:meth:`~pyramid.config.Configurator.set_locale_negotiator`, +:meth:`~pyramid.config.Configurator.set_default_permission`, +:meth:`~pyramid.config.Configurator.add_traverser`, +:meth:`~pyramid.config.Configurator.add_resource_url_adapter`, +and :meth:`~pyramid.config.Configurator.add_response_adapter`. :meth:`~pyramid.config.Configurator.add_static_view` also indirectly provides conflict detection, because it's implemented in terms of the -- cgit v1.2.3 From e0551cd9e73a20f2180fecb1134e07d5ebb90c68 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 08:39:33 -0500 Subject: move add_traverser and add_resource_url_adapter to adapters --- docs/narr/introspector.rst | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 08cc430f6..d465c47d9 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -540,10 +540,30 @@ introspectables in categories not described here. The (resolved) interface or class object that represents the return value of a root factory that this traverser will be used for. - ``factory`` + ``adapter`` The (resolved) traverser class. +``resource url adapters`` + + Each introspectable in the ``resource url adapters`` category represents a + call to :meth:`pyramid.config.Configurator.add_resource_url_adapter`; each + will have the following data. + + ``adapter`` + + The (resolved) resource URL adapter class. + + ``resource_iface`` + + The (resolved) interface or class object that represents the resource + interface that this url adapter is registered for. + + ``request_iface`` + + The (resolved) interface or class object that represents the request + interface that this url adapter is registered for. + Introspection in the Toolbar ---------------------------- -- cgit v1.2.3 From 95129f178f674a9f8def9aa853bacbc2b8e8f0d3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 18 Feb 2012 19:00:45 -0500 Subject: dont mention arg by name --- 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 a782b9ec6..eaccc14a3 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -495,7 +495,7 @@ For example: from myapp.traversal import ResourceURLAdapter from myapp.resources import MyRoot - config.add_resource_url_adapter(ResourceURLAdapter, resource_iface=MyRoot) + config.add_resource_url_adapter(ResourceURLAdapter, MyRoot) In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will be used to provide services to :meth:`~pyramid.request.Request.resource_url` -- cgit v1.2.3 From d21ba4b61e901b27ceae36f29dac23387a8129d5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 19 Feb 2012 11:05:33 -0500 Subject: - Put ``pyramid.includes`` targets within ini files in scaffolds on separate lines in order to be able to tell people to comment out only the ``pyramid_debugtoolbar`` line when they want to disable the toolbar. --- docs/narr/MyProject/development.ini | 3 ++- docs/narr/project.rst | 31 ++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 2ccedb27b..3c38e3805 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar +pyramid.includes = + pyramid_debugtoolbar [server:main] use = egg:waitress#main diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4566a4fb8..5a519ca30 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -348,27 +348,48 @@ when you use the ``production.ini`` file instead of the ``development.ini`` ini file to run the application. You can also turn the debug toolbar off by editing ``development.ini`` and -commenting out the line ``pyramid.includes = pyramid_debugtoolbar``. For -example, instead of: +commenting out a line. For example, instead of: .. code-block:: ini :linenos: [app:main] ... - pyramid.includes = pyramid_debugtoolbar + pyramid.includes = + pyramid_debugtoolbar -Put a hash mark in front of the ``pyramid.includes`` line: +Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: .. code-block:: ini :linenos: [app:main] ... - #pyramid.includes = pyramid_debugtoolbar + pyramid.includes = + # pyramid_debugtoolbar Then restart the application to see that the toolbar has been turned off. +Note that if you comment out the ``pryamid_debugtoolbar`` line, the ``#`` +*must* be in the first column. If you put the hash mark anywhere except the +first column instead, for example like this: + +.. code-block:: ini + :linenos: + + [app:main] + ... + pyramid.includes = + #pyramid_debugtoolbar + +When you attempt to restart the application with a section like the abvoe +you'll receive an error that ends something like this, and the application +will not start: + +.. code-block:: text + + ImportError: No module named #pyramid_debugtoolbar + .. index:: single: project structure -- cgit v1.2.3 From 844ed90133f051d013330cb0ed4c95dbb29eecc1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 20 Feb 2012 12:41:47 -0500 Subject: Features -------- - Add an ``introspection`` boolean to the Configurator constructor. If this is ``True``, actions registered using the Configurator will be registered with the introspector. If it is ``False``, they won't. The default is ``True``. Setting it to ``False`` during action processing will prevent introspection for any following registration statements, and setting it to ``True`` will start them up again. This addition is to service a requirement that the debug toolbar's own views and methods not show up in the introspector. Backwards Incompatibilities --------------------------- - Remove ``pyramid.config.Configurator.with_context`` class method. It was never an API, it is only used by ``pyramid_zcml`` and its functionality has been moved to that package's latest release. This means that you'll need to use the latest release of ``pyramid_zcml`` with this release of Pyramid. - The ``introspector`` argument to the ``pyramid.config.Configurator`` constructor API has been removed. It has been replaced by the boolean ``introspection`` flag. - The ``pyramid.registry.noop_introspector`` API object has been removed. --- docs/narr/introspector.rst | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index d465c47d9..74595cac8 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -576,17 +576,14 @@ relationships. It looks something like this: Disabling Introspection ----------------------- -You can disable Pyramid introspection by passing the object -:attr:`pyramid.registry.noop_introspector` to the :term:`Configurator` -constructor in your application setup: +You can disable Pyramid introspection by passing the flag +``introspection=False`` to the :term:`Configurator` constructor in your +application setup: .. code-block:: python from pyramid.config import Configurator - from pyramid.registry import noop_introspector - config = Configurator(..., introspector=noop_introspector) + config = Configurator(..., introspection=False) -When the noop introspector is active, all introspectables generated by -configuration directives are thrown away. A noop introspector behaves just -like a "real" introspector, but the methods of a noop introspector do nothing -and return null values. +When ``introspection`` is ``False``, all introspectables generated by +configuration directives are thrown away. -- cgit v1.2.3 From f4216ebb4097af71fc9477cd097360e08117d265 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Tue, 21 Feb 2012 21:46:48 +0200 Subject: Fix favicon_view example: open the file in binary mode. Without this fix Python 3 users might get Unicode errors, and Windows users might get data corruption. --- 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 4f80d33c7..2cc870619 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -374,7 +374,7 @@ do so, do things "by hand". First define the view callable. def favicon_view(request): here = os.path.dirname(__file__) - icon = open(os.path.join(here, 'static', 'favicon.ico')) + icon = open(os.path.join(here, 'static', 'favicon.ico'), 'rb') return Response(content_type='image/x-icon', app_iter=icon) The above bit of code within ``favicon_view`` computes "here", which is a -- cgit v1.2.3 From 0db4a157083d51251b4d3f574a1699fc76359c9d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 22 Feb 2012 15:37:50 -0500 Subject: - New API: ``pyramid.config.Configurator.add_notfound_view``. This is a wrapper for ``pyramid.Config.configurator.add_view`` which provides easy append_slash support. It should be preferred over calling ``add_view`` directly with ``context=HTTPNotFound`` as was previously recommended. - New API: ``pyramid.view.notfound_view_config``. This is a decorator constructor like ``pyramid.view.view_config`` that calls ``pyramid.config.Configurator.add_notfound_view`` when scanned. It should be preferred over using ``pyramid.view.view_config`` with ``context=HTTPNotFound`` as was previously recommended. - The older deprecated ``set_notfound_view`` Configurator method is now an alias for the new ``add_notfound_view`` Configurator method. This has the following impact: the ``context`` sent to views with a ``(context, request)`` call signature registered via the deprecated ``add_notfound_view``/``set_notfound_view`` will now be the HTTPNotFound exception object instead of the actual resource context found. Use ``request.context`` to get the actual resource context. It's also recommended to disuse ``set_notfound_view`` in favor of ``add_notfound_view``, despite the aliasing. - The API documentation for ``pyramid.view.append_slash_notfound_view`` and ``pyramid.view.AppendSlashNotFoundViewFactory`` was removed. These names still exist and are still importable, but they are no longer APIs. Use ``pyramid.config.Configurator.add_notfound_view(append_slash=True)`` or ``pyramid.view.notfound_view_config(append_slash=True)`` to get the same behavior. - The ``set_forbidden_view`` method of the Configurator was removed from the documentation. It has been deprecated since Pyramid 1.1. - The AppendSlashNotFoundViewFactory used request.path to match routes. This was wrong because request.path contains the script name, and this would cause it to fail in circumstances where the script name was not empty. It should have used request.path_info, and now does. - Updated the "Registering a Not Found View" section of the "Hooks" chapter, replacing explanations of registering a view using ``add_view`` or ``view_config`` with ones using ``add_notfound_view`` or ``notfound_view_config``. - Updated the "Redirecting to Slash-Appended Routes" section of the "URL Dispatch" chapter, replacing explanations of registering a view using ``add_view`` or ``view_config`` with ones using ``add_notfound_view`` or ``notfound_view_config`` --- docs/narr/hooks.rst | 81 +++++++++++++++++++++----- docs/narr/renderers.rst | 2 +- docs/narr/urldispatch.rst | 141 ++++++++++++++++++++++++---------------------- 3 files changed, 143 insertions(+), 81 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index eaccc14a3..cbc40ceee 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -19,24 +19,66 @@ found view`, which is a :term:`view callable`. A default notfound view exists. The default not found view can be overridden through application configuration. -The :term:`not found view` callable is a view callable like any other. The -:term:`view configuration` which causes it to be a "not found" view consists -only of naming the :exc:`pyramid.httpexceptions.HTTPNotFound` class as the -``context`` of the view configuration. - If your application uses :term:`imperative configuration`, you can replace -the Not Found view by using the :meth:`pyramid.config.Configurator.add_view` -method to register an "exception view": +the Not Found view by using the +:meth:`pyramid.config.Configurator.add_notfound_view` method: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPNotFound - from helloworld.views import notfound_view - config.add_view(notfound_view, context=HTTPNotFound) + from helloworld.views import notfound + config.add_notfound_view(notfound) + +Replace ``helloworld.views.notfound`` with a reference to the :term:`view +callable` you want to use to represent the Not Found view. The :term:`not +found view` callable is a view callable like any other. + +If your application instead uses :class:`pyramid.view.view_config` decorators +and a :term:`scan`, you can replace the Not Found view by using the +:class:`pyramid.view.notfound_view_config` decorator: + +.. code-block:: python + :linenos: + + from pyramid.view import notfound_view_config + + notfound_view_config() + def notfound(request): + return Response('Not Found, dude', status='404 Not Found') + + def main(globals, **settings): + config = Configurator() + config.scan() + +This does exactly what the imperative example above showed. -Replace ``helloworld.views.notfound_view`` with a reference to the -:term:`view callable` you want to use to represent the Not Found view. +Your application can define *multiple* not found views if necessary. Both +:meth:`pyramid.config.Configurator.add_notfound_view` and +:class:`pyramid.view.notfound_view_config` take most of the same arguments as +:class:`pyramid.config.Configurator.add_view` and +:class:`pyramid.view.view_config`, respectively. This means that not found +views can carry predicates limiting their applicability. For example: + +.. code-block:: python + :linenos: + + from pyramid.view import notfound_view_config + + notfound_view_config(request_method='GET') + def notfound_get(request): + return Response('Not Found during GET, dude', status='404 Not Found') + + notfound_view_config(request_method='POST') + def notfound_post(request): + return Response('Not Found during POST, dude', status='404 Not Found') + + def main(globals, **settings): + config = Configurator() + config.scan() + +The ``notfound_get`` view will be called when a view could not be found and +the request method was ``GET``. The ``notfound_post`` view will be called +when a view could not be found and the request method was ``POST``. Like any other view, the notfound view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``request`` is the @@ -45,6 +87,11 @@ used in the call signature) will be the instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the view to be called. +Both :meth:`pyramid.config.Configurator.add_notfound_view` and +:class:`pyramid.view.notfound_view_config` can be used to automatically +redirect requests to slash-appended routes. See +:ref:`redirecting_to_slash_appended_routes` for examples. + Here's some sample code that implements a minimal NotFound view callable: .. code-block:: python @@ -52,7 +99,7 @@ Here's some sample code that implements a minimal NotFound view callable: from pyramid.httpexceptions import HTTPNotFound - def notfound_view(request): + def notfound(request): return HTTPNotFound() .. note:: @@ -66,6 +113,14 @@ Here's some sample code that implements a minimal NotFound view callable: ``pyramid.debug_notfound`` environment setting is true than it is when it is false. +.. note:: + + Both :meth:`pyramid.config.Configurator.add_notfound_view` and + :class:`pyramid.view.notfound_view_config` are new as of Pyramid 1.3. + Older Pyramid documentation instructed users to use ``add_view`` instead, + with a ``context`` of ``HTTPNotFound``. This still works; the convenience + method and decorator are just wrappers around this functionality. + .. warning:: When a NotFound view callable accepts an argument list as diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 1f1b1943b..76035cbdf 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -103,7 +103,7 @@ Likewise for an :term:`HTTP exception` response: .. code-block:: python :linenos: - from pyramid.httpexceptions import HTTPNotFound + from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config @view_config(renderer='json') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a7bf74786..7c0b437c1 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -772,95 +772,102 @@ ignored when ``static`` is ``True``. Redirecting to Slash-Appended Routes ------------------------------------ -For behavior like Django's ``APPEND_SLASH=True``, use the -:func:`~pyramid.view.append_slash_notfound_view` view as the :term:`Not Found -view` in your application. Defining this view as the :term:`Not Found view` -is a way to automatically redirect requests where the URL lacks a trailing -slash, but requires one to match the proper route. When configured, along -with at least one other route in your application, this view will be invoked -if the value of ``PATH_INFO`` does not already end in a slash, and if the -value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this -case it does an HTTP redirect to the slash-appended ``PATH_INFO``. - -Let's use an example, because this behavior is a bit magical. If the -``append_slash_notfound_view`` is configured in your application and your -route configuration looks like so: +For behavior like Django's ``APPEND_SLASH=True``, use the ``append_slash`` +argument to :meth:`pyramid.config.Configurator.add_notfound_view` or the +equivalent ``append_slash`` argument to the +:class:`pyramid.view.notfound_view_config` decorator. + +Adding ``append_slash=True`` is a way to automatically redirect requests +where the URL lacks a trailing slash, but requires one to match the proper +route. When configured, along with at least one other route in your +application, this view will be invoked if the value of ``PATH_INFO`` does not +already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash +matches any route's pattern. In this case it does an HTTP redirect to the +slash-appended ``PATH_INFO``. + +To configure the slash-appending not found view in your application, change +the application's startup configuration, adding the following stanza: .. code-block:: python :linenos: - config.add_route('noslash', 'no_slash') - config.add_route('hasslash', 'has_slash/') +Let's use an example. If the following routes are configured in your +application: + +.. code-block:: python + :linenos: + + from pyramid.httpexceptions import HTTPNotFound + + def notfound(request): + return HTTPNotFound('Not found, bro.') + + def no_slash(request): + return Response('No slash') - config.add_view('myproject.views.no_slash', route_name='noslash') - config.add_view('myproject.views.has_slash', route_name='hasslash') + def has_slash(request): + return Response('Has slash') + + def main(g, **settings): + config = Configurator() + config.add_route('noslash', 'no_slash') + config.add_route('hasslash', 'has_slash/') + config.add_view(no_slash, route_name='noslash') + config.add_view(has_slash, route_name='hasslash') + config.add_notfound_view(notfound, append_slash=True) + +If a request enters the application with the ``PATH_INFO`` value of +``/no_slash``, the first route will match and the browser will show "No +slash". However, if a request enters the application with the ``PATH_INFO`` +value of ``/no_slash/``, *no* route will match, and the slash-appending not +found view will not find a matching route with an appended slash. As a +result, the ``notfound`` view will be called and it will return a "Not found, +bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash``, a route *will* be found by the slash-appending not found view. An HTTP redirect to -``/has_slash/`` will be returned to the user's browser. +``/has_slash/`` will be returned to the user's browser. As a result, the +``notfound`` view will never actually be called. -If a request enters the application with the ``PATH_INFO`` value of -``/no_slash``, the first route will match. However, if a request enters the -application with the ``PATH_INFO`` value of ``/no_slash/``, *no* route will -match, and the slash-appending not found view will *not* find a matching -route with an appended slash. - -.. warning:: - - You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original - request. - -To configure the slash-appending not found view in your application, change -the application's startup configuration, adding the following stanza: +The following application uses the :class:`pyramid.view.notfound_view_config` +and :class:`pyramid.view.view_config` decorators and a :term:`scan` to do +exactly the same job: .. code-block:: python :linenos: - config.add_view('pyramid.view.append_slash_notfound_view', - context='pyramid.httpexceptions.HTTPNotFound') - -See :ref:`view_module` and :ref:`changing_the_notfound_view` for more -information about the slash-appending not found view and for a more general -description of how to configure a not found view. + from pyramid.httpexceptions import HTTPNotFound + from pyramid.view import notfound_view_config, view_config -Custom Not Found View With Slash Appended Routes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @notfound_view_config(append_slash=True) + def notfound(request): + return HTTPNotFound('Not found, bro.') -There can only be one :term:`Not Found view` in any :app:`Pyramid` -application. Even if you use :func:`~pyramid.view.append_slash_notfound_view` -as the Not Found view, :app:`Pyramid` still must generate a ``404 Not Found`` -response when it cannot redirect to a slash-appended URL; this not found -response will be visible to site users. + @view_config(route_name='noslash') + def no_slash(request): + return Response('No slash') -If you don't care what this 404 response looks like, and only you need -redirections to slash-appended route URLs, you may use the -:func:`~pyramid.view.append_slash_notfound_view` object as the Not Found view -as described above. However, if you wish to use a *custom* notfound view -callable when a URL cannot be redirected to a slash-appended URL, you may -wish to use an instance of the -:class:`~pyramid.view.AppendSlashNotFoundViewFactory` class as the Not Found -view, supplying a :term:`view callable` to be used as the custom notfound -view as the first argument to its constructor. For instance: + @view_config(route_name='hasslash') + def has_slash(request): + return Response('Has slash') -.. code-block:: python - :linenos: - - from pyramid.httpexceptions import HTTPNotFound - from pyramid.view import AppendSlashNotFoundViewFactory + def main(g, **settings): + config = Configurator() + config.add_route('noslash', 'no_slash') + config.add_route('hasslash', 'has_slash/') + config.scan() - def notfound_view(context, request): - return HTTPNotFound('It aint there, stop trying!') +.. warning:: - custom_append_slash = AppendSlashNotFoundViewFactory(notfound_view) - config.add_view(custom_append_slash, context=HTTPNotFound) + You **should not** rely on this mechanism to redirect ``POST`` requests. + The redirect of the slash-appending not found view will turn a ``POST`` + request into a ``GET``, losing any ``POST`` data in the original + request. -The ``notfound_view`` supplied must adhere to the two-argument view callable -calling convention of ``(context, request)`` (``context`` will be the -exception object). +See :ref:`view_module` and :ref:`changing_the_notfound_view` for for a more +general description of how to configure a view and/or a not found view. .. index:: pair: debugging; route matching -- cgit v1.2.3 From a7fe30f0eabd6c6fd3bcc910faa41720a75056de Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 22 Feb 2012 19:24:09 -0500 Subject: - New API: ``pyramid.config.Configurator.add_forbidden_view``. This is a wrapper for ``pyramid.Config.configurator.add_view`` which does the right thing about permissions. It should be preferred over calling ``add_view`` directly with ``context=HTTPForbidden`` as was previously recommended. - New API: ``pyramid.view.forbidden_view_config``. This is a decorator constructor like ``pyramid.view.view_config`` that calls ``pyramid.config.Configurator.add_forbidden_view`` when scanned. It should be preferred over using ``pyramid.view.view_config`` with ``context=HTTPForbidden`` as was previously recommended. - Updated the "Creating a Not Forbidden View" section of the "Hooks" chapter, replacing explanations of registering a view using ``add_view`` or ``view_config`` with ones using ``add_forbidden_view`` or ``forbidden_view_config``. - Updated all tutorials to use ``pyramid.view.forbidden_view_config`` rather than ``pyramid.view.view_config`` with an HTTPForbidden context. --- docs/narr/hooks.rst | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index cbc40ceee..b7f052b00 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -145,23 +145,40 @@ the view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "forbidden" view consists -only of naming the :exc:`pyramid.httpexceptions.HTTPForbidden` class as the -``context`` of the view configuration. +of using the meth:`pyramid.config.Configurator.add_forbidden_view` API or the +:class:`pyramid.view.forbidden_view_config` decorator. -You can replace the forbidden view by using the -:meth:`pyramid.config.Configurator.add_view` method to register an "exception -view": +For example, you can add a forbidden view by using the +:meth:`pyramid.config.Configurator.add_forbidden_view` method to register a +forbidden view: .. code-block:: python :linenos: from helloworld.views import forbidden_view from pyramid.httpexceptions import HTTPForbidden - config.add_view(forbidden_view, context=HTTPForbidden) + config.add_forbidden_view(forbidden_view) Replace ``helloworld.views.forbidden_view`` with a reference to the Python :term:`view callable` you want to use to represent the Forbidden view. +If instead you prefer to use decorators and a :term:`scan`, you can use the +:class:`pyramid.view.forbidden_view_config` decorator to mark a view callable +as a forbidden view: + +.. code-block:: python + :linenos: + + from pyramid.view import forbidden_view_config + + forbidden_view_config() + def forbidden(request): + return Response('forbidden') + + def main(globals, **settings): + config = Configurator() + config.scan() + Like any other view, the forbidden view must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``context`` (available as ``request.context`` if you're using the request-only view argument -- cgit v1.2.3 From c2e82a7505bd0cac9304b31c4e84fbafe521e0e1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 22 Feb 2012 20:22:27 -0500 Subject: allow user to pass content type and encoding, change favicon example to use FileResponse --- docs/narr/assets.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 2cc870619..bad666066 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -370,19 +370,22 @@ do so, do things "by hand". First define the view callable. :linenos: import os - from pyramid.response import Response + from pyramid.response import FileResponse def favicon_view(request): here = os.path.dirname(__file__) - icon = open(os.path.join(here, 'static', 'favicon.ico'), 'rb') - return Response(content_type='image/x-icon', app_iter=icon) + icon = os.path.join(here, 'static', 'favicon.ico') + return FileResponse(icon, request=request) The above bit of code within ``favicon_view`` computes "here", which is a path relative to the Python file in which the function is defined. It then uses the Python ``open`` function to obtain a file handle to a file within -"here" named ``static``, and returns a response using the open the file -handle as the response's ``app_iter``. It makes sure to set the right -content_type too. +"here" named ``static``, and returns a :class:`pyramid.response.Fileresponse` +using the file path as the response's ``path`` argument and the request as +the response's ``request`` argument. :class:`pyramid.response.FileResponse` +will serve the file as quickly as possible when it's used this way. It makes +sure to set the right content length and content_type too based on the file +extension of the file you pass. You might register such a view via configuration as a view callable that should be called as the result of a traversal: -- cgit v1.2.3 From a1317263c3a4dafd366d3a272c37a3ed8ac3613a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 22 Feb 2012 20:23:26 -0500 Subject: fix --- 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 bad666066..22b38c929 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -380,7 +380,7 @@ do so, do things "by hand". First define the view callable. The above bit of code within ``favicon_view`` computes "here", which is a path relative to the Python file in which the function is defined. It then uses the Python ``open`` function to obtain a file handle to a file within -"here" named ``static``, and returns a :class:`pyramid.response.Fileresponse` +"here" named ``static``, and returns a :class:`pyramid.response.FileResponse` using the file path as the response's ``path`` argument and the request as the response's ``request`` argument. :class:`pyramid.response.FileResponse` will serve the file as quickly as possible when it's used this way. It makes -- cgit v1.2.3 From 3b9e5f1df23e42eabfc41e8726c27a7227230b61 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 23 Feb 2012 20:42:57 -0500 Subject: fix --- docs/narr/assets.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 22b38c929..e8e915297 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -379,13 +379,12 @@ do so, do things "by hand". First define the view callable. The above bit of code within ``favicon_view`` computes "here", which is a path relative to the Python file in which the function is defined. It then -uses the Python ``open`` function to obtain a file handle to a file within -"here" named ``static``, and returns a :class:`pyramid.response.FileResponse` -using the file path as the response's ``path`` argument and the request as -the response's ``request`` argument. :class:`pyramid.response.FileResponse` -will serve the file as quickly as possible when it's used this way. It makes -sure to set the right content length and content_type too based on the file -extension of the file you pass. +creates a :class:`pyramid.response.FileResponse` using the file path as the +response's ``path`` argument and the request as the response's ``request`` +argument. :class:`pyramid.response.FileResponse` will serve the file as +quickly as possible when it's used this way. It makes sure to set the right +content length and content_type too based on the file extension of the file +you pass. You might register such a view via configuration as a view callable that should be called as the result of a traversal: -- cgit v1.2.3 From 3213d8e0a9f925ab2a6211b1134b087fc5adbad8 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Fri, 24 Feb 2012 14:06:44 -0500 Subject: Trivial typos --- docs/narr/testing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 7ee432fa7..5ce2c8a66 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -303,12 +303,12 @@ In :app:`Pyramid`, a *unit test* typically relies on "mock" or "dummy" implementations to give the code under test only enough context to run. "Integration testing" implies another sort of testing. In the context of a -:app:`Pyramid`, integration test, the test logic tests the functionality of +:app:`Pyramid` integration test, the test logic tests the functionality of some code *and* its integration with the rest of the :app:`Pyramid` framework. In :app:`Pyramid` applications that are plugins to Pyramid, you can create an -integration test by including it's ``includeme`` function via +integration test by including its ``includeme`` function via :meth:`pyramid.config.Configurator.include` in the test's setup code. This causes the entire :app:`Pyramid` environment to be set up and torn down as if your application was running "for real". This is a heavy-hammer way of @@ -372,7 +372,7 @@ Creating Functional Tests Functional tests test your literal application. The below test assumes that your application's package name is ``myapp``, and -that there is view that returns an HTML body when the root URL is invoked. +that there is a view that returns an HTML body when the root URL is invoked. It further assumes that you've added a ``tests_require`` dependency on the ``WebTest`` package within your ``setup.py`` file. :term:`WebTest` is a functional testing package written by Ian Bicking. -- cgit v1.2.3 From 283494c2338dbd6e89a7da79a05318992ee04cfc Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Fri, 24 Feb 2012 14:24:50 -0500 Subject: More trivial typos --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 763c0e131..23b4fde68 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -900,7 +900,7 @@ When a non-``None`` ``http_cache`` argument is passed to a view configuration, Pyramid will set ``Expires`` and ``Cache-Control`` response headers in the resulting response, causing browsers to cache the response data for some time. See ``http_cache`` in :ref:`nonpredicate_view_args` for -the its allowable values and what they mean. +the allowable values and what they mean. Sometimes it's undesirable to have these headers set as the result of returning a response from a view, even though you'd like to decorate the view -- cgit v1.2.3 From 01eac92dcdbe0d51b75783350997e69a7613da9e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 24 Feb 2012 15:15:18 -0500 Subject: docs-deprecate tmpl_context --- docs/narr/webob.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 21c368350..a8c11acec 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -117,8 +117,8 @@ Special Attributes Added to the Request by :app:`Pyramid` In addition to the standard :term:`WebOb` attributes, :app:`Pyramid` adds special attributes to every request: ``context``, ``registry``, ``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root``, -``virtual_root_path``, ``session``, and ``tmpl_context``, ``matchdict``, and -``matched_route``. These attributes are documented further within the +``virtual_root_path``, ``session``, ``matchdict``, and ``matched_route``. +These attributes are documented further within the :class:`pyramid.request.Request` API documentation. .. index:: -- cgit v1.2.3 From 81c63fee1dae8dcf12b5063f93faf0eeed54659c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 26 Feb 2012 13:36:14 -0500 Subject: make latex render again --- docs/narr/urldispatch.rst | 6 ------ 1 file changed, 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 7c0b437c1..f036ce94e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -785,12 +785,6 @@ already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this case it does an HTTP redirect to the slash-appended ``PATH_INFO``. -To configure the slash-appending not found view in your application, change -the application's startup configuration, adding the following stanza: - -.. code-block:: python - :linenos: - Let's use an example. If the following routes are configured in your application: -- cgit v1.2.3 From 46eccc677d8a4995ac08023b1b7c41b79c171fed Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 26 Feb 2012 14:58:14 -0500 Subject: fix instance creation --- 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 b7f052b00..c44323201 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -776,7 +776,7 @@ as keyword arguments. def wrapper(context, request): matchdict = request.matchdict.copy() matchdict.pop('action', None) - inst = view() + inst = view(request) meth = getattr(inst, attr) return meth(**matchdict) return wrapper -- cgit v1.2.3 From 25d7c28c6830d7f55b206b0467cd987e77f07515 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 29 Feb 2012 08:59:48 -0500 Subject: fix decorators --- docs/narr/hooks.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index c44323201..f1a122c6c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -42,7 +42,7 @@ and a :term:`scan`, you can replace the Not Found view by using the from pyramid.view import notfound_view_config - notfound_view_config() + @notfound_view_config() def notfound(request): return Response('Not Found, dude', status='404 Not Found') @@ -64,11 +64,11 @@ views can carry predicates limiting their applicability. For example: from pyramid.view import notfound_view_config - notfound_view_config(request_method='GET') + @notfound_view_config(request_method='GET') def notfound_get(request): return Response('Not Found during GET, dude', status='404 Not Found') - notfound_view_config(request_method='POST') + @notfound_view_config(request_method='POST') def notfound_post(request): return Response('Not Found during POST, dude', status='404 Not Found') -- cgit v1.2.3 From 6269a1c058a77438b90a165c6541685c1bfaa8db Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Thu, 1 Mar 2012 14:52:49 +0100 Subject: Remove mention of the `root_factory` argument. The example code earlier on the page does not use the `root_factory` argument, only the `settings` argument. This is a fix for pyramid issue #452. --- docs/narr/startup.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 78b119687..8e28835af 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -102,10 +102,9 @@ Here's a high-level time-ordered overview of what happens when you press the meanings of these keys. #. The ``main`` function first constructs a - :class:`~pyramid.config.Configurator` instance, passing a root resource - factory (constructor) to it as its ``root_factory`` argument, and - ``settings`` dictionary captured via the ``**settings`` kwarg as its - ``settings`` argument. + :class:`~pyramid.config.Configurator` instance, passing the ``settings`` + dictionary captured via the ``**settings`` kwarg as its ``settings`` + argument. The ``settings`` dictionary contains all the options in the ``[app:main]`` section of our .ini file except the ``use`` option (which is internal to -- cgit v1.2.3 From 9103fbc2a3cd40d59c0405e0c65ae62af3a690a7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 1 Mar 2012 20:33:18 -0500 Subject: wrong class name, fixes #451 --- docs/narr/scaffolding.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 3e7b102fd..9ac579a87 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -123,7 +123,7 @@ defining your scaffold template: paste_script_template_renderer = None from pyramid.scaffolds import PyramidTemplate - class CoolExtensionTemplateTemplate(PyramidTemplate): + class CoolExtensionTemplate(PyramidTemplate): _template_dir = 'coolextension_scaffold' summary = 'My cool extension' template_renderer = staticmethod(paste_script_template_renderer) -- cgit v1.2.3 From ae6d08b96d3a366f979719c05926dc5292d904d3 Mon Sep 17 00:00:00 2001 From: Ruslan Spivak Date: Fri, 2 Mar 2012 03:45:54 -0500 Subject: Remove some confusion about finished callbacks. Rework an example code and remove an incorrect statement about request.exception being set when an exception occurs in a view. The reason for the change is issue #454: https://github.com/Pylons/pyramid/issues/454 --- docs/narr/hooks.rst | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index f1a122c6c..24ea5de21 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -421,15 +421,14 @@ parameter: ``request``. For example: .. code-block:: python :linenos: - import transaction + import logging - def commit_callback(request): - '''commit or abort the transaction associated with request''' - if request.exception is not None: - transaction.abort() - else: - transaction.commit() - request.add_finished_callback(commit_callback) + log = logging.getLogger(__name__) + + def log_callback(request): + """Log information at the end of request""" + log.debug('Request is finished.') + request.add_finished_callback(log_callback) Finished callbacks are called in the order they're added (first-to-most-recently-added). Finished callbacks (unlike a @@ -447,12 +446,6 @@ meaningful effect, because response processing will have already occurred, and the request's scope will expire almost immediately after all finished callbacks have been processed. -It is often necessary to tell whether an exception occurred within -:term:`view callable` code from within a finished callback: in such a case, -the :attr:`request.exception` attribute of the request when it enters a -response callback will be an exception object instead of its default value of -``None``. - Errors raised by finished callbacks are not handled specially. They will be propagated to the caller of the :app:`Pyramid` router application. -- cgit v1.2.3 From 56766163ece5d860f3f1ea9d2006b1a3d3d6f937 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Fri, 2 Mar 2012 11:30:55 +0100 Subject: Correct minor grammatical error. --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index dbc702de8..c3bbbd50e 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -178,7 +178,7 @@ HTTP Exceptions All classes documented in the :mod:`pyramid.httpexceptions` module documented as inheriting from the :class:`pryamid.httpexceptions.HTTPException` are -:term:`http exception` objects. An instances of an HTTP exception object may +:term:`http exception` objects. Instances of an HTTP exception object may either be *returned* or *raised* from within view code. In either case (return or raise) the instance will be used as as the view's response. -- cgit v1.2.3 From 49c5838d43b377c9204375e9462ef9200660eca7 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Fri, 2 Mar 2012 11:51:22 +0100 Subject: Correct section name in pshell example. The section in the example is called 'app:main', not 'app:MyProject'. --- docs/narr/commandline.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 95927cfca..886e075e3 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -142,11 +142,11 @@ might have a ``[app:main]`` section that looks like so: pyramid.default_locale_name = en If so, you can use the following command to invoke a debug shell using the -name ``MyProject`` as a section name: +name ``main`` as a section name: .. code-block:: text - chrism@thinko env26]$ bin/pshell starter/development.ini#MyProject + chrism@thinko env26]$ bin/pshell starter/development.ini#main Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. -- cgit v1.2.3 From 13305e14b74c4ef6bbd44817ed0eac5c36499c2b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 5 Mar 2012 03:26:27 -0500 Subject: add_traverser --- 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 24ea5de21..b6e3dd163 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -474,7 +474,7 @@ via configuration. from pyramid.config import Configurator from myapp.traversal import Traverser config = Configurator() - config.set_traverser(Traverser) + config.add_traverser(Traverser) In the example above, ``myapp.traversal.Traverser`` is assumed to be a class that implements the following interface: @@ -524,7 +524,7 @@ used. Otherwise, the default traverser would be used. For example: from myapp.resources import MyRoot from pyramid.config import Configurator config = Configurator() - config.set_traverser(Traverser, MyRoot) + config.add_traverser(Traverser, MyRoot) If the above stanza was added to a Pyramid ``__init__.py`` file's ``main`` function, :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only -- cgit v1.2.3 From d66d9a6507a983f4a6510ba19a0d4f3e87e39c4b Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 11 Mar 2012 17:13:35 -0600 Subject: view class methods were missing self parameter. --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 92955aafd..507201439 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -260,11 +260,11 @@ Here's a few views defined as methods of a class instead: self.request = request @view_config(route_name='view_one') - def view_one(request): + def view_one(self, request): return Response('one') @view_config(route_name='view_two') - def view_two(request): + def view_two(self, request): return Response('two') See also :ref:`view_config_placement`. -- cgit v1.2.3 From e73a5496b04952c45201449a5ce75d89c6678b7e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 11 Mar 2012 19:16:53 -0700 Subject: only self --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 507201439..d7e719bb1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -260,11 +260,11 @@ Here's a few views defined as methods of a class instead: self.request = request @view_config(route_name='view_one') - def view_one(self, request): + def view_one(self): return Response('one') @view_config(route_name='view_two') - def view_two(self, request): + def view_two(self): return Response('two') See also :ref:`view_config_placement`. -- cgit v1.2.3 From c946fc7b717359cf26dab45a9b84f06f6c1bc466 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Tue, 13 Mar 2012 17:19:18 -0700 Subject: Typos --- docs/narr/advconfig.rst | 2 +- docs/narr/introduction.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 0060ef65c..9cb4db325 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -227,7 +227,7 @@ to :meth:`~pyramid.config.Configurator.commit` between them: In the above example we've issued a call to :meth:`~pyramid.config.Configurator.commit` between the two ``add_view`` -calls. :meth:`~pyramid.config.Configurator.commit` will cause any pending +calls. :meth:`~pyramid.config.Configurator.commit` will execute any pending configuration statements. Calling :meth:`~pyramid.config.Configurator.commit` is safe at any time. It diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d7e719bb1..8f7b17dc3 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -347,7 +347,7 @@ You can do this: When this view callable is called by Pyramid, the ``{'a':1}`` dictionary will be rendered to a response on your behalf. The string passed as ``renderer=`` above is an :term:`asset specification`. It is in the form -``packagename:directoryname/filename.ext``. In this case, it names the +``packagename:directoryname/filename.ext``. In this case, it refers to the ``mytemplate.pt`` file in the ``templates`` directory within the ``myapp`` Python package. Asset specifications are omnipresent in Pyramid: see :ref:`intro_asset_specs` for more information. -- cgit v1.2.3 From 488ea03753d0434b1ddf0c3b2204463c229e7244 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Mar 2012 09:02:18 -0700 Subject: remove debug_templates untruths related to issue #491 --- docs/narr/project.rst | 12 +++------- docs/narr/templates.rst | 63 ++++--------------------------------------------- 2 files changed, 8 insertions(+), 67 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 5a519ca30..96ea8036c 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -497,15 +497,9 @@ exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako` template changes will not require an application restart to be detected. See :ref:`reload_templates_section` for more information. -The ``pyramid.debug_templates`` setting in the ``[app:main]`` section is a -:app:`Pyramid` -specific setting which is passed into the framework. If it -exists, and its value is ``true``, :term:`Chameleon` template exceptions will -contain more detailed and helpful information about the error than when this -value is ``false``. See :ref:`debug_templates_section` for more information. - -.. warning:: The ``pyramid.reload_templates`` and ``pyramid.debug_templates`` - options should be turned off for production applications, as template - rendering is slowed when either is turned on. +.. warning:: The ``pyramid.reload_templates`` option should be turned off for + production applications, as template rendering is slowed when it is turned + on. The ``pyramid.includes`` setting in the ``[app:main]`` section tells Pyramid to "include" configuration from another package. In this case, the line diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 11318d9eb..ed700f7b4 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -593,56 +593,11 @@ extension so that these ``svn:ignore`` patterns work. .. index:: pair: debugging; templates -.. _debug_templates_section: +Debugging Templates +------------------- -Nicer Exceptions in Chameleon Templates ---------------------------------------- - -The exceptions raised by Chameleon templates when a rendering fails -are sometimes less than helpful. :app:`Pyramid` allows you to -configure your application development environment so that exceptions -generated by Chameleon during template compilation and execution will -contain nicer debugging information. - -.. warning:: Template-debugging behavior is not recommended for - production sites as it slows renderings; it's usually - only desirable during development. - -In order to turn on template exception debugging, you can use an -environment variable setting or a configuration file setting. - -To use an environment variable, start your application under a shell -using the ``PYRAMID_DEBUG_TEMPLATES`` operating system environment -variable set to ``1``, For example: - -.. code-block:: text - - $ PYRAMID_DEBUG_TEMPLATES=1 bin/pserve myproject.ini - -To use a setting in the application ``.ini`` file for the same -purpose, set the ``pyramid.debug_templates`` key to ``true`` within -the application's configuration section, e.g.: - -.. code-block:: ini - :linenos: - - [app:main] - use = egg:MyProject - pyramid.debug_templates = true - -With template debugging off, a :exc:`NameError` exception resulting -from rendering a template with an undefined variable -(e.g. ``${wrong}``) might end like this: - -.. code-block:: text - - File "...", in __getitem__ - raise NameError(key) - NameError: wrong - -Note that the exception has no information about which template was -being rendered when the error occured. But with template debugging -on, an exception resulting from the same problem might end like so: +A :exc:`NameError` exception resulting from rendering a template with an +undefined variable (e.g. ``${wrong}``) might will end like this: .. code-block:: text @@ -660,17 +615,9 @@ on, an exception resulting from the same problem might end like so: NameError: wrong -The latter tells you which template the error occurred in, as well as +The output tells you which template the error occurred in, as well as displaying the arguments passed to the template itself. -.. note:: - - Turning on ``pyramid.debug_templates`` has the same effect as using the - Chameleon environment variable ``CHAMELEON_DEBUG``. See `Chameleon - Environment Variables - `_ - for more information. - .. index:: single: template internationalization single: internationalization (of templates) -- cgit v1.2.3 From 343fb59c318e35c656611b58e7fe870373e33452 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 17 Mar 2012 14:48:01 -0400 Subject: - Remove references to do-nothing ``pyramid.debug_templates`` setting in all Pyramid-provided ``.ini`` files. This setting previously told Chameleon to render better exceptions; now Chameleon always renders nice exceptions regardless of the value of this setting. Fixes #491. --- docs/narr/MyProject/development.ini | 1 - docs/narr/MyProject/production.ini | 1 - 2 files changed, 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 3c38e3805..84e08c2d0 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -5,7 +5,6 @@ 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 pyramid.includes = pyramid_debugtoolbar diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 43ea1d140..3396125f2 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -5,7 +5,6 @@ pyramid.reload_templates = false pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false -pyramid.debug_templates = false pyramid.default_locale_name = en [server:main] -- cgit v1.2.3 From f57b56a73237a6f0b2f5b14b1062eca1f55a1c61 Mon Sep 17 00:00:00 2001 From: Rachid Belaid Date: Sat, 17 Mar 2012 22:32:11 +0000 Subject: misspelling : change 'pryamid_debugtoolbar' into 'pyramid_debugtoolbar' --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 96ea8036c..b9b381cdf 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -370,7 +370,7 @@ Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: Then restart the application to see that the toolbar has been turned off. -Note that if you comment out the ``pryamid_debugtoolbar`` line, the ``#`` +Note that if you comment out the ``pyramid_debugtoolbar`` line, the ``#`` *must* be in the first column. If you put the hash mark anywhere except the first column instead, for example like this: -- cgit v1.2.3 From bf1cb91ee2c34edbfa92e538f312e8d60d900478 Mon Sep 17 00:00:00 2001 From: Rachid Belaid Date: Sun, 18 Mar 2012 04:01:52 +0000 Subject: Keep the same notation, 'myproject' is used previously. 'mypackage' is correct and generic, after following the previous step of the documentation the user would have only one package which is 'myproject' --- 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 b9b381cdf..f6790e863 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -750,8 +750,8 @@ also informs Python that the directory which contains it is a *package*. Line 6 creates an instance of a :term:`Configurator`. Line 7 registers a static view, which will serve up the files from the - ``mypackage:static`` :term:`asset specification` (the ``static`` - directory of the ``mypackage`` package). + ``myproject:static`` :term:`asset specification` (the ``static`` + directory of the ``myproject`` package). Line 8 adds a :term:`route` to the configuration. This route is later used by a view in the ``views`` module. -- cgit v1.2.3 From cd6281b34a45ad4ec08b732597059b33da45883a Mon Sep 17 00:00:00 2001 From: Rachid Belaid Date: Sun, 18 Mar 2012 04:20:11 +0000 Subject: Keep the same vocabulary than previously in the doc, at this stage of the instruction the user doesn't have more than one package which myproject --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b9b381cdf..42d8b27e8 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -888,7 +888,7 @@ If your project package name was ``myproject`` and you wanted to arrange all your views in a Python subpackage within the ``myproject`` :term:`package` named ``views`` instead of within a single ``views.py`` file, you might: -- Create a ``views`` directory inside your ``mypackage`` package directory +- Create a ``views`` directory inside your ``myproject`` package directory (the same directory which holds ``views.py``). - *Move* the existing ``views.py`` file to a file inside the new ``views`` -- cgit v1.2.3 From c2a5f8ab1dcec36082c5fd4902e63ac1e82c173a Mon Sep 17 00:00:00 2001 From: Rachid Belaid Date: Sun, 18 Mar 2012 04:36:56 +0000 Subject: Suggestion : giving at least the name the command to use as an indication . Even if this information it's not enough, when you read the doc via pdf that give you which command to use without having to jump of section. I find it better for the learning flow of the reader than jumping around. --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b9b381cdf..b9c495b43 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -908,7 +908,7 @@ is restarted. Using the Interactive Shell --------------------------- -It is possible to use a Python interpreter prompt loaded with a similar +It is possible to use the ``pshell`` command to load a Python interpreter prompt with a similar configuration as would be loaded if you were running your Pyramid application via ``pserve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. -- cgit v1.2.3 From 926fbeab87285c98bd58575f87c7e34d6f70f530 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 18 Mar 2012 02:11:56 -0500 Subject: Fixed line width. --- docs/narr/project.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 63d9432f1..318d932fe 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -908,10 +908,10 @@ is restarted. Using the Interactive Shell --------------------------- -It is possible to use the ``pshell`` command to load a Python interpreter prompt with a similar -configuration as would be loaded if you were running your Pyramid application -via ``pserve``. This can be a useful debugging tool. See -:ref:`interactive_shell` for more details. +It is possible to use the ``pshell`` command to load a Python interpreter +prompt with a similar configuration as would be loaded if you were running +your Pyramid application via ``pserve``. This can be a useful debugging tool. +See :ref:`interactive_shell` for more details. What Is This ``pserve`` Thing ----------------------------- -- cgit v1.2.3 From 7b55442a0947663f3f1e76a504a9cb33d8d53086 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 18 Mar 2012 23:50:24 -0400 Subject: warn about project names that shadow stdlib names, change UNIX prompt to gt --- docs/narr/project.rst | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 318d932fe..0134f4c74 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -83,7 +83,7 @@ Or on Windows: .. code-block:: text - $ Scripts\pcreate -s starter MyProject + > Scripts\pcreate -s starter MyProject The above command uses the ``pcreate`` command to create a project with the ``starter`` scaffold. To use a different scaffold, such as @@ -98,7 +98,7 @@ Or on Windows: .. code-block:: text - $ Scripts\pcreate -s alchemy MyProject + > Scripts\pcreate -s alchemy MyProject Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: @@ -132,6 +132,14 @@ The ``MyProject`` project directory contains an additional subdirectory named :term:`package` which holds very simple :app:`Pyramid` sample code. This is where you'll edit your application's Python code and templates. +.. warning:: + + You’ll need to avoid using ``pcreate`` to create a project with the same + as a Python standard library component. In particular, this means you + should avoid using names the names ``site`` or ``test``, both of which + conflict with Python standard library packages. You should also avoid + using the name ``pyramid``, which will conflict with Pyramid itself. + .. index:: single: setup.py develop single: development install @@ -161,8 +169,8 @@ Or on Windows: .. code-block:: text - $ cd MyProject - $ ..\Scripts\python.exe setup.py develop + > cd MyProject + > ..\Scripts\python.exe setup.py develop Elided output from a run of this command on UNIX is shown below: @@ -200,7 +208,7 @@ Or on Windows: .. code-block:: text - $ ..\Scripts\python.exe setup.py test -q + > ..\Scripts\python.exe setup.py test -q Here's sample output from a test run on UNIX: @@ -256,7 +264,7 @@ On Windows: .. code-block:: text - $ ..\Scripts\pserve development.ini + > ..\Scripts\pserve development.ini Here's sample output from a run of ``pserve`` on UNIX: -- cgit v1.2.3 From 545654d60719161bdde4633afa42704cd5fedde5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Mar 2012 00:06:48 -0400 Subject: explain where things might go in reality and explain gt example Windows convention --- docs/narr/project.rst | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 0134f4c74..ba5eee03a 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -68,10 +68,13 @@ Creating the Project 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. In -:ref:`installing_chapter` we called the virtualenv directory ``env``; the -following command assumes that our current working directory is that -directory. We'll choose the ``starter`` scaffold for this purpose. +the ``pcreate`` command installed within the virtualenv. We'll choose the +``starter`` scaffold for this purpose. When we invoke ``pcreate``, it will +create a directory that represents our project. + +In :ref:`installing_chapter` we called the virtualenv directory ``env``; the +following commands assume that our current working directory is the ``env`` +directory. On UNIX: @@ -132,6 +135,17 @@ The ``MyProject`` project directory contains an additional subdirectory named :term:`package` which holds very simple :app:`Pyramid` sample code. This is where you'll edit your application's Python code and templates. +We created this project within an ``env`` virtualenv directory. However, +note that this is not mandatory. The project directory can go more or less +anywhere on your filesystem. You don't need to put it in a special "web +server" directory, and you don't need to put it within a virtualenv +directory. The author uses Linux mainly, and tends to put project +directories which he creates within his ``~/projects`` directory. On +Windows, it's a good idea to put project directories within a directory that +contains no space characters, so it's wise to *avoid* a path that contains +i.e. ``My Documents``. As a result, the author, when he uses Windows, just +puts his projects in ``C:\\projects``. + .. warning:: You’ll need to avoid using ``pcreate`` to create a project with the same -- cgit v1.2.3 From 7a89a410f86b3c7d606f1a2e1adbaf035ffd7077 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Mar 2012 00:22:05 -0400 Subject: provide instructions about how to change the port, warn against changing the server, put code reloading into its own section --- docs/narr/project.rst | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ba5eee03a..4a34b7568 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -292,6 +292,37 @@ By default, :app:`Pyramid` applications generated from a scaffold will listen on TCP port 6543. You can shut down a server started this way by pressing ``Ctrl-C``. +The default server used to run your Pyramid application when a project is +created from a scaffold is named :term:`Waitress`. This server is what +prints the ``serving on...`` line when you run ``pserve``. It's a good idea +to use this server during development, because it's very simple. It can also +be used for light production. Setting your application up under a different +server is not advised until you've done some development work under the +default server, particularly if you're not yet experienced with Python web +development. Python web server setup can be complex, and you should get some +confidence that your application works in a default environment before trying +to optimize it or make it "more like production". It's awfully easy to get +sidetracked trying to set up a nondefault server for hours without actually +starting to do any development. One of the nice things about Python web +servers is that they're largely interchangeable, so if your application works +under the default server, it will almost certainly work under any other +server in production if you choose to use a different one. + +You can change the port on which the server runs on by changing the +``development.ini`` file. For example, you can change the ``port = 6543`` +line in the ``development.ini`` file's ``[server:main]`` section to ``port = +8080`` to run the server on port 8080 instead of port 6543. + +For more detailed information about the startup process, see +:ref:`startup_chapter`. For more information about environment variables and +configuration file settings that influence startup and runtime behavior, see +:ref:`environment_chapter`. + +.. _reloading_code: + +Reloading Code +~~~~~~~~~~~~~~ + During development, it's often useful to run ``pserve`` using its ``--reload`` option. When ``--reload`` is passed to ``pserve``, changes to any Python module your project uses will cause the server to restart. This @@ -307,11 +338,6 @@ For example, on UNIX: Starting server in PID 16601. Starting HTTP server on http://0.0.0.0:6543 -For more detailed information about the startup process, see -:ref:`startup_chapter`. For more information about environment variables and -configuration file settings that influence startup and runtime behavior, see -:ref:`environment_chapter`. - .. index:: single: WSGI -- cgit v1.2.3 From 5991d92b9508223df12ecd07f65ec8e9bbfdc3d9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Mar 2012 00:34:19 -0400 Subject: show the effect of a server restart under reload; explain that template changes dont require a restart --- docs/narr/project.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 4a34b7568..8c837be74 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -338,6 +338,22 @@ For example, on UNIX: Starting server in PID 16601. Starting HTTP server on http://0.0.0.0: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: + +.. code-block:: text + + development.ini changed; reloading... + -------------------- Restarting -------------------- + Starting server in PID 16602. + Starting HTTP server on http://0.0.0.0: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 long as the ``pyramid.reload_templates`` setting in the +``development.ini`` file is ``true``. Changes made to template files when +this setting is true will take effect immediately without a server restart. + .. index:: single: WSGI -- cgit v1.2.3 From db598dde142cab1f77d4b7218c64f0bcce76d3cd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Mar 2012 00:37:00 -0400 Subject: use the correct message --- 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 8c837be74..78f0372e0 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -336,7 +336,7 @@ For example, on UNIX: $ ../bin/pserve development.ini --reload Starting subprocess with file monitor Starting server in PID 16601. - Starting HTTP server on http://0.0.0.0:6543 + serving on http://0.0.0.0: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: @@ -346,7 +346,7 @@ files, you'll see the server restart automatically: development.ini changed; reloading... -------------------- Restarting -------------------- Starting server in PID 16602. - Starting HTTP server on http://0.0.0.0:6543 + serving on http://0.0.0.0: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 -- cgit v1.2.3 From 66a9c5d47cf0f3c985f0186de2d6459a81418c39 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Mar 2012 00:47:42 -0400 Subject: wording --- docs/narr/project.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 78f0372e0..460d620bb 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -114,10 +114,10 @@ Here's sample output from a run of ``pcreate`` on UNIX for a project we name # ... more output ... Running /Users/chrism/projects/pyramid/bin/python setup.py egg_info -As a result of invoking the ``pcreate`` command, a project is created in a -directory named ``MyProject``. That directory is a :term:`project` -directory. The ``setup.py`` file in that directory can be used to distribute -your application, or install your application for deployment or development. +As a result of invoking the ``pcreate`` command, a directory named +``MyProject`` is created. That directory is a :term:`project` directory. +The ``setup.py`` file in that directory can be used to distribute your +application, or install your application for deployment or development. A ``.ini`` file named ``development.ini`` will be created in the project directory. You will use this ``.ini`` file to configure a server, to run @@ -306,7 +306,8 @@ sidetracked trying to set up a nondefault server for hours without actually starting to do any development. One of the nice things about Python web servers is that they're largely interchangeable, so if your application works under the default server, it will almost certainly work under any other -server in production if you choose to use a different one. +server in production if you eventually choose to use a different one. Don't +worry about it right now. You can change the port on which the server runs on by changing the ``development.ini`` file. For example, you can change the ``port = 6543`` -- cgit v1.2.3 From dd08cceff6c650f211c4e3fd3c7c73e37616ea7c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Mar 2012 00:49:20 -0400 Subject: windows --- docs/narr/project.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 460d620bb..57073900f 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1028,4 +1028,5 @@ details. Another good production alternative is :term:`Green Unicorn` (aka ``gunicorn``). It's faster than Waitress and slightly easier to configure than mod_wsgi, although it depends, in its default configuration, on having a -buffering HTTP proxy in front of it. +buffering HTTP proxy in front of it. It does not, as of this writing, work +on Windows. -- cgit v1.2.3 From eb33944d0d861bbb3aebdf069cce64f8c1c3faef Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 21 Mar 2012 18:58:22 -0400 Subject: flesh out system values --- docs/narr/templates.rst | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index ed700f7b4..9db0b1c4d 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -253,16 +253,26 @@ System Values Used During Rendering When a template is rendered using :func:`~pyramid.renderers.render_to_response` or -:func:`~pyramid.renderers.render`, the renderer representing the -template will be provided with a number of *system* values. These -values are provided in a dictionary to the renderer and include: - -``context`` - The current :app:`Pyramid` context if ``request`` was provided as - a keyword argument, or ``None``. +:func:`~pyramid.renderers.render`, or a ``renderer=`` argument to view +configuration (see :ref:`templates_used_as_renderers`), the renderer +representing the template will be provided with a number of *system* values. +These values are provided to the template: ``request`` - The request provided as a keyword argument. + The value provided as the ``request`` keyword argument to + ``render_to_response`` or ``render`` *or* the request object passed to the + view when the ``renderer=`` argument to view configuration is being used to + render the template. + +``req`` + An alias for ``request``. + +``context`` + The current :app:`Pyramid` :term:`context` if ``request`` was provided as a + keyword argument to ``render_to_response`` or ``render``, or ``None`` if + the ``request`` keyword argument was not provided. This value will always + be provided if the template is rendered as the result of a ``renderer=`` + argument to view configuration being used. ``renderer_name`` The renderer name used to perform the rendering, @@ -270,17 +280,24 @@ values are provided in a dictionary to the renderer and include: ``renderer_info`` An object implementing the :class:`pyramid.interfaces.IRendererInfo` - interface. Basically, an object with the following attributes: - ``name``, ``package`` and ``type``. + interface. Basically, an object with the following attributes: ``name``, + ``package`` and ``type``. + +``view`` + The view callable object that was used to render this template. If the + view callable is a method of a class-based view, this will be an instance + of the class that the method was defined on. If the view callable is a + function or instance, it will be that function or instance. Note that this + value will only be automatically present when a template is rendered as a + result of a ``renderer=`` argument; it will be ``None`` when the + ``render_to_response`` or ``render`` APIs are used. -You can define more values which will be passed to every template -executed as a result of rendering by defining :term:`renderer -globals`. +You can define more values which will be passed to every template executed as +a result of rendering by defining :term:`renderer globals`. What any particular renderer does with these system values is up to the -renderer itself, but most template renderers, including Chameleon and -Mako renderers, make these names available as top-level template -variables. +renderer itself, but most template renderers, including Chameleon and Mako +renderers, make these names available as top-level template variables. .. index:: pair: renderer; templates -- cgit v1.2.3 From d81ea33ac67ac750053acbfd12616db0130de3c8 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 10 Jan 2012 22:52:24 -0600 Subject: intermediate commit --- docs/narr/renderers.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 76035cbdf..47182c09e 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -177,8 +177,8 @@ using the API of the ``request.response`` attribute. See .. index:: pair: renderer; JSON -``json``: JSON Renderer -~~~~~~~~~~~~~~~~~~~~~~~ +JSON Renderer +~~~~~~~~~~~~~ The ``json`` renderer renders view callable results to :term:`JSON`. It passes the return value through the ``json.dumps`` standard library function, @@ -207,7 +207,10 @@ representing the JSON serialization of the return value: '{"content": "Hello!"}' The return value needn't be a dictionary, but the return value must contain -values serializable by :func:`json.dumps`. +values serializable by :func:`json.dumps`. Extra arguments can be passed +to :func:`json.dumps` by overriding the default renderer. See +:class:`pyramid.renderers.JSON` and +:ref:`_adding_and_overriding_renderers` for more information. You can configure a view to use the JSON renderer by naming ``json`` as the ``renderer`` argument of a view configuration, e.g. by using @@ -221,7 +224,6 @@ You can configure a view to use the JSON renderer by naming ``json`` as the context='myproject.resources.Hello', renderer='json') - Views which use the JSON renderer can vary non-body response attributes by using the api of the ``request.response`` attribute. See :ref:`request_response_attr`. -- cgit v1.2.3 From ba60524b56a639ecad42f85b63af2120d9d96cdc Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Wed, 28 Mar 2012 12:03:52 -0400 Subject: JSON-API rework and Object.__json__ support --- docs/narr/renderers.rst | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 47182c09e..52e97d091 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -212,6 +212,13 @@ to :func:`json.dumps` by overriding the default renderer. See :class:`pyramid.renderers.JSON` and :ref:`_adding_and_overriding_renderers` for more information. +Custom objects can be easily serialized by defining a :func:`__json__` method +on the object. This method should return values serializable by +:func:`json_dumps`. By defining this method and using a :term:`JSON` +renderer the :class:`pyramid.renderers.ObjectJSONEncoder` class will be used +for encoding your object. If you later define your own custom encoder it will +override :class:`pyramid.renderers.ObjectJSONEncoder`. + You can configure a view to use the JSON renderer by naming ``json`` as the ``renderer`` argument of a view configuration, e.g. by using :meth:`~pyramid.config.Configurator.add_view`: -- cgit v1.2.3 From de797c4cefb03f16cfe3505c85d94c0af24eb066 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 29 Mar 2012 04:21:30 -0400 Subject: - Coverage and docs updates for custom JSON class. - Fork point: master now represents a future 1.4 release. --- docs/narr/renderers.rst | 68 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 52e97d091..34bee3c7f 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -207,17 +207,13 @@ representing the JSON serialization of the return value: '{"content": "Hello!"}' The return value needn't be a dictionary, but the return value must contain -values serializable by :func:`json.dumps`. Extra arguments can be passed -to :func:`json.dumps` by overriding the default renderer. See -:class:`pyramid.renderers.JSON` and -:ref:`_adding_and_overriding_renderers` for more information. - -Custom objects can be easily serialized by defining a :func:`__json__` method -on the object. This method should return values serializable by -:func:`json_dumps`. By defining this method and using a :term:`JSON` -renderer the :class:`pyramid.renderers.ObjectJSONEncoder` class will be used -for encoding your object. If you later define your own custom encoder it will -override :class:`pyramid.renderers.ObjectJSONEncoder`. +values serializable by ``json.dumps``. + +.. note:: + + Extra arguments can be passed to ``json.dumps`` by overriding the default + ``json`` renderer. See :class:`pyramid.renderers.JSON` and + :ref:`adding_and_overriding_renderers` for more information. You can configure a view to use the JSON renderer by naming ``json`` as the ``renderer`` argument of a view configuration, e.g. by using @@ -235,13 +231,57 @@ Views which use the JSON renderer can vary non-body response attributes by using the api of the ``request.response`` attribute. See :ref:`request_response_attr`. +.. _json_serializing_custom_objects: + +Serializing Custom Objects +++++++++++++++++++++++++++ + +Custom objects can be made easily JSON-serializable in Pyramid by defining a +``__json__`` method on the object's class. This method should return values +natively serializable by ``json.dumps`` (such as ints, lists, dictionaries, +strings, and so forth). + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + class MyObject(object): + def __init__(self, x): + self.x = x + + def __json__(self): + return {'x':self.x} + + @view_config(renderer='json') + def objects(request): + return [MyObject(1), MyObject(2)] + + # the JSON value returned by ``objects`` will be: + # [{"x": 1}, {"x": 2}] + +.. note:: + + Honoring the ``__json__`` method of custom objects is a feature new in + Pyramid 1.4. + +.. warning:: + + The machinery which performs the ``__json__`` method-calling magic is in + the :class:`pyramid.renderers.ObjectJSONEncoder` class. This class will + be used for encoding any non-basic Python object when you use the default + ```json`` or ``jsonp`` renderers. But if you later define your own custom + JSON renderer and pass it a "cls" argument signifying a different encoder, + the encoder you pass will override Pyramid's use of + :class:`pyramid.renderers.ObjectJSONEncoder`. + .. index:: pair: renderer; JSONP .. _jsonp_renderer: JSONP Renderer --------------- +~~~~~~~~~~~~~~ .. note:: This feature is new in Pyramid 1.1. @@ -306,6 +346,10 @@ The string ``callback=?`` above in the the ``url`` param to the JQuery a JSONP request; the ``callback`` parameter will be automatically filled in for you and used. +The same custom-object serialization scheme defined used for a "normal" JSON +renderer in :ref:`json_serializing_custom_objects` can be used when passing +values to a JSONP renderer too. + .. index:: pair: renderer; chameleon -- cgit v1.2.3 From 9834f2a0d95126001d32c34b4f2bec2b980df55e Mon Sep 17 00:00:00 2001 From: David Gay Date: Mon, 2 Apr 2012 18:49:39 -0400 Subject: addressed #327 --- docs/narr/views.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index c3bbbd50e..59bc16e6b 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -571,6 +571,16 @@ callable code itself. No matter which view calling convention is used, the view code always has access to the context via ``request.context``. +.. index:: + single: Passing in configuration variables + +.. _passing_in_config_variables: + +Passing Configuration Variables to a View +----------------------------------------- +For information on passing a variable from the configuration .ini files to a +view, see :ref:`deployment_settings`. + .. index:: single: Pylons-style controller dispatch -- cgit v1.2.3 From aa1b1eda9d2e507c2c0d7c12785d6f57bfa17129 Mon Sep 17 00:00:00 2001 From: David Gay Date: Mon, 2 Apr 2012 18:49:39 -0400 Subject: addressed #327 --- docs/narr/views.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index c3bbbd50e..f6ee9a8d5 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -571,6 +571,17 @@ callable code itself. No matter which view calling convention is used, the view code always has access to the context via ``request.context``. +.. index:: + single: Passing in configuration variables + +.. _passing_in_config_variables: + +Passing Configuration Variables to a View +----------------------------------------- + +For information on passing a variable from the configuration .ini files to a +view, see :ref:`deployment_settings`. + .. index:: single: Pylons-style controller dispatch -- cgit v1.2.3 From 77e06770dc174f4269c50bb5443c4b67bc6d3da2 Mon Sep 17 00:00:00 2001 From: David Gay Date: Mon, 2 Apr 2012 19:18:09 -0400 Subject: removed strange text that showed up --- docs/narr/views.rst | 3 --- 1 file changed, 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 6291f01b4..f6ee9a8d5 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -578,10 +578,7 @@ access to the context via ``request.context``. Passing Configuration Variables to a View ----------------------------------------- -<<<<<<< HEAD -======= ->>>>>>> 9834f2a0d95126001d32c34b4f2bec2b980df55e For information on passing a variable from the configuration .ini files to a view, see :ref:`deployment_settings`. -- cgit v1.2.3 From 7c3cf41997cb9c903d7ca8a712062f3846381ead Mon Sep 17 00:00:00 2001 From: Veeti Paananen Date: Fri, 13 Apr 2012 00:40:06 +0300 Subject: Fix a typo in the documentation --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 57073900f..d18d93605 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -447,7 +447,7 @@ first column instead, for example like this: pyramid.includes = #pyramid_debugtoolbar -When you attempt to restart the application with a section like the abvoe +When you attempt to restart the application with a section like the above you'll receive an error that ends something like this, and the application will not start: -- cgit v1.2.3 From bce621a99ee495d8d82f744eaa209ae0f1ac504e Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Fri, 6 Apr 2012 18:22:13 -0500 Subject: Typos --- docs/narr/hooks.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b6e3dd163..a2143b3c5 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -145,7 +145,7 @@ the view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The :term:`view configuration` which causes it to be a "forbidden" view consists -of using the meth:`pyramid.config.Configurator.add_forbidden_view` API or the +of using the :meth:`pyramid.config.Configurator.add_forbidden_view` API or the :class:`pyramid.view.forbidden_view_config` decorator. For example, you can add a forbidden view by using the @@ -171,7 +171,7 @@ as a forbidden view: from pyramid.view import forbidden_view_config - forbidden_view_config() + @forbidden_view_config() def forbidden(request): return Response('forbidden') @@ -625,7 +625,7 @@ converts the arbitrary return value into something that implements :class:`~pyramid.interfaces.IResponse`. For example, if you'd like to allow view callables to return bare string -objects (without requiring a a :term:`renderer` to convert a string to a +objects (without requiring a :term:`renderer` to convert a string to a response object), you can register an adapter which converts the string to a Response: -- cgit v1.2.3 From 1f0d9d2193bb9557d4475885776b5679c8dbfa23 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 16 Apr 2012 23:19:14 -0500 Subject: docs for json defaults --- docs/narr/renderers.rst | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 34bee3c7f..50349c409 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -223,9 +223,9 @@ You can configure a view to use the JSON renderer by naming ``json`` as the :linenos: config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='json') + name='hello', + context='myproject.resources.Hello', + renderer='json') Views which use the JSON renderer can vary non-body response attributes by using the api of the ``request.response`` attribute. See @@ -260,20 +260,21 @@ strings, and so forth). # the JSON value returned by ``objects`` will be: # [{"x": 1}, {"x": 2}] -.. note:: +If you don't own the objects being serialized, it's difficult to add a custom +``__json__`` method to the object. In this case, a callback can be supplied +to the renderer which is invoked when other options have failed. - Honoring the ``__json__`` method of custom objects is a feature new in - Pyramid 1.4. +.. code-block:: python + :linenos: + + def default(obj): + if isinstance(obj, datetime.datetime): + return obj.isoformat() + raise TypeError -.. warning:: +.. note:: - The machinery which performs the ``__json__`` method-calling magic is in - the :class:`pyramid.renderers.ObjectJSONEncoder` class. This class will - be used for encoding any non-basic Python object when you use the default - ```json`` or ``jsonp`` renderers. But if you later define your own custom - JSON renderer and pass it a "cls" argument signifying a different encoder, - the encoder you pass will override Pyramid's use of - :class:`pyramid.renderers.ObjectJSONEncoder`. + Serializing custom objects is a feature new in Pyramid 1.4. .. index:: pair: renderer; JSONP -- cgit v1.2.3 From 18410a6d9d64786f272268db6368981955ff9f10 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 17 Apr 2012 04:59:33 -0400 Subject: default_encode->_default_encode, dumps->_dumps, massage docs --- docs/narr/renderers.rst | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 50349c409..02063a112 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -177,6 +177,8 @@ using the API of the ``request.response`` attribute. See .. index:: pair: renderer; JSON +.. _json_renderer: + JSON Renderer ~~~~~~~~~~~~~ @@ -260,17 +262,34 @@ strings, and so forth). # the JSON value returned by ``objects`` will be: # [{"x": 1}, {"x": 2}] -If you don't own the objects being serialized, it's difficult to add a custom -``__json__`` method to the object. In this case, a callback can be supplied -to the renderer which is invoked when other options have failed. +If you aren't the author of the objects being serialized, it won't be +possible (or at least not reasonable) to add a custom ``__json__`` method to +to their classes in order to influence serialization. If the object passed +to the renderer is not a serializable type, and has no ``__json__`` method, +usually a :exc:`TypeError` will be raised during serialization. You can +change this behavior by creating a JSON renderer with a "default" function +which tries to "sniff" at the object, and returns a valid serialization (a +string) or raises a TypeError if it can't determine what to do with the +object. A short example follows: .. code-block:: python :linenos: + from pyramid.renderers import JSON + def default(obj): if isinstance(obj, datetime.datetime): return obj.isoformat() - raise TypeError + raise TypeError('%r is not serializable % (obj,)) + + json_renderer = JSON(default=default) + + # then during configuration .... + config = Configurator() + config.add_renderer('json', json_renderer) + +See :class:`pyramid.renderers.JSON` and +:ref:`adding_and_overriding_renderers` for more information. .. note:: -- cgit v1.2.3 From 677216d2c4ddc5f0df857b8f9e8fa6ccfd5fd55a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 18 Apr 2012 00:50:10 -0500 Subject: reverted back to using a component registry during json encoding --- docs/narr/renderers.rst | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 02063a112..c36caeb87 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -182,10 +182,10 @@ using the API of the ``request.response`` attribute. See JSON Renderer ~~~~~~~~~~~~~ -The ``json`` renderer renders view callable results to :term:`JSON`. It -passes the return value through the ``json.dumps`` standard library function, -and wraps the result in a response object. It also sets the response -content-type to ``application/json``. +The ``json`` renderer renders view callable results to :term:`JSON`. By +default, it passes the return value through the ``json.dumps`` standard +library function, and wraps the result in a response object. It also sets +the response content-type to ``application/json``. Here's an example of a view that returns a dictionary. Since the ``json`` renderer is specified in the configuration for this view, the view will @@ -209,11 +209,11 @@ representing the JSON serialization of the return value: '{"content": "Hello!"}' The return value needn't be a dictionary, but the return value must contain -values serializable by ``json.dumps``. +values serializable by the configured serializer (by default ``json.dumps``). .. note:: - Extra arguments can be passed to ``json.dumps`` by overriding the default + Extra arguments can be passed to the serializer by overriding the default ``json`` renderer. See :class:`pyramid.renderers.JSON` and :ref:`adding_and_overriding_renderers` for more information. @@ -240,8 +240,8 @@ Serializing Custom Objects Custom objects can be made easily JSON-serializable in Pyramid by defining a ``__json__`` method on the object's class. This method should return values -natively serializable by ``json.dumps`` (such as ints, lists, dictionaries, -strings, and so forth). +natively JSON-serializable (such as ints, lists, dictionaries, strings, and +so forth). .. code-block:: python :linenos: @@ -267,22 +267,18 @@ possible (or at least not reasonable) to add a custom ``__json__`` method to to their classes in order to influence serialization. If the object passed to the renderer is not a serializable type, and has no ``__json__`` method, usually a :exc:`TypeError` will be raised during serialization. You can -change this behavior by creating a JSON renderer with a "default" function -which tries to "sniff" at the object, and returns a valid serialization (a -string) or raises a TypeError if it can't determine what to do with the -object. A short example follows: +change this behavior by creating a custom JSON renderer and adding adapters +to handle custom types. The renderer will attempt to adapt non-serializable +objects using the registered adapters. It will raise a :exc:`TypeError` if it +can't determine what to do with the object. A short example follows: .. code-block:: python :linenos: from pyramid.renderers import JSON - def default(obj): - if isinstance(obj, datetime.datetime): - return obj.isoformat() - raise TypeError('%r is not serializable % (obj,)) - - json_renderer = JSON(default=default) + json_renderer = JSON() + json_renderer.add_adapter(datetime.datetime, lambda x: x.isoformat()) # then during configuration .... config = Configurator() -- cgit v1.2.3 From 60ea901969e7ea87a68e7ca3da4032724ca90bb7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 19 Apr 2012 16:43:31 -0400 Subject: take out 'or dotted python name' --- docs/narr/startup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 8e28835af..2a764b0ec 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -42,8 +42,8 @@ Here's a high-level time-ordered overview of what happens when you press ``[pipeline:main]``, or ``[composite:main]`` in the ``.ini`` file. This section represents the configuration of a :term:`WSGI` application that will be served. If you're using a simple application (e.g. - ``[app:main]``), the application :term:`entry point` or :term:`dotted - Python name` will be named on the ``use=`` line within the section's + ``[app:main]``), the application's ``paste.app_factory`` :term:`entry + point` will be named on the ``use=`` line within the section's configuration. If, instead of a simple application, you're using a WSGI :term:`pipeline` (e.g. a ``[pipeline:main]`` section), the application named on the "last" element will refer to your :app:`Pyramid` application. -- cgit v1.2.3 From 0569f999db99e50ffd962eb06d51ec1fb4731181 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 19 Apr 2012 16:45:51 -0400 Subject: squash another reference to dotted name --- docs/narr/startup.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 2a764b0ec..f5c741f52 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -59,11 +59,11 @@ Here's a high-level time-ordered overview of what happens when you press system for this application. See :ref:`logging_config` for more information. -#. The application's *constructor* named by the entry point reference or - dotted Python name on the ``use=`` line of the section representing your - :app:`Pyramid` application is passed the key/value parameters mentioned - within the section in which it's defined. The constructor is meant to - return a :term:`router` instance, which is a :term:`WSGI` application. +#. The application's *constructor* named by the entry point reference on the + ``use=`` line of the section representing your :app:`Pyramid` application + is passed the key/value parameters mentioned within the section in which + it's defined. The constructor is meant to return a :term:`router` + instance, which is a :term:`WSGI` application. For :app:`Pyramid` applications, the constructor will be a function named ``main`` in the ``__init__.py`` file within the :term:`package` in which -- cgit v1.2.3 From ea7a26856e27f4256ec0157635b4c64197f37053 Mon Sep 17 00:00:00 2001 From: VlAleVas Date: Fri, 27 Apr 2012 16:10:13 +0300 Subject: Update docs/narr/urldispatch.rst --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f036ce94e..acbccbdfd 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -547,7 +547,7 @@ add to your application: config.add_route('idea', 'ideas/{idea}') config.add_route('user', 'users/{user}') - config.add_route('tag', 'tags/{tags}') + config.add_route('tag', 'tags/{tag}') config.add_view('mypackage.views.idea_view', route_name='idea') config.add_view('mypackage.views.user_view', route_name='user') -- cgit v1.2.3 From 39e0d1d2b8e9bc1169c6b2f159fa16d468aaf6c5 Mon Sep 17 00:00:00 2001 From: Dan Jacka Date: Mon, 30 Apr 2012 12:46:44 +1200 Subject: Separator between name and value in --header option to prequest is ':', not '=' --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 886e075e3..1485caefc 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -460,7 +460,7 @@ to the console. You can add request header values by using the ``--header`` option:: - $ bin/prequest --header=Host=example.com development.ini / + $ bin/prequest --header=Host:example.com development.ini / Headers are added to the WSGI environment by converting them to their CGI/WSGI equivalents (e.g. ``Host=example.com`` will insert the ``HTTP_HOST`` -- cgit v1.2.3 From b9cead35e09b11c13693d6f6838b70948b568f6c Mon Sep 17 00:00:00 2001 From: Dan Jacka Date: Tue, 1 May 2012 13:33:35 +1200 Subject: Change the example script's description string to match the console_script's name: show_settings --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 1485caefc..4be436836 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -718,7 +718,7 @@ we'll pretend you have a distribution with a package in it named def settings_show(): description = """\ Print the deployment settings for a Pyramid application. Example: - 'psettings deployment.ini' + 'show_settings deployment.ini' """ usage = "usage: %prog config_uri" parser = optparse.OptionParser( -- cgit v1.2.3 From e012aa12760f6c29bfc9967c50a51d3f47db47da Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 3 May 2012 02:42:55 -0400 Subject: allow __json__ and custom adapters to accept request arg --- docs/narr/renderers.rst | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index c36caeb87..57b5bc65b 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -241,7 +241,8 @@ Serializing Custom Objects Custom objects can be made easily JSON-serializable in Pyramid by defining a ``__json__`` method on the object's class. This method should return values natively JSON-serializable (such as ints, lists, dictionaries, strings, and -so forth). +so forth). It should accept a single additional argument, ``request``, which +will be the active request object at render time. .. code-block:: python :linenos: @@ -252,7 +253,7 @@ so forth). def __init__(self, x): self.x = x - def __json__(self): + def __json__(self, request): return {'x':self.x} @view_config(renderer='json') @@ -269,8 +270,7 @@ to the renderer is not a serializable type, and has no ``__json__`` method, usually a :exc:`TypeError` will be raised during serialization. You can change this behavior by creating a custom JSON renderer and adding adapters to handle custom types. The renderer will attempt to adapt non-serializable -objects using the registered adapters. It will raise a :exc:`TypeError` if it -can't determine what to do with the object. A short example follows: +objects using the registered adapters. A short example follows: .. code-block:: python :linenos: @@ -278,12 +278,19 @@ can't determine what to do with the object. A short example follows: from pyramid.renderers import JSON json_renderer = JSON() - json_renderer.add_adapter(datetime.datetime, lambda x: x.isoformat()) + def datetime_adapter(obj, request): + return obj.isoformat() + json_renderer.add_adapter(datetime.datetime, datetime_adapter) # then during configuration .... config = Configurator() config.add_renderer('json', json_renderer) +The adapter should accept two arguments: the object needing to be serialized +and ``request``, which will be the current request object at render time. +The adapter should raise a :exc:`TypeError` if it can't determine what to do +with the object. + See :class:`pyramid.renderers.JSON` and :ref:`adding_and_overriding_renderers` for more information. -- cgit v1.2.3 From 5d0989efeb3eecd4cc55fd9c1dcaf1134ced56b2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 4 May 2012 19:56:00 -0400 Subject: add introspection to whats unique --- docs/narr/introduction.rst | 28 ++++++++++++++++++++++++++++ docs/narr/introspector.rst | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8f7b17dc3..2d04a4f5a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -801,6 +801,34 @@ within a function called when another user uses the See also :ref:`add_directive`. +Programmatic Introspection +-------------------------- + +If you're building a large system that other users may plug code into, it's +useful to be able to get an enumeration of what code they plugged in *at +application runtime*. For example, you might want to show them a set of tabs +at the top of the screen based on an enumeration of views they registered. + +This is possible using Pyramid's :term:`introspector`. + +Here's an example of using Pyramid's introspector from within a view +callable: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + + @view_config(route_name='bar') + def show_current_route_pattern(request): + introspector = request.registry.introspector + route_name = request.matched_route.name + route_intr = introspector.get('routes', route_name) + return Response(str(route_intr['pattern'])) + +See also :ref:`using_introspection`. + Testing ~~~~~~~ diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 74595cac8..6bfaf11c0 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -32,7 +32,7 @@ callable: from pyramid.response import Response @view_config(route_name='bar') - def route_accepts(request): + def show_current_route_pattern(request): introspector = request.registry.introspector route_name = request.matched_route.name route_intr = introspector.get('routes', route_name) -- cgit v1.2.3 From d6a9543c1149c02c19aca3d053a5afd9ca0f1dbf Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 4 May 2012 19:59:50 -0400 Subject: garden --- docs/narr/introduction.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 2d04a4f5a..a1f1c7d5e 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -593,11 +593,12 @@ it is to shoehorn a route into an ordered list of other routes, or to create another entire instance of an application to service a department and glue code to allow disparate apps to share data. It's a great fit for sites that naturally lend themselves to changing departmental hierarchies, such as -content management systems and document management systems. Traversal also lends itself well to -systems that require very granular security ("Bob can edit *this* document" -as opposed to "Bob can edit documents"). +content management systems and document management systems. Traversal also +lends itself well to systems that require very granular security ("Bob can +edit *this* document" as opposed to "Bob can edit documents"). -Example: :ref:`hello_traversal_chapter` and :ref:`much_ado_about_traversal_chapter`. +Examples: :ref:`hello_traversal_chapter` and +:ref:`much_ado_about_traversal_chapter`. Tweens ~~~~~~ -- cgit v1.2.3 From 1252ab764fda606003aa23a0e3bfa89ba948e3f1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 4 May 2012 20:07:10 -0400 Subject: add python 3 as a uniqueness --- docs/narr/introduction.rst | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a1f1c7d5e..9b3a63089 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -830,6 +830,14 @@ callable: See also :ref:`using_introspection`. +Python 3 Compatibility +---------------------- + +Pyramid and most of its add-ons are Python 3 compatible. If you develop a +Pyramid application today, you won't need to worry that five years from now +you'll be backwatered because there are language features you'd like to use +but your framework doesn't support newer Python versions. + Testing ~~~~~~~ -- cgit v1.2.3 From 1d03bbca7fe9f005d4a08c7dfe7eb139ab4b0df1 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Mon, 7 May 2012 21:45:40 -0500 Subject: Two grammatical fixes --- docs/narr/advconfig.rst | 2 +- docs/narr/introduction.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 9cb4db325..2949dc808 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -282,7 +282,7 @@ Pyramid application, and they want to customize the configuration of this application without hacking its code "from outside", they can "include" a configuration function from the package and override only some of its configuration statements within the code that does the include. No conflicts -will be generated by configuration statements within the code which does the +will be generated by configuration statements within the code that does the including, even if configuration statements in the included code would conflict if it was moved "up" to the calling code. diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 9b3a63089..b5fa6a9f7 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -534,14 +534,14 @@ Configuration extensibility ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike other systems, Pyramid provides a structured "include" mechanism (see -:meth:`~pyramid.config.Configurator.include`) that allows you to compose +:meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be performed by included packages including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's configuration in your own, overriding or adding new views and routes to -it. This has the potential to allow you to compose a big application out of +it. This has the potential to allow you to create a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the ``include`` statement with a ``route_prefix``; the new application will live -- cgit v1.2.3 From f35062faf63dc62addc8f05e9d8f0637bbee58e0 Mon Sep 17 00:00:00 2001 From: Bryce Boe Date: Tue, 15 May 2012 19:38:46 -0700 Subject: Fixed spelling errors and double backslash in `C:\`. --- docs/narr/project.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index d18d93605..da184ada7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -144,13 +144,13 @@ directories which he creates within his ``~/projects`` directory. On Windows, it's a good idea to put project directories within a directory that contains no space characters, so it's wise to *avoid* a path that contains i.e. ``My Documents``. As a result, the author, when he uses Windows, just -puts his projects in ``C:\\projects``. +puts his projects in ``C:\projects``. .. warning:: You’ll need to avoid using ``pcreate`` to create a project with the same as a Python standard library component. In particular, this means you - should avoid using names the names ``site`` or ``test``, both of which + should avoid using the names ``site`` or ``test``, both of which conflict with Python standard library packages. You should also avoid using the name ``pyramid``, which will conflict with Pyramid itself. @@ -684,7 +684,7 @@ testing your application, packaging, and distributing your application. .. note:: - ``setup.py`` is the defacto standard which Python developers use to + ``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 @@ -966,7 +966,7 @@ named ``views`` instead of within a single ``views.py`` file, you might: You can then continue to add view callable functions to the ``blog.py`` module, but you can also add other ``.py`` files which contain view callable functions to the ``views`` directory. As long as you use the -``@view_config`` directive to register views in conjuction with +``@view_config`` directive to register views in conjunction with ``config.scan()`` they will be picked up automatically when the application is restarted. @@ -994,7 +994,7 @@ run a :app:`Pyramid` application is purely conventional based on the output of its scaffolding. But we strongly recommend using while developing your application, because many other convenience introspection commands (such as ``pviews``, ``prequest``, ``proutes`` and others) are also implemented in -terms of configuration availaibility of this ``.ini`` file format. It also +terms of configuration availability of this ``.ini`` file format. It also configures Pyramid logging and provides the ``--reload`` switch for convenient restarting of the server when code changes. -- cgit v1.2.3 From 1aa978c074afce7f821634e5aa8366caa07ee437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20B=C3=BCchler?= Date: Wed, 23 May 2012 09:28:53 +0300 Subject: Fixed a few glitches in the "Using a Route Prefix to Compose Applications" section of the docs/narr/urldispatch.rst docs. --- docs/narr/urldispatch.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index acbccbdfd..ecf3d026a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -954,7 +954,7 @@ will be prepended with the first: from pyramid.config import Configurator def timing_include(config): - config.add_route('show_times', /times') + config.add_route('show_times', '/times') def users_include(config): config.add_route('show_users', '/show') @@ -966,7 +966,7 @@ will be prepended with the first: In the above configuration, the ``show_users`` route will still have an effective route pattern of ``/users/show``. The ``show_times`` route -however, will have an effective pattern of ``/users/timing/show_times``. +however, will have an effective pattern of ``/users/timing/times``. Route prefixes have no impact on the requirement that the set of route *names* in any given Pyramid configuration must be entirely unique. If you @@ -981,7 +981,7 @@ that may be added in the future. For example: from pyramid.config import Configurator def timing_include(config): - config.add_route('timing.show_times', /times') + config.add_route('timing.show_times', '/times') def users_include(config): config.add_route('users.show_users', '/show') -- cgit v1.2.3 From be8e3acc64767e5a0ba798037118da9f262bdf93 Mon Sep 17 00:00:00 2001 From: Zeb Palmer Date: Thu, 31 May 2012 21:03:38 -0600 Subject: Added missing word "name" --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index da184ada7..1e2c225d2 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -149,7 +149,7 @@ puts his projects in ``C:\projects``. .. warning:: You’ll need to avoid using ``pcreate`` to create a project with the same - as a Python standard library component. In particular, this means you + name as a Python standard library component. In particular, this means you should avoid using the names ``site`` or ``test``, both of which conflict with Python standard library packages. You should also avoid using the name ``pyramid``, which will conflict with Pyramid itself. -- cgit v1.2.3 From a319249fdb6e0539e65e0b297829ed8c7f799b98 Mon Sep 17 00:00:00 2001 From: Jeff Cook Date: Thu, 7 Jun 2012 14:00:07 -0600 Subject: Update documentation to clarify purpose of BeforeRender.rendering_val. --- docs/narr/hooks.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a2143b3c5..30eec04f0 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -289,6 +289,21 @@ keys added to the renderer globals dictionary by all :class:`pyramid.events.BeforeRender` subscribers and renderer globals factories must be unique. +The dictionary returned from the view is accessible through the +:attr:`rendering_val` attribute of a :class:`~pyramid.events.BeforeRender` +event, like so: + +.. code-block:: python + :linenos: + + from pyramid.events import subscriber + from pyramid.events import BeforeRender + + @subscriber(BeforeRender) + def read_return(event): + # 'mykey' is returned from the view + print(event.rendering_val['mykey']) + See the API documentation for the :class:`~pyramid.events.BeforeRender` event interface at :class:`pyramid.interfaces.IBeforeRender`. -- cgit v1.2.3 From 0487d5e05dd61d6d7482212d40fb5884e06f582a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 12 Jun 2012 11:18:37 -0500 Subject: docs reference setup_logging instead of fileConfig --- docs/narr/commandline.rst | 7 +++++-- docs/narr/logging.rst | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 4be436836..af53c1f78 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -654,8 +654,11 @@ use the following command: .. code-block:: python - import logging.config - logging.config.fileConfig('/path/to/my/development.ini') + import pyramid.paster + pyramid.paster.setup_logging('/path/to/my/development.ini') + +See :ref:`logging_chapter` for more information on logging within +:app:`Pyramid`. .. index:: single: console script diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 044655c1f..f4c38abb6 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -14,7 +14,7 @@ how to send log messages to loggers that you've configured. which help configure logging. All of the scaffolds which ship along with :app:`Pyramid` do this. If you're not using a scaffold, or if you've used a third-party scaffold which does not create these files, the - configuration information in this chapter will not be applicable. + configuration information in this chapter may not be applicable. .. _logging_config: @@ -36,10 +36,11 @@ application-related and logging-related sections in the configuration file can coexist peacefully, and the logging-related sections in the file are used from when you run ``pserve``. -The ``pserve`` command calls the `logging.fileConfig function +The ``pserve`` command calls the :func:`pyramid.paster.setup_logging` +function, a thin wrapper around the `logging.fileConfig `_ using the specified ini file if it contains a ``[loggers]`` section (all of the -scaffold-generated ``.ini`` files do). ``logging.fileConfig`` reads the +scaffold-generated ``.ini`` files do). ``setup_logging`` reads the logging configuration from the ini file upon which ``pserve`` was invoked. -- cgit v1.2.3 From fbbb20c7953370c86f999e865b1a9d682690eb70 Mon Sep 17 00:00:00 2001 From: Brian Sutherland Date: Sat, 16 Jun 2012 12:57:46 +0200 Subject: A context manager for test setup --- docs/narr/testing.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 5ce2c8a66..89bc1a089 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -157,6 +157,30 @@ We use a "dummy" request implementation supplied by :class:`pyramid.testing.DummyRequest` because it's easier to construct than a "real" :app:`Pyramid` request object. +Test setup using a context manager +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An alternative style of setting up a test configuration is to use the +`with` statement and :func:`pyramid.testing.testConfig` to create a +context manager. The context manager will call +:func:`pyramid.testing.setUp` before the code under test and +:func:`pyramid.testing.tearDown` afterwards. + +This style is useful for small self-contained tests. For example: + +.. code-block:: python + :linenos: + + import unittest + + class MyTest(unittest.TestCase): + + def test_my_function(self): + from pyramid import testing + with testing.testConfig() as config: + config.add_route('bar', '/bar/{id}') + my_function_which_needs_route_bar() + What? ~~~~~ -- cgit v1.2.3 From 2516df30d73afdf6606ad3d89b7c24ab496f356d Mon Sep 17 00:00:00 2001 From: Jeff Cook Date: Sun, 17 Jun 2012 01:20:37 -0600 Subject: docs: Add view callable example to section on rendering_val. --- docs/narr/hooks.rst | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 30eec04f0..332805152 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -291,18 +291,33 @@ factories must be unique. The dictionary returned from the view is accessible through the :attr:`rendering_val` attribute of a :class:`~pyramid.events.BeforeRender` -event, like so: +event. + +Suppose you return ``{'mykey': 'somevalue', 'mykey2': 'somevalue2'}`` from +your view callable, like so: .. code-block:: python - :linenos: + :linenos: - from pyramid.events import subscriber - from pyramid.events import BeforeRender + from pyramid.view import view_config - @subscriber(BeforeRender) - def read_return(event): - # 'mykey' is returned from the view - print(event.rendering_val['mykey']) + @view_config(renderer='some_renderer') + def myview(request): + return {'mykey': 'somevalue', 'mykey2': 'somevalue2'} + +:attr:`rendering_val` can be used to access these values from the +:class:`~pyramid.events.BeforeRender` object: + +.. code-block:: python + :linenos: + + from pyramid.events import subscriber + from pyramid.events import BeforeRender + + @subscriber(BeforeRender) + def read_return(event): + # {'mykey': 'somevalue'} is returned from the view + print(event.rendering_val['mykey']) See the API documentation for the :class:`~pyramid.events.BeforeRender` event interface at :class:`pyramid.interfaces.IBeforeRender`. -- cgit v1.2.3 From ea009a6d4a1ffa8585faa85581848f6e74a57dfc Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 20:12:55 -0400 Subject: added docs and changes for using defs in mako renderer --- docs/narr/templates.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 9db0b1c4d..4ac01c96e 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -714,6 +714,22 @@ This template doesn't use any advanced features of Mako, only the :term:`renderer globals`. See the `the Mako documentation `_ to use more advanced features. +Using def inside Mako Templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use a def inside a Mako template, given a :term:`Mako` template file named +``foo.mak`` and a def named ``bar``, you can configure the template as a +:term:`renderer` like so: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + @view_config(renderer='foo#defname.mak') + def my_view(request): + return {'project':'my project'} + .. index:: single: automatic reloading of templates single: template automatic reload -- cgit v1.2.3 From 6cea47e9c34841cdf109899e8d965c67af3a5ce9 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 20:20:17 -0400 Subject: fixed typos --- docs/narr/templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 4ac01c96e..5656026ae 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -718,7 +718,7 @@ Using def inside Mako Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To use a def inside a Mako template, given a :term:`Mako` template file named -``foo.mak`` and a def named ``bar``, you can configure the template as a +``foo.mak`` and a defname ``bar``, you can configure the template as a :term:`renderer` like so: .. code-block:: python -- cgit v1.2.3 From c2d65ff71dac6a9b15119db8c2fb09884f4060e3 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 20:22:34 -0400 Subject: fixed typos --- docs/narr/templates.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 5656026ae..860010a1a 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -718,7 +718,7 @@ Using def inside Mako Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To use a def inside a Mako template, given a :term:`Mako` template file named -``foo.mak`` and a defname ``bar``, you can configure the template as a +``foo.mak`` and a def named ``bar``, you can configure the template as a :term:`renderer` like so: .. code-block:: python @@ -726,7 +726,7 @@ To use a def inside a Mako template, given a :term:`Mako` template file named from pyramid.view import view_config - @view_config(renderer='foo#defname.mak') + @view_config(renderer='foo#bar.mak') def my_view(request): return {'project':'my project'} -- cgit v1.2.3 From fe9316332511de945924effd8a049db79f34e761 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 19 Jun 2012 21:42:44 -0400 Subject: point at pyramid_beaker docs rather than its github page --- docs/narr/sessions.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 6ff9e3dea..1aa1b6341 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -151,13 +151,12 @@ Using Alternate Session Factories --------------------------------- At the time of this writing, exactly one alternate session factory -implementation exists, named ``pyramid_beaker``. This is a session -factory that uses the `Beaker `_ library -as a backend. Beaker has support for file-based sessions, database -based sessions, and encrypted cookie-based sessions. See -`http://github.com/Pylons/pyramid_beaker -`_ for more information about -``pyramid_beaker``. +implementation exists, named ``pyramid_beaker``. This is a session factory +that uses the `Beaker `_ library as a backend. +Beaker has support for file-based sessions, database based sessions, and +encrypted cookie-based sessions. See `the pyramid_beaker documentation +`_ for more +information about ``pyramid_beaker``. .. index:: single: session factory (custom) -- cgit v1.2.3 From cabcd3788beceb9a41eca2414068ab32aaf3340e Mon Sep 17 00:00:00 2001 From: David Gay Date: Sun, 29 Jul 2012 19:05:07 -0400 Subject: prettify CSS stored in docs tutorials --- docs/narr/MyProject/myproject/static/pylons.css | 435 ++++++++++++++++++++---- 1 file changed, 371 insertions(+), 64 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/static/pylons.css b/docs/narr/MyProject/myproject/static/pylons.css index c54499ddd..4b1c017cd 100644 --- a/docs/narr/MyProject/myproject/static/pylons.css +++ b/docs/narr/MyProject/myproject/static/pylons.css @@ -1,65 +1,372 @@ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ -vertical-align:baseline;background:transparent;} -body{line-height:1;} -ol,ul{list-style:none;} -blockquote,q{quotes:none;} -blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -:focus{outline:0;} -ins{text-decoration:none;} -del{text-decoration:line-through;} -table{border-collapse:collapse;border-spacing:0;} -sub{vertical-align:sub;font-size:smaller;line-height:normal;} -sup{vertical-align:super;font-size:smaller;line-height:normal;} -ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} -ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} -li{display:list-item;} -ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} -.hidden{display:none;} -p{line-height:1.5em;} -h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} -h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} -html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;} -a{color:#1b61d6;text-decoration:none;} -a:hover{color:#e88f00;text-decoration:underline;} -body h1, -body h2, -body h3, -body h4, -body h5, -body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} -#wrap{min-height:100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} -#header{background:#000000;top:0;font-size:14px;} -#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} -.header,.footer{width:750px;margin-right:auto;margin-left:auto;} -.wrapper{width:100%} -#top,#top-small,#bottom{width:100%;} -#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} -#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} -#bottom{color:#222;background-color:#ffffff;} -.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} -.top{padding-top:40px;} -.top-small{padding-top:10px;} -#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} -.app-welcome{margin-top:25px;} -.app-name{color:#000000;font-weight:bold;} -.bottom{padding-top:50px;} -#left{width:350px;float:left;padding-right:25px;} -#right{width:350px;float:right;padding-left:25px;} -.align-left{text-align:left;} -.align-right{text-align:right;} -.align-center{text-align:center;} -ul.links{margin:0;padding:0;} -ul.links li{list-style-type:none;font-size:14px;} -form{border-style:none;} -fieldset{border-style:none;} -input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text],input[type=password]{width:205px;} -input[type=submit]{background-color:#ddd;font-weight:bold;} +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td +{ + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; /* 16px */ + vertical-align: baseline; + background: transparent; +} + +body +{ + line-height: 1; +} + +ol, ul +{ + list-style: none; +} + +blockquote, q +{ + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after +{ + content: ''; + content: none; +} + +:focus +{ + outline: 0; +} + +ins +{ + text-decoration: none; +} + +del +{ + text-decoration: line-through; +} + +table +{ + border-collapse: collapse; + border-spacing: 0; +} + +sub +{ + vertical-align: sub; + font-size: smaller; + line-height: normal; +} + +sup +{ + vertical-align: super; + font-size: smaller; + line-height: normal; +} + +ul, menu, dir +{ + display: block; + list-style-type: disc; + margin: 1em 0; + padding-left: 40px; +} + +ol +{ + display: block; + list-style-type: decimal-leading-zero; + margin: 1em 0; + padding-left: 40px; +} + +li +{ + display: list-item; +} + +ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl +{ + margin-top: 0; + margin-bottom: 0; +} + +ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir +{ + list-style-type: circle; +} + +ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir +{ + list-style-type: square; +} + +.hidden +{ + display: none; +} + +p +{ + line-height: 1.5em; +} + +h1 +{ + font-size: 1.75em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h2 +{ + font-size: 1.5em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h3 +{ + font-size: 1.25em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h4 +{ + font-size: 1em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +html, body +{ + width: 100%; + height: 100%; +} + +body +{ + margin: 0; + padding: 0; + background-color: #fff; + position: relative; + font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; +} + +a +{ + color: #1b61d6; + text-decoration: none; +} + +a:hover +{ + color: #e88f00; + text-decoration: underline; +} + +body h1, body h2, body h3, body h4, body h5, body h6 +{ + font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; + font-weight: 400; + color: #373839; + font-style: normal; +} + +#wrap +{ + min-height: 100%; +} + +#header, #footer +{ + width: 100%; + color: #fff; + height: 40px; + position: absolute; + text-align: center; + line-height: 40px; + overflow: hidden; + font-size: 12px; + vertical-align: middle; +} + +#header +{ + background: #000; + top: 0; + font-size: 14px; +} + +#footer +{ + bottom: 0; + background: #000 url(footerbg.png) repeat-x 0 top; + position: relative; + margin-top: -40px; + clear: both; +} + +.header, .footer +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.wrapper +{ + width: 100%; +} + +#top, #top-small, #bottom +{ + width: 100%; +} + +#top +{ + color: #000; + height: 230px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#top-small +{ + color: #000; + height: 60px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#bottom +{ + color: #222; + background-color: #fff; +} + +.top, .top-small, .middle, .bottom +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.top +{ + padding-top: 40px; +} + +.top-small +{ + padding-top: 10px; +} + +#middle +{ + width: 100%; + height: 100px; + background: url(middlebg.png) repeat-x; + border-top: 2px solid #fff; + border-bottom: 2px solid #b2b2b2; +} + +.app-welcome +{ + margin-top: 25px; +} + +.app-name +{ + color: #000; + font-weight: 700; +} + +.bottom +{ + padding-top: 50px; +} + +#left +{ + width: 350px; + float: left; + padding-right: 25px; +} + +#right +{ + width: 350px; + float: right; + padding-left: 25px; +} + +.align-left +{ + text-align: left; +} + +.align-right +{ + text-align: right; +} + +.align-center +{ + text-align: center; +} + +ul.links +{ + margin: 0; + padding: 0; +} + +ul.links li +{ + list-style-type: none; + font-size: 14px; +} + +form +{ + border-style: none; +} + +fieldset +{ + border-style: none; +} + +input +{ + color: #222; + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 12px; + line-height: 16px; +} + +input[type=text], input[type=password] +{ + width: 205px; +} + +input[type=submit] +{ + background-color: #ddd; + font-weight: 700; +} + /*Opera Fix*/ -body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before +{ + content: ""; + height: 100%; + float: left; + width: 0; + margin-top: -32767px; +} -- cgit v1.2.3 From c746ba4d0893ed7f4322492fdba548f3cd2a1ac5 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 3 Aug 2012 00:44:41 -0700 Subject: Adding helpful link to installing chapter from first app --- docs/narr/firstapp.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 1ca188d7e..a86826d86 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -8,7 +8,8 @@ Creating Your First :app:`Pyramid` Application In this chapter, we will walk through the creation of a tiny :app:`Pyramid` application. After we're finished creating the application, we'll explain in -more detail how it works. +more detail how it works. It assumes you already have :app:`Pyramid` installed. +If you do not, head over to the :ref:`installing_chapter` section. .. _helloworld_imperative: -- cgit v1.2.3 From 4aeb44f1ea912c3c3611bc677f654602488fedb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Fidosz?= Date: Fri, 3 Aug 2012 22:56:49 +0200 Subject: fixed indentation in narr/helloworld.py --- docs/narr/helloworld.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/helloworld.py b/docs/narr/helloworld.py index 7c26c8cdc..c01329af9 100644 --- a/docs/narr/helloworld.py +++ b/docs/narr/helloworld.py @@ -2,14 +2,15 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response + def hello_world(request): - return Response('Hello %(name)s!' % request.matchdict) + return Response('Hello %(name)s!' % request.matchdict) if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.add_view(hello_world, route_name='hello') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8080, app) - server.serve_forever() + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_view(hello_world, route_name='hello') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() -- cgit v1.2.3 From a0243a5264371a3e69fd188cee17c6fbfd8341a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Fidosz?= Date: Sun, 5 Aug 2012 10:33:07 +0200 Subject: fixed line numbers in firstapp --- docs/narr/firstapp.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index a86826d86..dbdc48549 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -127,7 +127,7 @@ defined imports and function definitions, placed within the confines of an .. literalinclude:: helloworld.py :linenos: - :lines: 8-13 + :lines: 9-15 Let's break this down piece-by-piece. @@ -136,7 +136,7 @@ Configurator Construction .. literalinclude:: helloworld.py :linenos: - :lines: 8-9 + :lines: 9-10 The ``if __name__ == '__main__':`` line in the code sample above represents a Python idiom: the code inside this if clause is not invoked unless the script @@ -169,7 +169,7 @@ Adding Configuration .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 10-11 + :lines: 11-12 First line above calls the :meth:`pyramid.config.Configurator.add_route` method, which registers a :term:`route` to match any URL path that begins @@ -189,7 +189,7 @@ WSGI Application Creation .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 12 + :lines: 13 After configuring views and ending configuration, the script creates a WSGI *application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` @@ -218,7 +218,7 @@ WSGI Application Serving .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 13 + :lines: 14 Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :mod:`wsgiref` ``make_server`` server -- cgit v1.2.3 From 0196b2a06ef66d2e8b33a03cc84373ab84ba44be Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 6 Aug 2012 00:48:29 -0400 Subject: add docs for third-party view predicates --- docs/narr/hooks.rst | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 332805152..bdd968362 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1232,3 +1232,97 @@ Displaying Tween Ordering The ``ptweens`` command-line utility can be used to report the current implict and explicit tween chains used by an application. See :ref:`displaying_tweens`. + +.. _registering_thirdparty_predicates: + +Adding A Third Party View or Route Predicate +-------------------------------------------- + +View and route predicates used during view configuration allow you to narrow +the set of circumstances under which a view or route will match. For +example, the ``request_method`` view predicate can be used to ensure a view +callable is only invoked when the request's method is ``POST``: + +.. code-block:: python + + @view_config(request_method='POST') + def someview(request): + ... + +Likewise, a similar predicate can be used as a *route* predicate: + +.. code-block:: python + + config.add_route('name', '/foo', request_method='POST') + +Many other built-in predicates exists (``request_param``, and others). You +can add third-party predicates to the list of available predicates by using +one of :meth:`pyramid.config.Configurator.add_view_predicate` or +:meth:`pyramid.config.Configurator.add_route_predicate`. The former adds a +view predicate, the latter a route predicate. + +When using one of those APIs, you pass a *name* and a *factory* to add a +predicate during Pyramid's configuration stage. For example: + +.. code-block:: python + + config.add_view_predicate('content_type', ContentTypePredicate) + +The above example adds a new predicate named ``content_type`` to the list of +available predicates for views. This will allow the following view +configuration statement to work: + +.. code-block:: python + :linenos: + + @view_config(content_type='File') + def aview(request): ... + +The first argument to :meth:`pyramid.config.Configurator.add_view_predicate`, +the name, is a string representing the name that is expected to be passed to +``view_config`` (or its imperative analogue ``add_view``). + +The second argument is a predicate factory. A predicate factory is most +often a class with a constructor (``__init__``), a ``text`` method, a +``phash`` method and a ``__call__`` method. For example: + +.. code-block:: python + :linenos: + + class ContentTypePredicate(object): + def __init__(self, val, config): + self.val + + def text(self): + return 'content_type = %s' % (self.val,) + + phash = text + + def __call__(self, context, request): + return getattr(context, 'content_type', None) == self.val + +The constructor of a predicate factory takes two arguments: ``val`` and +``config``. The ``val`` argument will be the argument passed to +``view_config`` (or ``add_view``). In the example above, it will be the +string ``File``. The second arg, ``config`` will be the Configurator +instance at the time of configuration. + +The ``text`` method must return a string. It should be useful to describe +the behavior of the predicate in error messages. + +The ``phash`` method must return a string or a sequence of strings. It's +most often the same as ``text``, as long as ``text`` uniquely describes the +predicate's name and the value passed to the constructor. If ``text`` is +more general, or doesn't describe things that way, ``phash`` should return a +string with the name and the value serialized. The result of ``phash`` is +not seen in output anywhere, it just informs the uniqueness constraints for +view configuration. + +The ``__call__`` method of a predicate factory must accept a resource +(``context``) and a request, and must return ``True`` or ``False``. It is +the "meat" of the predicate. + +You can use the same predicate factory as both a view predicate and as a +route predicate, but you'll need to call ``add_view_predicate`` and +``add_route_predicate`` separately with the same factory. + -- cgit v1.2.3 From cff71c316eb8b77b936bfc14a29d7ff9727edf70 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 6 Aug 2012 00:05:12 -0500 Subject: garden --- 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 bdd968362..9482bfcf8 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1291,7 +1291,7 @@ often a class with a constructor (``__init__``), a ``text`` method, a class ContentTypePredicate(object): def __init__(self, val, config): - self.val + self.val = val def text(self): return 'content_type = %s' % (self.val,) -- cgit v1.2.3 From 5664c428e22d73f8b4315b678588150d9bb2f0f5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 6 Aug 2012 11:10:15 -0400 Subject: add as-of-version notes --- docs/narr/hooks.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index bdd968362..73ee655ea 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1238,6 +1238,10 @@ implict and explicit tween chains used by an application. See Adding A Third Party View or Route Predicate -------------------------------------------- +.. note:: + + Third-party predicates are a feature new as of Pyramid 1.4. + View and route predicates used during view configuration allow you to narrow the set of circumstances under which a view or route will match. For example, the ``request_method`` view predicate can be used to ensure a view -- cgit v1.2.3 From 32178572428cafec64f73dc06cad5c02feaceba8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 11 Aug 2012 02:18:21 -0600 Subject: get heading levels right --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b5fa6a9f7..7c0f9223f 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -803,7 +803,7 @@ within a function called when another user uses the See also :ref:`add_directive`. Programmatic Introspection --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ If you're building a large system that other users may plug code into, it's useful to be able to get an enumeration of what code they plugged in *at @@ -831,7 +831,7 @@ callable: See also :ref:`using_introspection`. Python 3 Compatibility ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ Pyramid and most of its add-ons are Python 3 compatible. If you develop a Pyramid application today, you won't need to worry that five years from now -- cgit v1.2.3 From bad3d5184bbc9a8bc42e9d15a611b7f9f84d8131 Mon Sep 17 00:00:00 2001 From: Kees Hink Date: Tue, 14 Aug 2012 18:45:04 +0300 Subject: Typo pwteens -> ptweens --- docs/narr/commandline.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index af53c1f78..3bdf8c5cd 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -349,7 +349,7 @@ setting) orderings using the ``ptweens`` command. Tween factories will show up represented by their standard Python dotted name in the ``ptweens`` output. -For example, here's the ``pwteens`` command run against a system +For example, here's the ``ptweens`` command run against a system configured without any explicit tweens: .. code-block:: text @@ -367,7 +367,7 @@ configured without any explicit tweens: 1 pyramid.tweens.excview_tween_factory excview - - MAIN -Here's the ``pwteens`` command run against a system configured *with* +Here's the ``ptweens`` command run against a system configured *with* explicit tweens defined in its ``development.ini`` file: .. code-block:: text -- cgit v1.2.3 From 2c25342383eed7b10e349b2396eed08d332cfb80 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 16 Aug 2012 02:28:43 -0500 Subject: docs-deprecated set_request_property --- docs/narr/advconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 2949dc808..0ad2fdc95 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -296,7 +296,7 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.add_renderer`, :meth:`~pyramid.config.Configurator.set_request_factory`, :meth:`~pyramid.config.Configurator.set_session_factory`, -:meth:`~pyramid.config.Configurator.set_request_property`, +:meth:`~pyramid.config.Configurator.set_request_method`, :meth:`~pyramid.config.Configurator.set_root_factory`, :meth:`~pyramid.config.Configurator.set_view_mapper`, :meth:`~pyramid.config.Configurator.set_authentication_policy`, -- cgit v1.2.3 From 9cdb28614e558a886cb75d1d9ce9689621199722 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 16 Aug 2012 11:25:23 -0400 Subject: readd set_request_property to docs (just so when people run across it in in-the-wild code they're not totally confused); we'll remove it later --- docs/narr/advconfig.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 0ad2fdc95..b1ea652d6 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -297,6 +297,7 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.set_request_factory`, :meth:`~pyramid.config.Configurator.set_session_factory`, :meth:`~pyramid.config.Configurator.set_request_method`, +:meth:`~pyramid.config.Configurator.set_request_property`, :meth:`~pyramid.config.Configurator.set_root_factory`, :meth:`~pyramid.config.Configurator.set_view_mapper`, :meth:`~pyramid.config.Configurator.set_authentication_policy`, -- cgit v1.2.3 From 75a5885afc250db7f19a4c80d947b2bef5826356 Mon Sep 17 00:00:00 2001 From: Ronan Amicel Date: Thu, 23 Aug 2012 17:02:22 +0300 Subject: Fixed typo in docs/narr/views.rst --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index f6ee9a8d5..9e41464a6 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -177,7 +177,7 @@ HTTP Exceptions ~~~~~~~~~~~~~~~ All classes documented in the :mod:`pyramid.httpexceptions` module documented -as inheriting from the :class:`pryamid.httpexceptions.HTTPException` are +as inheriting from the :class:`pyramid.httpexceptions.HTTPException` are :term:`http exception` objects. Instances of an HTTP exception object may either be *returned* or *raised* from within view code. In either case (return or raise) the instance will be used as as the view's response. -- cgit v1.2.3 From eb403ffe22501ae0546c02c7c24b54b5e3d1eb83 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 23 Aug 2012 09:57:35 -0500 Subject: exposed the serve_forever line to the helloworld narrative --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index dbdc48549..ccaa6e9e2 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -218,7 +218,7 @@ WSGI Application Serving .. ignore-next-block .. literalinclude:: helloworld.py :linenos: - :lines: 14 + :lines: 14-15 Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :mod:`wsgiref` ``make_server`` server -- cgit v1.2.3 From 95f766bc7c380797c569da464f1f41d12b05bdbe Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 25 Aug 2012 00:10:46 -0400 Subject: Subscriber predicates: - Add ``add_subscriber_predicate`` method to Configurator. - Allow ``add_subscriber`` and ``subscriber`` venusian decorator to accept ``**predicates`` arguments. - Document subscriber predicate feature. - Share more code between view, route, and subscriber related method wrt predicates. --- docs/narr/hooks.rst | 122 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 112 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 2c15cd690..96fa77a07 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1235,17 +1235,23 @@ implict and explicit tween chains used by an application. See .. _registering_thirdparty_predicates: -Adding A Third Party View or Route Predicate --------------------------------------------- +Adding A Third Party View, Route, or Subscriber Predicate +--------------------------------------------------------- .. note:: - Third-party predicates are a feature new as of Pyramid 1.4. + Third-party view, route, and subscriber predicates are a feature new as of + Pyramid 1.4. -View and route predicates used during view configuration allow you to narrow -the set of circumstances under which a view or route will match. For -example, the ``request_method`` view predicate can be used to ensure a view -callable is only invoked when the request's method is ``POST``: +.. _view_and_route_predicates: + +View and Route Predicates +~~~~~~~~~~~~~~~~~~~~~~~~~ + +View and route predicates used during configuration allow you to narrow the +set of circumstances under which a view or route will match. For example, +the ``request_method`` view predicate can be used to ensure a view callable +is only invoked when the request's method is ``POST``: .. code-block:: python @@ -1286,9 +1292,9 @@ The first argument to :meth:`pyramid.config.Configurator.add_view_predicate`, the name, is a string representing the name that is expected to be passed to ``view_config`` (or its imperative analogue ``add_view``). -The second argument is a predicate factory. A predicate factory is most -often a class with a constructor (``__init__``), a ``text`` method, a -``phash`` method and a ``__call__`` method. For example: +The second argument is a view or route predicate factory. A view or route +predicate factory is most often a class with a constructor (``__init__``), a +``text`` method, a ``phash`` method and a ``__call__`` method. For example: .. code-block:: python :linenos: @@ -1330,3 +1336,99 @@ You can use the same predicate factory as both a view predicate and as a route predicate, but you'll need to call ``add_view_predicate`` and ``add_route_predicate`` separately with the same factory. +.. _subscriber_predicates: + +Subscriber Predicates +~~~~~~~~~~~~~~~~~~~~~ + +Subscriber predicates work almost exactly like view and route predicates. +They narrow the set of circumstances in which a subscriber will be called. +There are several minor differences between a subscriber predicate and a +view/route predicate: + +- There are no default subscriber predicates. You must register one to use + one. + +- The ``__call__`` method of a subscriber predicate accepts a single + ``event`` object instead of a ``context`` and a ``request``. + +- Not every subscriber predicate can be used with every event type. Some + subscriber predicates will assume a certain event type. + +Here's an example of a subscriber predicate that can be used in conjunction +with a subscriber that subscribes to the :class:`pyramid.events.NewReqest` +event type. + +.. code-block:: python + :linenos: + + class RequestPathStartsWith(object): + def __init__(self, val, config): + self.val = val + + def text(self): + return 'path_startswith = %s' % (self.val,) + + phash = text + + def __call__(self, event): + return event.request.path.startswith(self.val) + +Once you've created a subscriber predicate, it may registered via +:meth:`pyramid.config.Configurator.add_subscriber_predicate`. For example: + +.. code-block:: python + + config.add_subscriber_predicate( + 'request_path_startswith', RequestPathStartsWith) + +Once a subscriber predicate is registered, you can use it in a call to +:meth:`pyramid.config.Configurator.add_subscriber` or to +:class:`pyramid.events.subscriber`. Here's an example of using the +previously registered ``request_path_startswith`` predicate in a call to +:meth:`~pyramid.config.Configurator.add_subscriber`: + +.. code-block:: python + :linenos: + + # define a subscriber in your code + + def yosubscriber(event): + event.request.yo = 'YO!' + + # and at configuration time + + config.add_subscriber(yosubscriber, NewRequest, + request_path_startswith='/add_yo') + +Here's the same subscriber/predicate/event-type combination used via +:class:`~pyramid.events.subscriber`. + +.. code-block:: python + :linenos: + + from pyramid.events import subscriber + + @subscriber(NewRequest, request_path_startswith='/add_yo') + def yosubscriber(event): + event.request.yo = 'YO!' + +In either of the above configurations, the ``yosubscriber`` callable will +only be called if the request path starts with ``/add_yo``. Otherwise the +event subscriber will not be called. + +Note that the ``request_path_startswith`` subscriber you defined can be used +with events that have a ``request`` attribute, but not ones that do not. So, +for example, the predicate can be used with subscribers registered for +:class:`pyramid.events.NewRequest` and :class:`pyramid.events.ContextFound` +events, but it cannot be used with subscribers registered for +:class:`pyramid.events.ApplicationCreated` because the latter type of event +has no ``request`` attribute. The point being: unlike route and view +predicates, not every type of subscriber predicate will necessarily be +applicable for use 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. + + + -- cgit v1.2.3 From eecaa867d72d06fec45dd151fcd2e93d02927cef Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 29 Aug 2012 16:07:54 -0400 Subject: add docs about chameleon zpt macro feature --- docs/narr/templates.rst | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 860010a1a..adc671766 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -534,6 +534,30 @@ And ``templates/mytemplate.pt`` might look like so: + +Using A Chameleon Macro Name Within a Chameleon ZPT Template +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sommetime you'd like to render a macro inside of a Chameleon ZPT template +instead of the full Chameleon ZPT template. To render the content of a +``define-macro`` field inside a Chameleon ZPT template, given a Chameleon +template file named ``foo.pt`` and a macro named ``bar`` defined within it +(e.g. ``
    ...
    ``, you can configure the +template as a :term:`renderer` like so: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + @view_config(renderer='foo#bar.pt') + def my_view(request): + return {'project':'my project'} + +The above will render the ``bar`` macro from within the ``foo.pt`` template +instead of the entire template. + + .. index:: single: Chameleon text templates @@ -714,12 +738,13 @@ This template doesn't use any advanced features of Mako, only the :term:`renderer globals`. See the `the Mako documentation `_ to use more advanced features. -Using def inside Mako Templates -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Using A Mako def name Within a Renderer Name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To use a def inside a Mako template, given a :term:`Mako` template file named -``foo.mak`` and a def named ``bar``, you can configure the template as a -:term:`renderer` like so: +Sommetime you'd like to render a ``def`` inside of a Mako template instead of +the full Mako template. To render a def inside a Mako template, given a +:term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can +configure the template as a :term:`renderer` like so: .. code-block:: python :linenos: @@ -730,6 +755,9 @@ To use a def inside a Mako template, given a :term:`Mako` template file named def my_view(request): return {'project':'my project'} +The above will render the ``bar`` def from within the ``foo.mak`` template +instead of the entire template. + .. index:: single: automatic reloading of templates single: template automatic reload -- cgit v1.2.3 From 3a9232533139456c86483a9a53001b8500e433e9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 29 Aug 2012 16:10:26 -0400 Subject: wording --- docs/narr/templates.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index adc671766..4e6570865 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -535,8 +535,8 @@ And ``templates/mytemplate.pt`` might look like so: -Using A Chameleon Macro Name Within a Chameleon ZPT Template -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Using A Chameleon Macro Name Within a Renderer Name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sommetime you'd like to render a macro inside of a Chameleon ZPT template instead of the full Chameleon ZPT template. To render the content of a -- cgit v1.2.3 From cc8962d5da32bb30bbfc37c96286282b5ed751ff Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 29 Aug 2012 17:21:14 -0400 Subject: add newness markers --- docs/narr/renderers.rst | 4 +++- docs/narr/templates.rst | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 57b5bc65b..63287e2cd 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -306,7 +306,9 @@ See :class:`pyramid.renderers.JSON` and JSONP Renderer ~~~~~~~~~~~~~~ -.. note:: This feature is new in Pyramid 1.1. +.. note:: + + This feature is new in Pyramid 1.1. :class:`pyramid.renderers.JSONP` is a `JSONP `_ renderer factory helper which diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 4e6570865..656cf4773 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -557,6 +557,9 @@ template as a :term:`renderer` like so: The above will render the ``bar`` macro from within the ``foo.pt`` template instead of the entire template. +.. note:: + + This feature is new in Pyramid 1.4. .. index:: single: Chameleon text templates @@ -758,6 +761,10 @@ configure the template as a :term:`renderer` like so: The above will render the ``bar`` def from within the ``foo.mak`` template instead of the entire template. +.. note:: + + This feature is new in Pyramid 1.4. + .. index:: single: automatic reloading of templates single: template automatic reload -- cgit v1.2.3 From 3aeb794d49655e7cd81b7d553f0da275b0cde3a9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 29 Aug 2012 18:05:52 -0400 Subject: close paren --- docs/narr/templates.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 656cf4773..5930bb379 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -542,7 +542,7 @@ Sommetime you'd like to render a macro inside of a Chameleon ZPT template instead of the full Chameleon ZPT template. To render the content of a ``define-macro`` field inside a Chameleon ZPT template, given a Chameleon template file named ``foo.pt`` and a macro named ``bar`` defined within it -(e.g. ``
    ...
    ``, you can configure the +(e.g. ``
    ...
    ``), you can configure the template as a :term:`renderer` like so: .. code-block:: python @@ -554,8 +554,8 @@ template as a :term:`renderer` like so: def my_view(request): return {'project':'my project'} -The above will render the ``bar`` macro from within the ``foo.pt`` template -instead of the entire template. +The above will render only the ``bar`` macro defined within the ``foo.pt`` +template instead of the entire template. .. note:: -- cgit v1.2.3 From eb72972b51f58037d1bc1c2e5d81ee10abd82afe Mon Sep 17 00:00:00 2001 From: Ronan Amicel Date: Thu, 30 Aug 2012 22:49:01 +0300 Subject: Fixed broken link in docs/narr/testing.rst Fixed link to "Dive into Python" (previous mirror is down). --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 5ce2c8a66..50e9d5604 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -52,7 +52,7 @@ The suggested mechanism for unit and integration testing of a :app:`Pyramid` application is the Python :mod:`unittest` module. Although this module is named :mod:`unittest`, it is actually capable of driving both unit and integration tests. A good :mod:`unittest` tutorial is available within `Dive -Into Python `_ by Mark +Into Python `_ by Mark Pilgrim. :app:`Pyramid` provides a number of facilities that make unit, integration, -- cgit v1.2.3 From 023c88b67b907dd3682ef71216245609c9bbdbe1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 9 Sep 2012 23:01:06 -0400 Subject: rename set_request_method to add_request_method. closes #683 --- docs/narr/advconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index b1ea652d6..165cf7474 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -294,9 +294,9 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.add_view`, :meth:`~pyramid.config.Configurator.add_route`, :meth:`~pyramid.config.Configurator.add_renderer`, +:meth:`~pyramid.config.Configurator.add_request_method`, :meth:`~pyramid.config.Configurator.set_request_factory`, :meth:`~pyramid.config.Configurator.set_session_factory`, -:meth:`~pyramid.config.Configurator.set_request_method`, :meth:`~pyramid.config.Configurator.set_request_property`, :meth:`~pyramid.config.Configurator.set_root_factory`, :meth:`~pyramid.config.Configurator.set_view_mapper`, -- cgit v1.2.3 From b72ba1a98ebc6fc6c8d9a11ab1c340b89015e644 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 13 Sep 2012 02:05:19 -0400 Subject: add upgrading chapter, make docs render again --- docs/narr/templates.rst | 30 ++----- docs/narr/upgrading.rst | 229 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 24 deletions(-) create mode 100644 docs/narr/upgrading.rst (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 656cf4773..9a825c2ab 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -46,20 +46,6 @@ within the body of a view callable like so: {'foo':1, 'bar':2}, request=request) -.. warning:: - - Earlier iterations of this documentation - (pre-version-1.3) encouraged the application developer to use - ZPT-specific APIs such as - :func:`pyramid.chameleon_zpt.render_template_to_response` and - :func:`pyramid.chameleon_zpt.render_template` to render templates - directly. This style of rendering still works, but at least for - purposes of this documentation, those functions are deprecated. - Application developers are encouraged instead to use the functions - available in the :mod:`pyramid.renderers` module to perform - rendering tasks. This set of functions works to render templates - for all renderer extensions registered with :app:`Pyramid`. - The ``sample_view`` :term:`view callable` function above returns a :term:`response` object which contains the body of the ``templates/foo.pt`` template. In this case, the ``templates`` @@ -79,12 +65,12 @@ prefix on Windows. .. warning:: Only :term:`Chameleon` templates support defining a renderer for a - template relative to the location of the module where the view - callable is defined. Mako templates, and other templating system - bindings work differently. In particular, Mako templates use a - "lookup path" as defined by the ``mako.directories`` configuration - file instead of treating relative paths as relative to the current - view module. See :ref:`mako_templates`. + template relative to the location of the module where the view callable is + defined. Mako templates, and other templating system bindings work + differently. In particular, Mako templates use a "lookup path" as defined + by the ``mako.directories`` configuration file instead of treating + relative paths as relative to the current view module. See + :ref:`mako_templates`. The path can alternately be a :term:`asset specification` in the form ``some.dotted.package_name:relative/path``. This makes it possible to @@ -600,10 +586,6 @@ When the template is rendered, it will show: Hello, world! -If you'd rather use templates directly within a view callable (without -the indirection of using a renderer), see :ref:`chameleon_text_module` -for the API description. - See also :ref:`built_in_renderers` for more general information about renderers, including Chameleon text renderers. diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst new file mode 100644 index 000000000..19cc2f4e6 --- /dev/null +++ b/docs/narr/upgrading.rst @@ -0,0 +1,229 @@ +Upgrading Pyramid +================= + +When a new version of Pyramid is released, it will sometimes deprecate an old +feature or remove an already-deprecated feature. When features are removed +from Pyramid, applications that depend on those features will begin to break. +This chapter explains how to ensure your Pyramid applications keep working +when you upgrade the Pyramid version you're using. + +.. sidebar:: About Release Numbering + + Conventionally, application version numbering in Python is described as + ``major.minor.micro``. If your Pyramid version is "1.2.3", it means + you're running a version of Pyramid with the major version "1", the minor + version "2" and the micro version "3". A "major" release is one that + increments the first-dot number; 2.X.X might follow 1.X.X. A "minor" + release is one that increments the second-dot number; 1.3.X might follow + 1.2.X. A "micro" release is one that increments the third-dot number; + 1.2.3 might follow 1.2.2. In general, micro releases are "bugfix-only", + and contain no new features, minor releases contain new features but are + largely backwards compatible with older versions, and a major release + indicates a large set of backwards incompatibilities. + +The Pyramid core team is conservative when it comes to removing features. We +don't remove features unnecessarily, but we're human, and we make mistakes +which cause some features to be evolutionary dead ends. Though we are +willing to support dead-end features for some amount of time, some eventually +have to be removed when the cost of supporting them outweighs the benefit of +keeping them around, because each feature in Pyramid represents a certain +documentation and maintenance burden. + +Deprecation and Removal Policy +------------------------------ + +When a feature is scheduled for removal from Pyramid or any of its official +add-ons, the core development team takes these steps: + +- Using the feature will begin to generate a `DeprecationWarning`, indicating + the version in which the feature became deprecated. + +- A note is added to the documentation indicating that the feature is + deprecated. + +- A note is added to the :ref:`changelog` about the deprecation. + +When a deprecated feature is eventually removed: + +- The feature is removed. + +- A note is added to the :ref:`changelog` about the removal. + +Features are never removed in *micro* releases. They are only removed in +minor and major releases. Deprecated features are kept around for at least +*three* minor releases from the time the feature became deprecated. +Therefore, if a feature is added in Pyramid 1.0, but it's deprecated in +Pyramid 1.1, it will be kept around through all 1.1.X releases, all 1.2.X +releases and all 1.3.X releases. It will finally be removed in the first +1.4.X release. + +Sometimes features are "docs-deprecated" instead of formally deprecated. +This means that the feature will be kept around indefinitely, but it will be +removed from the documentation or a note will be added to the documentation +telling folks to use some other newer feature. This happens when the cost of +keeping an old feature around is very minimal and the support and +documentation burden is very low. For example, we might rename a function +that is an API without changing the arguments it accepts. In this case, +we'll often rename the function, and change the docs to point at the new +function name, but leave around a backwards compatibility alias to the old +function name so older code doesn't break. + +"Docs deprecated" features tend to work "forever", meaning that they won't be +removed, and they'll never generate a deprecation warning. However, such +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. + +Consulting the Change History +----------------------------- + +Your first line of defense against application failures caused by upgrading +to a newer Pyramid release is always to read the :ref:`changelog`. to find +the deprecations and removals for each release between the release you're +currently running and the one you wish to upgrade to. The change history +notes every deprecation within a ``Deprecation`` section and every removal +within a ``Backwards Incompatibilies`` section for each release. + +The change history often contains instructions for changing your code to +avoid deprecation warnings and how to change docs-deprecated spellings to +newer ones. You can follow along with each deprecation explanation in the +change history, simply doing a grep or other code search to your application, +using the change log examples to remediate each potential problem. + +.. _testing_under_new_release: + +Testing Your Application Under a New Pyramid Release +---------------------------------------------------- + +Once you've upgraded your application to a new Pyramid release and you've +remediated as much as possible by using the change history notes, you'll want +to run your application's tests (see :ref:`running_tests`) in such a way that +you can see DeprecationWarnings printed to the console when the tests run. + +.. code-block:: bash + + $ python -Wd setup.py test -q + +The ``-Wd`` argument is an argument that tells Python to print deprecation +warnings to the console. Note that the ``-Wd`` flag is only required for +Python 2.7 and better: Python versions 2.6 and older print deprecation +warnings to the console by default. See `the Python -W flag documentation +`_ for more +information. + +As your tests run, deprecation warnings will be printed to the console +explaining the deprecation and providing instructions about how to prevent +the deprecation warning from being issued. For example: + +.. code-block:: text + + $ python -Wd setup.py test -q + # .. elided ... + running build_ext + /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: DeprecationWarning: static: The "pyramid.view.static" class is deprecated as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with the "use_subpath" argument set to True. + from pyramid.view import static + . + ---------------------------------------------------------------------- + Ran 1 test in 0.014s + + OK + +In the above case, it's line #3 in the ``myproj.views`` module (``from +pyramid.view import static``) that is causing the problem: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + from pyramid.view import static + myview = static('static', 'static') + +The deprecation warning tells me how to fix it, so I can change the code to +do things the newer way: + +.. code-block:: python + :linenos: + + from pyramid.view. import view_config + + from pyramid.static import static_view + myview = static_view('static', 'static', use_subpath=True) + +When I run the tests again, the deprecation warning is no longer printed to +my console: + +.. code-block:: text + + $ python -Wd setup.py test -q + # .. elided ... + running build_ext + . + ---------------------------------------------------------------------- + Ran 1 test in 0.014s + + OK + + +My Application Doesn't Have Any Tests or Has Few Tests +------------------------------------------------------ + +If your application has no tests, or has only moderate test coverage, running +tests won't tell you very much, because the Pyramid codepaths that generate +deprecation warnings won't be executed. + +In this circumstance, you can start your application interactively under a +server run with the ``PYTHONWARNINGS`` environment variable set to +``default``. On UNIX, you can do that via: + +.. code-block:: bash + + $ PYTHONWARNINGS=default bin/pserve development.ini + +On Windows, you need to issue two commands: + +.. code-block:: bash + + C:\> set PYTHONWARNINGS=default + C:\> Scripts/pserve.exe development.ini + +At this point, it's ensured that deprecation warnings will be printed to the +console whenever a codepath is hit that generates one. You can then click +around in your application interactively to try to generate them, and +remediate as explained in :ref:`testing_under_new_release`. + +See `the PYTHONWARNINGS environment variable documentation +`_ or `the +Python -W flag documentation +`_ for more +information. + +Upgrading to the Very Latest Pyramid Release +-------------------------------------------- + +When you upgrade your application to the very most recent Pyramid release, +it's advisable to upgrade step-wise through each most recent minor release, +beginning with the one that you know your application currently runs under, +and ending on the most recent release. For example, if your application is +running in production on Pyramid 1.2.1, and the most recent Pyramid 1.3 +release is Pyramid 1.3.3, and the most recent Pyramid release is 1.4.4, it's +advisable to do this: + +- Upgrade your environment to the most recent 1.2 release. For example, the + most recent 1.2 release might be 1.2.3, so upgrade to it. Then run your + application's tests under 1.2.3 as described in + :ref:`testing_under_new_release`. Note any deprecation warnings and + remediate. + +- Upgrade to the most recent 1.3 release, 1.3.3. Run your application's + tests, note any deprecation warnings and remediate. + +- Upgrade to 1.4.4. Run your application's tests, note any deprecation + warnings and remediate. + +If you skip testing your application under each minor release (for example if +you upgrade directly from 1.2.1 to 1.4.4), you might miss a deprecation +warning and waste more time trying to figure out an error caused by a feature +removal than it would take to upgrade stepwise through each minor release. + + -- cgit v1.2.3 From 1b58346235c9d2284dde4872734f65e35eb9fdde Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 13 Sep 2012 02:08:21 -0400 Subject: docs rendering --- docs/narr/upgrading.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index 19cc2f4e6..e52c129fa 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -120,7 +120,10 @@ the deprecation warning from being issued. For example: $ python -Wd setup.py test -q # .. elided ... running build_ext - /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: DeprecationWarning: static: The "pyramid.view.static" class is deprecated as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with the "use_subpath" argument set to True. + /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: + DeprecationWarning: static: The "pyramid.view.static" class is deprecated + as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with + the "use_subpath" argument set to True. from pyramid.view import static . ---------------------------------------------------------------------- -- cgit v1.2.3 From c3b9c428b9fd1b90471deb393bfedf51372e6bab Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 13 Sep 2012 02:11:16 -0400 Subject: wording --- docs/narr/upgrading.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index e52c129fa..92f125c0a 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -1,11 +1,11 @@ Upgrading Pyramid ================= -When a new version of Pyramid is released, it will sometimes deprecate an old -feature or remove an already-deprecated feature. When features are removed -from Pyramid, applications that depend on those features will begin to break. -This chapter explains how to ensure your Pyramid applications keep working -when you upgrade the Pyramid version you're using. +When a new version of Pyramid is released, it will sometimes deprecate a +feature or remove a feature that was deprecated in an older release. When +features are removed from Pyramid, applications that depend on those features +will begin to break. This chapter explains how to ensure your Pyramid +applications keep working when you upgrade the Pyramid version you're using. .. sidebar:: About Release Numbering -- cgit v1.2.3 From d501b7cb23a26b85882d01deb1c8381acd75447e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 15 Sep 2012 04:17:12 -0400 Subject: point at cookbook --- docs/narr/advconfig.rst | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 165cf7474..ad22a82c9 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -414,3 +414,10 @@ constraints: the routes they imply require relative ordering. Such ordering constraints are not absolved by two-phase configuration. Routes are still added in configuration execution order. +More Information +---------------- + +For more information, see the article entitled `"A Whirlwind Rour of Advanced +Configuration Tactics" +`_ +in the Pyramid Cookbook. -- cgit v1.2.3 From 54d3e3ecf8929f90373669b9682b9db3b4ce3290 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 15 Sep 2012 23:24:48 -0400 Subject: add a whatsnew-1.4 document --- docs/narr/upgrading.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index 92f125c0a..839f59c35 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -1,3 +1,5 @@ +.. _upgrading_chapter: + Upgrading Pyramid ================= -- cgit v1.2.3 From 37d2c224b804dfebe9ee217c7a536364eacdee15 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:25:17 -0400 Subject: docs and test --- docs/narr/subrequest.rst | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 docs/narr/subrequest.rst (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst new file mode 100644 index 000000000..6ed679579 --- /dev/null +++ b/docs/narr/subrequest.rst @@ -0,0 +1,143 @@ +.. index:: + single: subrequest + +.. _subrequest_chapter: + +Invoking a Subrequest +===================== + +.. warning:: + + This feature was added in Pyramid 1.4a1. + +:app:`Pyramid` allows you to invoke a subrequest at any point during the +processing of a request. Invoking a subrequest allows you to obtain a +:term:`response` object from a view callable within your :app:`Pyramid` +application while you're executing a different view callable within the same +application. + +Here's an example application which uses a subrequest: + +.. code-block:: python + + from wsgiref.simple_server import make_server + from pyramid.config import Configurator + from pyramid.request import Request + + def view_one(request): + subreq = Request.blank('/view_two') + response = request.subrequest(subreq) + return response + + def view_two(request): + request.response.body = 'This came from view_two' + return request.response + + if __name__ == '__main__': + config = Configurator() + config.add_route('one', '/view_one') + config.add_route('two', '/view_two') + config.add_view(view_one, route_name='one') + config.add_view(view_two, route_name='two') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() + +When ``/view_one`` is visted in a browser, the text printed in the browser +pane will be ``This came from view_two``. The ``view_one`` view used the +:meth:`pyramid.request.Request.subrequest` API to obtain a response from +another view (``view_two``) within the same application when it executed. It +did so by constructing a new request that had a URL that it knew would match +the ``view_two`` view registration, and passed that new request along to +:meth:`pyramid.request.Request.subrequest`. The ``view_two`` view callable +was invoked, and it returned a response. The ``view_one`` view callable then +simply returned the response it obtained from the ``view_two`` view callable. + +Note that it doesn't matter if the view callable invoked via a subrequest +actually returns a literal Response object. Any view callable that uses a +renderer or which returns an object that can be interpreted by a response +adapter will work too: + +.. code-block:: python + + from wsgiref.simple_server import make_server + from pyramid.config import Configurator + from pyramid.request import Request + + def view_one(request): + subreq = Request.blank('/view_two') + response = request.subrequest(subreq) + return response + + def view_two(request): + return 'This came from view_two' + + if __name__ == '__main__': + config = Configurator() + config.add_route('one', '/view_one') + config.add_route('two', '/view_two') + config.add_view(view_one, route_name='one') + config.add_view(view_two, route_name='two', renderer='string') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() + +Being able to unconditionally obtain a response object by invoking a view +callable indirectly is the main advantage to using +:meth:`pyramid.request.Request.subrequest` instead of simply importing it and +executing it directly. Note that there's not much advantage to invoking a +view using a subrequest if you *can* invoke a view callable directly. It's +much slower to use a subrequest. + +The :meth:`pyramid.request.Request.subrequest` API accepts two arguments: a +positional argument ``request`` that must be provided, and and ``use_tweens`` +keyword argument that is optional; it defaults to ``False``. + +The ``request`` object passed to the API must be an object that implements +the Pyramid request interface (such as a :class:`pyramid.request.Request` +instance). If ``use_tweens`` is ``True``, the request will be sent to the +:term:`tween` in the tween stack closest to the request ingress. If +``use_tweens`` is ``False``, the request will be sent to the main router +handler, and no tweens will be invoked. It's usually best to not invoke any +tweens when executing a subrequest, because the original request will invoke +any tween logic as necessary. The :meth:`pyramid.request.Request.subrequest` +function also: + +- manages the threadlocal stack so that + :func:`~pyramid.threadlocal.get_current_request` and + :func:`~pyramid.threadlocal.get_current_registry` work during a request + (they will return the subrequest instead of the original request) + +- Adds a ``registry`` attribute and a ``subrequest`` attribute to the request + object it's handed. + +- sets request extensions (such as those added via + :meth:`~pyramid.config.Configurator.add_request_method` or + :meth:`~pyramid.config.Configurator.set_request_property`) on the subrequest + object passed as ``request`` + +- causes a :class:`~pyramid.event.NewRequest` event to be sent at the + beginning of request processing. + +- causes a :class:`~pyramid.event.ContextFound` event to be sent when a + context resource is found. + +- causes a :class:`~pyramid.event.NewResponse` event to be sent when the + Pyramid application returns a response. + +- Calls any :term:`response callback` functions defined within the subrequest's + lifetime if a response is obtained from the Pyramid application. + +- Calls any :term:`finished callback` functions defined within the subrequest's + lifetime. + +It's a poor idea to use the original ``request`` object as an argument to +:meth:`~pyramid.request.Request.subrequest`. You should construct a new +request instead as demonstrated in the above example, using +:meth:`pyramid.request.Request.blank`. Once you've constructed a request +object, you'll need to massage the it to match the view callable you'd like +to be executed during the subrequest. This can be done by adjusting the +subrequest's URL, its headers, its request method, and other attributes. See +the documentation for :class:`pyramid.request.Request` to understand how to +massage your new request object into something that will match the view you'd +like to call via a subrequest. -- cgit v1.2.3 From 3f3917f9c70ddc83263e440a8bc781bacb33bb6e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:27:00 -0400 Subject: moar --- docs/narr/subrequest.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 6ed679579..5067fa890 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -84,10 +84,10 @@ adapter will work too: Being able to unconditionally obtain a response object by invoking a view callable indirectly is the main advantage to using -:meth:`pyramid.request.Request.subrequest` instead of simply importing it and -executing it directly. Note that there's not much advantage to invoking a -view using a subrequest if you *can* invoke a view callable directly. It's -much slower to use a subrequest. +:meth:`pyramid.request.Request.subrequest` instead of simply importing the +view callable and executing it directly. Note that there's not much +advantage to invoking a view using a subrequest if you *can* invoke a view +callable directly. It's much slower to use a subrequest. The :meth:`pyramid.request.Request.subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and ``use_tweens`` @@ -141,3 +141,7 @@ subrequest's URL, its headers, its request method, and other attributes. See the documentation for :class:`pyramid.request.Request` to understand how to massage your new request object into something that will match the view you'd like to call via a subrequest. + +We've demonstrated use of a subrequest from within a view callable, but you +can use the :meth:`~pyramid.request.Request.subrequest` API from within a +tween or an event handler as well. -- cgit v1.2.3 From ab84e1038b9004c978ea49829c2d1b7a2d48d3d4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:30:28 -0400 Subject: explain --- docs/narr/subrequest.rst | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 5067fa890..045cec279 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -82,6 +82,11 @@ adapter will work too: server = make_server('0.0.0.0', 8080, app) server.serve_forever() +Even though the ``view_two`` view callable returned a string, it was invoked +in such a way that the ``string`` renderer associated with the view +registration that was found turned it into a "real" response object for +consumption by ``view_one``. + Being able to unconditionally obtain a response object by invoking a view callable indirectly is the main advantage to using :meth:`pyramid.request.Request.subrequest` instead of simply importing the -- cgit v1.2.3 From fef69b67c5d07f7b7294fe9b52f70fb9de22d17f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:31:40 -0400 Subject: explain --- docs/narr/subrequest.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 045cec279..8429fe7fe 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -92,7 +92,9 @@ callable indirectly is the main advantage to using :meth:`pyramid.request.Request.subrequest` instead of simply importing the view callable and executing it directly. Note that there's not much advantage to invoking a view using a subrequest if you *can* invoke a view -callable directly. It's much slower to use a subrequest. +callable directly. Subrequests are slower and are less convenient if you +actually do want just the literal information returned by a function that +happens to be a view callable. The :meth:`pyramid.request.Request.subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and ``use_tweens`` -- cgit v1.2.3 From 1e59ef41026d9754ac9dc21522dd68edfcaf18d7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:37:37 -0400 Subject: garden todo, add docs about exception handling --- docs/narr/subrequest.rst | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 8429fe7fe..39f985520 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -96,6 +96,36 @@ callable directly. Subrequests are slower and are less convenient if you actually do want just the literal information returned by a function that happens to be a view callable. +Note that if a view callable invoked by a subrequest raises an exception, the +exception will usually bubble up to the invoking code: + +.. code-block:: python + + from wsgiref.simple_server import make_server + from pyramid.config import Configurator + from pyramid.request import Request + + def view_one(request): + subreq = Request.blank('/view_two') + response = request.subrequest(subreq) + return response + + def view_two(request): + raise ValueError('foo') + + if __name__ == '__main__': + config = Configurator() + config.add_route('one', '/view_one') + config.add_route('two', '/view_two') + config.add_view(view_one, route_name='one') + config.add_view(view_two, route_name='two', renderer='string') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() + +In the above application, the call to ``request.subrequest(subreq)`` will +raise a :exc:`ValueError` exception instead of obtaining a "500" response. + The :meth:`pyramid.request.Request.subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and ``use_tweens`` keyword argument that is optional; it defaults to ``False``. -- cgit v1.2.3 From b895defdcecbf9d758ad92b1bbf6a49f21620c8a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:39:26 -0400 Subject: wording --- docs/narr/subrequest.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 39f985520..4f132f72f 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -124,7 +124,8 @@ exception will usually bubble up to the invoking code: server.serve_forever() In the above application, the call to ``request.subrequest(subreq)`` will -raise a :exc:`ValueError` exception instead of obtaining a "500" response. +actually raise a :exc:`ValueError` exception instead of retrieving a "500" +response from the attempted invocation of ``view_two``. The :meth:`pyramid.request.Request.subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and ``use_tweens`` -- cgit v1.2.3 From 64452edb014423054d1bbc0bb3ed8a3e47b6f611 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 03:54:08 -0400 Subject: rename subrequest to invoke_subrequest --- docs/narr/subrequest.rst | 53 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 4f132f72f..bd50b6053 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -26,7 +26,7 @@ Here's an example application which uses a subrequest: def view_one(request): subreq = Request.blank('/view_two') - response = request.subrequest(subreq) + response = request.invoke_subrequest(subreq) return response def view_two(request): @@ -45,13 +45,14 @@ Here's an example application which uses a subrequest: When ``/view_one`` is visted in a browser, the text printed in the browser pane will be ``This came from view_two``. The ``view_one`` view used the -:meth:`pyramid.request.Request.subrequest` API to obtain a response from -another view (``view_two``) within the same application when it executed. It -did so by constructing a new request that had a URL that it knew would match -the ``view_two`` view registration, and passed that new request along to -:meth:`pyramid.request.Request.subrequest`. The ``view_two`` view callable -was invoked, and it returned a response. The ``view_one`` view callable then -simply returned the response it obtained from the ``view_two`` view callable. +:meth:`pyramid.request.Request.invoke_subrequest` API to obtain a response +from another view (``view_two``) within the same application when it +executed. It did so by constructing a new request that had a URL that it +knew would match the ``view_two`` view registration, and passed that new +request along to :meth:`pyramid.request.Request.invoke_subrequest`. The +``view_two`` view callable was invoked, and it returned a response. The +``view_one`` view callable then simply returned the response it obtained from +the ``view_two`` view callable. Note that it doesn't matter if the view callable invoked via a subrequest actually returns a literal Response object. Any view callable that uses a @@ -66,7 +67,7 @@ adapter will work too: def view_one(request): subreq = Request.blank('/view_two') - response = request.subrequest(subreq) + response = request.invoke_subrequest(subreq) return response def view_two(request): @@ -89,8 +90,8 @@ consumption by ``view_one``. Being able to unconditionally obtain a response object by invoking a view callable indirectly is the main advantage to using -:meth:`pyramid.request.Request.subrequest` instead of simply importing the -view callable and executing it directly. Note that there's not much +:meth:`pyramid.request.Request.invoke_subrequest` instead of simply importing +the view callable and executing it directly. Note that there's not much advantage to invoking a view using a subrequest if you *can* invoke a view callable directly. Subrequests are slower and are less convenient if you actually do want just the literal information returned by a function that @@ -107,7 +108,7 @@ exception will usually bubble up to the invoking code: def view_one(request): subreq = Request.blank('/view_two') - response = request.subrequest(subreq) + response = request.invoke_subrequest(subreq) return response def view_two(request): @@ -123,13 +124,13 @@ exception will usually bubble up to the invoking code: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -In the above application, the call to ``request.subrequest(subreq)`` will -actually raise a :exc:`ValueError` exception instead of retrieving a "500" -response from the attempted invocation of ``view_two``. +In the above application, the call to ``request.invoke_subrequest(subreq)`` +will actually raise a :exc:`ValueError` exception instead of retrieving a +"500" response from the attempted invocation of ``view_two``. -The :meth:`pyramid.request.Request.subrequest` API accepts two arguments: a -positional argument ``request`` that must be provided, and and ``use_tweens`` -keyword argument that is optional; it defaults to ``False``. +The :meth:`pyramid.request.Request.invoke_subrequest` API accepts two +arguments: a positional argument ``request`` that must be provided, and and +``use_tweens`` keyword argument that is optional; it defaults to ``False``. The ``request`` object passed to the API must be an object that implements the Pyramid request interface (such as a :class:`pyramid.request.Request` @@ -138,16 +139,16 @@ instance). If ``use_tweens`` is ``True``, the request will be sent to the ``use_tweens`` is ``False``, the request will be sent to the main router handler, and no tweens will be invoked. It's usually best to not invoke any tweens when executing a subrequest, because the original request will invoke -any tween logic as necessary. The :meth:`pyramid.request.Request.subrequest` -function also: +any tween logic as necessary. The +:meth:`pyramid.request.Request.invoke_subrequest` function also: - manages the threadlocal stack so that :func:`~pyramid.threadlocal.get_current_request` and :func:`~pyramid.threadlocal.get_current_registry` work during a request (they will return the subrequest instead of the original request) -- Adds a ``registry`` attribute and a ``subrequest`` attribute to the request - object it's handed. +- Adds a ``registry`` attribute and a ``invoke_subrequest`` attribute (a + callable) to the request object it's handed. - sets request extensions (such as those added via :meth:`~pyramid.config.Configurator.add_request_method` or @@ -170,8 +171,8 @@ function also: lifetime. It's a poor idea to use the original ``request`` object as an argument to -:meth:`~pyramid.request.Request.subrequest`. You should construct a new -request instead as demonstrated in the above example, using +:meth:`~pyramid.request.Request.invoke_subrequest`. You should construct a +new request instead as demonstrated in the above example, using :meth:`pyramid.request.Request.blank`. Once you've constructed a request object, you'll need to massage the it to match the view callable you'd like to be executed during the subrequest. This can be done by adjusting the @@ -181,5 +182,5 @@ massage your new request object into something that will match the view you'd like to call via a subrequest. We've demonstrated use of a subrequest from within a view callable, but you -can use the :meth:`~pyramid.request.Request.subrequest` API from within a -tween or an event handler as well. +can use the :meth:`~pyramid.request.Request.invoke_subrequest` API from +within a tween or an event handler as well. -- cgit v1.2.3 From 7259e7e9f3d8f8eb70bcf782f622f8613f99a51d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 13:04:14 -0400 Subject: make use_tweens=True the default, add some more tests --- docs/narr/subrequest.rst | 83 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index bd50b6053..1c26da73a 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -91,14 +91,14 @@ consumption by ``view_one``. Being able to unconditionally obtain a response object by invoking a view callable indirectly is the main advantage to using :meth:`pyramid.request.Request.invoke_subrequest` instead of simply importing -the view callable and executing it directly. Note that there's not much +a view callable and executing it directly. Note that there's not much advantage to invoking a view using a subrequest if you *can* invoke a view callable directly. Subrequests are slower and are less convenient if you actually do want just the literal information returned by a function that happens to be a view callable. Note that if a view callable invoked by a subrequest raises an exception, the -exception will usually bubble up to the invoking code: +exception will usually be converted to a response: .. code-block:: python @@ -124,23 +124,69 @@ exception will usually bubble up to the invoking code: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -In the above application, the call to ``request.invoke_subrequest(subreq)`` -will actually raise a :exc:`ValueError` exception instead of retrieving a -"500" response from the attempted invocation of ``view_two``. +Because the exception view handling tween is generally in the tween list, if +we run the above code, the default :term:`exception view` will generate a +"500" error response, which will be returned to us within ``view_one``: a +Python exception will not be raised. The :meth:`pyramid.request.Request.invoke_subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and -``use_tweens`` keyword argument that is optional; it defaults to ``False``. +``use_tweens`` keyword argument that is optional; it defaults to ``True``. The ``request`` object passed to the API must be an object that implements the Pyramid request interface (such as a :class:`pyramid.request.Request` instance). If ``use_tweens`` is ``True``, the request will be sent to the :term:`tween` in the tween stack closest to the request ingress. If ``use_tweens`` is ``False``, the request will be sent to the main router -handler, and no tweens will be invoked. It's usually best to not invoke any -tweens when executing a subrequest, because the original request will invoke -any tween logic as necessary. The -:meth:`pyramid.request.Request.invoke_subrequest` function also: +handler, and no tweens will be invoked. + +In the example above, the call to +:meth:`~pyramid.request.Request.invoke_subrequest` will generally always +return a Response object, even when the view it invokes raises an exception, +because it uses the default ``use_tweens=True``. + +We can cause the subrequest to not be run through the tween stack by passing +``use_tweens=False`` to the call to +:meth:`~pyramid.request.Request.invoke_subrequest`, like this: + +.. code-block:: python + + from wsgiref.simple_server import make_server + from pyramid.config import Configurator + from pyramid.request import Request + + def view_one(request): + subreq = Request.blank('/view_two') + response = request.invoke_subrequest(subreq, use_tweens=False) + return response + + def view_two(request): + raise ValueError('foo') + + if __name__ == '__main__': + config = Configurator() + config.add_route('one', '/view_one') + config.add_route('two', '/view_two') + config.add_view(view_one, route_name='one') + config.add_view(view_two, route_name='two', renderer='string') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() + +In the above case, the call to ``request.invoke_subrequest(subreq)`` will +actually raise a :exc:`ValueError` exception instead of retrieving a "500" +response from the attempted invocation of ``view_two``, because the tween +which invokes an exception view to generate a response is never run. + +This is one of the major differences between specifying the +``use_tweens=True`` and ``use_tweens=False`` arguments to +:meth:`~pyramid.request.Request.invoke_subrequest`. ``use_tweens=True`` may +also imply invoking transaction commit/abort for the logic executed in the +subrequest if you've got ``pyramid_tm`` in the tween list, injecting debug +HTML if you've got ``pyramid_debugtoolbar`` in the tween list, and other +tween-related side effects as defined by your particular tween list. + +The :meth:`~pyramid.request.Request.invoke_subrequest` function also: - manages the threadlocal stack so that :func:`~pyramid.threadlocal.get_current_request` and @@ -176,11 +222,18 @@ new request instead as demonstrated in the above example, using :meth:`pyramid.request.Request.blank`. Once you've constructed a request object, you'll need to massage the it to match the view callable you'd like to be executed during the subrequest. This can be done by adjusting the -subrequest's URL, its headers, its request method, and other attributes. See -the documentation for :class:`pyramid.request.Request` to understand how to -massage your new request object into something that will match the view you'd -like to call via a subrequest. +subrequest's URL, its headers, its request method, and other attributes. The +documentation for :class:`pyramid.request.Request` exposes the methods you +should call and attributes you should set on the request you create to +massage it into something that will actually match the view you'd like to +call via a subrequest. We've demonstrated use of a subrequest from within a view callable, but you can use the :meth:`~pyramid.request.Request.invoke_subrequest` API from -within a tween or an event handler as well. +within a tween or an event handler as well. It's usually a poor idea to +invoke :meth:`~pyramid.request.Request.invoke_subrequest` from within a +tween, because tweens already by definition have access to a function that +will cause a subrequest (they are passed a ``handle`` function), but you can +do it. It's fine to invoke +:meth:`~pyramid.request.Request.invoke_subrequest` from within an event +handler, however. -- cgit v1.2.3 From 0966cfb8bd7ac43f8ce3b6dd903b03ae3bab8ac6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 13:08:42 -0400 Subject: explain how this works with the exception view --- docs/narr/subrequest.rst | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 1c26da73a..43876b45a 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -98,7 +98,8 @@ actually do want just the literal information returned by a function that happens to be a view callable. Note that if a view callable invoked by a subrequest raises an exception, the -exception will usually be converted to a response: +exception will usually be converted to a response if you have a +:term:`exception view` configured: .. code-block:: python @@ -114,20 +115,26 @@ exception will usually be converted to a response: def view_two(request): raise ValueError('foo') + def excview(request): + request.response.body = b'An exception was raised' + request.response.status_int = 500 + return request.response + if __name__ == '__main__': config = Configurator() config.add_route('one', '/view_one') config.add_route('two', '/view_two') config.add_view(view_one, route_name='one') config.add_view(view_two, route_name='two', renderer='string') + config.add_view(excview, context=Exception) app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever() Because the exception view handling tween is generally in the tween list, if -we run the above code, the default :term:`exception view` will generate a +we run the above code, the ``excview`` :term:`exception view` will generate a "500" error response, which will be returned to us within ``view_one``: a -Python exception will not be raised. +Python exception will not be raised. The :meth:`pyramid.request.Request.invoke_subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and @@ -143,7 +150,8 @@ handler, and no tweens will be invoked. In the example above, the call to :meth:`~pyramid.request.Request.invoke_subrequest` will generally always return a Response object, even when the view it invokes raises an exception, -because it uses the default ``use_tweens=True``. +because it uses the default ``use_tweens=True`` and a :term:`exception view` +is configured. We can cause the subrequest to not be run through the tween stack by passing ``use_tweens=False`` to the call to @@ -163,12 +171,18 @@ We can cause the subrequest to not be run through the tween stack by passing def view_two(request): raise ValueError('foo') + def excview(request): + request.response.body = b'An exception was raised' + request.response.status_int = 500 + return request.response + if __name__ == '__main__': config = Configurator() config.add_route('one', '/view_one') config.add_route('two', '/view_two') config.add_view(view_one, route_name='one') config.add_view(view_two, route_name='two', renderer='string') + config.add_view(excview, context=Exception) app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever() @@ -176,7 +190,8 @@ We can cause the subrequest to not be run through the tween stack by passing In the above case, the call to ``request.invoke_subrequest(subreq)`` will actually raise a :exc:`ValueError` exception instead of retrieving a "500" response from the attempted invocation of ``view_two``, because the tween -which invokes an exception view to generate a response is never run. +which invokes an exception view to generate a response is never run, and +therefore ``excview`` is never executed. This is one of the major differences between specifying the ``use_tweens=True`` and ``use_tweens=False`` arguments to -- cgit v1.2.3 From eab66f3e3f5c6ddbe88c5e632d78263a5c3d7cd4 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 14:36:44 -0400 Subject: update docs to recommend 2.7, add distribute-related instructions for python 3, add windows instructions for python 3, closes #653 --- docs/narr/install.rst | 213 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 156 insertions(+), 57 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 172cfd6d3..e8482a289 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -14,13 +14,13 @@ run :app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.6.6, - Python 2.7.2, and Python 3.2. :app:`Pyramid` does not run under any - version of Python before 2.6. + As of this writing, :app:`Pyramid` has been tested under Python 2.6.8, + Python 2.7.3, Python 3.2.3, and Python 3.3b1. :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, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on :term:`PyPy` (1.6+). +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 @@ -45,15 +45,15 @@ system's package manager is slightly different, but the "flavor" of them is usually the same. For example, on an Ubuntu Linux system, to use the system package -manager to install a Python 2.6 interpreter, use the following +manager to install a Python 2.7 interpreter, use the following command: .. code-block:: text - $ sudo apt-get install python2.6-dev + $ sudo apt-get install python2.7-dev Once these steps are performed, the Python interpreter will usually be -invokable via ``python2.6`` from a shell prompt. +invokable via ``python2.7`` from a shell prompt. .. index:: pair: install; Python (from source, UNIX) @@ -80,7 +80,7 @@ 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.6 interpreter from *source*, on the same system, +install a Python 2.7 interpreter from *source*, on the same system, using the following commands: .. code-block:: text @@ -90,15 +90,15 @@ using the following commands: [chrism@vitaminf ~]$ mkdir opt [chrism@vitaminf ~]$ cd tmp [chrism@vitaminf tmp]$ wget \ - http://www.python.org/ftp/python/2.6.4/Python-2.6.4.tgz - [chrism@vitaminf tmp]$ tar xvzf Python-2.6.4.tgz - [chrism@vitaminf tmp]$ cd Python-2.6.4 - [chrism@vitaminf Python-2.6.4]$ ./configure \ - --prefix=$HOME/opt/Python-2.6.4 - [chrism@vitaminf Python-2.6.4]$ make; make install + http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz + [chrism@vitaminf tmp]$ tar xvzf Python-2.7.3.tgz + [chrism@vitaminf tmp]$ cd Python-2.7.3 + [chrism@vitaminf Python-2.7.3]$ ./configure \ + --prefix=$HOME/opt/Python-2.7.3 + [chrism@vitaminf Python-2.7.3]$ make; make install Once these steps are performed, the Python interpreter will be -invokable via ``$HOME/opt/Python-2.6.4/bin/python`` from a shell +invokable via ``$HOME/opt/Python-2.7.3/bin/python`` from a shell prompt. .. index:: @@ -108,7 +108,7 @@ If You Don't Yet Have A Python Interpreter (Windows) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If your Windows system doesn't have a Python interpreter, you'll need -to install it by downloading a Python 2.6-series interpreter +to install it by downloading a Python 2.7-series interpreter executable from `python.org's download section `_ (the files labeled "Windows Installer"). Once you've downloaded it, double click on the @@ -119,7 +119,7 @@ extensions `_. .. warning:: After you install Python on Windows, you may need to add the - ``C:\Python26`` directory to your environment's ``Path`` in order + ``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`` @@ -141,39 +141,62 @@ 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. Invoke ``import -setuptools`` within the Python interpreter you'd like to run -:app:`Pyramid` under: +To set up a virtualenv in which to install :app:`Pyramid`, first ensure that +:term:`setuptools` or :term:`distribute` is installed. To do so, invoke +``import setuptools`` within the Python interpreter you'd like to run +:app:`Pyramid` under. + +Here's the output you'll expect if setuptools or distribute is already +installed: .. code-block:: text - [chrism@vitaminf pyramid]$ python - Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) - [GCC 4.4.3] on linux2 + [chrism@thinko docs]$ python2.7 + Python 2.7.3 (default, Aug 1 2012, 05:14:39) + [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import setuptools + >>> -If running ``import setuptools`` does not raise an ``ImportError``, it -means that setuptools is already installed into your Python -interpreter. If ``import setuptools`` fails, you will need to install -setuptools manually. Note that above we're using a Python 2.6-series -interpreter on Mac OS X; your output may differ if you're using a -later Python version or a different platform. - -If you are using a "system" Python (one installed by your OS -distributor or a 3rd-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. - -To install setuptools by hand, first download `ez_setup.py -`_ then invoke it -using the Python interpreter into which you want to install -setuptools. +Here's the output you can expect if setuptools or distribute is not already +installed: + +.. code-block:: text + + [chrism@thinko docs]$ python2.7 + Python 2.7.3 (default, Aug 1 2012, 05:14:39) + [GCC 4.6.3] on linux2 + Type "help", "copyright", "credits" or "license" for more information. + >>> import setutptools + Traceback (most recent call last): + File "", line 1, in + ImportError: No module named setutptools + >>> + +If ``import setuptools`` raises an :exc:`ImportError` as it does above, you +will need to install setuptools or distribute manually. Note that above +we're using a Python 2.7-series interpreter on Mac OS X; your output may +differ if you're using a later Python version or a different platform. + +If you are using a "system" Python (one installed by your OS distributor or a +3rd-party packager such as Fink or MacPorts), you can usually install the +setuptools or distribute 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 or distribute "by hand". Installing +setuptools or distribute "by hand" is always a reasonable thing to do, even +if your package manager already has a pre-chewed version of setuptools for +installation. + +If you're using Python 2, you'll want to install ``setuptools``. If you're +using Python 3, you'll want to install ``distribute``. Below we tell you how +to do both. + +Installing Setuptools On Python 2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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 @@ -188,16 +211,37 @@ the script. To remediate this, you may need to do: $ sudo python ez_setup.py +Installing Distribute On Python 3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``setuptools`` doesn't work under Python 3. Instead, you can use +``distribute``, which is a fork of setuptools that does work on Python 3. To +install it, first download `distribute_setup.py +`_ then invoke it using the +Python interpreter into which you want to install setuptools. + +.. code-block:: text + + $ python3 distribute_setup.py + +Once this command is invoked, distribute 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: + +.. code-block:: text + + $ sudo python3 distribute_setup.py + .. index:: pair: install; virtualenv Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -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. +Once you've got setuptools or distribute 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. .. code-block:: text @@ -269,35 +313,90 @@ complete, as it downloads and installs a number of dependencies. Installing :app:`Pyramid` on a Windows System ------------------------------------------------- -#. Install, or find `Python 2.6 - `_ for your system. +You can use Pyramid on Windows under Python 2 or under Python 3. Directions +for both versions are included below. + +Windows Using Python 2 +~~~~~~~~~~~~~~~~~~~~~~ + +#. Install, or find `Python 2.7 + `_ for your system. #. Install the `Python for Windows extensions `_. Make sure to - pick the right download for Python 2.6 and install it using the + pick the right download for Python 2.7 and install it using the same Python installation from the previous step. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py `_ and run it using - the ``python`` interpreter of your Python 2.6 installation using a + the ``python`` interpreter of your Python 2.7 installation using a command prompt: .. code-block:: text - c:\> c:\Python26\python ez_setup.py + c:\> c:\Python27\python ez_setup.py + +#. Use that Python's `bin/easy_install` to install `virtualenv`: + + .. code-block:: text + + c:\> c:\Python27\Scripts\easy_install virtualenv + +#. Use that Python's virtualenv to make a workspace: + + .. code-block:: text + + c:\> c:\Python27\Scripts\virtualenv --no-site-packages env + +#. Switch to the ``env`` directory: + + .. code-block:: text + + c:\> cd env + +#. (Optional) Consider using ``Scripts\activate.bat`` to make your shell + environment wired to use the virtualenv. + +#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies + installed: + + .. code-block:: text + + c:\env> Scripts\easy_install pyramid + +Windows Using Python 3 +~~~~~~~~~~~~~~~~~~~~~~ + +#. Install, or find `Python 3.2 + `_ for your system. + +#. Install the `Python for Windows extensions + `_. Make sure to + pick the right download for Python 3.2 and install it using the + same Python installation from the previous step. + +#. Install latest :term:`distribute` distribution into the Python you + obtained/installed/found in the step above: download `distribute_setup.py + `_ and run it using the + ``python`` interpreter of your Python 3.2 installation using a command + prompt: + + .. code-block:: text + + c:\> c:\Python32\python distribute_setup.py #. Use that Python's `bin/easy_install` to install `virtualenv`: .. code-block:: text - c:\> c:\Python26\Scripts\easy_install virtualenv + c:\> c:\Python32\Scripts\easy_install virtualenv #. Use that Python's virtualenv to make a workspace: .. code-block:: text - c:\> c:\Python26\Scripts\virtualenv --no-site-packages env + c:\> c:\Python32\Scripts\virtualenv --no-site-packages env #. Switch to the ``env`` directory: @@ -308,8 +407,8 @@ Installing :app:`Pyramid` on a Windows System #. (Optional) Consider using ``Scripts\activate.bat`` to make your shell environment wired to use the virtualenv. -#. Use ``easy_install`` pointed at the "current" index to get - :app:`Pyramid` and its direct dependencies installed: +#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies + installed: .. code-block:: text -- cgit v1.2.3 From dace59817bea583145f6ecf0910712b527ef2d0b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 21:42:25 -0400 Subject: describe how to restrict access to 127.0.0.1, closes #489 --- docs/narr/project.rst | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 1e2c225d2..b08948e43 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -286,11 +286,39 @@ Here's sample output from a run of ``pserve`` on UNIX: $ ../bin/pserve development.ini Starting server in PID 16601. - serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 + serving on http://0.0.0.0:6543 -By default, :app:`Pyramid` applications generated from a scaffold -will listen on TCP port 6543. You can shut down a server started this way by -pressing ``Ctrl-C``. +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://129.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 +``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 +example:: + + [server:main] + use = egg:waitress#main + host = 127.0.0.1 + port = 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]`` +section to ``port = 8080`` to run the server on port 8080 instead of +port 6543. + +You can shut down a server started this way by pressing ``Ctrl-C``. The default server used to run your Pyramid application when a project is created from a scaffold is named :term:`Waitress`. This server is what @@ -309,11 +337,6 @@ under the default server, it will almost certainly work under any other server in production if you eventually choose to use a different one. Don't worry about it right now. -You can change the port on which the server runs on by changing the -``development.ini`` file. For example, you can change the ``port = 6543`` -line in the ``development.ini`` file's ``[server:main]`` section to ``port = -8080`` to run the server on port 8080 instead of port 6543. - For more detailed information about the startup process, see :ref:`startup_chapter`. For more information about environment variables and configuration file settings that influence startup and runtime behavior, see -- cgit v1.2.3 From db2a03786ec76f2c6b7eaebb6f1b7c8b844d8c82 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 16 Sep 2012 22:32:26 -0400 Subject: make use_tweens=False the default --- docs/narr/subrequest.rst | 63 ++++++++++++++++++++++++++++++------------------ docs/narr/views.rst | 10 ++++++++ 2 files changed, 50 insertions(+), 23 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 43876b45a..89551ab35 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -55,9 +55,11 @@ request along to :meth:`pyramid.request.Request.invoke_subrequest`. The the ``view_two`` view callable. Note that it doesn't matter if the view callable invoked via a subrequest -actually returns a literal Response object. Any view callable that uses a +actually returns a *literal* Response object. Any view callable that uses a renderer or which returns an object that can be interpreted by a response -adapter will work too: +adapter when found and invoked via +:meth:`pyramid.request.Request.invoke_subrequest` will return a Response +object: .. code-block:: python @@ -97,8 +99,9 @@ callable directly. Subrequests are slower and are less convenient if you actually do want just the literal information returned by a function that happens to be a view callable. -Note that if a view callable invoked by a subrequest raises an exception, the -exception will usually be converted to a response if you have a +Note that, by default, if a view callable invoked by a subrequest raises an +exception, the exception will be raised to the caller of +:meth:`~pyramid.request.Request.invoke_subrequest` even if you have a :term:`exception view` configured: .. code-block:: python @@ -131,14 +134,16 @@ exception will usually be converted to a response if you have a server = make_server('0.0.0.0', 8080, app) server.serve_forever() -Because the exception view handling tween is generally in the tween list, if -we run the above code, the ``excview`` :term:`exception view` will generate a -"500" error response, which will be returned to us within ``view_one``: a -Python exception will not be raised. +When we run the above code and visit ``/view_one`` in a browser, the +``excview`` :term:`exception view` will *not* be executed. Instead, the call +to :meth:`~pyramid.request.Request.invoke_subrequest` will cause a +:exc:`ValueError` exception to be raised and a response will never be +generated. We can change this behavior; how to do so is described below in +our discussion of the ``use_tweens`` argument. The :meth:`pyramid.request.Request.invoke_subrequest` API accepts two arguments: a positional argument ``request`` that must be provided, and and -``use_tweens`` keyword argument that is optional; it defaults to ``True``. +``use_tweens`` keyword argument that is optional; it defaults to ``False``. The ``request`` object passed to the API must be an object that implements the Pyramid request interface (such as a :class:`pyramid.request.Request` @@ -148,13 +153,16 @@ instance). If ``use_tweens`` is ``True``, the request will be sent to the handler, and no tweens will be invoked. In the example above, the call to -:meth:`~pyramid.request.Request.invoke_subrequest` will generally always -return a Response object, even when the view it invokes raises an exception, -because it uses the default ``use_tweens=True`` and a :term:`exception view` -is configured. - -We can cause the subrequest to not be run through the tween stack by passing -``use_tweens=False`` to the call to +:meth:`~pyramid.request.Request.invoke_subrequest` will always raise an +exception. This is because it's using the default value for ``use_tweens``, +which is ``False``. You can pass ``use_tweens=True`` instead to ensure that +it will convert an exception to a Response if an :term:`exception view` is +configured instead of raising the exception. This because exception views +are called by the exception view :term:`tween` as described in +:ref:`exception_views` when any view raises an exception. + +We can cause the subrequest to be run through the tween stack by passing +``use_tweens=True`` to the call to :meth:`~pyramid.request.Request.invoke_subrequest`, like this: .. code-block:: python @@ -165,7 +173,7 @@ We can cause the subrequest to not be run through the tween stack by passing def view_one(request): subreq = Request.blank('/view_two') - response = request.invoke_subrequest(subreq, use_tweens=False) + response = request.invoke_subrequest(subreq, use_tweens=True) return response def view_two(request): @@ -187,11 +195,11 @@ We can cause the subrequest to not be run through the tween stack by passing server = make_server('0.0.0.0', 8080, app) server.serve_forever() -In the above case, the call to ``request.invoke_subrequest(subreq)`` will -actually raise a :exc:`ValueError` exception instead of retrieving a "500" -response from the attempted invocation of ``view_two``, because the tween -which invokes an exception view to generate a response is never run, and -therefore ``excview`` is never executed. +In the above case, the call to ``request.invoke_subrequest(subreq)`` will not +raise an exception. Instead, it will retrieve a "500" response from the +attempted invocation of ``view_two``, because the tween which invokes an +exception view to generate a response is run, and therefore ``excview`` is +executed. This is one of the major differences between specifying the ``use_tweens=True`` and ``use_tweens=False`` arguments to @@ -201,7 +209,8 @@ subrequest if you've got ``pyramid_tm`` in the tween list, injecting debug HTML if you've got ``pyramid_debugtoolbar`` in the tween list, and other tween-related side effects as defined by your particular tween list. -The :meth:`~pyramid.request.Request.invoke_subrequest` function also: +The :meth:`~pyramid.request.Request.invoke_subrequest` function also +unconditionally: - manages the threadlocal stack so that :func:`~pyramid.threadlocal.get_current_request` and @@ -222,6 +231,9 @@ The :meth:`~pyramid.request.Request.invoke_subrequest` function also: - causes a :class:`~pyramid.event.ContextFound` event to be sent when a context resource is found. +- Ensures that the user implied by the request passed has the necessary + authorization to invoke view callable before calling it. + - causes a :class:`~pyramid.event.NewResponse` event to be sent when the Pyramid application returns a response. @@ -231,6 +243,11 @@ The :meth:`~pyramid.request.Request.invoke_subrequest` function also: - Calls any :term:`finished callback` functions defined within the subrequest's lifetime. +The invocation of a subrequest has more or less exactly the same effect as +the invocation of a request received by the Pyramid router from a web client +when ``use_tweens=True``. When ``use_tweens=False``, the tweens are skipped +but all the other steps take place. + It's a poor idea to use the original ``request`` object as an argument to :meth:`~pyramid.request.Request.invoke_subrequest`. You should construct a new request instead as demonstrated in the above example, using diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 9e41464a6..07d018127 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -338,6 +338,16 @@ exception views which have a name will be ignored. Exception views can be configured with any view registration mechanism: ``@view_config`` decorator or imperative ``add_view`` styles. +.. note:: + + Pyramid's :term:`exception view` handling logic is implemented as a tween + factory function: :func:`pyramid.tweens.excview_tween_factory`. If + Pyramid exception view handling is desired, and tween factories are + specified via the ``pyramid.tweens`` configuration setting, the + :func:`pyramid.tweens.excview_tween_factory` function must be added to the + ``pyramid.tweens`` configuration setting list explicitly. If it is not + present, Pyramid will not perform exception view handling. + .. index:: single: view http redirect single: http redirect (from a view) -- cgit v1.2.3 From 643a83473a6faabd0ff08547a0cbca09e9cdda1c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 19 Sep 2012 04:46:01 -0400 Subject: A ``check_csrf`` view predicate was added. For example, you can now do ``config.add_view(someview, check_csrf=True)``. When the predicate is checked, if the ``csrf_token`` value in ``request.params`` matches the csrf token in the request's session, the view will be permitted to execute. Otherwise, it will not be permitted to execute. --- docs/narr/introspector.rst | 4 ++++ docs/narr/viewconfig.rst | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 6bfaf11c0..b88f3f0c8 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -393,6 +393,10 @@ introspectables in categories not described here. The ``match_param`` argument passed to ``add_view``. + ``csrf_token`` + + The ``csrf_token`` argument passed to ``add_view``. + ``callable`` The (resolved) ``view`` argument passed to ``add_view``. Represents the diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 23b4fde68..f65435cc6 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -394,6 +394,28 @@ configured view. consideration when deciding whether or not to invoke the associated view callable. +``check_csrf`` + If specified, this value should be one of ``None``, ``True``, ``False``, or + a string representing the 'check name'. If the value is ``True`` or a + string, CSRF checking will be performed. If the value is ``False`` or + ``None``, CSRF checking will not be performed. + + If the value provided is a string, that string will be used as the 'check + name'. If the value provided is ``True``, ``csrf_token`` will be used as + the check name. + + If CSRF checking is performed, the checked value will be the value of + ``request.params[check_name]``. This value will be compared against the + value of ``request.session.get_csrf_token()``, and the check will pass if + these two values are the same. If the check passes, the associated view + will be permitted to execute. If the check fails, the associated view + will not be permitted to execute. + + Note that using this feature requires a :term:`session factory` to have + been configured. + + .. versionadded:: 1.4a2 + ``custom_predicates`` If ``custom_predicates`` is specified, it must be a sequence of references to custom predicate callables. Use custom predicates when no set of @@ -407,6 +429,15 @@ configured view. If ``custom_predicates`` is not specified, no custom predicates are used. +``predicates`` + Pass a key/value pair here to use a third-party predicate registered via + :meth:`pyramid.config.Configurator.add_view_predicate`. More than one + key/value pair can be used at the same time. See + :ref:`view_and_route_predicates` for more information about third-party + predicates. + + .. versionadded:: 1.4a1 + .. index:: single: view_config decorator -- cgit v1.2.3 From 5f0e510c7de2735f8cb84479be07a94a9617b8b8 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Fri, 28 Sep 2012 01:14:27 -0500 Subject: Remove duplicate word --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7c0f9223f..b35c61720 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -315,7 +315,7 @@ Rendered views can return dictionaries If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a -dictionary instead, and Pyramid will take care of converting that dictionary +dictionary, and Pyramid will take care of converting that dictionary to a Response using a template on your behalf. This makes the view easier to test, because you don't have to parse HTML in your tests; just make an assertion instead that the view returns "the right stuff" in the dictionary -- cgit v1.2.3 From 06a904f88a64dc0c12b8ed7803287bac8786ff67 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Oct 2012 19:02:01 -0400 Subject: add docs and changelog note --- docs/narr/viewconfig.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index f65435cc6..3c7897969 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -290,12 +290,13 @@ configured view. of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. ``request_param`` - This value can be any string. A view declaration with this argument - ensures that the view will only be called when the :term:`request` has a - key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST`` - variable) that has a name which matches the supplied value. + This value can be any string or a sequence of strings. A view declaration + with this argument ensures that the view will only be called when the + :term:`request` has a key in the ``request.params`` dictionary (an HTTP + ``GET`` or ``POST`` variable) that has a name which matches the a + supplied value. - If the value supplied has a ``=`` sign in it, + If any value supplied has a ``=`` sign in it, e.g. ``request_param="foo=123"``, then the key (``foo``) must both exist in the ``request.params`` dictionary, *and* the value must match the right hand side of the expression (``123``) for the view to "match" the current -- cgit v1.2.3 From c25a8fd5d2895a117d8eb77162ed8388f0482674 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 26 Oct 2012 00:32:08 -0400 Subject: - New ``physical_path`` view predicate. If specified, this value should be a string or a tuple representing the physical traversal path of the context found via traversal for this predicate to match as true. For example: ``physical_path='/'`` or ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``. This is not a path prefix match or a regex, it's a whole-path match. It's useful when you want to always potentially show a view when some object is traversed to, but you can't be sure about what kind of object it will be, so you can't use the ``context`` predicate. The individual path elements inbetween slash characters or in tuple elements should be the Unicode representation of the name of the resource and should not be encoded in any way. --- docs/narr/viewconfig.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 3c7897969..752e6ad72 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -417,6 +417,20 @@ configured view. .. versionadded:: 1.4a2 +``physical_path`` + If specified, this value should be a string or a tuple representing the + :term:`physical path` of the context found via traversal for this predicate + to match as true. For example: ``physical_path='/'`` or + ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``. This is + not a path prefix match or a regex, it's a whole-path match. It's useful + when you want to always potentially show a view when some object is traversed + to, but you can't be sure about what kind of object it will be, so you can't + use the ``context`` predicate. The individual path elements inbetween slash + characters or in tuple elements should be the Unicode representation of the + name of the resource and should not be encoded in any way. + + .. versionadded:: 1.4a3 + ``custom_predicates`` If ``custom_predicates`` is specified, it must be a sequence of references to custom predicate callables. Use custom predicates when no set of -- cgit v1.2.3 From c7337ba1b02915824cb33803993c8ba236ed23b9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 28 Oct 2012 23:17:31 -0400 Subject: - Added an ``effective_principals`` route and view predicate. --- docs/narr/viewconfig.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 752e6ad72..6373a8d26 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -431,6 +431,18 @@ configured view. .. versionadded:: 1.4a3 +``effective_principals`` + + If specified, this value should be a :term:`principal` identifier or a + sequence of principal identifiers. If the + :func:`pyramid.security.effective_principals` method indicates that every + principal named in the argument list is present in the current request, this + predicate will return True; otherwise it will return False. For example: + ``effective_principals=pyramid.security.Authenticated`` or + ``effective_principals=('fred', 'group:admins')``. + + .. versionadded:: 1.4a4 + ``custom_predicates`` If ``custom_predicates`` is specified, it must be a sequence of references to custom predicate callables. Use custom predicates when no set of -- cgit v1.2.3 From a2b3e2847ba6e09bf24c1e455dda96b35a090b50 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Fri, 2 Nov 2012 00:06:58 -0600 Subject: typo --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 63287e2cd..1158d2225 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -329,7 +329,7 @@ time "by hand". Configure a JSONP renderer using the Once this renderer is registered via :meth:`~pyramid.config.Configurator.add_renderer` as above, you can use ``jsonp`` as the ``renderer=`` parameter to ``@view_config`` or -:meth:`pyramid.config.Configurator.add_view``: +:meth:`pyramid.config.Configurator.add_view`: .. code-block:: python -- cgit v1.2.3 From 76430b07f199cdbdbd19f463367c72eda1b537c3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Nov 2012 13:13:26 -0400 Subject: explain csrf token stealing potentiality --- docs/narr/sessions.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 1aa1b6341..f7da7838e 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -63,10 +63,15 @@ application by using the ``session_factory`` argument to the this implementation is, by default, *unencrypted*. You should not use it when you keep sensitive information in the session object, as the information can be easily read by both users of your application and third - parties who have access to your users' network traffic. Use a different - session factory implementation (preferably one which keeps session data on - the server) for anything but the most basic of applications where "session - security doesn't matter". + parties who have access to your users' network traffic. And if you use this + sessioning implementation, and you inadvertently create a cross-site + scripting vulnerability in your application, because the session data is + stored unencrypted in a cookie, it will also be easier for evildoers to + obtain the current user's cross-site scripting token. In short, use a + different session factory implementation (preferably one which keeps session + data on the server) for anything but the most basic of applications where + "session security doesn't matter", and you are sure your application has no + cross-site scripting vulnerabilities. .. index:: single: session object -- cgit v1.2.3 From 04875452db1da40bd8ed0841869d511b8d86527d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 4 Nov 2012 01:51:42 -0500 Subject: fix docs, upgrade tutorials, add change note, deprecate using zope.deprecation instead of a warning, make hashalg arg a kwarg in certain cases in case someone (maybe me) is using nonapi function imports from authentication --- docs/narr/security.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 07ec0f21e..3c9759e6c 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -90,9 +90,9 @@ For example: :linenos: from pyramid.config import Configurator - from pyramid.authentication import AuthTktAuthenticationPolicy + from pyramid.authentication import SHA512AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy - authentication_policy = AuthTktAuthenticationPolicy('seekrit') + authentication_policy = SHA512AuthTktAuthenticationPolicy('seekrit') authorization_policy = ACLAuthorizationPolicy() config = Configurator() config.set_authentication_policy(authentication_policy) -- cgit v1.2.3 From 19b8207ff1e959669d296407ed112545364a495d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 4 Nov 2012 11:19:41 -0600 Subject: merged SHA512AuthTktAuthenticationPolicy into AuthTktAuthenticationPolicy AuthTktAuthenticationPolicy now accepts a hashalg parameter and is no longer deprecated. Docs recommend overriding hashalg and using 'sha512'. --- docs/narr/security.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 3c9759e6c..3a94b4f7d 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -90,13 +90,13 @@ For example: :linenos: from pyramid.config import Configurator - from pyramid.authentication import SHA512AuthTktAuthenticationPolicy + from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy - authentication_policy = SHA512AuthTktAuthenticationPolicy('seekrit') - authorization_policy = ACLAuthorizationPolicy() + authn_policy = AuthTktAuthenticationPolicy('seekrit', hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() config = Configurator() - config.set_authentication_policy(authentication_policy) - config.set_authorization_policy(authorization_policy) + config.set_authentication_policy(authn_policy) + config.set_authorization_policy(authz_policy) .. note:: the ``authentication_policy`` and ``authorization_policy`` arguments may also be passed to their respective methods mentioned above -- cgit v1.2.3 From 8818ea59e253b855e1b0f09b856560cb71c9e8de Mon Sep 17 00:00:00 2001 From: Robert Jackiewicz Date: Mon, 12 Nov 2012 12:27:23 -0500 Subject: Modified the hooks documentation to currently describe how to access the context in a forbidden view. --- docs/narr/hooks.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 96fa77a07..ea75e5fe4 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -180,11 +180,14 @@ as a forbidden view: config.scan() Like any other view, the forbidden view must accept at least a ``request`` -parameter, or both ``context`` and ``request``. The ``context`` (available -as ``request.context`` if you're using the request-only view argument -pattern) is the context found by the router when the view invocation was -denied. The ``request`` is the current :term:`request` representing the -denied action. +parameter, or both ``context`` and ``request``. If a forbidden view +callable accepts both ``context`` and ``request``, the HTTP Exception is passed +as context. The ``context`` as found by the router when view was +denied (that you normally would expect) is available as +``request.context``. The ``request`` is the current :term:`request` +representing the denied action. + + Here's some sample code that implements a minimal forbidden view: -- cgit v1.2.3 From 4df5975a690d1f0921efb84f48f544211b4f869d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 21 Nov 2012 22:56:25 -0500 Subject: document new introspectable attrs --- docs/narr/introspector.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index b88f3f0c8..bd81fb56a 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -130,6 +130,23 @@ introspectables in categories not described here. A sequence of interfaces (or classes) that are subscribed to (the resolution of the ``ifaces`` argument passed to ``add_subscriber``). + ``derived_subscriber`` + + A wrapper around the subscriber used internally by the system so it can + call it with more than one argument if your original subscriber accepts + only one. + + ``predicates`` + + The predicate objects created as the result of passing predicate arguments + to ``add_susbcriber`` + + ``derived_predicates`` + + Wrappers around the predicate objects created as the result of passing + predicate arguments to ``add_susbcriber`` (to be used when predicates take + only one value but must be passed more than one). + ``response adapters`` Each introspectable in the ``response adapters`` category represents a call -- cgit v1.2.3 From 5acf4b4809e88dfeb3882f5033622a9517763d02 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 22 Nov 2012 00:39:19 -0500 Subject: appeasement --- docs/narr/install.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index e8482a289..32f331550 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -243,6 +243,17 @@ Once you've got setuptools or distribute 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. +.. warning:: + + Even though Python 3.3 and better comes with ``pyvenv`` out of the box, + which is similar to ``virtualenv``, we suggest using ``virtualenv`` instead. + ``virtualenv`` works on well Python 3.3. This isn't a recommendation made + for technical reasons, it's one made because it's not possible for the + authors of this guide to explain setup using multiple virtual environment + systems. ``pyenv`` will work fine. However, if you use ``pyvenv`` instead, + you'll need to understand how to install software such as ``distribute`` + into the virtual environment manually, which this guide does not cover. + .. code-block:: text $ easy_install virtualenv -- cgit v1.2.3 From 5d9c28f4e7f1fd3eba75e5bb51aebcbb56440df8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 22 Nov 2012 00:40:47 -0500 Subject: more appeasement --- docs/narr/install.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 32f331550..663f0df6c 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -248,11 +248,14 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Even though Python 3.3 and better comes with ``pyvenv`` out of the box, which is similar to ``virtualenv``, we suggest using ``virtualenv`` instead. ``virtualenv`` works on well Python 3.3. This isn't a recommendation made - for technical reasons, it's one made because it's not possible for the + for technical reasons, it's one made because it's not feasible for the authors of this guide to explain setup using multiple virtual environment - systems. ``pyenv`` will work fine. However, if you use ``pyvenv`` instead, - you'll need to understand how to install software such as ``distribute`` - into the virtual environment manually, which this guide does not cover. + systems. We are aiming to not need to make the installation documentation + Turing-complete. + + ``pyenv`` will work fine. However, if you use ``pyvenv`` instead, you'll + need to understand how to install software such as ``distribute`` into the + virtual environment manually, which this guide does not cover. .. code-block:: text -- cgit v1.2.3 From fb30e2cb79490f9dcafaea3d5ce2c0af140eae71 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 22 Nov 2012 13:28:41 -0500 Subject: typos --- docs/narr/install.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 663f0df6c..882e76f11 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -253,9 +253,10 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. systems. We are aiming to not need to make the installation documentation Turing-complete. - ``pyenv`` will work fine. However, if you use ``pyvenv`` instead, you'll - need to understand how to install software such as ``distribute`` into the - virtual environment manually, which this guide does not cover. + ``pyvenv`` will work fine. However, if you use ``pyvenv`` instead of + ``virtualenv``, you'll need to understand how to install software such as + ``distribute`` into the virtual environment manually, which this guide does + not cover. .. code-block:: text -- cgit v1.2.3 From d85569e38ba88029864b7908dbee3f948b103712 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Thu, 29 Nov 2012 22:10:38 -0600 Subject: Sync MyProject files with the starter scaffold - Line numbers are mentioned only in the Creating a Pyramid Project chapter; those that are affected were updated. --- docs/narr/MyProject/myproject/__init__.py | 1 + docs/narr/MyProject/myproject/tests.py | 1 + docs/narr/MyProject/myproject/views.py | 3 ++- docs/narr/MyProject/setup.py | 6 +++--- docs/narr/project.rst | 14 +++++++------- 5 files changed, 14 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py index 31b02cf02..6c512f52f 100644 --- a/docs/narr/MyProject/myproject/__init__.py +++ b/docs/narr/MyProject/myproject/__init__.py @@ -1,5 +1,6 @@ from pyramid.config import Configurator + def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py index d8b764041..64dcab1d5 100644 --- a/docs/narr/MyProject/myproject/tests.py +++ b/docs/narr/MyProject/myproject/tests.py @@ -2,6 +2,7 @@ import unittest from pyramid import testing + class ViewTests(unittest.TestCase): def setUp(self): self.config = testing.setUp() diff --git a/docs/narr/MyProject/myproject/views.py b/docs/narr/MyProject/myproject/views.py index f571a5976..c383c5716 100644 --- a/docs/narr/MyProject/myproject/views.py +++ b/docs/narr/MyProject/myproject/views.py @@ -1,5 +1,6 @@ from pyramid.view import view_config + @view_config(route_name='home', renderer='templates/mytemplate.pt') def my_view(request): - return {'project':'MyProject'} + return {'project': 'MyProject'} diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index b119a954b..f24b6984e 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -15,10 +15,10 @@ requires = [ setup(name='MyProject', version='0.0', description='MyProject', - long_description=README + '\n\n' + CHANGES, + long_description=README + '\n\n' + CHANGES, classifiers=[ "Programming Language :: Python", - "Framework :: Pylons", + "Framework :: Pyramid", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", ], @@ -32,7 +32,7 @@ setup(name='MyProject', install_requires=requires, tests_require=requires, test_suite="myproject", - entry_points = """\ + entry_points="""\ [paste.app_factory] main = myproject:main """, diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b08948e43..fb62f4bd2 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -829,25 +829,25 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Lines 3-10 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. Within this function, application configuration is performed. - Line 6 creates an instance of a :term:`Configurator`. + Line 7 creates an instance of a :term:`Configurator`. - Line 7 registers a static view, which will serve up the files from the + Line 8 registers a static view, which will serve up the files from the ``myproject:static`` :term:`asset specification` (the ``static`` directory of the ``myproject`` package). - Line 8 adds a :term:`route` to the configuration. This route is later + Line 9 adds a :term:`route` to the configuration. This route is later used by a view in the ``views`` module. - Line 9 calls ``config.scan()``, which picks up view registrations declared + Line 10 calls ``config.scan()``, which picks up view registrations declared elsewhere in the package (in this case, in the ``views.py`` module). - Line 10 returns a :term:`WSGI` application to the caller of the function + Line 11 returns a :term:`WSGI` application to the caller of the function (Pyramid's pserve). .. index:: @@ -865,7 +865,7 @@ and which returns a :term:`response`. :language: python :linenos: -Lines 3-5 define and register a :term:`view callable` named ``my_view``. The +Lines 4-6 define and register a :term:`view callable` named ``my_view``. The function named ``my_view`` is decorated with a ``view_config`` decorator (which is processed by the ``config.scan()`` line in our ``__init__.py``). The view_config decorator asserts that this view be found when a -- cgit v1.2.3 From 76aa5150d5ba25386817d06e0777c8891c7ef3a1 Mon Sep 17 00:00:00 2001 From: Reinout van Rees Date: Sat, 22 Dec 2012 21:19:49 +0100 Subject: Typo pakage => package --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ecf3d026a..480b0e0cc 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -86,7 +86,7 @@ setup code. However, the above :term:`scan` execution ``config.scan('mypackage')`` will pick up all :term:`configuration decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python -pakage. For example, if you have a ``views.py`` in your package, a scan will +package. For example, if you have a ``views.py`` in your package, a scan will pick up any of its configuration decorators, so we can add one there that that references ``myroute`` as a ``route_name`` parameter: -- cgit v1.2.3 From 10bf7ee0e6eba03e693a15c68048c7568dbba3ec Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 29 Dec 2012 07:43:35 +0200 Subject: typo --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index ccaa6e9e2..0b85d68d3 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -228,7 +228,7 @@ listens only on the ``127.0.0.1`` interface, which is problematic if you're running the server on a remote system and you wish to access it with a web browser from a local system. We also specify a TCP port number to listen on, which is 8080, passing it as the second argument. The final argument is the -``app`` object (a :term:`router`), which is the the application we wish to +``app`` object (a :term:`router`), which is the application we wish to serve. Finally, we call the server's ``serve_forever`` method, which starts the main loop in which it will wait for requests from the outside world. -- cgit v1.2.3 From f71723d2499ac2db1a82b8f74198b72b9012ab52 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 1 Jan 2013 00:48:38 +0200 Subject: typo --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 6373a8d26..799de768f 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -986,7 +986,7 @@ there's a ``should_cache`` GET or POST variable: Note that the ``http_cache`` machinery will overwrite or add to caching headers you set within the view itself unless you use ``prevent_auto``. -You can also turn of the effect of ``http_cache`` entirely for the duration +You can also turn off the effect of ``http_cache`` entirely for the duration of a Pyramid application lifetime. To do so, set the ``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the ``pyramid.prevent_http_cache`` configuration value setting to a true value. -- cgit v1.2.3 From b27d66f81274625446c301c2675638b36b5e16b3 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 1 Jan 2013 20:12:47 +0200 Subject: fix #746: explain why a dev package is installed --- docs/narr/install.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 882e76f11..c9cdb745a 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -52,6 +52,10 @@ command: $ sudo apt-get install python2.7-dev +This command will install both the Python interpreter and its header files. +Note that these headers are required by some dependencies you will use +in this docomentation, not by Pyramid itself. + Once these steps are performed, the Python interpreter will usually be invokable via ``python2.7`` from a shell prompt. -- cgit v1.2.3 From 78bacaa69f63fe2bc6980d7d40fc0523d5af9199 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 1 Jan 2013 21:52:33 +0200 Subject: typos --- 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 882e76f11..09c37c7f2 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -167,10 +167,10 @@ installed: Python 2.7.3 (default, Aug 1 2012, 05:14:39) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. - >>> import setutptools + >>> import setuptools Traceback (most recent call last): File "", line 1, in - ImportError: No module named setutptools + ImportError: No module named setuptools >>> If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -- cgit v1.2.3 From 78bba61a7a53949529c1b7444fd6611e116b725d Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 1 Jan 2013 23:34:09 +0200 Subject: improve wording regarding pyvenv --- docs/narr/install.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 882e76f11..8a8513348 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -245,18 +245,19 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. .. warning:: - Even though Python 3.3 and better comes with ``pyvenv`` out of the box, - which is similar to ``virtualenv``, we suggest using ``virtualenv`` instead. - ``virtualenv`` works on well Python 3.3. This isn't a recommendation made - for technical reasons, it's one made because it's not feasible for the + 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. - ``pyvenv`` will work fine. However, if you use ``pyvenv`` instead of - ``virtualenv``, you'll need to understand how to install software such as - ``distribute`` into the virtual environment manually, which this guide does - not cover. + If you insist on using ``pyvenv``, you'll need to understand how to install + software such as``distribute`` into the virtual environment manually, + which this guide does not cover. .. code-block:: text -- cgit v1.2.3 From 08c2217e7f831379016e1ddee0b5d51eeca53878 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 1 Jan 2013 23:56:02 +0200 Subject: eliminate repeated "the" words --- docs/narr/assets.rst | 2 +- docs/narr/commandline.rst | 2 +- docs/narr/hybrid.rst | 2 +- docs/narr/renderers.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index e8e915297..7b620548d 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -252,7 +252,7 @@ static assets that live *outside* the :app:`Pyramid` application. This will happen when the :meth:`~pyramid.config.Configurator.add_static_view` API associated with the path fed to :meth:`~pyramid.request.Request.static_url` is a *URL* instead of a view name. For example, the ``name`` argument may be -``http://example.com`` while the the ``path`` given may be +``http://example.com`` while the ``path`` given may be ``mypackage:images``: .. code-block:: python diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 3bdf8c5cd..8d6b9d984 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -758,7 +758,7 @@ we'll pretend you have a distribution with a package in it named This script uses the Python ``optparse`` module to allow us to make sense out of extra arguments passed to the script. It uses the -:func:`pyramid.paster.bootstrap` function to get information about the the +:func:`pyramid.paster.bootstrap` function to get information about the application defined by a config file, and prints the deployment settings defined in that config file. diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index ab1bf20bb..1773a6b8c 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -477,7 +477,7 @@ Registering a Default View for a Route That Has a ``view`` Attribute ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. warning:: As of :app:`Pyramid` 1.1 this section is slated to be removed in - a later documentation release because the the ability to add views + a later documentation release because the ability to add views directly to the :term:`route configuration` by passing a ``view`` argument to ``add_route`` has been deprecated. diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 1158d2225..9017156a6 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -366,7 +366,7 @@ For example (Javascript): '&callback=?'; jqhxr = $.getJSON(api_url); -The string ``callback=?`` above in the the ``url`` param to the JQuery +The string ``callback=?`` above in the ``url`` param to the JQuery ``getAjax`` function indicates to jQuery that the query should be made as a JSONP request; the ``callback`` parameter will be automatically filled in for you and used. -- cgit v1.2.3 From 043ccddb909327106264d10ed5d413760a51770d Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 2 Jan 2013 02:22:52 +0200 Subject: eliminate other repeated words --- docs/narr/extconfig.rst | 2 +- docs/narr/hooks.rst | 2 +- docs/narr/i18n.rst | 2 +- docs/narr/introspector.rst | 2 +- docs/narr/renderers.rst | 2 +- docs/narr/subrequest.rst | 2 +- docs/narr/templates.rst | 2 +- docs/narr/urldispatch.rst | 4 ++-- docs/narr/views.rst | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 5e7fe2753..875bc9006 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -289,7 +289,7 @@ The ``title`` is a human-consumable string that can be used by introspection system frontends to show a friendly summary of this introspectable. The ``type_name`` is a value that can be used to subtype this introspectable -within its category for for sorting and presentation purposes. It can be any +within its category for sorting and presentation purposes. It can be any value. An introspectable is also dictionary-like. It can contain any set of diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index ea75e5fe4..b5efc0df1 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1082,7 +1082,7 @@ entirely by the relative ordering of calls to :meth:`pyramid.config.Configurator.add_tween`. However, the caller of add_tween can provide an optional hint that can influence the implicit tween chain ordering by supplying ``under`` or ``over`` (or both) arguments to -:meth:`~pyramid.config.Configurator.add_tween`. These hints are only used +:meth:`~pyramid.config.Configurator.add_tween`. These hints are only used when an explicit tween ordering is not used. See :ref:`explicit_tween_ordering` for a description of how to set an explicit tween ordering. diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index e261f9a11..511464322 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -301,7 +301,7 @@ You need to add a few boilerplate lines to your application's ``setup.py`` file in order to properly generate :term:`gettext` files from your application. -.. note:: See :ref:`project_narr` to learn about about the +.. note:: See :ref:`project_narr` to learn about the composition of an application's ``setup.py`` file. In particular, add the ``Babel`` and ``lingua`` distributions to the diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index bd81fb56a..7784e8960 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -496,7 +496,7 @@ introspectables in categories not described here. ``translation directories`` Each introspectable in the ``asset overrides`` category represents an - individual element in a ``specs`` argument passed to to + individual element in a ``specs`` argument passed to :meth:`pyramid.config.Configurator.add_translation_dirs`; each will have the following data. diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 9017156a6..ecf625251 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -264,7 +264,7 @@ will be the active request object at render time. # [{"x": 1}, {"x": 2}] If you aren't the author of the objects being serialized, it won't be -possible (or at least not reasonable) to add a custom ``__json__`` method to +possible (or at least not reasonable) to add a custom ``__json__`` method to their classes in order to influence serialization. If the object passed to the renderer is not a serializable type, and has no ``__json__`` method, usually a :exc:`TypeError` will be raised during serialization. You can diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 89551ab35..b5bc5ec48 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -142,7 +142,7 @@ generated. We can change this behavior; how to do so is described below in our discussion of the ``use_tweens`` argument. The :meth:`pyramid.request.Request.invoke_subrequest` API accepts two -arguments: a positional argument ``request`` that must be provided, and and +arguments: a positional argument ``request`` that must be provided, and ``use_tweens`` keyword argument that is optional; it defaults to ``False``. The ``request`` object passed to the API must be an object that implements diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index ba72ebfbf..1cec26fbc 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -109,7 +109,7 @@ supply the renderer with more correct system values (see to compose proper system values is present in the request. If your template relies on the name ``request`` or ``context``, or if you've configured special :term:`renderer globals`, make sure to pass -``request`` as a keyword argument in every call to to a +``request`` as a keyword argument in every call to a ``pyramid.renderers.render_*`` function. Every view must return a :term:`response` object, except for views diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 480b0e0cc..46f908b7c 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -87,7 +87,7 @@ setup code. However, the above :term:`scan` execution decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python package. For example, if you have a ``views.py`` in your package, a scan will -pick up any of its configuration decorators, so we can add one there that +pick up any of its configuration decorators, so we can add one there that references ``myroute`` as a ``route_name`` parameter: .. code-block:: python @@ -860,7 +860,7 @@ exactly the same job: request into a ``GET``, losing any ``POST`` data in the original request. -See :ref:`view_module` and :ref:`changing_the_notfound_view` for for a more +See :ref:`view_module` and :ref:`changing_the_notfound_view` for a more general description of how to configure a view and/or a not found view. .. index:: diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 07d018127..4f30bb7fa 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -180,7 +180,7 @@ All classes documented in the :mod:`pyramid.httpexceptions` module documented as inheriting from the :class:`pyramid.httpexceptions.HTTPException` are :term:`http exception` objects. Instances of an HTTP exception object may either be *returned* or *raised* from within view code. In either case -(return or raise) the instance will be used as as the view's response. +(return or raise) the instance will be used as the view's response. For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception can be raised. This will cause a response to be generated with a ``401 -- cgit v1.2.3 From 638ce950df1c8c8393c44a578270480f86dd060c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 1 Jan 2013 21:11:38 -0500 Subject: fix rationale and typo --- docs/narr/install.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c9cdb745a..a1c7b0d64 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -52,9 +52,9 @@ command: $ sudo apt-get install python2.7-dev -This command will install both the Python interpreter and its header files. -Note that these headers are required by some dependencies you will use -in this docomentation, not by Pyramid itself. +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. -- cgit v1.2.3 From 00d83a42a4499a1a94d9019b740cc477270960cf Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 1 Jan 2013 21:23:12 -0500 Subject: reflow, typo --- docs/narr/install.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 8947a891f..6db0d88f5 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -250,17 +250,15 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. .. warning:: 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 + 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. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as``distribute`` into the virtual environment manually, + software such as ``distribute`` into the virtual environment manually, which this guide does not cover. .. code-block:: text -- cgit v1.2.3 From f65e191ed7da0ff97638879cf854c0b1cb505aaa Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 2 Jan 2013 23:09:40 +0200 Subject: typos --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b35c61720..956d7a177 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -101,7 +101,7 @@ frameworks for small and large applications is just false; a well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework. -To this end, Pyramid provides a set of features, that, combined, are unique +To this end, Pyramid provides a set of features that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features; Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -- cgit v1.2.3 From 73ea91b1e3859e412252a8d3263389147a05223e Mon Sep 17 00:00:00 2001 From: Reed O'Brien Date: Sun, 6 Jan 2013 13:24:50 -0500 Subject: fix import typo in docs --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 799de768f..f00dae451 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -834,7 +834,7 @@ decorator on the RESTView class: .. code-block:: python :linenos: - from pyramid.view import view_config + from pyramid.view import view_defaults from pyramid.response import Response from pyramid.config import Configurator -- cgit v1.2.3 From a03b29ccc094537fa0d80b2545a9d16fc94566cb Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 8 Jan 2013 00:50:24 +0200 Subject: typos --- docs/narr/introduction.rst | 2 +- docs/narr/upgrading.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b35c61720..187b81702 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -475,7 +475,7 @@ per route. For example, you can create a route with the pattern ``/items`` and when the route is matched, you can shuffle off the request to one view if the request method is GET, another view if the request method is POST, etc. A system known as "view predicates" allows for this. Request method matching -is the very most basic thing you can do with a view predicate. You can also +is the most basic thing you can do with a view predicate. You can also associate views with other request parameters such as the elements in the query string, the Accept header, whether the request is an XHR request or not, and lots of other things. This feature allows you to keep your diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index 839f59c35..20487b448 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -206,7 +206,7 @@ information. Upgrading to the Very Latest Pyramid Release -------------------------------------------- -When you upgrade your application to the very most recent Pyramid release, +When you upgrade your application to the most recent Pyramid release, it's advisable to upgrade step-wise through each most recent minor release, beginning with the one that you know your application currently runs under, and ending on the most recent release. For example, if your application is -- cgit v1.2.3 From 22ed77d69b0f2348983be0c4e8758a44cf160671 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 9 Jan 2013 02:30:47 +0200 Subject: take advantage of the -c option of Python --- docs/narr/install.rst | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index ff89553ae..a78c1b2bd 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -150,32 +150,21 @@ To set up a virtualenv in which to install :app:`Pyramid`, first ensure that ``import setuptools`` within the Python interpreter you'd like to run :app:`Pyramid` under. -Here's the output you'll expect if setuptools or distribute is already -installed: +The following command will not display anything if setuptools or distribute is +already installed: .. code-block:: text - [chrism@thinko docs]$ python2.7 - Python 2.7.3 (default, Aug 1 2012, 05:14:39) - [GCC 4.6.3] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> import setuptools - >>> + $ python2.7 -c 'import setuptools' -Here's the output you can expect if setuptools or distribute is not already -installed: +Running the same command will yield the following output if setuptools or +distribute is not yet installed: .. code-block:: text - [chrism@thinko docs]$ python2.7 - Python 2.7.3 (default, Aug 1 2012, 05:14:39) - [GCC 4.6.3] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> import setuptools 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 or distribute manually. Note that above -- cgit v1.2.3 From 8109ae8ef7e04135a4724963951983ee260293a7 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 13 Jan 2013 22:45:36 +0200 Subject: typo; should be 'titled', but would be redundant --- docs/narr/advconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index ad22a82c9..7caea28b8 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -417,7 +417,7 @@ added in configuration execution order. More Information ---------------- -For more information, see the article entitled `"A Whirlwind Rour of Advanced +For more information, see the article `"A Whirlwind Tour of Advanced Configuration Tactics" `_ in the Pyramid Cookbook. -- cgit v1.2.3 From b00f1e46f100d8a23041a1bb7a7b37b026170fe3 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Mon, 14 Jan 2013 08:50:51 -0500 Subject: Punctuate. --- docs/narr/advconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 7caea28b8..ba43f3ea6 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -417,7 +417,7 @@ added in configuration execution order. More Information ---------------- -For more information, see the article `"A Whirlwind Tour of Advanced +For more information, see the article,`"A Whirlwind Tour of Advanced Configuration Tactics" -`_ +`_, in the Pyramid Cookbook. -- cgit v1.2.3 From 8e5b2d196a1d7825ecd59a39709ef0dbd2c134e1 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 16 Jan 2013 00:39:52 +0200 Subject: improve flow --- docs/narr/firstapp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 0b85d68d3..9aea50185 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -200,7 +200,7 @@ and various other configuration settings have been performed). The be used by any WSGI server to present an application to a requestor. :term:`WSGI` is a protocol that allows servers to talk to Python applications. We don't discuss :term:`WSGI` in any depth within this book, -however, you can learn more about it by visiting `wsgi.org +but you can learn more about it by visiting `wsgi.org `_. The :app:`Pyramid` application object, in particular, is an instance of a -- cgit v1.2.3 From 362d8b0548410e7ab3e28d0d420342121496a1d2 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 16 Jan 2013 00:44:45 +0200 Subject: improve flow --- docs/narr/firstapp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 0b85d68d3..45cb917f7 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -194,8 +194,8 @@ WSGI Application Creation After configuring views and ending configuration, the script creates a WSGI *application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` method. A call to ``make_wsgi_app`` implies that all configuration is -finished (meaning all method calls to the configurator which set up views, -and various other configuration settings have been performed). The +finished (meaning all method calls to the configurator, which sets up views +and various other configuration settings, have been performed). The ``make_wsgi_app`` method returns a :term:`WSGI` application object that can be used by any WSGI server to present an application to a requestor. :term:`WSGI` is a protocol that allows servers to talk to Python -- cgit v1.2.3 From 7e10cd0fd38bdeeba988e6ecf1b6179a0086559c Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 17 Jan 2013 22:06:50 +0200 Subject: miscellaneous doc improvements * the word "system" can be misleading, so use a clearer choice of words * reduce repetition * mention Debian, since it is similar to Ubuntu, and is major enough * it is now "Ubuntu", not "Ubuntu Linux" --- docs/narr/install.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index a78c1b2bd..6653243d5 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -40,13 +40,11 @@ UNIX system that has development tools. Package Manager Method ++++++++++++++++++++++ -You can use your system's "package manager" to install Python. Every -system's package manager is slightly different, but the "flavor" of +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 an Ubuntu Linux system, to use the system package -manager to install a Python 2.7 interpreter, use the following -command: +For example, on a Debian or Ubuntu system, use the following command: .. code-block:: text -- cgit v1.2.3 From b31e5c9c46f4d87177b114f50328a8b0b39908be Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 17 Jan 2013 22:30:25 +0200 Subject: fix #747 --- docs/narr/install.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index a78c1b2bd..19c144156 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -70,7 +70,8 @@ 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. +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 -- cgit v1.2.3 From e241c7e479b411a7f465b0a3d86021301702f8af Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 18 Jan 2013 23:58:04 +0200 Subject: make example links clickable, for convenience --- docs/narr/firstapp.rst | 2 +- docs/narr/urldispatch.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 0b85d68d3..50aa02692 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -40,7 +40,7 @@ On Windows: This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the server will simply serve up the text "Hello world!". If your application is -running on your local system, using ``http://localhost:8080/hello/world`` +running on your local system, using ``_ in a browser will show this result. Each time you visit a URL served by the application in a browser, a logging diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 46f908b7c..ec97bf3b2 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -38,7 +38,7 @@ application. A route has a *name*, which acts as an identifier to be used for URL generation. The name also allows developers to associate a view configuration with the route. A route also has a *pattern*, meant to match against the ``PATH_INFO`` portion of a URL (the portion following the scheme -and port, e.g. ``/foo/bar`` in the URL ``http://localhost:8080/foo/bar``). It +and port, e.g. ``/foo/bar`` in the URL ``_). It also optionally has a ``factory`` and a set of :term:`route predicate` attributes. -- cgit v1.2.3 From 1e7d75e55428127865cd8bf18576fd71bdf7e5ee Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 21 Jan 2013 00:03:25 +0200 Subject: fix typos --- docs/narr/renderers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index ecf625251..5379a4a99 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -823,8 +823,8 @@ sets an ``override_renderer`` attribute on the request itself, which is the .. code-block:: python :linenos: - from pyramid.event import subscriber - from pyramid.event import NewRequest + from pyramid.events import subscriber + from pyramid.events import NewRequest @subscriber(NewRequest) def set_xmlrpc_params(event): -- cgit v1.2.3 From 2b126ef15ee7d8457592faea02f837cf2a6062d4 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 22 Jan 2013 07:51:49 +0200 Subject: consistency fixes --- docs/narr/renderers.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 5379a4a99..794e3cffa 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -73,13 +73,13 @@ which renders view return values to a :term:`JSON` response serialization. Other built-in renderers include renderers which use the :term:`Chameleon` templating language to render a dictionary to a response. Additional -renderers can be added by developers to the system as necessary (see -:ref:`adding_and_overriding_renderers`). +renderers can be added by developers to the system as necessary. +See :ref:`adding_and_overriding_renderers`. Views which use a renderer and return a non-Response value can vary non-body response attributes (such as headers and the HTTP status code) by attaching a -property to the ``request.response`` attribute See -:ref:`request_response_attr`. +property to the ``request.response`` attribute. +See :ref:`request_response_attr`. If the :term:`view callable` associated with a :term:`view configuration` returns a Response object directly, any renderer associated with the view -- cgit v1.2.3 From b515ddcf759ebe267b9ee74a1d5af72da8639ae0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 23 Jan 2013 21:56:28 +0200 Subject: displaying line numbers for 1-line snippets is overkill --- docs/narr/renderers.rst | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 794e3cffa..5391a6669 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -63,7 +63,6 @@ the ``renderer`` attribute. For example, this call to with a view callable: .. code-block:: python - :linenos: config.add_view('myproject.views.my_view', renderer='json') @@ -166,7 +165,6 @@ The body of the response returned by such a view will be a string representing the ``str()`` serialization of the return value: .. code-block:: python - :linenos: {'content': 'Hello!'} @@ -204,7 +202,6 @@ The body of the response returned by such a view will be a string representing the JSON serialization of the return value: .. code-block:: python - :linenos: '{"content": "Hello!"}' @@ -619,7 +616,6 @@ For example, to add a renderer which renders views which have a ``renderer`` attribute that is a path that ends in ``.jinja2``: .. code-block:: python - :linenos: config.add_renderer('.jinja2', 'mypackage.MyJinja2Renderer') @@ -725,10 +721,8 @@ Here's an example of the registration of a more complicated renderer factory, which expects to be passed a filesystem path: .. code-block:: python - :linenos: - config.add_renderer(name='.jinja2', - factory='my.package.MyJinja2Renderer') + config.add_renderer(name='.jinja2', factory='my.package.MyJinja2Renderer') Adding the above code to your application startup will allow you to use the ``my.package.MyJinja2Renderer`` renderer factory implementation in view @@ -769,7 +763,6 @@ extension for the same kinds of templates. For example, to associate the :meth:`pyramid.config.Configurator.add_renderer` method: .. code-block:: python - :linenos: config.add_renderer('.zpt', 'pyramid.chameleon_zpt.renderer_factory') @@ -781,7 +774,6 @@ rendered via a Chameleon ZPT page template renderer, use a variation on the following in your application's startup code: .. code-block:: python - :linenos: config.add_renderer('.pt', 'mypackage.pt_renderer') @@ -794,7 +786,6 @@ ones which do not possess a ``renderer`` attribute), pass ``None`` as the ``name`` attribute to the renderer tag: .. code-block:: python - :linenos: config.add_renderer(None, 'mypackage.json_renderer_factory') -- cgit v1.2.3 From 5ed0d3df82787f95338a0dffa8c6a56efb28c6ee Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 23 Jan 2013 21:59:46 +0200 Subject: use 'versionadded' Sphinx directive --- docs/narr/renderers.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 5391a6669..deb0f6ee8 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -291,9 +291,8 @@ with the object. See :class:`pyramid.renderers.JSON` and :ref:`adding_and_overriding_renderers` for more information. -.. note:: - - Serializing custom objects is a feature new in Pyramid 1.4. +.. versionadded:: 1.4 + Serializing custom objects. .. index:: pair: renderer; JSONP @@ -303,9 +302,7 @@ See :class:`pyramid.renderers.JSON` and JSONP Renderer ~~~~~~~~~~~~~~ -.. note:: - - This feature is new in Pyramid 1.1. +.. versionadded:: 1.1 :class:`pyramid.renderers.JSONP` is a `JSONP `_ renderer factory helper which -- cgit v1.2.3 From 2947141248946db191843c5bc1629c60e7ad8f3a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 23 Jan 2013 22:00:10 +0200 Subject: user 'deprecated' Sphinx directive --- docs/narr/renderers.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index deb0f6ee8..b7d3479dc 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -565,7 +565,8 @@ in :ref:`request_module`. For more information on the API of Deprecated Mechanism to Vary Attributes of Rendered Responses ------------------------------------------------------------- -.. warning:: This section describes behavior deprecated in Pyramid 1.1. +.. deprecated:: 1.1 + The behavior described in this entire section. In previous releases of Pyramid (1.0 and before), the ``request.response`` attribute did not exist. Instead, Pyramid required users to set special -- cgit v1.2.3 From 531a2ad34ab0a806513681cddd5d99e50a31c4c6 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 23 Jan 2013 22:01:56 +0200 Subject: provide a link to the class; lineno for a 1-liner is overkill --- docs/narr/renderers.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b7d3479dc..863932e83 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -683,12 +683,10 @@ There are essentially two different kinds of renderer factories: :term:`package`. Here's an example of the registration of a simple renderer factory via -:meth:`~pyramid.config.Configurator.add_renderer`: +:meth:`~pyramid.config.Configurator.add_renderer`, where ``config`` +is an instance of :meth:`pyramid.config.Configurator`: .. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator config.add_renderer(name='amf', factory='my.package.MyAMFRenderer') -- cgit v1.2.3 From fdcd1beef58e106b556f6586f4a95e02d6aec1f4 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 28 Jan 2013 08:27:05 +0200 Subject: use a more correct directive --- docs/narr/environment.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 8206e0bcb..def5e12a4 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -504,12 +504,13 @@ default, this is ``false``. Mako Preprocessor ~~~~~~~~~~~~~~~~~ +.. versionadded:: 1.1 + A callable (or a :term:`dotted Python name` which names a callable) which is called to preprocess the source before the template is called. The callable will be passed the full template source before it is parsed. The return result of the callable will be used as the template source code. -.. note:: This feature is new in Pyramid 1.1. +-----------------------------+ | Config File Setting Name | -- cgit v1.2.3 From 9db1a14cd16f6e92fdb72650d2a3e3ef6e55ef9a Mon Sep 17 00:00:00 2001 From: kusut Date: Mon, 28 Jan 2013 23:42:27 +0700 Subject: narrative docs for add_request_method --- docs/narr/hooks.rst | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b5efc0df1..957426ec2 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -256,6 +256,97 @@ already constructed a :term:`configurator` it can also be registered via the config = Configurator() config.set_request_factory(MyRequest) +.. index:: + single: request method + +.. _adding_request_method: + +Adding Methods or Properties to Request Object +---------------------------------------------- + +Since each pyramid application can only have one :term:`request` factory, +:ref:`changing the request factory ` +is not that extensible especially if you want to build composable features +(e.g., pyramid add-ons and plugins). + +A lazy property can be registered to the request object via the +:meth:`pyramid.config.Configurator.add_request_method` API. This allows you +to specify a callable that will be available on the request object, but will not +actually execute the function until accessed. + +.. note:: This feature is new as of Pyramid 1.4. + +.. warning:: This will silently override methods and properties from + :term:`request factory` that have the same name. + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def total(request, *args): + return sum(args) + + def prop(request): + print "getting the property" + return "the property" + + config = Configurator() + config.add_request_method(total) + config.add_request_method(prop, reify=True) + +In the above example, ``total`` is added as a method. However, ``prop`` is added +as a property and its result is cached per-request by setting ``reify=True``. +This way, we eliminate the overhead of running the function multiple times. + + >>> request.total(1, 2, 3) + 6 + >>> request.prop + getting the property + the property + >>> request.prop + the property + +To not cache the result of ``request.prop``, set ``property=True`` instead of +``reify=True``. + +Here is an example of passing a class to ``Configurator.add_request_method``: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.decorator import reify + + + class ExtraStuff(object): + + def __init__(self, request): + self.request = request + + def total(self, *args): + return sum(args) + + # use @property if you don't want to cache the result + @reify + def prop(self): + print "getting the property" + return "the property" + + config = Configurator() + config.add_request_method(ExtraStuff, 'extra', reify=True) + +We attach and cache an object named ``extra`` to the ``request`` object. + + >>> request.extra.total(1, 2, 3) + 6 + >>> request.extra.prop + getting the property + the property + >>> request.extra.prop + the property + + .. index:: single: before render event single: adding renderer globals -- cgit v1.2.3 From 1c0e0e94b6665ba715236be82cbd2b12b6a0a79f Mon Sep 17 00:00:00 2001 From: Calvin Hendryx-Parker Date: Mon, 28 Jan 2013 17:08:21 -0500 Subject: Update docs/narr/extending.rst Fixed grammatical typo --- docs/narr/extending.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index c464203f0..dd9281c73 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -84,7 +84,7 @@ function in your application's ``__init__.py``. For example, rather than: config.add_view('myapp.views.view1', name='view1') config.add_view('myapp.views.view2', name='view2') -You should do move the calls to ``add_view`` outside of the (non-reusable) +You should move the calls to ``add_view`` outside of the (non-reusable) ``if __name__ == '__main__'`` block, and into a reusable function: .. code-block:: python -- cgit v1.2.3 From 0a9a29e9391e9b8639de61473bbe4865a6b0551e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 29 Jan 2013 00:16:29 +0200 Subject: pluralize --- docs/narr/sessions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index f7da7838e..fa4affd8a 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -29,7 +29,7 @@ during your :app:`Pyramid` configuration. A very basic, insecure sample session factory implementation is provided in the :app:`Pyramid` core. It uses a cookie to store session information. This implementation has the following -limitation: +limitations: - The session information in the cookies used by this implementation is *not* encrypted, so it can be viewed by anyone with access to the -- cgit v1.2.3 From 479447a1ebc231096155290f918f563b884a3432 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 29 Jan 2013 01:03:37 +0200 Subject: replace 'note' with the more correct 'versionadded' directive --- docs/narr/urldispatch.rst | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ec97bf3b2..749a2d49a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -758,11 +758,8 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. -.. note:: - - the ``static`` argument to - :meth:`~pyramid.config.Configurator.add_route` is new as of :app:`Pyramid` - 1.1. +.. versionadded:: 1.1 + the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` .. index:: single: redirecting to slash-appended routes @@ -906,7 +903,7 @@ routes configured in your application; for more information, see Using a Route Prefix to Compose Applications -------------------------------------------- -.. note:: This feature is new as of :app:`Pyramid` 1.2. +.. versionadded:: 1.2 The :meth:`pyramid.config.Configurator.include` method allows configuration statements to be included from separate files. See -- cgit v1.2.3 From 5b9c21ebe7d295bb9ac4356033899181ac69396e Mon Sep 17 00:00:00 2001 From: kusut Date: Tue, 29 Jan 2013 22:16:00 +0700 Subject: enhance! --- docs/narr/hooks.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 957426ec2..d693149e4 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -264,18 +264,18 @@ already constructed a :term:`configurator` it can also be registered via the Adding Methods or Properties to Request Object ---------------------------------------------- -Since each pyramid application can only have one :term:`request` factory, +.. versionadded:: 1.4. + +Since each Pyramid application can only have one :term:`request` factory, :ref:`changing the request factory ` -is not that extensible especially if you want to build composable features -(e.g., pyramid add-ons and plugins). +is not that extensible, especially if you want to build composable features +(e.g., Pyramid add-ons and plugins). A lazy property can be registered to the request object via the :meth:`pyramid.config.Configurator.add_request_method` API. This allows you to specify a callable that will be available on the request object, but will not actually execute the function until accessed. -.. note:: This feature is new as of Pyramid 1.4. - .. warning:: This will silently override methods and properties from :term:`request factory` that have the same name. @@ -318,7 +318,6 @@ Here is an example of passing a class to ``Configurator.add_request_method``: from pyramid.config import Configurator from pyramid.decorator import reify - class ExtraStuff(object): def __init__(self, request): @@ -346,7 +345,6 @@ We attach and cache an object named ``extra`` to the ``request`` object. >>> request.extra.prop the property - .. index:: single: before render event single: adding renderer globals -- cgit v1.2.3 From 40dbf42a2df1783c3d803adf950380c21512bb91 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 30 Jan 2013 00:41:23 +0200 Subject: use the more appropriate directives --- docs/narr/commandline.rst | 3 ++- docs/narr/extconfig.rst | 4 +--- docs/narr/hooks.rst | 19 ++++++++----------- docs/narr/templates.rst | 8 ++------ docs/narr/viewconfig.rst | 8 +++----- docs/narr/views.rst | 4 ++-- docs/narr/webob.rst | 2 +- 7 files changed, 19 insertions(+), 29 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 8d6b9d984..8e360216d 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -504,7 +504,8 @@ environment much like the environment produced when a particular using the :func:`pyramid.paster.bootstrap` command in the body of your script. -.. note:: This feature is new as of :app:`Pyramid` 1.1. +.. versionadded:: 1.1 + This feature. In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a single argument, which accepts the :term:`PasteDeploy` ``.ini`` file diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 875bc9006..f33326279 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -227,9 +227,7 @@ augment Pyramid's configuration introspection system. Adding Configuration Introspection ---------------------------------- -.. note:: - - The introspection subsystem is new in Pyramid 1.3. +.. versionadded:: 1.3 Pyramid provides a configuration introspection system that can be used by debugging tools to provide visibility into the configuration of a running diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b5efc0df1..fc5c0ff23 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -336,9 +336,9 @@ when adding renderer global values exists in :ref:`adding_renderer_globals`. Adding Renderer Globals (Deprecated) ------------------------------------ -.. warning:: this feature is deprecated as of Pyramid 1.1. A non-deprecated - mechanism which allows event subscribers to add renderer global values - is documented in :ref:`beforerender_event`. +.. deprecated:: 1.1 + An alternative mechanism which allows event subscribers to add renderer + global values is documented in :ref:`beforerender_event`. Whenever :app:`Pyramid` handles a request to perform a rendering (after a view with a ``renderer=`` configuration attribute is invoked, or when any of @@ -635,13 +635,13 @@ See :meth:`pyramid.config.add_resource_url_adapter` for more information. Changing How Pyramid Treats View Responses ------------------------------------------ +.. versionadded:: 1.1 + It is possible to control how Pyramid treats the result of calling a view callable on a per-type basis by using a hook involving :meth:`pyramid.config.Configurator.add_response_adapter` or the :class:`~pyramid.response.response_adapter` decorator. -.. note:: This feature is new as of Pyramid 1.1. - Pyramid, in various places, adapts the result of calling a view callable to the :class:`~pyramid.interfaces.IResponse` interface to ensure that the object returned by the view callable is a "true" response object. The vast @@ -936,8 +936,8 @@ For full details, please read the `Venusian documentation Registering "Tweens" -------------------- -.. note:: Tweens are a feature which were added in Pyramid 1.2. They are - not available in any previous version. +.. versionadded:: 1.2 + Tweens A :term:`tween` (a contraction of the word "between") is a bit of code that sits between the Pyramid router's main request handling function and the @@ -1241,10 +1241,7 @@ implict and explicit tween chains used by an application. See Adding A Third Party View, Route, or Subscriber Predicate --------------------------------------------------------- -.. note:: - - Third-party view, route, and subscriber predicates are a feature new as of - Pyramid 1.4. +.. versionadded:: 1.4 .. _view_and_route_predicates: diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 1cec26fbc..6a1fbf916 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -543,9 +543,7 @@ template as a :term:`renderer` like so: The above will render only the ``bar`` macro defined within the ``foo.pt`` template instead of the entire template. -.. note:: - - This feature is new in Pyramid 1.4. +.. versionadded:: 1.4 .. index:: single: Chameleon text templates @@ -743,9 +741,7 @@ configure the template as a :term:`renderer` like so: The above will render the ``bar`` def from within the ``foo.mak`` template instead of the entire template. -.. note:: - - This feature is new in Pyramid 1.4. +.. versionadded:: 1.4 .. index:: single: automatic reloading of templates diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index f00dae451..7001cd980 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -306,7 +306,7 @@ configured view. consideration of keys and values in the ``request.params`` dictionary. ``match_param`` - .. note:: This feature is new as of :app:`Pyramid` 1.2. + .. versionadded:: 1.2 This param may be either a single string of the format "key=value" or a dict of key/value pairs. @@ -724,9 +724,7 @@ configuration to take effect. ``@view_defaults`` Class Decorator ---------------------------------- -.. note:: - - This feature is new in Pyramid 1.3. +.. versionadded:: 1.3 If you use a class as a view, you can use the :class:`pyramid.view.view_defaults` class decorator on the class to provide @@ -952,7 +950,7 @@ for more information about how, and where to set these values. Influencing HTTP Caching ------------------------ -.. note:: This feature is new in Pyramid 1.1. +.. versionadded:: 1.1 When a non-``None`` ``http_cache`` argument is passed to a view configuration, Pyramid will set ``Expires`` and ``Cache-Control`` response diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 4f30bb7fa..860c380f3 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -227,8 +227,8 @@ equivalent to ``raise HTTPUnauthorized()``. Documentation which maps each HTTP response code to its purpose and its associated HTTP exception object is provided within :mod:`pyramid.httpexceptions`. -.. note:: The :func:`~pyramid.httpexceptions.exception_response` function is - new as of Pyramid 1.1. +.. versionadded:: 1.1 + The :func:`~pyramid.httpexceptions.exception_response` function. How Pyramid Uses HTTP Exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index a8c11acec..44940f9e6 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -251,7 +251,7 @@ API documentation for a multidict exists as Dealing With A JSON-Encoded Request Body ++++++++++++++++++++++++++++++++++++++++ -.. note:: this feature is new as of Pyramid 1.1. +.. versionadded:: 1.1 :attr:`pyramid.request.Request.json_body` is a property that returns a :term:`JSON` -decoded representation of the request body. If the request -- cgit v1.2.3 From 6821582d7e691b8c068ce80ec067319c65195716 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 30 Jan 2013 01:18:06 +0200 Subject: this obsolete info should have been removed in commit 22ed77d --- docs/narr/install.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 224a62db7..c467779f4 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -166,9 +166,7 @@ distribute is not yet installed: ImportError: No module named setuptools If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools or distribute manually. Note that above -we're using a Python 2.7-series interpreter on Mac OS X; your output may -differ if you're using a later Python version or a different platform. +will need to install setuptools or distribute manually. If you are using a "system" Python (one installed by your OS distributor or a 3rd-party packager such as Fink or MacPorts), you can usually install the -- cgit v1.2.3 From 3a6bdf983b51d8d0df124999ae217084c7dddbc6 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 3 Feb 2013 12:38:55 +0200 Subject: use clearer language --- docs/narr/environment.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index def5e12a4..281bb6919 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -203,7 +203,7 @@ Using the setting is equivalent to using the | | +---------------------------------+ -The value supplied as ``pyramid.includes`` should be a sequence. The +The value assigned to ``pyramid.includes`` should be a sequence. The sequence can take several different forms. 1) It can be a string. @@ -323,7 +323,7 @@ the behest of an add-on author. | | +---------------------------------+ -The value supplied as ``pyramid.tweens`` should be a sequence. The +The value assigned to ``pyramid.tweens`` should be a sequence. The sequence can take several different forms. 1) It can be a string. -- cgit v1.2.3 From 01c184719d026b8c61267e55b0646da9b86bd6a0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 3 Feb 2013 23:44:51 +0200 Subject: remove questionable sentence I could not tell whether it was meant to be humorous, or if it simply was a mistake. Regardless, I think it does not add much. If Speed needs to be defended, perhaps something better would do. For now, I remove. --- docs/narr/introduction.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index c4f2ea512..809732220 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -52,9 +52,7 @@ Documentation Speed :app:`Pyramid` is designed to provide noticeably fast execution for common - tasks such as templating and simple response generation. Although "hardware - is cheap", the limits of this approach become painfully evident when one - finds him or herself responsible for managing a great many machines. + tasks such as templating and simple response generation. Reliability :app:`Pyramid` is developed conservatively and tested exhaustively. Where -- cgit v1.2.3 From 1d3b11ea4c7ce0e05ca80063f997596791f75fda Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 4 Feb 2013 20:53:03 +0200 Subject: fix and shorten broken sentence --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index c4f2ea512..3540ee5c4 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -749,7 +749,7 @@ that we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own directives. For example, let's say you find yourself calling :meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can take the boring away by using existing shortcuts, but let's say that this is -a case such a way that no existing shortcut works to take the boring away: +a case where there is no such shortcut: .. code-block:: python :linenos: -- cgit v1.2.3 From bd070e77f4183a34507fe6f19604751cb78e3e8c Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 4 Feb 2013 21:15:08 +0200 Subject: unuglify Unix Python installation instructions --- docs/narr/install.rst | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c467779f4..e18716baa 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -88,17 +88,15 @@ using the following commands: .. code-block:: text - [chrism@vitaminf ~]$ cd ~ - [chrism@vitaminf ~]$ mkdir tmp - [chrism@vitaminf ~]$ mkdir opt - [chrism@vitaminf ~]$ cd tmp - [chrism@vitaminf tmp]$ wget \ - http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tgz - [chrism@vitaminf tmp]$ tar xvzf Python-2.7.3.tgz - [chrism@vitaminf tmp]$ cd Python-2.7.3 - [chrism@vitaminf Python-2.7.3]$ ./configure \ - --prefix=$HOME/opt/Python-2.7.3 - [chrism@vitaminf Python-2.7.3]$ make; make install + $ 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 -- cgit v1.2.3 From 148c7da017ef775932b2a4baeb0bd3057976adcc Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 4 Feb 2013 21:27:03 +0200 Subject: no need to be so specific This should reduce the frequency of needing to update it. --- 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 c467779f4..91e1cae6f 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -14,8 +14,8 @@ run :app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.6.8, - Python 2.7.3, Python 3.2.3, and Python 3.3b1. :app:`Pyramid` does not + As of this writing, :app:`Pyramid` has been tested under Python 2.6, + Python 2.7, Python 3.2, and Python 3.3. :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 -- cgit v1.2.3 From 37da2cf374792b2ab12ae39be6994540c9dfe623 Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Mon, 4 Feb 2013 15:23:46 -0800 Subject: narr/project.rst: Correct IP address 129.168.1.50 -> 192.168.1.50 --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index fb62f4bd2..5a8ea0ecf 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -297,7 +297,7 @@ 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://129.168.1.50:6543/``. However, *other people* on other computers on +``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/``. -- cgit v1.2.3 From cb659d206463607b5387878a857ead770c4df8cc Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 6 Feb 2013 23:25:42 +0200 Subject: displaying lineno for 1-line snippet is overkill --- docs/narr/configuration.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index cd3dab099..820dda269 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -144,7 +144,6 @@ In the example above, the scanner translates the arguments to .. ignore-next-block .. code-block:: python - :linenos: config.add_view(hello) -- cgit v1.2.3 From 6a4c6cb1c6ebe148e948726ddf668a3c2aa6c86c Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 6 Feb 2013 23:38:01 +0200 Subject: no need for a 'topic' directive --- docs/narr/configuration.rst | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index cd3dab099..4370367c0 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -99,29 +99,27 @@ available for a :term:`scan` to find it later. A :term:`scan` of a :term:`module` or a :term:`package` and its subpackages for decorations happens when the :meth:`pyramid.config.Configurator.scan` method is invoked: scanning implies searching for configuration declarations -in a package and its subpackages. For example: - -.. topic:: Starting A Scan - - .. code-block:: python - :linenos: - - from wsgiref.simple_server import make_server - from pyramid.config import Configurator - from pyramid.response import Response - from pyramid.view import view_config - - @view_config() - def hello(request): - return Response('Hello') - - if __name__ == '__main__': - from pyramid.config import Configurator - config = Configurator() - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8080, app) - server.serve_forever() +in a package and its subpackages. For example:: + +.. code-block:: python + :linenos: + + from wsgiref.simple_server import make_server + from pyramid.config import Configurator + from pyramid.response import Response + from pyramid.view import view_config + + @view_config() + def hello(request): + return Response('Hello') + + if __name__ == '__main__': + from pyramid.config import Configurator + config = Configurator() + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8080, app) + server.serve_forever() The scanning machinery imports each module and subpackage in a package or module recursively, looking for special attributes attached to objects -- cgit v1.2.3 From c7e558156dff1c8fdc96fe0382e48ca4d5bf8205 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 8 Feb 2013 20:48:08 +0200 Subject: fix a Sphinx warning --- docs/narr/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index cc26c55d9..6f82baf32 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -99,7 +99,7 @@ available for a :term:`scan` to find it later. A :term:`scan` of a :term:`module` or a :term:`package` and its subpackages for decorations happens when the :meth:`pyramid.config.Configurator.scan` method is invoked: scanning implies searching for configuration declarations -in a package and its subpackages. For example:: +in a package and its subpackages. For example: .. code-block:: python :linenos: -- cgit v1.2.3 From 1bdfad6c7303a810b05c60c53443dacc4d111852 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 9 Feb 2013 00:47:47 +0200 Subject: remove obvious, and therefore redundant, info --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index b092f73bc..85dfd5bf4 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -203,7 +203,7 @@ Installing Distribute On Python 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``setuptools`` doesn't work under Python 3. Instead, you can use -``distribute``, which is a fork of setuptools that does work on Python 3. To +``distribute``, which is a fork of setuptools. To install it, first download `distribute_setup.py `_ then invoke it using the Python interpreter into which you want to install setuptools. -- cgit v1.2.3 From 0d40143635c5a248453b881247db66d2ba1f8d00 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 9 Feb 2013 14:17:56 +0200 Subject: avoid repetition; the heading already mentions that this stuff is deprecated --- docs/narr/renderers.rst | 3 --- 1 file changed, 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 863932e83..34b9ad00c 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -565,9 +565,6 @@ in :ref:`request_module`. For more information on the API of Deprecated Mechanism to Vary Attributes of Rendered Responses ------------------------------------------------------------- -.. deprecated:: 1.1 - The behavior described in this entire section. - In previous releases of Pyramid (1.0 and before), the ``request.response`` attribute did not exist. Instead, Pyramid required users to set special ``response_`` -prefixed attributes of the request to influence response -- cgit v1.2.3 From c7a06f41d56d076dc979d800388c8befc1b8e5e5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 9 Feb 2013 19:54:32 -0500 Subject: fix warning block for newer docutils versions --- docs/narr/hooks.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 43bf48289..7d4d03b89 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -276,8 +276,10 @@ A lazy property can be registered to the request object via the to specify a callable that will be available on the request object, but will not actually execute the function until accessed. -.. warning:: This will silently override methods and properties from - :term:`request factory` that have the same name. +.. warning:: + + This will silently override methods and properties from :term:`request + factory` that have the same name. .. code-block:: python :linenos: -- cgit v1.2.3 From e3ed0ee85d3edc49740637e3bf76a04f1e6a6963 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 10 Feb 2013 13:31:12 +0200 Subject: use a more approriate Sphinx directive --- docs/narr/subrequest.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index b5bc5ec48..033f045a6 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -6,9 +6,7 @@ Invoking a Subrequest ===================== -.. warning:: - - This feature was added in Pyramid 1.4a1. +.. versionadded:: 1.4 :app:`Pyramid` allows you to invoke a subrequest at any point during the processing of a request. Invoking a subrequest allows you to obtain a -- cgit v1.2.3 From 800a1f3ed76b0d4ab3895f67b6d8c35d6f392ca7 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 11 Feb 2013 22:26:29 +0200 Subject: what was added? --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 8e360216d..0a5feafc4 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -505,7 +505,7 @@ using the :func:`pyramid.paster.bootstrap` command in the body of your script. .. versionadded:: 1.1 - This feature. + :func:`pyramid.paster.bootstrap` In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a single argument, which accepts the :term:`PasteDeploy` ``.ini`` file -- cgit v1.2.3 From 8c952d940272d883169973833ca215ac3248e94e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 13 Feb 2013 18:28:37 -0600 Subject: add import in code block --- docs/narr/renderers.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 34b9ad00c..08ebd881e 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -316,6 +316,7 @@ time "by hand". Configure a JSONP renderer using the .. code-block:: python from pyramid.config import Configurator + from pyramid.renderers import JSONP config = Configurator() config.add_renderer('jsonp', JSONP(param_name='callback')) -- cgit v1.2.3 From a33ac9438f62c6d85263c772d601d77e1b2b1e3c Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 22 Feb 2013 00:25:06 +0200 Subject: paster use is outdated --- docs/narr/environment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 281bb6919..fb3c3d7e3 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -546,7 +546,7 @@ for settings documented as such. For example, you might start your .. code-block:: text $ PYRAMID_DEBUG_AUTHORIZATION=1 PYRAMID_RELOAD_TEMPLATES=1 \ - bin/paster serve MyProject.ini + bin/pserve MyProject.ini If you started your application this way, your :app:`Pyramid` application would behave in the same manner as if you had placed the -- cgit v1.2.3 From 5b966a49227cbb9702d2b085b3658e3c91d9eed7 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 12:17:13 +0200 Subject: simplify sentence and fix its grammar --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 860c380f3..b9330b881 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -176,7 +176,7 @@ exception` objects. HTTP Exceptions ~~~~~~~~~~~~~~~ -All classes documented in the :mod:`pyramid.httpexceptions` module documented +All :mod:`pyramid.httpexceptions` classes which are documented as inheriting from the :class:`pyramid.httpexceptions.HTTPException` are :term:`http exception` objects. Instances of an HTTP exception object may either be *returned* or *raised* from within view code. In either case -- cgit v1.2.3 From 2afc385f203be30638db41673b3a771772184c81 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 12:36:06 +0200 Subject: make easier on the eyes Also fixes grammar, and removes repetition. --- docs/narr/views.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 860c380f3..7acec49e5 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -236,12 +236,11 @@ How Pyramid Uses HTTP Exceptions HTTP exceptions are meant to be used directly by application developers. However, Pyramid itself will raise two HTTP exceptions at various points during normal operations: -:exc:`pyramid.httpexceptions.HTTPNotFound` and -:exc:`pyramid.httpexceptions.HTTPForbidden`. Pyramid will raise the -:exc:`~pyramid.httpexceptions.HTTPNotFound` exception are raised when it -cannot find a view to service a request. Pyramid will raise the -:exc:`~pyramid.httpexceptions.Forbidden` exception or when authorization was -forbidden by a security policy. + +* :exc:`~pyramid.httpexceptions.HTTPNotFound` + gets raised when a view to service a request is not found. +* :exc:`~pyramid.httpexceptions.HTTPForbidden` + gets raised when authorization was forbidden by a security policy. If :exc:`~pyramid.httpexceptions.HTTPNotFound` is raised by Pyramid itself or within view code, the result of the :term:`Not Found View` will be returned -- cgit v1.2.3 From 580d74db2a032fa6c84662d1d89362f83d068d48 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 12:42:52 +0200 Subject: replace awkward explanation --- docs/narr/hooks.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 7d4d03b89..f38d57e73 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -15,9 +15,8 @@ Changing the Not Found View --------------------------- When :app:`Pyramid` can't map a URL to view code, it invokes a :term:`not -found view`, which is a :term:`view callable`. A default notfound view -exists. The default not found view can be overridden through application -configuration. +found view`, which is a :term:`view callable`. The default Not Found View +can be overridden through application configuration. If your application uses :term:`imperative configuration`, you can replace the Not Found view by using the -- cgit v1.2.3 From 1fbbb4dd9b4b735e1ba91f8eb25829ac96833566 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 18:58:16 +0200 Subject: this info was given in the preceding paragraph --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 7001cd980..eafec164e 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -68,7 +68,7 @@ the registered view callable will be invoked. The fewer number of predicates which are supplied to a particular view configuration, the more likely it is that the associated view callable will be invoked. A view with five predicates will always be found and evaluated before a view with two, for -example. All predicates must match for the associated view to be called. +example. This does not mean however, that :app:`Pyramid` "stops looking" when it finds a view registration with predicates that don't match. If one set -- cgit v1.2.3 From c0e0acd981a1bfbcf4c039e0439ea183d3ce41bf Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 25 Feb 2013 08:07:15 +0200 Subject: grammar --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 7001cd980..2d4caab40 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -293,7 +293,7 @@ configured view. This value can be any string or a sequence of strings. A view declaration with this argument ensures that the view will only be called when the :term:`request` has a key in the ``request.params`` dictionary (an HTTP - ``GET`` or ``POST`` variable) that has a name which matches the a + ``GET`` or ``POST`` variable) that has a name which matches the supplied value. If any value supplied has a ``=`` sign in it, -- cgit v1.2.3 From 58661e6744a9588e84988c2b02b4ebb913ab0ac3 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Feb 2013 01:50:02 +0200 Subject: grammar --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 2d4caab40..e7c79b09b 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -475,7 +475,7 @@ Adding View Configuration Using the ``@view_config`` Decorator .. warning:: - Using this feature tends to slows down application startup slightly, as + Using this feature tends to slow down application startup slightly, as more work is performed at application startup to scan for view configuration declarations. For maximum startup performance, use the view configuration method described in -- cgit v1.2.3 From 8b96432b0c285ae5422ef32c8e97284b20e7f678 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Feb 2013 02:16:14 +0200 Subject: improve paragraph --- docs/narr/viewconfig.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 7001cd980..126d7fd06 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -706,11 +706,10 @@ this method are very similar to the arguments that you provide to the # pyramid.config.Configurator class config.add_view(hello_world, route_name='hello') -The first argument, ``view``, is required. It must either be a Python object -which is the view itself or a :term:`dotted Python name` to such an object. -In the above example, ``view`` is the ``hello_world`` function. All other -arguments are optional. See :meth:`pyramid.config.Configurator.add_view` for -more information. +The first argument, a :term:`view callable`, is the only required argument. +It must either be a Python object which is the view itself or a +:term:`dotted Python name` to such an object. +In the above example, the ``view callable`` is the ``hello_world`` function. When you use only :meth:`~pyramid.config.Configurator.add_view` to add view configurations, you don't need to issue a :term:`scan` in order for the view -- cgit v1.2.3 From 16f2011492d96f1e6169bfbd05cd003192b07329 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Feb 2013 23:08:10 +0200 Subject: grammar --- docs/narr/templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 6a1fbf916..89024a34e 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -621,7 +621,7 @@ Debugging Templates ------------------- A :exc:`NameError` exception resulting from rendering a template with an -undefined variable (e.g. ``${wrong}``) might will end like this: +undefined variable (e.g. ``${wrong}``) might end up looking like this: .. code-block:: text -- cgit v1.2.3 From 6ffabc1e9d4cf18e9cedc25bb2134ad46debd89b Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 27 Feb 2013 21:05:06 +0200 Subject: readability --- docs/narr/commandline.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 0a5feafc4..48df6b9a8 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -276,10 +276,10 @@ exposed, and the request is configured to generate urls from the host IPython or bpython ~~~~~~~~~~~~~~~~~~ -If you have `IPython `_ or -`bpython `_ or both installed in +If you have `IPython `_ and/or +`bpython `_ in the interpreter you use to invoke the ``pshell`` command, ``pshell`` will -autodiscover them and use the first respectively found in this order : +autodiscover and use the first one found, in this order: IPython, bpython, standard Python interpreter. However you could specifically invoke one of your choice with the ``-p choice`` or ``--python-shell choice`` option. -- cgit v1.2.3 From ca402b50f2440b3ab7d7e0d9d058e72c20e9948b Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 27 Feb 2013 23:15:12 +0200 Subject: should be one word --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 20017064b..d5624469c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -70,7 +70,7 @@ Test Set Up and Tear Down -------------------------- :app:`Pyramid` uses a "global" (actually :term:`thread local`) data structure -to hold on to two items: the current :term:`request` and the current +to hold onto two items: the current :term:`request` and the current :term:`application registry`. These data structures are available via the :func:`pyramid.threadlocal.get_current_request` and :func:`pyramid.threadlocal.get_current_registry` functions, respectively. -- cgit v1.2.3 From 78080559e7add3203fbba64c03f2ae7d348cebb9 Mon Sep 17 00:00:00 2001 From: David Beitey Date: Thu, 28 Feb 2013 10:44:57 +1000 Subject: Update & clarify logging documentation Ensure that ``handlers`` is highlighted to be modified when adding an access log handler. --- docs/narr/logging.rst | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index f4c38abb6..f4d1d051d 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -350,7 +350,7 @@ called with no arguments, so it 'just works' in environments that don't configure logging. Since we've configured our own logging handlers, we need to disable that option via ``setup_console_handler = False``. -With the filter in place, TransLogger's logger (named the 'wsgi' logger) will +With the filter in place, TransLogger's logger (named the ``wsgi`` logger) will propagate its log messages to the parent logger (the root logger), sending its output to the console when we request a page: @@ -364,14 +364,18 @@ its output to the console when we request a page: Firefox/2.0.0.6" To direct TransLogger to an ``access.log`` FileHandler, we need to add that -FileHandler to the wsgi logger's list of handlers: +FileHandler to the list of handlers (named ``accesslog``), and ensure that the +``wsgi`` logger is configured and uses this handler accordingly: .. code-block:: ini # Begin logging configuration - [loggers] - keys = root, myapp, wsgi + [loggers] + keys = root, myapp, wsgi + + [handlers] + keys = console, accesslog [logger_wsgi] level = INFO @@ -387,20 +391,19 @@ FileHandler to the wsgi logger's list of handlers: As mentioned above, non-root loggers by default propagate their log records to the root logger's handlers (currently the console handler). Setting -``propagate`` to 0 (false) here disables this; so the ``wsgi`` logger directs -its records only to the ``accesslog`` handler. +``propagate`` to ``0`` (``False``) here disables this; so the ``wsgi`` logger +directs its records only to the ``accesslog`` handler. Finally, there's no need to use the ``generic`` formatter with TransLogger as TransLogger itself provides all the information we need. We'll use a -formatter that passes-through the log messages as is: +formatter that passes-through the log messages as is. Add a new formatter +called ``accesslog`` by include the following in your configuration file: .. code-block:: ini [formatters] keys = generic, accesslog -.. code-block:: ini - [formatter_accesslog] format = %(message)s -- cgit v1.2.3 From a85491f3cec005e9592c86bd78b66ec0d7a8e599 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Sun, 3 Mar 2013 15:41:37 -0500 Subject: No preposition needed at all. ;) --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index d5624469c..0801a8eae 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -70,7 +70,7 @@ Test Set Up and Tear Down -------------------------- :app:`Pyramid` uses a "global" (actually :term:`thread local`) data structure -to hold onto two items: the current :term:`request` and the current +to hold two items: the current :term:`request` and the current :term:`application registry`. These data structures are available via the :func:`pyramid.threadlocal.get_current_request` and :func:`pyramid.threadlocal.get_current_registry` functions, respectively. -- cgit v1.2.3 From eb3cee262ef52480198fc7f506debe0f35e3554a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 4 Mar 2013 22:30:32 +0200 Subject: fix #311 --- docs/narr/MyProject/setup.py | 6 ++++-- docs/narr/commandline.rst | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index f24b6984e..6969c73e7 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -3,8 +3,10 @@ import os from setuptools import setup, find_packages here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() +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 = [ 'pyramid', diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 48df6b9a8..5c4d58548 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -775,8 +775,10 @@ top-level directory your ``setup.py`` file will look something like this: from setuptools import setup, find_packages here = os.path.abspath(os.path.dirname(__file__)) - README = open(os.path.join(here, 'README.txt')).read() - CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + 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 = ['pyramid', 'pyramid_debugtoolbar'] @@ -830,8 +832,10 @@ The result will be something like: from setuptools import setup, find_packages here = os.path.abspath(os.path.dirname(__file__)) - README = open(os.path.join(here, 'README.txt')).read() - CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + 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 = ['pyramid', 'pyramid_debugtoolbar'] -- cgit v1.2.3 From 2605e0cc2ad089d4f25c00a5f2c4d99ffbfa4567 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 22:57:05 +0200 Subject: grammar fixes --- docs/narr/project.rst | 4 ++-- docs/narr/router.rst | 2 +- docs/narr/urldispatch.rst | 8 ++++---- docs/narr/viewconfig.rst | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 5a8ea0ecf..184d36512 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -829,7 +829,7 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 4-11 defines a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. @@ -865,7 +865,7 @@ and which returns a :term:`response`. :language: python :linenos: -Lines 4-6 define and register a :term:`view callable` named ``my_view``. The +Lines 4-6 defines and registers a :term:`view callable` named ``my_view``. The function named ``my_view`` is decorated with a ``view_config`` decorator (which is processed by the ``config.scan()`` line in our ``__init__.py``). The view_config decorator asserts that this view be found when a diff --git a/docs/narr/router.rst b/docs/narr/router.rst index b78362066..ac3deefdc 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -46,7 +46,7 @@ request enters a :app:`Pyramid` application through to the point that :class:`~pyramid.interfaces.IRoute` object representing the route which matched. The root object associated with the route found is also generated: if the :term:`route configuration` which matched has an - associated a ``factory`` argument, this factory is used to generate the + 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 diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 749a2d49a..34543c4bb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -16,12 +16,12 @@ receives the :term:`request` and returns a :term:`response` object. High-Level Operational Overview ------------------------------- -If route configuration is present in an application, the :app:`Pyramid` +If a route configuration is present in an application, the :app:`Pyramid` :term:`Router` checks every incoming request against an ordered set of URL matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request`, -:app:`Pyramid` will invoke :term:`view lookup` to find a matching view. +:app:`Pyramid` will invoke a :term:`view lookup` to find a matching view. If no route pattern in the route map matches the information in the :term:`request` provided in your application, :app:`Pyramid` will fail over @@ -71,7 +71,7 @@ invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's "setup" code, instead only using ``add_route`` statements using a -:term:`scan` for to associate view callables with routes. For example, if +:term:`scan` to associate view callables with routes. For example, if this is a portion of your project's ``__init__.py``: .. code-block:: python @@ -83,7 +83,7 @@ this is a portion of your project's ``__init__.py``: Note that we don't call :meth:`~pyramid.config.Configurator.add_view` in this setup code. However, the above :term:`scan` execution -``config.scan('mypackage')`` will pick up all :term:`configuration +``config.scan('mypackage')`` will pick up each :term:`configuration decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python package. For example, if you have a ``views.py`` in your package, a scan will diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e7c79b09b..63f9d1db5 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -62,9 +62,9 @@ particular view callable. :term:`View predicate` attributes are an important part of view configuration that enables the :term:`view lookup` subsystem to find and invoke the -appropriate view. The greater number of predicate attributes possessed by a +appropriate view. The greater the number of predicate attributes possessed by a view's configuration, the more specific the circumstances need to be before -the registered view callable will be invoked. The fewer number of predicates +the registered view callable will be invoked. The fewer the number of predicates which are supplied to a particular view configuration, the more likely it is that the associated view callable will be invoked. A view with five predicates will always be found and evaluated before a view with two, for -- cgit v1.2.3 From cd8ac801ac1ccefb81c2e015124be910cb8c93de Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 15 Feb 2013 00:48:08 +0200 Subject: update some links and fix others --- 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 f38d57e73..20cadc996 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -711,7 +711,7 @@ The API that must be implemented by your a class that provides The default context URL generator is available for perusal as the class :class:`pyramid.traversal.ResourceURL` in the `traversal module -`_ of the +`_ of the :term:`Pylons` GitHub Pyramid repository. See :meth:`pyramid.config.add_resource_url_adapter` for more information. -- cgit v1.2.3 From 62ea1b60f18d8ac0bab2331852f9ef8bee1fad57 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 01:10:49 +0200 Subject: fix link --- docs/narr/paste.rst | 2 ++ docs/narr/startup.rst | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index 86b047aec..efec1f092 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -85,6 +85,8 @@ function. This is the function called by :term:`PasteDeploy` when the ``pserve`` command is invoked against our application. It accepts a global configuration object and *returns* an instance of our application. +.. _defaults_section_of_pastedeploy_file: + ``[DEFAULTS]`` Section of a PasteDeploy ``.ini`` File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index f5c741f52..3a9225032 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -77,9 +77,9 @@ Here's a high-level time-ordered overview of what happens when you press Note that the constructor function accepts a ``global_config`` argument, which is a dictionary of key/value pairs mentioned in the ``[DEFAULT]`` - section of an ``.ini`` file (if `[DEFAULT] - `__ - is present). It also accepts a ``**settings`` argument, which collects + section of an ``.ini`` file + (if :ref:`[DEFAULT] ` is present). + It also accepts a ``**settings`` argument, which collects another set of arbitrary key/value pairs. The arbitrary key/value pairs received by this function in ``**settings`` will be composed of all the key/value pairs that are present in the ``[app:main]`` section (except for -- cgit v1.2.3 From 32c508a8d8870e877dd6d98e717e55b56457de8a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 21:50:53 +0200 Subject: use cross-references to fix some links Also fix grammar, and add a bit of consistency regarding formatting. --- docs/narr/logging.rst | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index f4d1d051d..bef9d119c 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -28,19 +28,17 @@ application. In particular, the :term:`PasteDeploy` ``development.ini`` and ``production.ini`` files created when you use a scaffold include a basic configuration for the Python :mod:`logging` package. -PasteDeploy ``.ini`` files use the Python standard library `ConfigParser -format `_; this the same -format used as the Python `logging module's Configuration file format -`_. The -application-related and logging-related sections in the configuration file +PasteDeploy ``.ini`` files use the Python standard library :mod:`ConfigParser +format `; this is the same format used as the Python +:ref:`logging module's Configuration file format `. +The application-related and logging-related sections in the configuration file can coexist peacefully, and the logging-related sections in the file are used from when you run ``pserve``. The ``pserve`` command calls the :func:`pyramid.paster.setup_logging` -function, a thin wrapper around the `logging.fileConfig -`_ using the specified -ini file if it contains a ``[loggers]`` section (all of the -scaffold-generated ``.ini`` files do). ``setup_logging`` reads the +function, a thin wrapper around the :func:`logging.config.fileConfig` +using the specified ``.ini`` file if it contains a ``[loggers]`` section +(all of the scaffold-generated ``.ini`` files do). ``setup_logging`` reads the logging configuration from the ini file upon which ``pserve`` was invoked. -- cgit v1.2.3 From 6ad5fb2a48c9a0c081eb3e2b138752bc8c4e63fb Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 18 Feb 2013 23:14:16 +0200 Subject: fix links --- docs/narr/paste.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index efec1f092..0b3457d1e 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -21,7 +21,7 @@ of starting, stopping, and debugging an application. This chapter is not a replacement for documentation about PasteDeploy; it only contextualizes the use of PasteDeploy within Pyramid. For detailed -documentation, see http://pythonpaste.org. +documentation, see http://pythonpaste.org/deploy/. PasteDeploy ----------- -- cgit v1.2.3 From 75ebabe886bbbe14c873e60597f16531c151a867 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 19 Feb 2013 23:26:45 +0200 Subject: fix broken link --- docs/narr/i18n.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 511464322..24cd3ff54 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -736,9 +736,7 @@ through translation before being rendered: The features represented by attributes of the ``i18n`` namespace of Chameleon will also consult the :app:`Pyramid` translations. -See -`http://chameleon.repoze.org/docs/latest/i18n.html#the-i18n-namespace -`_. +See http://chameleon.readthedocs.org/en/latest/reference.html#id50. .. note:: -- cgit v1.2.3 From 9547903b00196b7311b6f0c26f42fed78a91e933 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 19 Feb 2013 23:34:56 +0200 Subject: rm broken link; could not find existing equivalent --- docs/narr/introduction.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 3540ee5c4..47c32b0ba 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -219,7 +219,6 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: http://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 04a662656deeafe0a8db61d29c64733181badb73 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 11:55:14 +0200 Subject: DRY --- docs/narr/firstapp.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index d61d95685..ab6a46c2f 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -175,9 +175,9 @@ First line above calls the :meth:`pyramid.config.Configurator.add_route` method, which registers a :term:`route` to match any URL path that begins with ``/hello/`` followed by a string. -The second line, ``config.add_view(hello_world, route_name='hello')``, -registers the ``hello_world`` function as a :term:`view callable` and makes -sure that it will be called when the ``hello`` route is matched. +The second line registers the ``hello_world`` function as a +:term:`view callable` and makes sure that it will be called when the +``hello`` route is matched. .. index:: single: make_wsgi_app -- cgit v1.2.3 From 3284496e797e07695a2b190b83619fc34f670d0a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 22:45:09 +0200 Subject: DRY --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 5a8ea0ecf..5ddf89ec4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -703,7 +703,7 @@ work properly. The ``setup.py`` file is a :term:`setuptools` setup file. It is meant to be run directly from the command line to perform a variety of functions, such as -testing your application, packaging, and distributing your application. +testing, packaging, and distributing your application. .. note:: -- cgit v1.2.3 From 5c9da6debe11b52975fb296be55a4dcd8c41c533 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 17 Feb 2013 22:35:32 +0200 Subject: DRY --- docs/narr/urldispatch.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 749a2d49a..6cdcd81fb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -76,8 +76,6 @@ this is a portion of your project's ``__init__.py``: .. code-block:: python - # in your project's __init__.py (mypackage.__init__) - config.add_route('myroute', '/prefix/{one}/{two}') config.scan('mypackage') -- cgit v1.2.3 From 67486e9eec17b0209aebc9b2f2220fa704f23825 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 17 Feb 2013 22:47:39 +0200 Subject: DRY --- docs/narr/urldispatch.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 6cdcd81fb..2a7adea81 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -90,8 +90,6 @@ that references ``myroute`` as a ``route_name`` parameter: .. code-block:: python - # in your project's views.py module (mypackage.views) - from pyramid.view import view_config from pyramid.response import Response -- cgit v1.2.3 From 08f4a6ea291e065e56792ecde89abdeb0c57651f Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 18:07:35 +0200 Subject: a more concise explanation * This removes an needless example (it should really be obvious what the text means). * It also fixes an incomplete sentence, which also happens to have broken grammar. --- docs/narr/project.rst | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 5a8ea0ecf..959583ee2 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -459,20 +459,9 @@ Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: Then restart the application to see that the toolbar has been turned off. Note that if you comment out the ``pyramid_debugtoolbar`` line, the ``#`` -*must* be in the first column. If you put the hash mark anywhere except the -first column instead, for example like this: - -.. code-block:: ini - :linenos: - - [app:main] - ... - pyramid.includes = - #pyramid_debugtoolbar - -When you attempt to restart the application with a section like the above -you'll receive an error that ends something like this, and the application -will not start: +*must* be in the first column. If you put it anywhere else, +and then attempt to restart the application, +you'll receive an error that ends something like this: .. code-block:: text -- cgit v1.2.3 From c4c182b47d1abdf899077ecd433a268618f4f493 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 18:30:02 +0200 Subject: be more concise, and simplify * It should be obvious which file is referred to * Fix a typo * 'points at a string' is not ideal when referring to Python --- docs/narr/paste.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index 86b047aec..aee5f9069 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -62,7 +62,7 @@ Take a look at the generated ``setup.py`` file for this project. :language: python :linenos: -Note that the ``entry_point`` line in ``setup.py`` points at a string which +Note that ``entry_points`` is assigned a string which looks a lot like an ``.ini`` file. This string representation of an ``.ini`` file has a section named ``[paste.app_factory]``. Within this section, there is a key named ``main`` (the entry point name) which has a value -- cgit v1.2.3 From 5fd55bfc4eef314cab34cd485e0933e1b17bc5cf Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 01:39:35 +0200 Subject: fix wrong highlighting --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 5c4d58548..3fa3a1291 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -399,7 +399,7 @@ Here's the application configuration section of the ``development.ini`` used by the above ``ptweens`` command which reports that the explicit tween chain is used: -.. code-block:: text +.. code-block:: ini :linenos: [app:main] -- cgit v1.2.3 From 3144affbb05ecea581d0e1cc612a3e1672b55181 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 16:41:11 +0200 Subject: fix markup --- docs/narr/environment.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index fb3c3d7e3..c8a666b90 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -212,7 +212,7 @@ sequence can take several different forms. package1 package2 package3 - The package names can also be separated by carriage returns:: + The package names can also be separated by carriage returns:: package1 package2 -- cgit v1.2.3 From ea87985307731d1ad8597a8e37b7fb9c7950f11f Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 22:32:07 +0200 Subject: missing word --- docs/narr/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index f4d1d051d..6492bf371 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -334,7 +334,7 @@ To this: mypyramidapp Using PasteDeploy this way to form and serve a pipeline is equivalent to -wrapping your app in a TransLogger instance via the bottom the ``main`` +wrapping your app in a TransLogger instance via the bottom of the ``main`` function of your project's ``__init__`` file: .. code-block:: python -- cgit v1.2.3 From 6a2827684a13bb588b031f4ac9a6257344bb4e18 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 17 Feb 2013 22:47:53 +0200 Subject: fix grammar; shorten overlong sentence --- docs/narr/urldispatch.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 749a2d49a..7e460c885 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -70,8 +70,8 @@ via its ``route_name`` predicate, that view callable will always be found and invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's -"setup" code, instead only using ``add_route`` statements using a -:term:`scan` for to associate view callables with routes. For example, if +"setup" code. You will instead use ``add_route`` statements, and use a +:term:`scan` to associate view callables with routes. For example, if this is a portion of your project's ``__init__.py``: .. code-block:: python -- cgit v1.2.3 From feee096963f9c64681210d1fd11de337a5c9afbc Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 13:01:48 +0200 Subject: add missing word, add a :term: role where it was missing, improve readability --- docs/narr/views.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 8ebdfe219..afc2787ca 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -264,9 +264,9 @@ also be used by application developers to convert arbitrary exceptions to responses. To register a view that should be called whenever a particular exception is -raised from with :app:`Pyramid` view code, use the exception class or one of -its superclasses as the ``context`` of a view configuration which points at a -view callable you'd like to generate a response. +raised from within :app:`Pyramid` view code, use the exception class (or one of +its superclasses) as the :term:`context` of a view configuration which points +at a view callable you'd like to generate a response for. For example, given the following exception class in a module named ``helloworld.exceptions``: -- cgit v1.2.3 From bdbf854c95406c06c5b5e1bf85a89e5c961424f0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 18:26:32 +0200 Subject: we want 4-space indents --- docs/narr/views.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index afc2787ca..077d27366 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -542,7 +542,7 @@ The following types work as view callables in this style: from pyramid.response import Response def view(context, request): - return Response('OK') + return Response('OK') #. Classes that have an ``__init__`` method that accepts ``context, request`` and a ``__call__`` method which accepts no arguments, e.g.: @@ -553,12 +553,12 @@ The following types work as view callables in this style: from pyramid.response import Response class view(object): - def __init__(self, context, request): - self.context = context - self.request = request + def __init__(self, context, request): + self.context = context + self.request = request - def __call__(self): - return Response('OK') + def __call__(self): + return Response('OK') #. Arbitrary callables that have a ``__call__`` method that accepts ``context, request``, e.g.: @@ -569,8 +569,8 @@ The following types work as view callables in this style: from pyramid.response import Response class View(object): - def __call__(self, context, request): - return Response('OK') + def __call__(self, context, request): + return Response('OK') view = View() # this is the view callable This style of calling convention is most useful for :term:`traversal` based -- cgit v1.2.3 From 02e6877a79fe7874af5103d9e6c886d67a09eb7f Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 6 Mar 2013 00:09:54 +0200 Subject: address issues raised by Tres Seaver at #884 --- docs/narr/project.rst | 4 ++-- docs/narr/urldispatch.rst | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 184d36512..5a8ea0ecf 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -829,7 +829,7 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Lines 4-11 defines a function named ``main`` that returns a :app:`Pyramid` +#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. @@ -865,7 +865,7 @@ and which returns a :term:`response`. :language: python :linenos: -Lines 4-6 defines and registers a :term:`view callable` named ``my_view``. The +Lines 4-6 define and register a :term:`view callable` named ``my_view``. The function named ``my_view`` is decorated with a ``view_config`` decorator (which is processed by the ``config.scan()`` line in our ``__init__.py``). The view_config decorator asserts that this view be found when a diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 34543c4bb..e58d98416 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -16,12 +16,13 @@ receives the :term:`request` and returns a :term:`response` object. High-Level Operational Overview ------------------------------- -If a route configuration is present in an application, the :app:`Pyramid` +If any route configuration is present in an application, the :app:`Pyramid` :term:`Router` checks every incoming request against an ordered set of URL matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request`, -:app:`Pyramid` will invoke a :term:`view lookup` to find a matching view. +:app:`Pyramid` will invoke the :term:`view lookup` process to find a +matching view. If no route pattern in the route map matches the information in the :term:`request` provided in your application, :app:`Pyramid` will fail over -- cgit v1.2.3 From 58577149d79ed4e5aae6a90423c5b43edd811987 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 6 Mar 2013 01:11:12 +0200 Subject: fix typo, and change meaning --- docs/narr/templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 89024a34e..08fa9883e 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -524,7 +524,7 @@ And ``templates/mytemplate.pt`` might look like so: Using A Chameleon Macro Name Within a Renderer Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Sommetime you'd like to render a macro inside of a Chameleon ZPT template +At times, you may want to render a macro inside of a Chameleon ZPT template instead of the full Chameleon ZPT template. To render the content of a ``define-macro`` field inside a Chameleon ZPT template, given a Chameleon template file named ``foo.pt`` and a macro named ``bar`` defined within it -- cgit v1.2.3 From 38669d5403206693625ec3d09944d3c7b4eb6ce6 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 13 Feb 2013 01:50:27 +0200 Subject: provide .INI highlighting --- docs/narr/project.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 214440328..a9072e3bf 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -305,7 +305,9 @@ 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 ``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 -example:: +example: + +.. code-block:: ini [server:main] use = egg:waitress#main -- cgit v1.2.3 From 75e2cb6f3cfa97716a2ccd14b5ea8db72138f533 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 01:39:03 +0200 Subject: remove some clutter --- docs/narr/commandline.rst | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 5c4d58548..8ad153187 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -146,7 +146,7 @@ name ``main`` as a section name: .. code-block:: text - chrism@thinko env26]$ bin/pshell starter/development.ini#main + $ bin/pshell starter/development.ini#main Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -181,7 +181,7 @@ hash after the filename: .. code-block:: text - chrism@thinko env26]$ bin/pshell starter/development.ini + $ bin/pshell starter/development.ini Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). @@ -244,7 +244,7 @@ exposed, and the request is configured to generate urls from the host .. code-block:: text - chrism@thinko env26]$ bin/pshell starter/development.ini + $ bin/pshell starter/development.ini Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -286,8 +286,7 @@ specifically invoke one of your choice with the ``-p choice`` or .. code-block:: text - [chrism@vitaminf shellenv]$ ../bin/pshell -p ipython | bpython | python \ - development.ini#MyProject + $ ../bin/pshell -p ipython | bpython | python development.ini#MyProject .. index:: pair: routes; printing @@ -312,7 +311,7 @@ For example: .. code-block:: text :linenos: - [chrism@thinko MyProject]$ ../bin/proutes development.ini + $ ../bin/proutes development.ini Name Pattern View ---- ------- ---- home / @@ -355,7 +354,7 @@ configured without any explicit tweens: .. code-block:: text :linenos: - [chrism@thinko pyramid]$ myenv/bin/ptweens development.ini + $ myenv/bin/ptweens development.ini "pyramid.tweens" config value NOT set (implicitly ordered tweens used) Implicit Tween Chain @@ -373,7 +372,7 @@ explicit tweens defined in its ``development.ini`` file: .. code-block:: text :linenos: - [chrism@thinko pyramid]$ ptweens development.ini + $ ptweens development.ini "pyramid.tweens" config value set (explicitly ordered tweens used) Explicit Tween Chain (used) @@ -878,9 +877,7 @@ 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``:: - [chrism@thinko somevenv]$ bin/show_settings development.ini \ - --omit=pyramid \ - --omit=debugtoolbar + $ bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar debug_routematch False debug_templates True reload_templates True -- cgit v1.2.3 From 70b951b47c31af883aa7a6a5853d9265db7f6fdb Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 17:06:04 +0200 Subject: improve readability --- docs/narr/environment.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index fb3c3d7e3..1ac59bfb6 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -666,9 +666,9 @@ Here's how: def includeme(config): settings = config.registry.settings debug_frobnosticator = settings['debug_frobnosticator'] - -- In the runtime code that you need to access the new settings value, find - the value in the ``registry.settings`` dictionary and use it. In + +- In the runtime code from where you need to access the new settings value, + find the value in the ``registry.settings`` dictionary and use it. In :term:`view` code (or any other code that has access to the request), the easiest way to do this is via ``request.registry.settings``. For example: -- cgit v1.2.3 From 5e63681b1ee7da70e3249509f639b04701e76669 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 16 Feb 2013 21:32:36 +0200 Subject: better to use a cross-reference --- docs/narr/logging.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index f4d1d051d..36f41562a 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -22,8 +22,8 @@ Logging Configuration --------------------- A :app:`Pyramid` project created from a :term:`scaffold` is configured to -allow you to send messages to `Python standard library logging package -`_ loggers from within your +allow you to send messages to :mod:`Python standard library logging package +` loggers from within your application. In particular, the :term:`PasteDeploy` ``development.ini`` and ``production.ini`` files created when you use a scaffold include a basic configuration for the Python :mod:`logging` package. -- cgit v1.2.3 From 255cba2fde47f54ceae6ddf65174a6c02f308a16 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 13:11:20 +0200 Subject: uncapitalize --- docs/narr/views.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 8ebdfe219..cc443eb25 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -353,7 +353,7 @@ Exception views can be configured with any view registration mechanism: .. _http_redirect: -Using a View Callable to Do an HTTP Redirect +Using a View Callable to do an HTTP Redirect -------------------------------------------- You can issue an HTTP redirect by using the -- cgit v1.2.3 From 55d81bb135834ec1c2b89860398d5b864ce90cae Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 18:23:06 +0200 Subject: a touch of consistency --- docs/narr/views.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index cc443eb25..6120fa99f 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -524,7 +524,6 @@ The :term:`context` and :term:`request` arguments passed to a view function defined in this style can be defined as follows: context - The :term:`resource` object found via tree :term:`traversal` or :term:`URL dispatch`. -- cgit v1.2.3 From 03e38b7d8cee16292fe58433c5883b7f01908f66 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Feb 2013 18:51:00 +0200 Subject: capitalize --- docs/narr/viewconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e7c79b09b..792bf31d9 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -38,11 +38,11 @@ A view configuration statement is made about information present in the View configuration is performed in one of two ways: -- by running a :term:`scan` against application source code which has a +- By running a :term:`scan` against application source code which has a :class:`pyramid.view.view_config` decorator attached to a Python object as per :ref:`mapping_views_using_a_decorator_section`. -- by using the :meth:`pyramid.config.Configurator.add_view` method as per +- By using the :meth:`pyramid.config.Configurator.add_view` method as per :ref:`mapping_views_using_imperative_config_section`. .. index:: -- cgit v1.2.3 From 5d3e517aab23d7d40c6ee147ad0395855e337451 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Feb 2013 22:39:54 +0200 Subject: remove a distraction --- docs/narr/urldispatch.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2a7adea81..1ae7abcbc 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -875,8 +875,7 @@ which you started the application from. For example: .. code-block:: text :linenos: - [chrism@thinko pylonsbasic]$ PYRAMID_DEBUG_ROUTEMATCH=true \ - bin/pserve development.ini + $ PYRAMID_DEBUG_ROUTEMATCH=true bin/pserve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ -- cgit v1.2.3 From 5a20a11be7971e2d4676a7edd46fa1789525d232 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Feb 2013 22:50:13 +0200 Subject: brevity --- docs/narr/commandline.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 8ad153187..c7aed595f 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -320,8 +320,8 @@ For example: static/ static/*subpath catchall /*subpath -``proutes`` generates a table. The table has three columns: a Name -column, a Pattern column, and a View column. The items listed in the +``proutes`` generates a table with three columns: *Name*, *Pattern*, +and *View*. The items listed in the Name column are route names, the items listed in the Pattern column are route patterns, and the items listed in the View column are representations of the view callable that will be invoked when a request matches the associated -- cgit v1.2.3 From 136a1ec15e9f9558b87a35ec0274b56793119019 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 8 Mar 2013 01:08:21 +0200 Subject: 2.5 no longer supported --- docs/narr/viewconfig.rst | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e7c79b09b..9f3b91c26 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -583,8 +583,7 @@ If your view callable is a function, it may be used as a function decorator: return Response('edited!') If your view callable is a class, the decorator can also be used as a class -decorator in Python 2.6 and better (Python 2.5 and below do not support class -decorators). All the arguments to the decorator are the same when applied +decorator. All the arguments to the decorator are the same when applied against a class as when they are applied against a function. For example: .. code-block:: python @@ -601,25 +600,6 @@ against a class as when they are applied against a function. For example: def __call__(self): return Response('hello') -You can use the :class:`~pyramid.view.view_config` decorator as a simple -callable to manually decorate classes in Python 2.5 and below without the -decorator syntactic sugar, if you wish: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - from pyramid.view import view_config - - class MyView(object): - def __init__(self, request): - self.request = request - - def __call__(self): - return Response('hello') - - my_view = view_config(route_name='hello')(MyView) - More than one :class:`~pyramid.view.view_config` decorator can be stacked on top of any number of others. Each decorator creates a separate view registration. For example: -- cgit v1.2.3 From 2f4bdefd18073c418ae95fe9e5a8c7b2a9d1130e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 9 Mar 2013 03:06:17 +0200 Subject: capitalize; add term role --- docs/narr/assets.rst | 2 +- docs/narr/hooks.rst | 14 +++++++------- docs/narr/traversal.rst | 2 +- docs/narr/urldispatch.rst | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 7b620548d..deaf0ce08 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -323,7 +323,7 @@ its behavior is almost exactly the same once it's configured. ``add_view`` (at least those without a ``route_name``). A :class:`~pyramid.static.static_view` static view cannot be made root-relative when you use traversal unless it's registered as a - :term:`Not Found view`. + :term:`Not Found View`. To serve files within a directory located on your filesystem at ``/path/to/static/dir`` as the result of a "catchall" route hanging from the diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index f38d57e73..d7af5ab98 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -19,7 +19,7 @@ found view`, which is a :term:`view callable`. The default Not Found View can be overridden through application configuration. If your application uses :term:`imperative configuration`, you can replace -the Not Found view by using the +the Not Found View by using the :meth:`pyramid.config.Configurator.add_notfound_view` method: .. code-block:: python @@ -29,7 +29,7 @@ the Not Found view by using the config.add_notfound_view(notfound) Replace ``helloworld.views.notfound`` with a reference to the :term:`view -callable` you want to use to represent the Not Found view. The :term:`not +callable` you want to use to represent the Not Found View. The :term:`not found view` callable is a view callable like any other. If your application instead uses :class:`pyramid.view.view_config` decorators @@ -51,12 +51,12 @@ and a :term:`scan`, you can replace the Not Found view by using the This does exactly what the imperative example above showed. -Your application can define *multiple* not found views if necessary. Both +Your application can define *multiple* Not Found Views if necessary. Both :meth:`pyramid.config.Configurator.add_notfound_view` and :class:`pyramid.view.notfound_view_config` take most of the same arguments as :class:`pyramid.config.Configurator.add_view` and -:class:`pyramid.view.view_config`, respectively. This means that not found -views can carry predicates limiting their applicability. For example: +:class:`pyramid.view.view_config`, respectively. This means that Not Found +Views can carry predicates limiting their applicability. For example: .. code-block:: python :linenos: @@ -106,8 +106,8 @@ Here's some sample code that implements a minimal NotFound view callable: When a NotFound view callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will be an instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that - caused the not found view to be called. The value of - ``request.exception.message`` will be a value explaining why the not found + caused the Not Found View to be called. The value of + ``request.exception.message`` will be a value explaining why the Not Found error was raised. This message will be different when the ``pyramid.debug_notfound`` environment setting is true than it is when it is false. diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index 8e7f93a1b..1234620c2 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -389,7 +389,7 @@ Using the :term:`view name` (``baz``) and the type, view lookup asks the Let's say that view lookup finds no matching view type. In this circumstance, the :app:`Pyramid` :term:`router` returns the result of the -:term:`not found view` and the request ends. +:term:`Not Found View` and the request ends. However, for this tree: diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2a7adea81..16af4d088 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -814,7 +814,7 @@ bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash``, a route *will* be -found by the slash-appending not found view. An HTTP redirect to +found by the slash-appending :term:`Not Found View`. An HTTP redirect to ``/has_slash/`` will be returned to the user's browser. As a result, the ``notfound`` view will never actually be called. @@ -849,12 +849,12 @@ exactly the same job: .. warning:: You **should not** rely on this mechanism to redirect ``POST`` requests. - The redirect of the slash-appending not found view will turn a ``POST`` - request into a ``GET``, losing any ``POST`` data in the original + The redirect of the slash-appending :term:`Not Found View` will turn a + ``POST`` request into a ``GET``, losing any ``POST`` data in the original request. See :ref:`view_module` and :ref:`changing_the_notfound_view` for a more -general description of how to configure a view and/or a not found view. +general description of how to configure a view and/or a :term:`Not Found View`. .. index:: pair: debugging; route matching -- cgit v1.2.3 From cec2b05e74b3296ab8b54b9644223e08f269808b Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 9 Mar 2013 03:15:15 +0200 Subject: consistency --- docs/narr/hooks.rst | 9 +++++---- docs/narr/viewconfig.rst | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index d7af5ab98..d103ca1cd 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -79,7 +79,7 @@ The ``notfound_get`` view will be called when a view could not be found and the request method was ``GET``. The ``notfound_post`` view will be called when a view could not be found and the request method was ``POST``. -Like any other view, the notfound view must accept at least a ``request`` +Like any other view, the Not Found View must accept at least a ``request`` parameter, or both ``context`` and ``request``. The ``request`` is the current :term:`request` representing the denied action. The ``context`` (if used in the call signature) will be the instance of the @@ -91,7 +91,8 @@ Both :meth:`pyramid.config.Configurator.add_notfound_view` and redirect requests to slash-appended routes. See :ref:`redirecting_to_slash_appended_routes` for examples. -Here's some sample code that implements a minimal NotFound view callable: +Here's some sample code that implements a minimal :term:`Not Found View` +callable: .. code-block:: python :linenos: @@ -103,7 +104,7 @@ Here's some sample code that implements a minimal NotFound view callable: .. note:: - When a NotFound view callable is invoked, it is passed a + When a Not Found View callable is invoked, it is passed a :term:`request`. The ``exception`` attribute of the request will be an instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the Not Found View to be called. The value of @@ -122,7 +123,7 @@ Here's some sample code that implements a minimal NotFound view callable: .. warning:: - When a NotFound view callable accepts an argument list as + When a Not Found View callable accepts an argument list as described in :ref:`request_and_context_view_definitions`, the ``context`` passed as the first argument to the view callable will be the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception instance. If diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 9f3b91c26..96c0b88cf 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -81,7 +81,7 @@ invoked. If no view can be found with predicates which allow it to be matched up with the request, :app:`Pyramid` will return an error to the user's browser, representing a "not found" (404) page. See :ref:`changing_the_notfound_view` -for more information about changing the default notfound view. +for more information about changing the default :term:`Not Found View`. Other view configuration arguments are non-predicate arguments. These tend to modify the response of the view callable or prevent the view callable from -- cgit v1.2.3 From 291c31c09edfbc09346ae985a865dd13cab7987b Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 9 Mar 2013 16:28:27 +0200 Subject: grammar --- docs/narr/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 3a94b4f7d..be9ab8d03 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -80,7 +80,7 @@ policy. You must also enable an :term:`authentication policy` in order to enable the authorization policy. This is because authorization, in general, depends upon authentication. Use the -:meth:`~pyramid.config.Configurator.set_authentication_policy` and method +:meth:`~pyramid.config.Configurator.set_authentication_policy` method during application setup to specify the authentication policy. For example: -- cgit v1.2.3 From 416c38fc034ff55e70d72593493327ac44c280a9 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 10 Mar 2013 09:40:58 +0200 Subject: change awkward sentence --- docs/narr/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 3a94b4f7d..a6c9c196b 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -65,7 +65,7 @@ policies. Enabling an Authorization Policy -------------------------------- -By default, :app:`Pyramid` enables no authorization policy. All +:app:`Pyramid` does not enable any authorization policy by default. All views are accessible by completely anonymous users. In order to begin protecting views from execution based on security settings, you need to enable an authorization policy. -- cgit v1.2.3 From fcd48d5d33421f806080df00e29501c4a0fd1476 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 10 Mar 2013 09:47:18 +0200 Subject: capitalize --- docs/narr/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 3a94b4f7d..ede4b6749 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -98,7 +98,7 @@ For example: config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) -.. note:: the ``authentication_policy`` and ``authorization_policy`` +.. note:: The ``authentication_policy`` and ``authorization_policy`` arguments may also be passed to their respective methods mentioned above as :term:`dotted Python name` values, each representing the dotted name path to a suitable implementation global defined at Python module scope. -- cgit v1.2.3 From 07bd8622f4c5ec3340630e977e202991b67d59d8 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 12 Mar 2013 01:24:18 +0200 Subject: a warning is overkill --- docs/narr/introspector.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 7784e8960..dec22c5b1 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -7,6 +7,8 @@ Pyramid Configuration Introspection =================================== +.. versionadded:: 1.3 + When Pyramid starts up, each call to a :term:`configuration directive` causes one or more :term:`introspectable` objects to be registered with an :term:`introspector`. The introspector can be queried by application code to @@ -15,10 +17,6 @@ feature is useful for debug toolbars, command-line scripts which show some aspect of configuration, and for runtime reporting of startup-time configuration settings. -.. warning:: - - Introspection is new in Pyramid 1.3. - Using the Introspector ---------------------- -- cgit v1.2.3 From 18d0a34fbd804be11046efe7f10b7212f018091b Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 12 Mar 2013 19:55:09 +0200 Subject: fix markup --- docs/narr/advconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index ba43f3ea6..434e2bd6c 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -417,7 +417,7 @@ added in configuration execution order. More Information ---------------- -For more information, see the article,`"A Whirlwind Tour of Advanced +For more information, see the article, `"A Whirlwind Tour of Advanced Configuration Tactics" `_, in the Pyramid Cookbook. -- cgit v1.2.3 From 72f88a80d6b8a7ea758e8ba03d55fa622ff98bbe Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 12 Mar 2013 21:12:09 +0200 Subject: use a Sphinx ref instead of raw url Other than reducing ugliness, when building the doc with Python 3, the target is a Python 3 version of the class; same applies to Python 2. --- docs/narr/threadlocals.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst index 909f643a0..5ff70565c 100644 --- a/docs/narr/threadlocals.rst +++ b/docs/narr/threadlocals.rst @@ -62,8 +62,7 @@ Because one :app:`Pyramid` application is permitted to call (perhaps as a :term:`WSGI` app with help from the :func:`pyramid.wsgi.wsgiapp2` decorator), these variables are managed in a *stack* during normal system operations. The stack -instance itself is a `threading.local -`_. +instance itself is a :class:`threading.local`. During normal operations, the thread locals stack is managed by a :term:`Router` object. At the beginning of a request, the Router -- cgit v1.2.3 From 2dfdecd4c7a8255702aa08f2807b4a3341b270f7 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 12 Mar 2013 22:40:08 +0200 Subject: fix whitespace issue... remove tabs --- docs/narr/views.rst | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 077d27366..90f6825c0 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -537,41 +537,41 @@ The following types work as view callables in this style: e.g.: .. code-block:: python - :linenos: + :linenos: - from pyramid.response import Response + from pyramid.response import Response - def view(context, request): - return Response('OK') + def view(context, request): + return Response('OK') #. Classes that have an ``__init__`` method that accepts ``context, request`` and a ``__call__`` method which accepts no arguments, e.g.: .. code-block:: python - :linenos: + :linenos: - from pyramid.response import Response + from pyramid.response import Response - class view(object): - def __init__(self, context, request): - self.context = context - self.request = request + class view(object): + def __init__(self, context, request): + self.context = context + self.request = request - def __call__(self): - return Response('OK') + def __call__(self): + return Response('OK') #. Arbitrary callables that have a ``__call__`` method that accepts ``context, request``, e.g.: .. code-block:: python - :linenos: + :linenos: - from pyramid.response import Response + from pyramid.response import Response - class View(object): - def __call__(self, context, request): - return Response('OK') - view = View() # this is the view callable + class View(object): + def __call__(self, context, request): + return Response('OK') + view = View() # this is the view callable This style of calling convention is most useful for :term:`traversal` based applications, where the context object is frequently used within the view -- cgit v1.2.3 From f73f0e332658fac2583f51247dcd49bd36d63ce4 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 13 Mar 2013 23:05:17 +0200 Subject: consistency: use $VENV whenever virtualenv binaries are used --- docs/narr/commandline.rst | 28 ++++++++++---------- docs/narr/environment.rst | 2 +- docs/narr/extending.rst | 4 +-- docs/narr/firstapp.rst | 4 +-- docs/narr/i18n.rst | 13 +++++----- docs/narr/install.rst | 65 ++++++++++++++++++++++++----------------------- docs/narr/project.rst | 30 +++++++++++----------- docs/narr/security.rst | 2 +- docs/narr/templates.rst | 2 +- docs/narr/upgrading.rst | 2 +- docs/narr/urldispatch.rst | 2 +- 11 files changed, 77 insertions(+), 77 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 3c922d0c3..07c892439 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -32,7 +32,7 @@ Here is an example for a simple view configuration using :term:`traversal`: .. code-block:: text :linenos: - $ ../bin/pviews development.ini#tutorial /FrontPage + $ $VENV/bin/pviews development.ini#tutorial /FrontPage URL = /FrontPage @@ -56,7 +56,7 @@ A more complex configuration might generate something like this: .. code-block:: text :linenos: - $ ../bin/pviews development.ini#shootout /about + $ $VENV/bin/pviews development.ini#shootout /about URL = /about @@ -146,7 +146,7 @@ name ``main`` as a section name: .. code-block:: text - $ bin/pshell starter/development.ini#main + $ $VENV/bin starter/development.ini#main Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -181,7 +181,7 @@ hash after the filename: .. code-block:: text - $ bin/pshell starter/development.ini + $ $VENV/bin/pshell starter/development.ini Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). @@ -244,7 +244,7 @@ exposed, and the request is configured to generate urls from the host .. code-block:: text - $ bin/pshell starter/development.ini + $ $VENV/bin/pshell starter/development.ini Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -286,7 +286,7 @@ specifically invoke one of your choice with the ``-p choice`` or .. code-block:: text - $ ../bin/pshell -p ipython | bpython | python development.ini#MyProject + $ $VENV/bin/pshell -p ipython | bpython | python development.ini#MyProject .. index:: pair: routes; printing @@ -311,7 +311,7 @@ For example: .. code-block:: text :linenos: - $ ../bin/proutes development.ini + $ $VENV/bin/proutes development.ini Name Pattern View ---- ------- ---- home / @@ -354,7 +354,7 @@ configured without any explicit tweens: .. code-block:: text :linenos: - $ myenv/bin/ptweens development.ini + $ $VENV/bin/ptweens development.ini "pyramid.tweens" config value NOT set (implicitly ordered tweens used) Implicit Tween Chain @@ -441,7 +441,7 @@ There are two required arguments to ``prequest``: For example:: - $ bin/prequest development.ini / + $ $VENV/bin/prequest development.ini / This will print the body of the response to the console on which it was invoked. @@ -452,14 +452,14 @@ config file name or URL. ``prequest`` has a ``-d`` (aka ``--display-headers``) option which prints the status and headers returned by the server before the output:: - $ bin/prequest -d development.ini / + $ $VENV/bin/prequest -d development.ini / This will print the status, then the headers, then the body of the response to the console. You can add request header values by using the ``--header`` option:: - $ bin/prequest --header=Host:example.com development.ini / + $ $VENV/bin/prequest --header=Host:example.com development.ini / Headers are added to the WSGI environment by converting them to their CGI/WSGI equivalents (e.g. ``Host=example.com`` will insert the ``HTTP_HOST`` @@ -472,7 +472,7 @@ using the ``-m`` (aka ``--method``) option. ``GET``, ``HEAD``, ``POST`` and ``DELETE`` are currently supported. When you use ``POST``, the standard input of the ``prequest`` process is used as the ``POST`` body:: - $ bin/prequest -mPOST development.ini / < somefile + $ $VENV/bin/prequest -mPOST development.ini / < somefile .. _writing_a_script: @@ -866,7 +866,7 @@ The result will be something like: """, ) -Once you've done this, invoking ``$somevirtualenv/bin/python setup.py +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 @@ -877,7 +877,7 @@ 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``:: - $ bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar + $ $VENV/bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar debug_routematch False debug_templates True reload_templates True diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 35bfddb8d..e059acc4e 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -546,7 +546,7 @@ for settings documented as such. For example, you might start your .. code-block:: text $ PYRAMID_DEBUG_AUTHORIZATION=1 PYRAMID_RELOAD_TEMPLATES=1 \ - bin/pserve MyProject.ini + $VENV/bin/pserve MyProject.ini If you started your application this way, your :app:`Pyramid` application would behave in the same manner as if you had placed the diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index dd9281c73..beece7640 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -200,8 +200,8 @@ like this: overridden elements, such as templates and static assets as necessary. - Install the new package into the same Python environment as the original - application (e.g. ``$myvenv/bin/python setup.py develop`` or - ``$myvenv/bin/python setup.py install``). + application (e.g. ``$VENV/bin/python setup.py develop`` or + ``$VENV/bin/python setup.py install``). - Change the ``main`` function in the new package's ``__init__.py`` to include the original :app:`Pyramid` application's configuration functions via diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index ab6a46c2f..6d3786d8e 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -29,13 +29,13 @@ On UNIX: .. code-block:: text - $ /path/to/your/virtualenv/bin/python helloworld.py + $ $VENV/bin/python helloworld.py On Windows: .. code-block:: text - C:\> \path\to\your\virtualenv\Scripts\python.exe helloworld.py + C:\> %VENV%\Scripts\python.exe helloworld.py This command will not return and nothing will be printed to the console. When port 8080 is visited by a browser on the URL ``/hello/world``, the diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 24cd3ff54..74765f8e2 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -276,7 +276,7 @@ like so: .. code-block:: text $ cd /my/virtualenv - $ bin/easy_install Babel lingua + $ $VENV/bin/easy_install Babel lingua Installation on Windows +++++++++++++++++++++++ @@ -287,8 +287,7 @@ like so: .. code-block:: text - C> cd \my\virtualenv - C> Scripts\easy_install Babel lingua + C> %VENV%\Scripts\easy_install Babel lingua .. index:: single: Babel; message extractors @@ -347,7 +346,7 @@ extract the messages: $ cd /place/where/myapplication/setup.py/lives $ mkdir -p myapplication/locale - $ $myvenv/bin/python setup.py extract_messages + $ $VENV/bin/python setup.py extract_messages The message catalog ``.pot`` template will end up in: @@ -439,7 +438,7 @@ init_catalog`` command: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $myvenv/bin/python setup.py init_catalog -l es + $ $VENV/bin/python setup.py init_catalog -l es By default, the message catalog ``.po`` file will end up in: @@ -471,7 +470,7 @@ Then use the ``setup.py update_catalog`` command. .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $myvenv/bin/python setup.py update_catalog + $ $VENV/bin/python setup.py update_catalog .. index:: pair: compiling; message catalog @@ -487,7 +486,7 @@ translations, compile ``.po`` files to ``.mo`` files: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $myvenv/bin/python setup.py compile_catalog + $ $VENV/bin/python setup.py compile_catalog This will create a ``.mo`` file for each ``.po`` file in your application. As long as the :term:`translation directory` in which diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 85dfd5bf4..6656882c9 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -264,16 +264,21 @@ as your system's administrative user. For example: Creating the Virtual Python Environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once the :term:`virtualenv` package is installed in your Python, you -can then create a virtual environment. To do so, invoke the -following: +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 - $ virtualenv --no-site-packages env - New python executable in env/bin/python + $ export $VENV=~/env + $ virtualenv --no-site-packages $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. + .. warning:: Using ``--no-site-packages`` when generating your @@ -289,20 +294,16 @@ following: ``virtualenv`` script. It's perfectly acceptable (and desirable) to create a virtualenv as a normal user. -You should perform any following commands that mention a "bin" -directory from within the ``env`` virtualenv dir. Installing :app:`Pyramid` Into the Virtual Python Environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -After you've got your ``env`` virtualenv installed, you may install -:app:`Pyramid` itself using the following commands from within the -virtualenv (``env``) directory you created in the last step. +After you've got your virtualenv installed, you may install +:app:`Pyramid` itself using the following commands: .. code-block:: text - $ cd env - $ bin/easy_install pyramid + $ $VENV/bin/easy_install pyramid The ``easy_install`` command will take longer than the previous ones to complete, as it downloads and installs a number of dependencies. @@ -339,25 +340,25 @@ Windows Using Python 2 c:\> c:\Python27\python ez_setup.py -#. Use that Python's `bin/easy_install` to install `virtualenv`: +#. Install `virtualenv`: .. code-block:: text c:\> c:\Python27\Scripts\easy_install virtualenv -#. Use that Python's virtualenv to make a workspace: +#. Make a :term:`virtualenv` workspace: .. code-block:: text - c:\> c:\Python27\Scripts\virtualenv --no-site-packages env - -#. Switch to the ``env`` directory: - - .. code-block:: text + c:\> set VENV=c:\env + c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% - c:\> cd env + 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. -#. (Optional) Consider using ``Scripts\activate.bat`` to make your shell +#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell environment wired to use the virtualenv. #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies @@ -365,7 +366,7 @@ Windows Using Python 2 .. code-block:: text - c:\env> Scripts\easy_install pyramid + c:\env> %VENV%\Scripts\easy_install pyramid Windows Using Python 3 ~~~~~~~~~~~~~~~~~~~~~~ @@ -388,25 +389,25 @@ Windows Using Python 3 c:\> c:\Python32\python distribute_setup.py -#. Use that Python's `bin/easy_install` to install `virtualenv`: +#. Install :term:`virtualenv`: .. code-block:: text c:\> c:\Python32\Scripts\easy_install virtualenv -#. Use that Python's virtualenv to make a workspace: +#. Make a :term:`virtualenv` workspace: .. code-block:: text - c:\> c:\Python32\Scripts\virtualenv --no-site-packages env - -#. Switch to the ``env`` directory: - - .. code-block:: text + c:\> set VENV=c:\env + c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% - c:\> cd env + 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. -#. (Optional) Consider using ``Scripts\activate.bat`` to make your shell +#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell environment wired to use the virtualenv. #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies @@ -414,7 +415,7 @@ Windows Using Python 3 .. code-block:: text - c:\env> Scripts\easy_install pyramid + c:\env> %VEN%\Scripts\easy_install pyramid What Gets Installed ------------------- diff --git a/docs/narr/project.rst b/docs/narr/project.rst index a9072e3bf..a168c24eb 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -80,13 +80,13 @@ On UNIX: .. code-block:: text - $ bin/pcreate -s starter MyProject + $ $VENV/bin/pcreate -s starter MyProject Or on Windows: .. code-block:: text - > Scripts\pcreate -s starter MyProject + > %VENV%\Scripts\pcreate -s starter MyProject The above command uses the ``pcreate`` command to create a project with the ``starter`` scaffold. To use a different scaffold, such as @@ -95,20 +95,20 @@ on UNIX: .. code-block:: text - $ bin/pcreate -s alchemy MyProject + $ $VENV/bin/pcreate -s alchemy MyProject Or on Windows: .. code-block:: text - > Scripts\pcreate -s alchemy MyProject + > %VENV%\Scripts\pcreate -s alchemy MyProject Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: .. code-block:: text - $ bin/pcreate -s starter MyProject + $ $VENV/bin/pcreate -s starter MyProject Creating template pyramid Creating directory ./MyProject # ... more output ... @@ -177,21 +177,21 @@ On UNIX: .. code-block:: text $ cd MyProject - $ ../bin/python setup.py develop + $ $VENV/bin/python setup.py develop Or on Windows: .. code-block:: text > cd MyProject - > ..\Scripts\python.exe setup.py develop + > %VENV%\Scripts\python.exe setup.py develop Elided output from a run of this command on UNIX is shown below: .. code-block:: text $ cd MyProject - $ ../bin/python setup.py develop + $ $VENV/bin/python setup.py develop ... Finished processing dependencies for MyProject==0.0 @@ -216,19 +216,19 @@ On UNIX: .. code-block:: text - $ ../bin/python setup.py test -q + $ $VENV/bin/python setup.py test -q Or on Windows: .. code-block:: text - > ..\Scripts\python.exe setup.py test -q + > %VENV%\Scripts\python.exe setup.py test -q Here's sample output from a test run on UNIX: .. code-block:: text - $ ../bin/python setup.py test -q + $ $VENV/bin/python setup.py test -q running test running egg_info writing requirements to MyProject.egg-info/requires.txt @@ -272,19 +272,19 @@ On UNIX: .. code-block:: text - $ ../bin/pserve development.ini + $ $VENV/bin/pserve development.ini On Windows: .. code-block:: text - > ..\Scripts\pserve development.ini + > %VENV%\Scripts\pserve development.ini Here's sample output from a run of ``pserve`` on UNIX: .. code-block:: text - $ ../bin/pserve development.ini + $ $VENV/bin/pserve development.ini Starting server in PID 16601. serving on http://0.0.0.0:6543 @@ -359,7 +359,7 @@ For example, on UNIX: .. code-block:: text - $ ../bin/pserve development.ini --reload + $ $VENV/bin/pserve development.ini --reload Starting subprocess with file monitor Starting server in PID 16601. serving on http://0.0.0.0:6543 diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 5a1a92e08..5b79edd19 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -507,7 +507,7 @@ example: .. code-block:: text - $ PYRAMID_DEBUG_AUTHORIZATION=1 bin/pserve myproject.ini + $ PYRAMID_DEBUG_AUTHORIZATION=1 $VENV/bin/pserve myproject.ini When any authorization takes place during a top-level view rendering, a message will be logged to the console (to stderr) about what ACE in diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 08fa9883e..1f1c07027 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -771,7 +771,7 @@ variable set to ``1``, For example: .. code-block:: text - $ PYRAMID_RELOAD_TEMPLATES=1 bin/pserve myproject.ini + $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini To use a setting in the application ``.ini`` file for the same purpose, set the ``pyramid.reload_templates`` key to ``true`` within the diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index 20487b448..ca6dc565b 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -183,7 +183,7 @@ server run with the ``PYTHONWARNINGS`` environment variable set to .. code-block:: bash - $ PYTHONWARNINGS=default bin/pserve development.ini + $ PYTHONWARNINGS=default $VENV/bin/pserve development.ini On Windows, you need to issue two commands: diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a327e937b..181b07259 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -875,7 +875,7 @@ which you started the application from. For example: .. code-block:: text :linenos: - $ PYRAMID_DEBUG_ROUTEMATCH=true bin/pserve development.ini + $ PYRAMID_DEBUG_ROUTEMATCH=true $VENV/bin/pserve development.ini Starting server in PID 13586. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 2010-12-16 14:45:19,956 no route matched for url \ -- cgit v1.2.3 From 919643eec1a480cee442331a966a9c6c90fb0965 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 13 Mar 2013 23:36:18 +0200 Subject: typo --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 6656882c9..04a060ac3 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -415,7 +415,7 @@ Windows Using Python 3 .. code-block:: text - c:\env> %VEN%\Scripts\easy_install pyramid + c:\env> %VENV%\Scripts\easy_install pyramid What Gets Installed ------------------- -- cgit v1.2.3 From 2d931400b22f4c5764df68c2799be512e60a2de1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 18 Mar 2013 21:00:50 -0700 Subject: support acl as a callable --- docs/narr/security.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 5b79edd19..36c888559 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -270,6 +270,27 @@ resource instances with an ACL (as opposed to just decorating their class) in applications such as "CMS" systems where fine-grained access is required on an object-by-object basis. +Dynamic ACLs are also possible by turning the ACL into a callable on the +resource. This may allow the ACL to dynamically generate rules based on +properties of the instance. + +.. code-block:: python + :linenos: + + from pyramid.security import Allow + from pyramid.security import Everyone + + class Blog(object): + def __acl__(self): + return [ + (Allow, Everyone, 'view'), + (Allow, self.owner, 'edit'), + (Allow, 'group:editors', 'edit'), + ] + + def __init__(self, owner): + self.owner = owner + .. index:: single: ACE single: access control entry -- cgit v1.2.3 From 81e84fe86bee0c2753674fdaead001803936a2ba Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 18 Mar 2013 21:53:35 -0700 Subject: reorder some imports to be alphabetical --- docs/narr/security.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 36c888559..203aa2404 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -234,8 +234,8 @@ class: .. code-block:: python :linenos: - from pyramid.security import Everyone from pyramid.security import Allow + from pyramid.security import Everyone class Blog(object): __acl__ = [ @@ -250,8 +250,8 @@ Or, if your resources are persistent, an ACL might be specified via the .. code-block:: python :linenos: - from pyramid.security import Everyone from pyramid.security import Allow + from pyramid.security import Everyone class Blog(object): pass @@ -303,8 +303,8 @@ Here's an example ACL: .. code-block:: python :linenos: - from pyramid.security import Everyone from pyramid.security import Allow + from pyramid.security import Everyone __acl__ = [ (Allow, Everyone, 'view'), @@ -342,9 +342,9 @@ order dictated by the ACL*. So if you have an ACL like this: .. code-block:: python :linenos: - from pyramid.security import Everyone from pyramid.security import Allow from pyramid.security import Deny + from pyramid.security import Everyone __acl__ = [ (Allow, Everyone, 'view'), @@ -380,8 +380,8 @@ ACE, as below. .. code-block:: python :linenos: - from pyramid.security import Everyone from pyramid.security import Allow + from pyramid.security import Everyone __acl__ = [ (Allow, Everyone, 'view'), -- cgit v1.2.3 From ed214d879cab4f00f5151011279c69ea07da6540 Mon Sep 17 00:00:00 2001 From: Steven Citron-Pousty Date: Tue, 19 Mar 2013 13:00:29 -0700 Subject: fixed the syntax for exporting the VENV --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 04a060ac3..9bc62dc62 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -269,7 +269,7 @@ you can then create a virtual environment. To do so, invoke the following: .. code-block:: text - $ export $VENV=~/env + $ export VENV=~/env $ virtualenv --no-site-packages $VENV New python executable in /home/foo/env/bin/python Installing setuptools.............done. -- cgit v1.2.3 From 7c47008ad76199dd5a638bc8c3a912664bd9c7d6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 20 Mar 2013 14:36:06 -0700 Subject: Add special section for Mac OS X users. --- docs/narr/install.rst | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 9bc62dc62..0a03d9170 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -19,13 +19,32 @@ run :app:`Pyramid`. run under any version of Python before 2.6. :app:`Pyramid` is known to run on all popular UNIX-like systems such as -Linux, MacOS X, and FreeBSD as well as on Windows platforms. It is also -known to run on :term:`PyPy` (1.9+). +Linux, 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. +For Mac OS X Users +~~~~~~~~~~~~~~~~~~ + +From `Python.org `_: + + Python comes pre-installed on Mac OS X, but due to Apple's release + cycle, it's often one or even two years old. The overwhelming + recommendation of the "MacPython" community is to upgrade your + Python by downloading and installing a newer version from + `the Python standard release page `_. + +It is recommended to download one of the *installer* versions, unless you prefer to install your Python through a packgage manager (e.g., macports or homebrew) or to build your Python from source. + +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. + +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) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 21d0288a9211b175f61769d7e7cf471f12ee09cb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 21 Mar 2013 14:03:03 -0700 Subject: Generalize Python versions in Windows section. --- docs/narr/install.rst | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 0a03d9170..7f4742ee2 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -341,8 +341,8 @@ for both versions are included below. Windows Using Python 2 ~~~~~~~~~~~~~~~~~~~~~~ -#. Install, or find `Python 2.7 - `_ for your system. +#. Install, or find the most recent `Python 2.7.x version + `_ for your system. #. Install the `Python for Windows extensions `_. Make sure to @@ -390,36 +390,47 @@ Windows Using Python 2 Windows Using Python 3 ~~~~~~~~~~~~~~~~~~~~~~ -#. Install, or find `Python 3.2 - `_ for your system. +#. Install, or find the latest version of `Python 3.x + `_ for your system and which is + supported by Pyramid. #. Install the `Python for Windows extensions `_. Make sure to - pick the right download for Python 3.2 and install it using the + pick the right download for Python 3.x and install it using the same Python installation from the previous step. #. Install latest :term:`distribute` distribution into the Python you obtained/installed/found in the step above: download `distribute_setup.py `_ and run it using the - ``python`` interpreter of your Python 3.2 installation using a command + ``python`` interpreter of your Python 3.x installation using a command prompt: .. code-block:: text + # modify the command according to the python version, e.g.: + # for Python 3.2.x: c:\> c:\Python32\python distribute_setup.py + # for Python 3.3.x: + c:\> c:\Python33\python distribute_setup.py #. Install :term:`virtualenv`: .. code-block:: text + # for Python 3.2.x: c:\> c:\Python32\Scripts\easy_install virtualenv + # for Python 3.3.x: + c:\> c:\Python33\Scripts\easy_install virtualenv #. Make a :term:`virtualenv` workspace: .. code-block:: text c:\> set VENV=c:\env + # for Python 3.2.x: c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3.x: + c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% You can either follow the use of the environment variable, ``%VENV%``, or replace it with the root directory of the :term:`virtualenv`. -- cgit v1.2.3 From 1ad8de2b9032b5a452b75274b8f908645c732e57 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 22 Mar 2013 17:24:32 +0200 Subject: remove unused ignore-next-block directive --- docs/narr/assets.rst | 6 ------ docs/narr/configuration.rst | 1 - docs/narr/firstapp.rst | 3 --- docs/narr/security.rst | 2 -- docs/narr/templates.rst | 1 - docs/narr/urldispatch.rst | 1 - docs/narr/viewconfig.rst | 2 -- docs/narr/webob.rst | 2 -- docs/narr/zca.rst | 1 - 9 files changed, 19 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index deaf0ce08..99bcb187f 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -50,7 +50,6 @@ application might address the asset using the :term:`asset specification` ``myapp:templates/some_template.pt`` using that API within a ``views.py`` file inside a ``myapp`` package: -.. ignore-next-block .. code-block:: python :linenos: @@ -331,7 +330,6 @@ root that exists at the end of your routing table, create an instance of the :class:`~pyramid.static.static_view` class inside a ``static.py`` file in your application root as below. -.. ignore-next-block .. code-block:: python :linenos: @@ -458,7 +456,6 @@ The ``override_asset`` API An individual call to :meth:`~pyramid.config.Configurator.override_asset` can override a single asset. For example: -.. ignore-next-block .. code-block:: python :linenos: @@ -473,7 +470,6 @@ colon separator in a specification separates the *package name* from the are not specified, the override attempts to resolve every lookup into a package from the directory of another package. For example: -.. ignore-next-block .. code-block:: python :linenos: @@ -482,7 +478,6 @@ package from the directory of another package. For example: Individual subdirectories within a package can also be overridden: -.. ignore-next-block .. code-block:: python :linenos: @@ -511,7 +506,6 @@ construction file resides (or the ``package`` argument to the :class:`~pyramid.config.Configurator` class construction). For example: -.. ignore-next-block .. code-block:: python :linenos: diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 6f82baf32..f7a69d613 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -140,7 +140,6 @@ In the example above, the scanner translates the arguments to :class:`~pyramid.view.view_config` into a call to the :meth:`pyramid.config.Configurator.add_view` method, effectively: -.. ignore-next-block .. code-block:: python config.add_view(hello) diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index 6d3786d8e..e73ef66ac 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -166,7 +166,6 @@ the application. Adding Configuration ~~~~~~~~~~~~~~~~~~~~ -.. ignore-next-block .. literalinclude:: helloworld.py :linenos: :lines: 11-12 @@ -186,7 +185,6 @@ The second line registers the ``hello_world`` function as a WSGI Application Creation ~~~~~~~~~~~~~~~~~~~~~~~~~ -.. ignore-next-block .. literalinclude:: helloworld.py :linenos: :lines: 13 @@ -215,7 +213,6 @@ to its ``add_view`` and ``add_route`` methods. WSGI Application Serving ~~~~~~~~~~~~~~~~~~~~~~~~ -.. ignore-next-block .. literalinclude:: helloworld.py :linenos: :lines: 14-15 diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 203aa2404..e91e8c542 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -85,7 +85,6 @@ during application setup to specify the authentication policy. For example: -.. ignore-next-block .. code-block:: python :linenos: @@ -151,7 +150,6 @@ API: The equivalent view registration including the ``add`` permission name may be performed via the ``@view_config`` decorator: -.. ignore-next-block .. code-block:: python :linenos: diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 1f1c07027..d4cf20b93 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -150,7 +150,6 @@ string, then return that string as the body of a :app:`Pyramid` For example, here's an example of using "raw" `Mako `_ from within a :app:`Pyramid` :term:`view`: -.. ignore-next-block .. code-block:: python :linenos: diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 0656a1833..bcd5fff94 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -55,7 +55,6 @@ The :meth:`pyramid.config.Configurator.add_route` method adds a single :term:`route configuration` to the :term:`application registry`. Here's an example: -.. ignore-next-block .. code-block:: python # "config" below is presumed to be an instance of the diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e0338c442..14a2fc807 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -488,7 +488,6 @@ acts as a :app:`Pyramid` view callable. Here's an example of the :class:`~pyramid.view.view_config` decorator that lives within a :app:`Pyramid` application module ``views.py``: -.. ignore-next-block .. code-block:: python :linenos: @@ -503,7 +502,6 @@ lives within a :app:`Pyramid` application module ``views.py``: Using this decorator as above replaces the need to add this imperative configuration stanza: -.. ignore-next-block .. code-block:: python :linenos: diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 44940f9e6..63a08adaa 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -326,7 +326,6 @@ package that uses SQLAlchemy, and you'd like the current SQLAlchemy database session to be removed after each request. Put the following in the ``mypackage.__init__`` module: -.. ignore-next-block .. code-block:: python :linenos: @@ -491,7 +490,6 @@ reason for the error. For instance, :class:`pyramid.Response`, so you can manipulate the instances in the same way. A typical example is: -.. ignore-next-block .. code-block:: python :linenos: diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index f7707ea29..5499cf4a5 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -21,7 +21,6 @@ application can be opaque. For example, here is a typical "unnamed utility" lookup using the :func:`zope.component.getUtility` global API as it might appear in a traditional Zope application: -.. ignore-next-block .. code-block:: python :linenos: -- cgit v1.2.3 From a3251ddd6d9a2948fe8e762673ee6f3a6a66ea55 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 22 Mar 2013 21:50:00 +0200 Subject: remove visual noise In addition, we also get syntax highlighting... for free. --- docs/narr/muchadoabouttraversal.rst | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 40d498391..483b1bb16 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -168,18 +168,12 @@ hood, when ``adict`` is a dictionary-like object, Python translates ``adict['a']`` to ``adict.__getitem__('a')``. Try doing this in a Python interpreter prompt if you don't believe us: -.. code-block:: text - :linenos: - - Python 2.4.6 (#2, Apr 29 2010, 00:31:48) - [GCC 4.4.3] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> adict = {} - >>> adict['a'] = 1 - >>> adict['a'] - 1 - >>> adict.__getitem__('a') - 1 +>>> adict = {} +>>> adict['a'] = 1 +>>> adict['a'] +1 +>>> adict.__getitem__('a') +1 The dictionary-like root object stores the ids of all of its subresources as -- cgit v1.2.3 From 0bda2652728ae33ea37adc1f7f2f382e0ebbf4df Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 23 Mar 2013 03:32:23 -0400 Subject: create optionality note for traversal chapter, see issue #879 --- docs/narr/traversal.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index 1234620c2..a2eac61de 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -22,10 +22,13 @@ resource found as the result of a traversal becomes the subsystem is used to find some view code willing to "publish" this resource by generating a :term:`response`. -Using :term:`Traversal` to map a URL to code is optional. It is often -less easy to understand than :term:`URL dispatch`, so if you're a rank -beginner, it probably makes sense to use URL dispatch to map URLs to -code instead of traversal. In that case, you can skip this chapter. +.. note:: + + Using :term:`Traversal` to map a URL to code is optional. If you're creating + your first Pyramid application it probably makes more sense to use :term:`URL + dispatch` to map URLs to code instead of traversal, as new Pyramid developers + tend to find URL dispatch slightly easier to understand. If you use URL + dispatch, you needn't read this chapter. .. index:: single: traversal details -- cgit v1.2.3 From 88cafdd3cf621d0a117f0e2e8c924c07dfbf5ef1 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 23 Mar 2013 12:03:45 +0200 Subject: no need to qualify Python interactive sessions Sphinx automatically notices them as Python snippets and gives them syntax highlighting. These snippets are also too short to deserve linenos. --- docs/narr/sessions.rst | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index fa4affd8a..c4f4b5f07 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -252,25 +252,19 @@ that were added to the flash queue, and empties the queue. .. method:: pop_flash(queue='') -.. code-block:: python - :linenos: - - >>> request.session.flash('info message') - >>> request.session.pop_flash() - ['info message'] +>>> request.session.flash('info message') +>>> request.session.pop_flash() +['info message'] Calling ``session.pop_flash()`` again like above without a corresponding call to ``session.flash()`` will return an empty list, because the queue has already been popped. -.. code-block:: python - :linenos: - - >>> request.session.flash('info message') - >>> request.session.pop_flash() - ['info message'] - >>> request.session.pop_flash() - [] +>>> request.session.flash('info message') +>>> request.session.pop_flash() +['info message'] +>>> request.session.pop_flash() +[] .. index:: single: session.peek_flash @@ -285,18 +279,15 @@ popped from flash storage. .. method:: peek_flash(queue='') -.. code-block:: python - :linenos: - - >>> request.session.flash('info message') - >>> request.session.peek_flash() - ['info message'] - >>> request.session.peek_flash() - ['info message'] - >>> request.session.pop_flash() - ['info message'] - >>> request.session.peek_flash() - [] +>>> request.session.flash('info message') +>>> request.session.peek_flash() +['info message'] +>>> request.session.peek_flash() +['info message'] +>>> request.session.pop_flash() +['info message'] +>>> request.session.peek_flash() +[] .. index:: single: preventing cross-site request forgery attacks -- cgit v1.2.3 From 9c69d9a0de8c2a34820be05f36e32f68b29e5276 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 23 Mar 2013 03:30:41 -0700 Subject: remove 'or find' --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 7f4742ee2..8fc63f3a4 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -341,7 +341,7 @@ for both versions are included below. Windows Using Python 2 ~~~~~~~~~~~~~~~~~~~~~~ -#. Install, or find the most recent `Python 2.7.x version +#. Install the most recent `Python 2.7.x version `_ for your system. #. Install the `Python for Windows extensions -- cgit v1.2.3 From 29c8884747d3bc10b55aefce3db461a9e20b3527 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 26 Mar 2013 17:18:57 +0200 Subject: fix #948 --- docs/narr/startup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 3a9225032..1affa1758 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -8,12 +8,12 @@ you'll see something much like this show up on the console: .. code-block:: text - $ pserve myproject/MyProject.ini + $ pserve development.ini Starting server in PID 16601. serving on 0.0.0.0:6543 view at 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 myproject/MyProject.ini`` +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. -- cgit v1.2.3 From d4683cbbfc370fd908592399a36ea47db2570b72 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 31 Mar 2013 00:29:12 +0200 Subject: fix some cross-references Also add webtest to intersphinx_mapping --- docs/narr/testing.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 0801a8eae..bfb1287d9 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -128,7 +128,7 @@ functions accepts various arguments that influence the environment of the test. See the :ref:`testing_module` chapter for information about the extra arguments supported by these functions. -If you also want to make :func:`~pyramid.get_current_request` return something +If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something other than ``None`` during the course of a single test, you can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within the ``setUp`` method of your test: @@ -231,7 +231,7 @@ application registry is not created and populated (e.g. by initializing the configurator with an authorization policy), like when you invoke application code via a unit test, :app:`Pyramid` API functions will tend to either fail or return default results. So how do you test the branch of the code in this -view function that raises :exc:`HTTPForbidden`? +view function that raises :exc:`~pyramid.httpexceptions.HTTPForbidden`? The testing API provided by :app:`Pyramid` allows you to simulate various application registry registrations for use under a unit testing framework @@ -272,7 +272,7 @@ without needing to invoke the actual application configuration implied by its self.assertEqual(response, {'greeting':'hello'}) In the above example, we create a ``MyTest`` test case that inherits from -:mod:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will +:class:`unittest.TestCase`. If it's in our :app:`Pyramid` application, it will be found when ``setup.py test`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when @@ -287,8 +287,9 @@ request object that requires less setup than a "real" :app:`Pyramid` request. We call the function being tested with the manufactured request. When the function is called, :func:`pyramid.security.has_permission` will call the "dummy" authentication policy we've registered through -:meth:`~pyramid.config.Configuration.testing_securitypolicy`, which denies -access. We check that the view function raises a :exc:`HTTPForbidden` error. +:meth:`~pyramid.config.Configurator.testing_securitypolicy`, which denies +access. We check that the view function raises a +:exc:`~pyramid.httpexceptions.HTTPForbidden` error. The second test method, named ``test_view_fn_allowed`` tests the alternate case, where the authentication policy allows access. Notice that we pass @@ -425,4 +426,4 @@ invoke the root URL. We then assert that the returned HTML has the string ``Pyramid`` in it. See the :term:`WebTest` documentation for further information about the -methods available to a :class:`webtest.TestApp` instance. +methods available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From 50218d2d443c8773af3f2312fd0df095f993d4a9 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 1 Apr 2013 09:44:59 +0200 Subject: fix some cross-references --- docs/narr/traversal.rst | 14 +++++++------- docs/narr/views.rst | 2 +- docs/narr/zca.rst | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index a2eac61de..2eb6ece13 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -359,13 +359,13 @@ when this request comes in that we're traversing the following resource tree: Here's what happens: -- :mod:`traversal` traverses the root, and attempts to find "foo", which it +- :term:`traversal` traverses the root, and attempts to find "foo", which it finds. -- :mod:`traversal` traverses "foo", and attempts to find "bar", which it +- :term:`traversal` traverses "foo", and attempts to find "bar", which it finds. -- :mod:`traversal` traverses "bar", and attempts to find "baz", which it does +- :term:`traversal` traverses "bar", and attempts to find "baz", which it does not find (the "bar" resource raises a :exc:`KeyError` when asked for "baz"). @@ -410,16 +410,16 @@ However, for this tree: The user asks for ``http://example.com/foo/bar/baz/biz/buz.txt`` -- :mod:`traversal` traverses "foo", and attempts to find "bar", which it +- :term:`traversal` traverses "foo", and attempts to find "bar", which it finds. -- :mod:`traversal` traverses "bar", and attempts to find "baz", which it +- :term:`traversal` traverses "bar", and attempts to find "baz", which it finds. -- :mod:`traversal` traverses "baz", and attempts to find "biz", which it +- :term:`traversal` traverses "baz", and attempts to find "biz", which it finds. -- :mod:`traversal` traverses "biz", and attempts to find "buz.txt" which it +- :term:`traversal` traverses "biz", and attempts to find "buz.txt" which it does not find. The fact that it does not find a resource related to "buz.txt" at this point diff --git a/docs/narr/views.rst b/docs/narr/views.rst index 5a7be15b0..b2dd549ce 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -39,7 +39,7 @@ object. A request object represents a :term:`WSGI` environment provided to object contains everything your application needs to know about the specific HTTP request being made. -A view callable's ultimate responsibility is to create a :mod:`Pyramid` +A view callable's ultimate responsibility is to create a :app:`Pyramid` :term:`Response` object. This can be done by creating a :term:`Response` object in the view callable code and returning it directly or by raising special kinds of exceptions from within the body of a view callable. diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index 5499cf4a5..7e36ba030 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -44,7 +44,7 @@ framework implementation detail. However, developers who are already used to writing :term:`Zope` applications often still wish to use the ZCA while building a -:app:`Pyramid` application; :mod:`pyramid` makes this possible. +:app:`Pyramid` application; :app:`Pyramid` makes this possible. .. index:: single: get_current_registry -- cgit v1.2.3 From eb4ef09189bcc02559c1cfa49bf9be85bc2fbed9 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 24 Feb 2013 17:45:43 +0100 Subject: Fix wrong reference to non existent getAjax function --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 08ebd881e..a9a2aa42a 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -362,7 +362,7 @@ For example (Javascript): jqhxr = $.getJSON(api_url); The string ``callback=?`` above in the ``url`` param to the JQuery -``getAjax`` function indicates to jQuery that the query should be made as +``getJSON`` function indicates to jQuery that the query should be made as a JSONP request; the ``callback`` parameter will be automatically filled in for you and used. -- cgit v1.2.3 From dd1c538327c48555cc84111e37d929a0842494af Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 24 Feb 2013 17:56:44 +0100 Subject: Fix reST markup and spelling of "hand" --- docs/narr/viewconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 14a2fc807..6f0001f61 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -313,9 +313,9 @@ configured view. This argument ensures that the view will only be called when the :term:`request` has key/value pairs in its :term:`matchdict` that equal - those supplied in the predicate. e.g. ``match_param="action=edit" would + those supplied in the predicate. e.g. ``match_param="action=edit"`` would require the ``action`` parameter in the :term:`matchdict` match the right - hande side of the expression (``edit``) for the view to "match" the current + hand side of the expression (``edit``) for the view to "match" the current request. If the ``match_param`` is a dict, every key/value pair must match for the -- cgit v1.2.3 From e2b67957fddb01f8f17ee55ba726122977cdef1b Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 24 Feb 2013 18:01:17 +0100 Subject: Remove extra word --- 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 330eb0cd3..07983808c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -694,7 +694,7 @@ represents the type of interface that must be possessed by the resource for this resource url factory to be found. If the ``resource_iface`` argument is omitted, this resource url adapter will be used for *all* resources. -The API that must be implemented by your a class that provides +The API that must be implemented by a class that provides :class:`~pyramid.interfaces.IResourceURL` is as follows: .. code-block:: python -- cgit v1.2.3 From 172c98d010d10080e6cb0b1076eb703af7bd7c76 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 24 Feb 2013 18:22:05 +0100 Subject: my.package.MyJinja2Renderer is registered for .jinja2 files not .jinja --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index a9a2aa42a..b4eb95186 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -720,7 +720,7 @@ factory, which expects to be passed a filesystem path: Adding the above code to your application startup will allow you to use the ``my.package.MyJinja2Renderer`` renderer factory implementation in view -configurations by referring to any ``renderer`` which *ends in* ``.jinja`` in +configurations by referring to any ``renderer`` which *ends in* ``.jinja2`` in the ``renderer`` attribute of a :term:`view configuration`: .. code-block:: python -- cgit v1.2.3 From 46d5058a99dee32bc02c1ef93ec5fddf35867505 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 24 Feb 2013 18:34:08 +0100 Subject: Fix typo that broke the reference to pyramid.events.NewRequest --- 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 07983808c..c2c7417a7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1447,7 +1447,7 @@ view/route predicate: subscriber predicates will assume a certain event type. Here's an example of a subscriber predicate that can be used in conjunction -with a subscriber that subscribes to the :class:`pyramid.events.NewReqest` +with a subscriber that subscribes to the :class:`pyramid.events.NewRequest` event type. .. code-block:: python -- cgit v1.2.3 From 11169c3a294cfc32cd650cb244307d60262886f9 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 24 Feb 2013 18:42:02 +0100 Subject: Remove unused imports from code sample The import should be done only when actually using the global registry. --- docs/narr/zca.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index 7e36ba030..2ef8a7373 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -151,7 +151,6 @@ Consider the following bit of idiomatic :app:`Pyramid` startup code: .. code-block:: python :linenos: - from zope.component import getGlobalSiteManager from pyramid.config import Configurator def app(global_settings, **settings): @@ -188,7 +187,6 @@ For example: .. code-block:: python :linenos: - from zope.component import getGlobalSiteManager from pyramid.config import Configurator def app(global_settings, **settings): -- cgit v1.2.3 From fe30a28c0ab6e6b3ad50893baf06316aa68bd48f Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 31 Mar 2013 13:58:49 +0200 Subject: Remove extra word --- 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 033f045a6..7c0c61d71 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -250,7 +250,7 @@ It's a poor idea to use the original ``request`` object as an argument to :meth:`~pyramid.request.Request.invoke_subrequest`. You should construct a new request instead as demonstrated in the above example, using :meth:`pyramid.request.Request.blank`. Once you've constructed a request -object, you'll need to massage the it to match the view callable you'd like +object, you'll need to massage it to match the view callable you'd like to be executed during the subrequest. This can be done by adjusting the subrequest's URL, its headers, its request method, and other attributes. The documentation for :class:`pyramid.request.Request` exposes the methods you -- cgit v1.2.3 From af81e71c3417a5ee62fc06feb07a894a0691d11a Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 31 Mar 2013 14:09:26 +0200 Subject: Use into instead of in to Seems more correct and is consistent with the usage a few words further. --- docs/narr/extending.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index beece7640..7e83885fa 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -50,7 +50,7 @@ layers are apt to provide the necessary "opinions" (such as mandating a storage layer, a templating system, and a structured, well-documented pattern of registering that certain URLs map to certain bits of code) which makes the concept of a "pluggable application" possible. "Pluggable applications", -thus, should not plug in to Pyramid itself but should instead plug into a +thus, should not plug into Pyramid itself but should instead plug into a system written atop Pyramid. Although it does not provide for "pluggable applications", Pyramid *does* -- cgit v1.2.3 From ed960fb58c26e97a0a1614400b23ec6184987765 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 31 Mar 2013 14:11:07 +0200 Subject: Fix grammar --- docs/narr/extending.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index 7e83885fa..a60a49fea 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -209,7 +209,7 @@ like this: - Wire the new views and assets created in the new package up using imperative registrations within the ``main`` function of the - ``__init__.py`` file of the new application. These wiring should happen + ``__init__.py`` file of the new application. This wiring should happen *after* including the configuration functions of the old application. These registrations will extend or override any registrations performed by the original application. See :ref:`overriding_views`, -- cgit v1.2.3 From 37607c3a9382de7c3757799791a91b80e2d9888d Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 31 Mar 2013 14:33:24 +0200 Subject: Consistently link middleware term to the glossary --- docs/narr/commandline.rst | 8 ++++---- docs/narr/hooks.rst | 2 +- docs/narr/introduction.rst | 8 ++++---- docs/narr/logging.rst | 8 ++++---- docs/narr/webob.rst | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 07c892439..e1347f3ca 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -172,8 +172,8 @@ name ``main`` as a section name: The WSGI application that is loaded will be available in the shell as the ``app`` global. Also, if the application that is loaded is the :app:`Pyramid` -app with no surrounding middleware, the ``root`` object returned by the -default :term:`root factory`, ``registry``, and ``request`` will be +app with no surrounding :term:`middleware`, the ``root`` object returned by +the default :term:`root factory`, ``registry``, and ``request`` will be available. You can also simply rely on the ``main`` default section name by omitting any @@ -572,8 +572,8 @@ configuration implied by the ``[pipeline:main]`` section of your configuration file by default. Specifying ``/path/to/my/development.ini`` is logically equivalent to specifying ``/path/to/my/development.ini#main``. In this case, we'll be using a configuration that includes an ``app`` object -which is wrapped in the Paste "translogger" middleware (which logs requests -to the console). +which is wrapped in the Paste "translogger" :term:`middleware` (which logs +requests to the console). You can also specify a particular *section* of the PasteDeploy ``.ini`` file to load instead of ``main``: diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index c2c7417a7..e984dc24f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1036,7 +1036,7 @@ upstream WSGI component that uses :app:`Pyramid` as its "app". This is a feature that may be used by Pyramid framework extensions, to provide, for example, Pyramid-specific view timing support bookkeeping code that examines exceptions before they are returned to the upstream WSGI application. Tweens -behave a bit like :term:`WSGI` middleware but they have the benefit of +behave a bit like :term:`WSGI` :term:`middleware` but they have the benefit of running in a context in which they have access to the Pyramid :term:`application registry` as well as the Pyramid rendering machinery. diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index f9c25c69c..48164d323 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -600,10 +600,10 @@ Examples: :ref:`hello_traversal_chapter` and Tweens ~~~~~~ -Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be -hooked by arbitrary add-ons named "tweens". The debug toolbar is a "tween", -and the ``pyramid_tm`` transaction manager is also. Tweens are more useful -than WSGI middleware in some circumstances because they run in the context of +Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be hooked +by arbitrary add-ons named "tweens". The debug toolbar is a "tween", and the +``pyramid_tm`` transaction manager is also. Tweens are more useful than WSGI +:term:`middleware` in some circumstances because they run in the context of Pyramid itself, meaning you have access to templates and other renderers, a "real" request object, and other niceties. diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 3b903be4d..b3bfb8a1e 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -298,14 +298,14 @@ Request Logging with Paste's TransLogger ---------------------------------------- Paste provides the `TransLogger -`_ middleware for logging -requests using the `Apache Combined Log Format +`_ :term:`middleware` for +logging requests using the `Apache Combined Log Format `_. TransLogger combined with a FileHandler can be used to create an ``access.log`` file similar to Apache's. -Like any standard middleware with a Paste entry point, TransLogger can be -configured to wrap your application using ``.ini`` file syntax. First, +Like any standard :term:`middleware` with a Paste entry point, TransLogger can +be configured to wrap your application using ``.ini`` file syntax. First, rename your Pyramid ``.ini`` file's ``[app:main]`` section to ``[app:mypyramidapp]``, then add a ``[filter:translogger]`` section, then use a ``[pipeline:main]`` section file to form a WSGI pipeline with both the diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 63a08adaa..02c03c8db 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -354,7 +354,7 @@ initialization. cause ``DBSession.remove`` to be called in an application generated from any :app:`Pyramid` scaffold, because these all use the ``pyramid_tm`` package. The cleanup done by ``DBSession.remove`` is unnecessary when - ``pyramid_tm`` middleware is configured into the application. + ``pyramid_tm`` :term:`middleware` is configured into the application. More Details ++++++++++++ -- cgit v1.2.3 From 1ad37b0891c92087d54255ab1ee9dd0f28b2c150 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Mon, 1 Apr 2013 17:54:22 +0200 Subject: Add missing word --- 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 7c0c61d71..93ce747ee 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -155,7 +155,7 @@ In the example above, the call to exception. This is because it's using the default value for ``use_tweens``, which is ``False``. You can pass ``use_tweens=True`` instead to ensure that it will convert an exception to a Response if an :term:`exception view` is -configured instead of raising the exception. This because exception views +configured instead of raising the exception. This is because exception views are called by the exception view :term:`tween` as described in :ref:`exception_views` when any view raises an exception. -- cgit v1.2.3 From 991a1abd3ddf682240a540fcb7fd309dc1d50f34 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Mon, 1 Apr 2013 17:58:09 +0200 Subject: Remove extra word --- 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 e984dc24f..f16ab93d8 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1110,8 +1110,8 @@ Once you've created a tween factory, you can register it into the implicit tween chain using the :meth:`pyramid.config.Configurator.add_tween` method using its :term:`dotted Python name`. -Here's an example of registering the a tween factory as an "implicit" -tween in a Pyramid application: +Here's an example of registering a tween factory as an "implicit" tween in a +Pyramid application: .. code-block:: python :linenos: -- cgit v1.2.3 From 1b0d1cf0b970aa7a69a42a59617cd78983bc9942 Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Mon, 1 Apr 2013 17:58:19 +0200 Subject: Remove extra word --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index a168c24eb..9d69a65a5 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -416,7 +416,7 @@ If you don't see the debug toolbar image on the right hand top of the page, it means you're browsing from a system that does not have debugging access. By default, for security reasons, only a browser originating from ``localhost`` (``127.0.0.1``) can see the debug toolbar. To allow your -browser on a remote system to access the server, add the a line within the +browser on a remote system to access the server, add a line within the ``[app:main]`` section of the ``development.ini`` file in the form ``debugtoolbar.hosts = X.X.X.X``. For example, if your Pyramid application is running on a remote system, and you're browsing from a host with the IP -- cgit v1.2.3 From c69f357e79c9b1b619fa5a68137d9e11de39bc9e Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Mon, 1 Apr 2013 18:12:46 +0200 Subject: Improve phrasing --- docs/narr/hooks.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index f16ab93d8..a3de23baa 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -109,9 +109,8 @@ callable: instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the Not Found View to be called. The value of ``request.exception.message`` will be a value explaining why the Not Found - error was raised. This message will be different when the - ``pyramid.debug_notfound`` environment setting is true than it is when it - is false. + error was raised. This message has different values depending whether the + ``pyramid.debug_notfound`` environment setting is true or false. .. note:: @@ -208,9 +207,9 @@ Here's some sample code that implements a minimal forbidden view: that caused the forbidden view to be called. The value of ``request.exception.message`` will be a value explaining why the forbidden was raised and ``request.exception.result`` will be extended information - about the forbidden exception. These messages will be different when the - ``pyramid.debug_authorization`` environment setting is true than it is when - it is false. + about the forbidden exception. These messages have different values + depending whether the ``pyramid.debug_authorization`` environment setting + is true or false. .. index:: single: request factory -- cgit v1.2.3 From a9bd7d058ec1399927ae19c1850ec15195319403 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 2 Apr 2013 11:13:56 -0500 Subject: fix #964 --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index bcd5fff94..18cb3e4db 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1263,7 +1263,7 @@ invoked with the request that caused the invocation. For most usage, you needn't understand more than this; how it works is an implementation detail. In the interest of completeness, however, we'll -explain how it *does* work in the this section. You can skip it if you're +explain how it *does* work in this section. You can skip it if you're uninterested. When a view is associated with a route configuration, :app:`Pyramid` ensures -- cgit v1.2.3 From f8afd1638456fc89bc3d17858f309686b40a40a4 Mon Sep 17 00:00:00 2001 From: thapar Date: Wed, 3 Apr 2013 02:05:36 -0300 Subject: minor typo correction 'prepresents'-->'represents' --- 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 99bcb187f..09a2b83f2 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -119,7 +119,7 @@ from the ``/var/www/static`` directory of the computer which runs the # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='/var/www/static') -The ``name`` prepresents a URL *prefix*. In order for files that live in the +The ``name`` represents a URL *prefix*. In order for files that live in the ``path`` directory to be served, a URL that requests one of them must begin with that prefix. In the example above, ``name`` is ``static``, and ``path`` is ``/var/www/static``. In English, this means that you wish to serve the -- cgit v1.2.3 From e3d07fd8792bb06c69909e2b664403ae3bbba5d3 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 3 Apr 2013 19:59:45 +0200 Subject: add some more cross-references Also remove linenos setting, which is overkill for a one-liner. --- docs/narr/zca.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index 2ef8a7373..b0e9b1709 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -83,7 +83,7 @@ While this services a reasonable goal, it causes some issues when trying to use patterns which you might use to build a typical :term:`Zope` application to build a :app:`Pyramid` application. Without special help, ZCA "global" APIs such as -``zope.component.getUtility`` and ``zope.component.getSiteManager`` +:func:`zope.component.getUtility` and :func:`zope.component.getSiteManager` will use the ZCA "global" registry. Therefore, these APIs will appear to fail when used in a :app:`Pyramid` application, because they'll be consulting the ZCA global registry rather than the @@ -104,8 +104,8 @@ Disusing the Global ZCA API +++++++++++++++++++++++++++ ZCA "global" API functions such as ``zope.component.getSiteManager``, -``zope.component.getUtility``, ``zope.component.getAdapter``, and -``zope.component.getMultiAdapter`` aren't strictly necessary. Every +``zope.component.getUtility``, :func:`zope.component.getAdapter`, and +:func:`zope.component.getMultiAdapter` aren't strictly necessary. Every component registry has a method API that offers the same functionality; it can be used instead. For example, presuming the ``registry`` value below is a Zope Component Architecture component @@ -113,7 +113,6 @@ registry, the following bit of code is equivalent to ``zope.component.getUtility(IFoo)``: .. code-block:: python - :linenos: registry.getUtility(IFoo) -- cgit v1.2.3 From f758ec6487bb3b57fb5b1c3aa9ac1f28930d6bd8 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 5 Apr 2013 00:00:44 +0200 Subject: fix some cross-references --- docs/narr/scaffolding.rst | 2 +- docs/narr/security.rst | 2 +- docs/narr/subrequest.rst | 8 ++++---- docs/narr/threadlocals.rst | 2 +- docs/narr/viewconfig.rst | 7 ++++--- docs/narr/webob.rst | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 9ac579a87..420aac2dc 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -95,7 +95,7 @@ because that's the name we gave it in the entry point setup. Running output directory named ``MyStuff``. See the module documentation for :mod:`pyramid.scaffolds` for information -about the API of the :class:`pyramid.scaffolds.PyramidScaffold` class and +about the API of the :class:`pyramid.scaffolds.Template` class and related classes. You can override methods of this class to get special behavior. diff --git a/docs/narr/security.rst b/docs/narr/security.rst index e91e8c542..6517fedf8 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -331,7 +331,7 @@ A principal is usually a user id, however it also may be a group id if your authentication system provides group information and the effective :term:`authentication policy` policy is written to respect group information. For example, the -:class:`pyramid.authentication.RepozeWho1AuthenicationPolicy` respects group +:class:`pyramid.authentication.RepozeWho1AuthenticationPolicy` respects group information if you configure it with a ``callback``. Each ACE in an ACL is processed by an authorization policy *in the diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 93ce747ee..6437bd0fa 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -223,16 +223,16 @@ unconditionally: :meth:`~pyramid.config.Configurator.set_request_property`) on the subrequest object passed as ``request`` -- causes a :class:`~pyramid.event.NewRequest` event to be sent at the +- causes a :class:`~pyramid.events.NewRequest` event to be sent at the beginning of request processing. -- causes a :class:`~pyramid.event.ContextFound` event to be sent when a +- causes a :class:`~pyramid.events.ContextFound` event to be sent when a context resource is found. - + - Ensures that the user implied by the request passed has the necessary authorization to invoke view callable before calling it. -- causes a :class:`~pyramid.event.NewResponse` event to be sent when the +- causes a :class:`~pyramid.events.NewResponse` event to be sent when the Pyramid application returns a response. - Calls any :term:`response callback` functions defined within the subrequest's diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst index 5ff70565c..a90ee4905 100644 --- a/docs/narr/threadlocals.rst +++ b/docs/narr/threadlocals.rst @@ -129,7 +129,7 @@ follows: ever be called within application-specific forks of third-party library code. The library you've forked almost certainly has nothing to do with :app:`Pyramid`, and making it dependent on - :app:`Pyramid` (rather than making your :mod:`pyramid` + :app:`Pyramid` (rather than making your :app:`pyramid` application depend upon it) means you're forming a dependency in the wrong direction. diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 6f0001f61..241ce62b5 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -908,10 +908,11 @@ per :ref:`protecting_views`. .. _debug_notfound_section: -:exc:`NotFound` Errors -~~~~~~~~~~~~~~~~~~~~~~ +:exc:`~pyramid.exceptions.NotFound` Errors +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It's useful to be able to debug :exc:`NotFound` error responses when they +It's useful to be able to debug :exc:`~pyramid.exceptions.NotFound` +error responses when they occur unexpectedly due to an application registry misconfiguration. To debug these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the ``pyramid.debug_notfound`` configuration file setting. Details of why a view diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 02c03c8db..c0ca450b1 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -487,7 +487,7 @@ module. Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the reason for the error. For instance, :class:`pyramid.httpexceptions.HTTPNotFound` subclasses -:class:`pyramid.Response`, so you can manipulate the instances in the same +:class:`pyramid.response.Response`, so you can manipulate the instances in the same way. A typical example is: .. code-block:: python -- cgit v1.2.3 From 5e28d6fa6f2add7bd82aecad45f24c7c4672a253 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 5 Apr 2013 08:58:01 +0200 Subject: fix markup --- docs/narr/scaffolding.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 420aac2dc..0d1e3f448 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -74,11 +74,15 @@ concrete examples of scaffold directories (``zodb``, ``alchemy``, and After you've created the template directory, add the following to the ``entry_points`` value of your distribution's ``setup.py``: - [pyramid.scaffold] - coolextension=coolextension.scaffolds:CoolExtensionTemplate +.. code-block:: ini + + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate For example:: +.. code-block:: python + def setup( ..., entry_points = """\ -- cgit v1.2.3 From 9e7c30d777a29cb69629f4080941c8cb456a3eb5 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 5 Apr 2013 22:27:28 +0200 Subject: fix markup --- docs/narr/scaffolding.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 0d1e3f448..534b2caf4 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -79,7 +79,7 @@ After you've created the template directory, add the following to the [pyramid.scaffold] coolextension=coolextension.scaffolds:CoolExtensionTemplate -For example:: +For example: .. code-block:: python -- cgit v1.2.3 From e556961d789ccf52430d19d44297cceb1f537405 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 5 Apr 2013 22:33:18 +0200 Subject: replace a sentence that doesn't quite fit It's as if pyramid_traversalwrapper was already introduced. --- docs/narr/resources.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index a24c44f29..699a3d4ac 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -171,7 +171,7 @@ you will reach the filesystem root directory. URL generated (as opposed to a single leading slash or empty tuple element). -.. sidebar:: Using :mod:`pyramid_traversalwrapper` +.. sidebar:: For your convenience If you'd rather not manage the ``__name__`` and ``__parent__`` attributes of your resources "by hand", an add-on package named -- cgit v1.2.3 From f5eb753eebbda6fa55ccc5108fcc325931a17f85 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 5 Apr 2013 22:56:48 +0200 Subject: fix some cross-references --- docs/narr/advconfig.rst | 10 +++++----- docs/narr/assets.rst | 2 +- docs/narr/extconfig.rst | 4 ++-- docs/narr/hooks.rst | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 434e2bd6c..1b8e33de3 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -148,14 +148,14 @@ one: config.add_route(...) Don't call this function directly with ``config`` as an argument. Instead, -use :meth:`pyramid.config.Configuration.include`: +use :meth:`pyramid.config.Configurator.include`: .. code-block:: python :linenos: config.include(add_routes) -Using :meth:`~pyramid.config.Configuration.include` instead of calling the +Using :meth:`~pyramid.config.Configurator.include` instead of calling the function directly provides a modicum of automated conflict resolution, with the configuration statements you define in the calling code overriding those of the included function. See also :ref:`automatic_conflict_resolution` and @@ -333,7 +333,7 @@ his application: config.add_route(...) Rather than calling this function directly with ``config`` as an argument. -Instead, use :meth:`pyramid.config.Configuration.include`: +Instead, use :meth:`pyramid.config.Configurator.include`: .. code-block:: python :linenos: @@ -343,7 +343,7 @@ Instead, use :meth:`pyramid.config.Configuration.include`: Using ``include`` rather than calling the function directly will allow :ref:`automatic_conflict_resolution` to work. -:meth:`~pyramid.config.Configuration.include` can also accept a :term:`module` +:meth:`~pyramid.config.Configurator.include` can also accept a :term:`module` as an argument: .. code-block:: python @@ -357,7 +357,7 @@ For this to work properly, the ``myapp`` module must contain a callable with the special name ``includeme``, which should perform configuration (like the ``add_routes`` callable we showed above as an example). -:meth:`~pyramid.config.Configuration.include` can also accept a :term:`dotted +:meth:`~pyramid.config.Configurator.include` can also accept a :term:`dotted Python name` to a function or a module. .. note: See :ref:`the_include_tag` for a declarative alternative to diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 09a2b83f2..26b3e3a92 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -271,7 +271,7 @@ assets which begin with ``mypackage:images`` will be prefixed with # -> http://example.com/images/logo.png Using :meth:`~pyramid.request.Request.static_url` in conjunction with a -:meth:`~pyramid.configuration.Configurator.add_static_view` makes it possible +:meth:`~pyramid.config.Configurator.add_static_view` makes it possible to put static media on a separate webserver during production (if the ``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is a URL), while keeping static media package-internal and served by the diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index f33326279..659056952 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -129,8 +129,8 @@ called (either explicitly or as the result of calling :meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are potentially automatically resolved as per :ref:`automatic_conflict_resolution`. If a conflict cannot be automatically -resolved, a :exc:`ConfigurationConflictError` is raised and application -startup is prevented. +resolved, a :exc:`pyramid.exceptions.ConfigurationConflictError` is raised +and application startup is prevented. In our above example, therefore, if a consumer of our ``add_jammyjam`` directive did this: diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a3de23baa..77c66b0d2 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -929,7 +929,7 @@ set a *default* view mapper (overriding the superdefault view mapper used by Pyramid itself). A *single* view registration can use a view mapper by passing the mapper as -the ``mapper`` argument to :meth:`~pyramid.config.Configuration.add_view`. +the ``mapper`` argument to :meth:`~pyramid.config.Configurator.add_view`. .. index:: single: configuration decorator -- cgit v1.2.3 From 125ea45ae864a5513e6d83fdded6ceea9516b578 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 6 Apr 2013 07:07:37 +0200 Subject: fix some cross-references Also, pyramid_zcml is cross-referenced, so add it to intersphinx_mapping dict. --- docs/narr/environment.rst | 2 +- docs/narr/hooks.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index e059acc4e..f0c0c18fe 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -302,7 +302,7 @@ Ideally, you won't need to use the ``pyramid.tweens`` setting at all. Tweens are generally ordered and included "implicitly" when an add-on package which registers a tween is "included". Packages are included when you name a ``pyramid.includes`` setting in your configuration or when you call -:meth:`pyramid.config.Configuration.include`. +:meth:`pyramid.config.Configurator.include`. Authors of included add-ons provide "implicit" tween configuration ordering hints to Pyramid when their packages are included. However, the implicit diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 77c66b0d2..1bd294bd1 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -673,7 +673,7 @@ traverser. If you've added a traverser, you can change how :meth:`~pyramid.request.Request.resource_url` generates a URL for a specific type of resource by adding a call to -:meth:`pyramid.config.add_resource_url_adapter`. +:meth:`pyramid.config.Configurator.add_resource_url_adapter`. For example: -- cgit v1.2.3 From 439a02a420d9014a56d01f7e08db89ec65d943c5 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 21 Apr 2013 15:27:24 +0200 Subject: docs/narr/hooks.rst: some improvements * consistency fixes: "not found view" --> "Not Found View" * use comparable code for Imperative and Declarative configuration * remove unused import, HTTPForbidden --- docs/narr/hooks.rst | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 1bd294bd1..37a74b53a 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -14,8 +14,8 @@ in various ways. Changing the Not Found View --------------------------- -When :app:`Pyramid` can't map a URL to view code, it invokes a :term:`not -found view`, which is a :term:`view callable`. The default Not Found View +When :app:`Pyramid` can't map a URL to view code, it invokes a :term:`Not +Found View`, which is a :term:`view callable`. The default Not Found View can be overridden through application configuration. If your application uses :term:`imperative configuration`, you can replace @@ -25,15 +25,17 @@ the Not Found View by using the .. code-block:: python :linenos: - from helloworld.views import notfound - config.add_notfound_view(notfound) + def notfound(request): + return Response('Not Found, dude', status='404 Not Found') -Replace ``helloworld.views.notfound`` with a reference to the :term:`view -callable` you want to use to represent the Not Found View. The :term:`not -found view` callable is a view callable like any other. + def main(globals, **settings): + config = Configurator() + config.add_notfound_view(notfound) + +The :term:`Not Found View` callable is a view callable like any other. If your application instead uses :class:`pyramid.view.view_config` decorators -and a :term:`scan`, you can replace the Not Found view by using the +and a :term:`scan`, you can replace the Not Found View by using the :class:`pyramid.view.notfound_view_config` decorator: .. code-block:: python @@ -46,8 +48,8 @@ and a :term:`scan`, you can replace the Not Found view by using the return Response('Not Found, dude', status='404 Not Found') def main(globals, **settings): - config = Configurator() - config.scan() + config = Configurator() + config.scan() This does exactly what the imperative example above showed. @@ -154,12 +156,12 @@ forbidden view: .. code-block:: python :linenos: - from helloworld.views import forbidden_view - from pyramid.httpexceptions import HTTPForbidden - config.add_forbidden_view(forbidden_view) + def forbidden(request): + return Response('forbidden') -Replace ``helloworld.views.forbidden_view`` with a reference to the Python -:term:`view callable` you want to use to represent the Forbidden view. + def main(globals, **settings): + config = Configurator() + config.add_forbidden_view(forbidden_view) If instead you prefer to use decorators and a :term:`scan`, you can use the :class:`pyramid.view.forbidden_view_config` decorator to mark a view callable -- cgit v1.2.3 From 7a0b5905d65c047ed3ac160f26f6566dfeba8f6a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 21 Apr 2013 23:07:50 +0300 Subject: remove ambiguity by indicating that the target is API documentation --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index bfb1287d9..9065488b6 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -125,7 +125,7 @@ method attached to ``MyTest`` will use an isolated registry. The :func:`~pyramid.testing.setUp` and :func:`~pyramid.testing.tearDown` functions accepts various arguments that influence the environment of the -test. See the :ref:`testing_module` chapter for information about the extra +test. See the :ref:`testing_module` API for information about the extra arguments supported by these functions. If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something -- cgit v1.2.3 From 3fc77cfc0283315fe03497e79d07bbdaada6e006 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 21 Apr 2013 23:24:53 +0300 Subject: add a cross-ref... hyperlinks are nice --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index bfb1287d9..cc042fe39 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -202,7 +202,7 @@ any ``get_current*`` function. Using the ``Configurator`` and ``pyramid.testing`` APIs in Unit Tests --------------------------------------------------------------------- -The ``Configurator`` API and the ``pyramid.testing`` module provide a number +The ``Configurator`` API and the :mod:`pyramid.testing` module provide a number of functions which can be used during unit testing. These functions make :term:`configuration declaration` calls to the current :term:`application registry`, but typically register a "stub" or "dummy" feature in place of the -- cgit v1.2.3 From 8741e9a0e11adbbf58d360f115fb6ad99a76a76e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Apr 2013 21:08:00 +0200 Subject: no need to link to a chapter that follows immediately --- docs/narr/renderers.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b4eb95186..9f7390449 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -38,9 +38,7 @@ object from a view that is configured with a renderer, the renderer is bypassed entirely. Various types of renderers exist, including serialization renderers -and renderers which use templating systems. See also -:ref:`views_which_use_a_renderer`. - +and renderers which use templating systems. .. index:: single: renderer -- cgit v1.2.3 From 8104c862d38c4b823fe913b4a7c04161ebba5bbb Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Apr 2013 21:12:00 +0200 Subject: simplify explanation The sentence was simply too long-winded (and not too clear). --- docs/narr/renderers.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 9f7390449..9d6509b78 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -33,8 +33,7 @@ by the view must be compatible with the particular kind of renderer used, or an error may occur during view invocation. One exception exists: it is *always* OK to return a Response object, even -when a ``renderer`` is configured. If a view callable returns a response -object from a view that is configured with a renderer, the renderer is +when a ``renderer`` is configured. In such cases, the renderer is bypassed entirely. Various types of renderers exist, including serialization renderers -- cgit v1.2.3 From 61b021633fd6d5e9a5773f5409858b3998e48ca0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Apr 2013 21:18:06 +0200 Subject: grammar --- docs/narr/renderers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b4eb95186..8c88fd055 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -51,8 +51,8 @@ and renderers which use templating systems. See also Writing View Callables Which Use a Renderer ------------------------------------------- -As we've seen, view callables needn't always return a Response object. -Instead, they may return an arbitrary Python object, with the expectation +As we've seen, a view callable needn't always return a Response object. +Instead, it may return an arbitrary Python object, with the expectation that a :term:`renderer` will convert that object into a response instance on your behalf. Some renderers use a templating system; other renderers use object serialization techniques. -- cgit v1.2.3 From 6ce39f11b76dc599dfc897eab43bcf236b26c5d5 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Apr 2013 22:43:55 +0300 Subject: remove redundant text Also, this fact has already been explained in the chapter, so mention that. --- docs/narr/renderers.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b4eb95186..bcab0e3f4 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -80,12 +80,10 @@ response attributes (such as headers and the HTTP status code) by attaching a property to the ``request.response`` attribute. See :ref:`request_response_attr`. -If the :term:`view callable` associated with a :term:`view configuration` -returns a Response object directly, any renderer associated with the view -configuration is ignored, and the response is passed back to :app:`Pyramid` -unchanged. For example, if your view callable returns an instance of the -:class:`pyramid.response.Response` class as a response, no renderer -will be employed. +As already mentioned, if the :term:`view callable` associated with a +:term:`view configuration` returns a Response object (or its instance), +any renderer associated with the view configuration is ignored, +and the response is passed back to :app:`Pyramid` unchanged. For example: .. code-block:: python :linenos: -- cgit v1.2.3 From e8f87a048cf7cc4ac8673dd15d5743afa63e2fbb Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 22 Apr 2013 23:25:12 +0300 Subject: remove redundancy --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b4eb95186..2ebf9b20e 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -140,7 +140,7 @@ used in the ``renderer`` attribute of view configurations. ``string``: String Renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``string`` renderer is a renderer which renders a view callable result to +The ``string`` renderer renders a view callable result to a string. If a view callable returns a non-Response object, and the ``string`` renderer is associated in that view's configuration, the result will be to run the object through the Python ``str`` function to generate a -- cgit v1.2.3 From cdd8d40dac07d73bf60ebe5d9ddbb2d108d8666e Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 00:47:36 +0300 Subject: add missing comma --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 56c62b996..0d0e292bf 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -291,7 +291,7 @@ function is called, :func:`pyramid.security.has_permission` will call the access. We check that the view function raises a :exc:`~pyramid.httpexceptions.HTTPForbidden` error. -The second test method, named ``test_view_fn_allowed`` tests the alternate +The second test method, named ``test_view_fn_allowed``, tests the alternate case, where the authentication policy allows access. Notice that we pass different values to :meth:`~pyramid.config.Configurator.testing_securitypolicy` to obtain this -- cgit v1.2.3 From 727508ba9a19955fb0f65e2dead3b578cee450c3 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 01:24:51 +0300 Subject: replace deprecated method --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 56c62b996..89ed038f2 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -373,7 +373,7 @@ after accessing some values that require a fully set up environment. result = my_view(request) self.assertEqual(result.status, '200 OK') body = result.app_iter[0] - self.failUnless('Welcome to' in body) + self.assertTrue('Welcome to' in body) self.assertEqual(len(result.headerlist), 2) self.assertEqual(result.headerlist[0], ('Content-Type', 'text/html; charset=UTF-8')) -- cgit v1.2.3 From 1bf894d55e6a536f31a8c4c2b99c29e96b3bd3a9 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 01:26:58 +0300 Subject: replace deprecated method --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 56c62b996..de5a04f56 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -416,7 +416,7 @@ functional testing package written by Ian Bicking. def test_root(self): res = self.testapp.get('/', status=200) - self.failUnless('Pyramid' in res.body) + self.assertTrue('Pyramid' in res.body) When this test is run, each test creates a "real" WSGI application using the ``main`` function in your ``myapp.__init__`` module and uses :term:`WebTest` -- cgit v1.2.3 From 613a7e5972ac15c0c296307de47944bfb07969c0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 23 Apr 2013 09:35:48 +0300 Subject: add a note about missing code --- docs/narr/testing.rst | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index ec5952a7c..88d6904c7 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -222,6 +222,12 @@ function. raise HTTPForbidden return {'greeting':'hello'} +.. note:: + + This code implies that you have defined a renderer imperatively in a + relevant :class:`pyramid.config.Configurator` instance, + otherwise it would fail when run normally. + Without doing anything special during a unit test, the call to :func:`~pyramid.security.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts normally, -- cgit v1.2.3 From d95a2732eb2f972df9fb2f954ae374b8acd06727 Mon Sep 17 00:00:00 2001 From: Luke Cyca Date: Sun, 2 Jun 2013 19:08:44 -0700 Subject: Edited narrative docs about CSRF --- docs/narr/sessions.rst | 53 +++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index c4f4b5f07..52b4860b3 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -298,14 +298,15 @@ Preventing Cross-Site Request Forgery Attacks `Cross-site request forgery `_ attacks are a -phenomenon whereby a user with an identity on your website might click on a -URL or button on another website which secretly redirects the user to your -application to perform some command that requires elevated privileges. - -You can avoid most of these attacks by making sure that the correct *CSRF -token* has been set in an :app:`Pyramid` session object before performing any -actions in code which requires elevated privileges that is invoked via a form -post. To use CSRF token support, you must enable a :term:`session factory` +phenomenon whereby a user who is logged in to your website might inadvertantly +load a URL because it is linked from, or embedded in, an attacker's website. +If the URL is one that may modify or delete data, the consequences can be dire. + +You can avoid most of these attacks by issuing a unique token to the browser +and then requiring that it be present in all potentially unsafe requests. +:app:`Pyramid` sessions provide facilities to create and check CSRF tokens. + +To use CSRF tokens, you must first enable a :term:`session factory` as described in :ref:`using_the_default_session_factory` or :ref:`using_alternate_session_factories`. @@ -324,33 +325,41 @@ To get the current CSRF token from the session, use the The ``session.get_csrf_token()`` method accepts no arguments. It returns a CSRF *token* string. If ``session.get_csrf_token()`` or -``session.new_csrf_token()`` was invoked previously for this session, the +``session.new_csrf_token()`` was invoked previously for this session, then the existing token will be returned. If no CSRF token previously existed for -this session, a new token will be will be set into the session and returned. +this session, then a new token will be will be set into the session and returned. The newly created token will be opaque and randomized. You can use the returned token as the value of a hidden field in a form that -posts to a method that requires elevated privileges. The handler for the -form post should use ``session.get_csrf_token()`` *again* to obtain the -current CSRF token related to the user from the session, and compare it to -the value of the hidden form field. For example, if your form rendering -included the CSRF token obtained via ``session.get_csrf_token()`` as a hidden -input field named ``csrf_token``: +posts to a method that requires elevated privileges, or supply it as a request +header in AJAX requests. The handler for the URL that receives the request +should then require that the correct CSRF token is supplied. -.. code-block:: python - :linenos: +Using the ``session.check_csrf_token`` Method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - token = request.session.get_csrf_token() - if token != request.POST['csrf_token']: - raise ValueError('CSRF token did not match') +In request handling code, you can check the presence and validity of a CSRF +token with ``session.check_csrf_token(request)``. If the token is valid, +it will return True, otherwise it will raise ``HTTPBadRequest``. + +By default, it checks for a GET or POST parameter named ``csrf_token`` or a +header named ``X-CSRF-Token``. .. index:: single: session.new_csrf_token +Checking CSRF Tokens With A View Predicate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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_route`. + + Using the ``session.new_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To explicitly add a new CSRF token to the session, use the +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 -- cgit v1.2.3 From 009f843d7d72d3a9d8cc35c08db9b77e247111f5 Mon Sep 17 00:00:00 2001 From: Luke Cyca Date: Tue, 4 Jun 2013 22:25:37 -0700 Subject: Add examples to narrative CSRF docs --- docs/narr/sessions.rst | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 52b4860b3..7ec280c8a 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -332,7 +332,32 @@ The newly created token will be opaque and randomized. You can use the returned token as the value of a hidden field in a form that posts to a method that requires elevated privileges, or supply it as a request -header in AJAX requests. The handler for the URL that receives the request +header in AJAX requests. + +For example, include the CSRF token as a hidden field: + +.. code-block:: html + +
    + + +
    + +Or, include it as a header in a jQuery AJAX request: + +.. code-block:: javascript + + var csrfToken = ${request.session.get_csrf_token()}; + $.ajax({ + type: "POST", + url: "/myview", + headers: { 'X-CSRF-Token': csrfToken } + }).done(function() { + alert("Deleted"); + }); + + +The handler for the URL that receives the request should then require that the correct CSRF token is supplied. Using the ``session.check_csrf_token`` Method @@ -345,6 +370,16 @@ it will return True, otherwise it will raise ``HTTPBadRequest``. By default, it checks for a GET or POST parameter named ``csrf_token`` or a header named ``X-CSRF-Token``. +.. code-block:: python + + def myview(request): + session = request.session + + # Require CSRF Token + session.check_csrf_token(request): + + ... + .. index:: single: session.new_csrf_token @@ -355,6 +390,12 @@ 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_route`. +.. code-block:: python + + @view_config(request_method='POST', check_csrf=True, ...) + def myview(request): + ... + Using the ``session.new_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 05b5925b5341734e068cd40379709c0f330898fa Mon Sep 17 00:00:00 2001 From: Ole Morten Halvorsen Date: Thu, 6 Jun 2013 20:07:08 +1000 Subject: Resources.rst quick typo fix There's 3 keys in the info dict, not two. --- docs/narr/resources.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 699a3d4ac..b1bb611e5 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -300,7 +300,7 @@ the resource by :meth:`~pyramid.request.Request.resource_url`. The ``__resource_url__`` hook is passed two arguments: ``request`` and ``info``. ``request`` is the :term:`request` object passed to :meth:`~pyramid.request.Request.resource_url`. ``info`` is a dictionary with -two keys: +the following keys: ``physical_path`` A string representing the "physical path" computed for the resource, as -- cgit v1.2.3 From 47eaa189e115936a86357380accd8d472e4d9a6c Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 11 Jun 2013 14:54:58 -0400 Subject: About half of the first pass is done. --- docs/narr/project.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9d69a65a5..8cf67e104 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -992,6 +992,8 @@ prompt with a similar configuration as would be loaded if you were running your Pyramid application via ``pserve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. +.. _what_is_this_pserve_thing: + What Is This ``pserve`` Thing ----------------------------- -- cgit v1.2.3 From 5028d84aeb6ac79ee7db4dc4012ff4caaba10e77 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 18 Jul 2013 18:09:20 -0400 Subject: normalize notations used for string and json renderer return values, closes #1005 --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 20a9eda31..a2811dbae 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -198,7 +198,7 @@ representing the JSON serialization of the return value: .. code-block:: python - '{"content": "Hello!"}' + {"content": "Hello!"} The return value needn't be a dictionary, but the return value must contain values serializable by the configured serializer (by default ``json.dumps``). -- cgit v1.2.3 From 32333e4d84fe0e71ce097a5dca57025353956dbe Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Jul 2013 17:22:48 -0400 Subject: add not_ predicate feature --- docs/narr/viewconfig.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 241ce62b5..388371a0d 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -557,6 +557,33 @@ form of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. +Inverting Predicate Values +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can invert the meaning of any predicate value by wrapping it in a call to +:class:`pyramid.config.not_`. + +.. code-block:: python + :linenos: + + from pyramid.config import not_ + + config.add_view( + 'mypackage.views.my_view', + route_name='ok', + request_method=not_('POST') + ) + +The above example will ensure that the view is called if the request method +is *not* ``POST``, at least if no other view is more specific. + +This technique of wrapping a predicate value in ``not_`` can be used anywhere +predicate values are accepted: + +- :meth:`pyramid.config.Configurator.add_view` + +- :meth:`pyramid.view.view_config` + .. index:: single: view_config placement -- cgit v1.2.3 From bb9948168a9540d7b1b574ca8ee02bd07cbdede9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 24 Jul 2013 18:00:03 -0400 Subject: indicate version in which not_ was added --- docs/narr/viewconfig.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 388371a0d..b78b9b497 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -584,6 +584,8 @@ predicate values are accepted: - :meth:`pyramid.view.view_config` +.. versionadded:: 1.5 + .. index:: single: view_config placement -- cgit v1.2.3 From a6291243051b1977832b0b9a45c27eb68d7ba867 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 27 Jul 2013 03:03:08 -0600 Subject: Move .. versionadded:: 1.2 to end of ``match_param`` definition so that when building PDF it does not pause and wait for user to hit RETURN. This is now consistent with other placements of this directive as well. --- docs/narr/viewconfig.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index b78b9b497..fd3229339 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -290,9 +290,9 @@ configured view. of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. ``request_param`` - This value can be any string or a sequence of strings. A view declaration - with this argument ensures that the view will only be called when the - :term:`request` has a key in the ``request.params`` dictionary (an HTTP + This value can be any string or a sequence of strings. A view declaration + with this argument ensures that the view will only be called when the + :term:`request` has a key in the ``request.params`` dictionary (an HTTP ``GET`` or ``POST`` variable) that has a name which matches the supplied value. @@ -306,8 +306,6 @@ configured view. consideration of keys and values in the ``request.params`` dictionary. ``match_param`` - .. versionadded:: 1.2 - This param may be either a single string of the format "key=value" or a dict of key/value pairs. @@ -324,6 +322,8 @@ configured view. If ``match_param`` is not supplied, the view will be invoked without consideration of the keys and values in ``request.matchdict``. + .. versionadded:: 1.2 + ``containment`` This value should be a reference to a Python class or :term:`interface` that a parent object in the context resource's :term:`lineage` must provide @@ -505,7 +505,7 @@ configuration stanza: .. code-block:: python :linenos: - config.add_view('mypackage.views.my_view', route_name='ok', + config.add_view('mypackage.views.my_view', route_name='ok', request_method='POST', permission='read') All arguments to ``view_config`` may be omitted. For example: @@ -570,7 +570,7 @@ You can invert the meaning of any predicate value by wrapping it in a call to config.add_view( 'mypackage.views.my_view', - route_name='ok', + route_name='ok', request_method=not_('POST') ) -- cgit v1.2.3 From ff00405c65a901d5a952e27ec96ff4239c58b012 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Aug 2013 13:00:52 -0400 Subject: point at add-on documentation --- docs/narr/introduction.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 48164d323..fa2646134 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -217,6 +217,8 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. +Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation + Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From b210ce350a3856166376f63a32725cc1516ba294 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Aug 2013 19:14:29 -0400 Subject: add pdistreport command --- docs/narr/commandline.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index e1347f3ca..17e5227fa 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -474,6 +474,30 @@ input of the ``prequest`` process is used as the ``POST`` body:: $ $VENV/bin/prequest -mPOST development.ini / < somefile +Showing All Installed Distributions and their Versions +------------------------------------------------------ + +.. versionadded:: 1.5 + +You can use the ``pdistreport`` command to show the Pyramid version in use, the +Python version in use, and all installed versions of Python distributions in +your Python environment:: + + $ $VENV/bin/pdistreport + Pyramid version: 1.5dev + Platform Linux-3.2.0-51-generic-x86_64-with-debian-wheezy-sid + Packages: + authapp 0.0 + /home/chrism/projects/foo/src/authapp + beautifulsoup4 4.1.3 + /home/chrism/projects/foo/lib/python2.7/site-packages/beautifulsoup4-4.1.3-py2.7.egg + ... more output ... + +``pdistreport`` takes no options. Its output is useful to paste into a +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 -- cgit v1.2.3 From 83fefbf3f92183d1d899c8449a03546dd3c022a3 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Sat, 3 Aug 2013 11:23:20 -0400 Subject: "Web Application Development Framework" -> "Web Framework". Yay. --- docs/narr/MyProject/myproject/templates/mytemplate.pt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 0bfac946e..0fccba624 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

    Welcome to ${project}, an application generated by
    - the Pyramid web application development framework. + the Pyramid Web Framework.

  • -- cgit v1.2.3 From efcf8f1c8b1e1140a5e9d9bb6fea558150ae7c29 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Sat, 3 Aug 2013 11:34:05 -0400 Subject: Some more occurrences of "application framework". --- docs/narr/templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index d4cf20b93..f1e1634b8 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -711,7 +711,7 @@ look like:

    Welcome to ${project}, an application generated by the pyramid web application framework.

    + >pyramid web framework. -- cgit v1.2.3 From a5da4dbbb2f5876740004c5fc9ffb15ae600d35e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 6 Aug 2013 03:34:52 -0400 Subject: add redis session mention --- docs/narr/sessions.rst | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 7ec280c8a..82440060c 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -148,6 +148,7 @@ Some gotchas: .. index:: single: pyramid_beaker single: Beaker + single: pyramid_redis_sessions single: session factory (alternates) .. _using_alternate_session_factories: @@ -155,11 +156,17 @@ Some gotchas: Using Alternate Session Factories --------------------------------- -At the time of this writing, exactly one alternate session factory -implementation exists, named ``pyramid_beaker``. This is a session factory -that uses the `Beaker `_ library as a backend. -Beaker has support for file-based sessions, database based sessions, and -encrypted cookie-based sessions. See `the pyramid_beaker documentation +At the time of this writing, exactly two alternate session factories +exist. + +The first is named ``pyramid_redis_sessions``. It can be downloaded from PyPI. +It uses Redis as a backend. It is the recommended persistent session solution +at the time of this writing. + +The second is named ``pyramid_beaker``. This is a session factory that uses the +`Beaker `_ library as a backend. Beaker has +support for file-based sessions, database based sessions, and encrypted +cookie-based sessions. See `the pyramid_beaker documentation `_ for more information about ``pyramid_beaker``. -- cgit v1.2.3 From 1670e45561674bed100583665eccce5e5284439f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 6 Aug 2013 02:24:48 -0700 Subject: add missing word ``pserve`` --- docs/narr/project.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9d69a65a5..e25f3012a 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1005,12 +1005,12 @@ Pyramid application based on the data in the file. application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to run a :app:`Pyramid` application is purely conventional based on the output -of its scaffolding. But we strongly recommend using while developing your -application, because many other convenience introspection commands (such as -``pviews``, ``prequest``, ``proutes`` and others) are also implemented in -terms of configuration availability of this ``.ini`` file format. It also -configures Pyramid logging and provides the ``--reload`` switch for -convenient restarting of the server when code changes. +of its scaffolding. But we strongly recommend using ``pserve`` while +developing your application, because many other convenience introspection +commands (such as ``pviews``, ``prequest``, ``proutes`` and others) are also +implemented in terms of configuration availability of this ``.ini`` file +format. It also configures Pyramid logging and provides the ``--reload`` +switch for convenient restarting of the server when code changes. .. _alternate_wsgi_server: -- cgit v1.2.3 From 00f9fe4dc2425d58d4c30253c53695bdf2a21e99 Mon Sep 17 00:00:00 2001 From: tisdall Date: Thu, 8 Aug 2013 14:44:23 -0400 Subject: "langauges" to "languages" --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 74765f8e2..bb336784f 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -808,7 +808,7 @@ If this setting is supplied within the :app:`Pyramid` application default_locale_name = settings['pyramid.default_locale_name'] .. index:: - single: detecting langauges + single: detecting languages "Detecting" Available Languages ------------------------------- -- cgit v1.2.3 From dcc7d67cb55304483b3c9931fbec17e98447279a Mon Sep 17 00:00:00 2001 From: tisdall Date: Thu, 8 Aug 2013 15:11:43 -0400 Subject: "resouce" to "resource" --- docs/narr/traversal.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index 2eb6ece13..a60c5ba56 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -289,7 +289,7 @@ system uses this algorithm to find a :term:`context` resource and a return resource "C". #. Traversal ends when a) the entire path is exhausted or b) when any - resouce raises a :exc:`KeyError` from its ``__getitem__`` or c) when any + resource raises a :exc:`KeyError` from its ``__getitem__`` or c) when any non-final path element traversal does not have a ``__getitem__`` method (resulting in a :exc:`AttributeError`) or d) when any path element is prefixed with the set of characters ``@@`` (indicating that the characters -- cgit v1.2.3 From bfd928b5424c49343c6680715013d61bf4991cfa Mon Sep 17 00:00:00 2001 From: tisdall Date: Fri, 9 Aug 2013 14:42:49 -0400 Subject: "dermine" to "determine" --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index bb336784f..2964686d3 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -984,7 +984,7 @@ requires no additional coding or configuration. The default locale negotiator implementation named :class:`~pyramid.i18n.default_locale_negotiator` uses the following -set of steps to dermine the locale name. +set of steps to determine the locale name. - First, the negotiator looks for the ``_LOCALE_`` attribute of the request object (possibly set directly by view code or by a listener -- cgit v1.2.3 From 4a7ab035275b20b9a2926d65a3936b6fc8c35c3a Mon Sep 17 00:00:00 2001 From: tisdall Date: Fri, 9 Aug 2013 14:51:35 -0400 Subject: "offical" to "official" --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index fa2646134..032f4be6b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -859,7 +859,7 @@ It's our goal that no Pyramid question go unanswered. Whether you ask a question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow -users in our various offical support channels. We try to keep it well-lit +users in our various official support channels. We try to keep it well-lit and new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on -- cgit v1.2.3 From c40d20b20c3a8d0b3ac6f2e7ee1632889a69bfe5 Mon Sep 17 00:00:00 2001 From: tisdall Date: Fri, 9 Aug 2013 14:54:36 -0400 Subject: "repetion" to "repetition" --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index fd3229339..6a064c209 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -831,7 +831,7 @@ of this: config.add_view( RESTView, route_name='rest', attr='delete', request_method='DELETE') -To reduce the amount of repetion in the ``config.add_view`` statements, we +To reduce the amount of repetition in the ``config.add_view`` statements, we can move the ``route_name='rest'`` argument to a ``@view_default`` class decorator on the RESTView class: -- cgit v1.2.3 From 866944efa58accab20abca15409803d9e13368b4 Mon Sep 17 00:00:00 2001 From: tisdall Date: Fri, 9 Aug 2013 14:56:29 -0400 Subject: "arent" to "aren't" --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 18cb3e4db..310c160c0 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -865,7 +865,7 @@ Debugging Route Matching ------------------------ It's useful to be able to take a peek under the hood when requests that enter -your application arent matching your routes as you expect them to. To debug +your application aren't matching your routes as you expect them to. To debug route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or the ``pyramid.debug_routematch`` configuration file setting (set either to ``true``). Details of the route matching decision for a particular request to the -- cgit v1.2.3 From 7683e22a93a3df2a541dddb9afac540ef9094f49 Mon Sep 17 00:00:00 2001 From: Jeff Szusz Date: Mon, 12 Aug 2013 11:10:09 -0400 Subject: #967 fixed 'Sommetime' -> 'Sometime' in templates.rst --- docs/narr/templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index d4cf20b93..ddebb3fa2 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -723,7 +723,7 @@ This template doesn't use any advanced features of Mako, only the Using A Mako def name Within a Renderer Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Sommetime you'd like to render a ``def`` inside of a Mako template instead of +Sometime you'd like to render a ``def`` inside of a Mako template instead of the full Mako template. To render a def inside a Mako template, given a :term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can configure the template as a :term:`renderer` like so: -- cgit v1.2.3 From fc9d4cbc8b3ccbd2c2b5c942595bf420eeae4596 Mon Sep 17 00:00:00 2001 From: Jeff Szusz Date: Mon, 12 Aug 2013 11:28:53 -0400 Subject: Update templates.rst --- docs/narr/templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index ddebb3fa2..af5ad6c5c 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -723,7 +723,7 @@ This template doesn't use any advanced features of Mako, only the Using A Mako def name Within a Renderer Name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Sometime you'd like to render a ``def`` inside of a Mako template instead of +Sometimes you'd like to render a ``def`` inside of a Mako template instead of the full Mako template. To render a def inside a Mako template, given a :term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can configure the template as a :term:`renderer` like so: -- cgit v1.2.3 From 9d0643063615ef7ce54fe062461c5dbf92cde3b4 Mon Sep 17 00:00:00 2001 From: Amos Latteier Date: Mon, 12 Aug 2013 16:04:00 -0400 Subject: Add documentation for creating and firing custom events. See issue #982. --- docs/narr/events.rst | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 929208083..6065b67fd 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -53,7 +53,7 @@ method (see also :term:`Configurator`): from subscribers import mysubscriber - # "config" below is assumed to be an instance of a + # "config" below is assumed to be an instance of a # pyramid.config.Configurator object config.add_subscriber(mysubscriber, NewRequest) @@ -113,7 +113,7 @@ your application like so: :linenos: def handle_new_request(event): - print 'request', event.request + print 'request', event.request def handle_new_response(event): print 'response', event.response @@ -150,3 +150,78 @@ application, because the interface defined at :class:`pyramid.interfaces.INewResponse` says it must (:class:`pyramid.events.NewResponse` objects also have a ``request``). +.. _custom_events: + +Creating Your Own Events +------------------------ + +In addition to using the events that the Pyramid framework creates, +you can create your own events for use in your application. This can +be useful to decouple parts of your application. + +For example, suppose your application has to do many things when a new +document is created. Rather than putting all this logic in the view +that creates the document, you can create the document in your view +and then fire a custom event. Subscribers to the custom event can take +other actions, such as indexing the document, sending email, or +sending a message to a remote system. + +An event is simply an object. There are no required attributes or +method for your custom events. In general, your events should keep +track of the information that subscribers will need. Here are some +example custom event classes: + +.. code-block:: python + :linenos: + + class DocCreated(object): + def __init__(self, doc, request): + self.doc = doc + self.request = request + + class UserEvent(object): + def __init__(self, user): + self.user = user + + class UserLoggedIn(UserEvent): + pass + +Some Pyramid applications choose to define custom events classes in an +``events`` module. + +You can subscribe to custom events in the same way what you subscribe +to Pyramid events -- either imperatively or with a decorator. Here's +an example of subscribing to a custom event with a decorator: + +.. code-block:: python + :linenos: + + from pyramid.events import subscriber + from .events import DocCreated + from .index import index_doc + + @subscriber(DocCreated) + def index_doc(event): + # index the document using our application's index_doc function + index_doc(event.doc, event.request) + +The above example assumes that the application defines a +``DocCreated`` event class and an ``index_doc`` function. + +To fire your custom events use the +:meth:`pyramid.registry.Registry.notify` method, which is most often +accessed as ``request.registry.notify``. For example: + +.. code-block:: python + :linenos: + + from .events import DocCreated + + def new_doc_view(request): + doc = MyDoc() + event = DocCreated(doc, request) + request.registry.notify(event) + return {'document': doc} + +This example view will notify all subscribers to the custom +``DocCreated`` event. -- cgit v1.2.3 From 387051c91d5a3844db5fa0938a19c19f5881e056 Mon Sep 17 00:00:00 2001 From: Amos Latteier Date: Mon, 12 Aug 2013 16:27:41 -0400 Subject: Fix tab/space snafu. --- docs/narr/events.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 6065b67fd..702618843 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -177,7 +177,7 @@ example custom event classes: class DocCreated(object): def __init__(self, doc, request): self.doc = doc - self.request = request + self.request = request class UserEvent(object): def __init__(self, user): @@ -219,9 +219,9 @@ accessed as ``request.registry.notify``. For example: def new_doc_view(request): doc = MyDoc() - event = DocCreated(doc, request) - request.registry.notify(event) - return {'document': doc} + event = DocCreated(doc, request) + request.registry.notify(event) + return {'document': doc} This example view will notify all subscribers to the custom ``DocCreated`` event. -- cgit v1.2.3 From 29ab2b964164844daa012c3e80d276f49ccbe217 Mon Sep 17 00:00:00 2001 From: Amos Latteier Date: Mon, 12 Aug 2013 16:45:11 -0400 Subject: Minor fixes suggested by @tshepang and @mmerickel thanks! --- docs/narr/events.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 702618843..485247afc 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -77,7 +77,7 @@ type via the :func:`pyramid.events.subscriber` function. @subscriber(NewRequest) def mysubscriber(event): - event.request.foo = 1 + event.request.foo = 1 When the :func:`~pyramid.events.subscriber` decorator is used a :term:`scan` must be performed against the package containing the @@ -189,7 +189,7 @@ example custom event classes: Some Pyramid applications choose to define custom events classes in an ``events`` module. -You can subscribe to custom events in the same way what you subscribe +You can subscribe to custom events in the same way that you subscribe to Pyramid events -- either imperatively or with a decorator. Here's an example of subscribing to a custom event with a decorator: @@ -225,3 +225,7 @@ accessed as ``request.registry.notify``. For example: This example view will notify all subscribers to the custom ``DocCreated`` event. + +Note that when you fire an event, all subscribers are run +synchronously on the current thread. So it's generally not a good idea +to create event handlers that may take a long time to run. -- cgit v1.2.3 From 970dfae46bb398e862f57d89c3f6efe10c45e715 Mon Sep 17 00:00:00 2001 From: Amos Latteier Date: Mon, 12 Aug 2013 17:00:29 -0400 Subject: Mention subscriber predicates. --- docs/narr/events.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 485247afc..5004a1787 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -190,8 +190,10 @@ Some Pyramid applications choose to define custom events classes in an ``events`` module. You can subscribe to custom events in the same way that you subscribe -to Pyramid events -- either imperatively or with a decorator. Here's -an example of subscribing to a custom event with a decorator: +to Pyramid events -- either imperatively or with a decorator. You can +also use custom events with :ref:`subscriber predicates +`. Here's an example of subscribing to a custom +event with a decorator: .. code-block:: python :linenos: -- cgit v1.2.3 From 8339cd1095be5e49fe41662e3618b8da6055a4f0 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 12 Aug 2013 16:28:57 -0500 Subject: remove the "thread" reference --- docs/narr/events.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 5004a1787..11af89ca6 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -229,5 +229,7 @@ This example view will notify all subscribers to the custom ``DocCreated`` event. Note that when you fire an event, all subscribers are run -synchronously on the current thread. So it's generally not a good idea -to create event handlers that may take a long time to run. +synchronously so it's generally not a good idea +to create event handlers that may take a long time to run. Although +event handlers could be used as a central place to spawn tasks on your +own message queues. -- cgit v1.2.3 From 49d634bd813e63c3db5e56d29376126c2646182a Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Mon, 12 Aug 2013 19:29:23 -0400 Subject: All wrapped up, pre-merge. --- docs/narr/sessions.rst | 2 ++ docs/narr/templates.rst | 2 ++ docs/narr/viewconfig.rst | 2 ++ 3 files changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 7ec280c8a..7ba46c92c 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -181,6 +181,8 @@ implementation in the :mod:`pyramid.session` module as inspiration. .. index:: single: flash messages +.. _flash_messages: + Flash Messages -------------- diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index f1e1634b8..a70398c80 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -616,6 +616,8 @@ extension so that these ``svn:ignore`` patterns work. .. index:: pair: debugging; templates +.. _debugging_templates: + Debugging Templates ------------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 241ce62b5..047898cfe 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -976,6 +976,8 @@ invoked as the result of the ``http_cache`` argument to view configuration. .. index:: pair: view configuration; debugging +.. _debugging_view_configuration: + Debugging View Configuration ---------------------------- -- cgit v1.2.3 From 5710a15399fcbf7d682171087393418473fdea6a Mon Sep 17 00:00:00 2001 From: kusut Date: Thu, 15 Aug 2013 20:26:58 +0700 Subject: Update install.rst - simplify installation by removing distribute (merge with setuptools) - update setuptools link - simplify windows tutorial by dropping 3.2, latest python version only (2.7 and 3.3) --- docs/narr/install.rst | 144 ++++++++++++-------------------------------------- 1 file changed, 33 insertions(+), 111 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 8fc63f3a4..d05c8abeb 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -162,19 +162,19 @@ 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` or :term:`distribute` is installed. To do so, invoke +: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 or distribute is +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 or -distribute is not yet installed: +Running the same command will yield the following output if setuptools is not +yet installed: .. code-block:: text @@ -183,27 +183,23 @@ distribute is not yet installed: ImportError: No module named setuptools If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools or distribute manually. +will need to install setuptools manually. If you are using a "system" Python (one installed by your OS distributor or a 3rd-party packager such as Fink or MacPorts), you can usually install the -setuptools or distribute package by using your system's package manager. If +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 or distribute "by hand". Installing -setuptools or distribute "by hand" is always a reasonable thing to do, even +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. -If you're using Python 2, you'll want to install ``setuptools``. If you're -using Python 3, you'll want to install ``distribute``. Below we tell you how -to do both. - -Installing Setuptools On Python 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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. +`_ then +invoke it using the Python interpreter into which you want to install setuptools. .. code-block:: text @@ -218,35 +214,13 @@ the script. To remediate this, you may need to do: $ sudo python ez_setup.py -Installing Distribute On Python 3 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``setuptools`` doesn't work under Python 3. Instead, you can use -``distribute``, which is a fork of setuptools. To -install it, first download `distribute_setup.py -`_ then invoke it using the -Python interpreter into which you want to install setuptools. - -.. code-block:: text - - $ python3 distribute_setup.py - -Once this command is invoked, distribute 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: - -.. code-block:: text - - $ sudo python3 distribute_setup.py - .. index:: pair: install; virtualenv Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've got setuptools or distribute installed, you should install the +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. @@ -261,7 +235,7 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Turing-complete. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``distribute`` into the virtual environment manually, + software such as ``setuptools`` into the virtual environment manually, which this guide does not cover. .. code-block:: text @@ -335,91 +309,37 @@ 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 under Python 3. Directions -for both versions are included below. +You can use Pyramid on Windows under Python 2 or under Python 3. -Windows Using Python 2 -~~~~~~~~~~~~~~~~~~~~~~ - -#. Install the most recent `Python 2.7.x version +#. Install the most recent `Python 2.7.x or 3.3.x version `_ for your system. #. Install the `Python for Windows extensions `_. Make sure to - pick the right download for Python 2.7 and install it using the - same Python installation from the previous step. + pick the right download for Python 2.7 or Python 3.3 and install it + using the same Python installation from the previous step. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py - `_ and run it using - the ``python`` interpreter of your Python 2.7 installation using a - command prompt: + `_ + 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 - - c:\> c:\Python27\Scripts\easy_install virtualenv - -#. Make a :term:`virtualenv` workspace: - - .. code-block:: text - - c:\> set VENV=c:\env - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %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. - -#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell - environment wired to use the virtualenv. - -#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies - installed: - - .. code-block:: text - - c:\env> %VENV%\Scripts\easy_install pyramid - -Windows Using Python 3 -~~~~~~~~~~~~~~~~~~~~~~ - -#. Install, or find the latest version of `Python 3.x - `_ for your system and which is - supported by Pyramid. - -#. Install the `Python for Windows extensions - `_. Make sure to - pick the right download for Python 3.x and install it using the - same Python installation from the previous step. - -#. Install latest :term:`distribute` distribution into the Python you - obtained/installed/found in the step above: download `distribute_setup.py - `_ and run it using the - ``python`` interpreter of your Python 3.x installation using a command - prompt: - - .. code-block:: text - # modify the command according to the python version, e.g.: - # for Python 3.2.x: - c:\> c:\Python32\python distribute_setup.py - # for Python 3.3.x: - c:\> c:\Python33\python distribute_setup.py - -#. Install :term:`virtualenv`: - - .. code-block:: text - - # for Python 3.2.x: - c:\> c:\Python32\Scripts\easy_install virtualenv - # for Python 3.3.x: + # for Python 2.7: + c:\> c:\Python27\Scripts\easy_install virtualenv + # for Python 3.3: c:\> c:\Python33\Scripts\easy_install virtualenv #. Make a :term:`virtualenv` workspace: @@ -427,9 +347,11 @@ Windows Using Python 3 .. code-block:: text c:\> set VENV=c:\env - # for Python 3.2.x: - c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% - # for Python 3.3.x: + + # modify the command according to the python version, e.g.: + # for Python 2.7: + c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3: c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% You can either follow the use of the environment variable, ``%VENV%``, -- cgit v1.2.3 From 58c5fefd37109fe7f27ca77a3d0896cc4b8e0470 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 15 Aug 2013 21:57:48 +0200 Subject: fix some rST issues --- docs/narr/install.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index d05c8abeb..ef5772f79 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -336,6 +336,7 @@ You can use Pyramid on Windows under Python 2 or under Python 3. #. 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 -- cgit v1.2.3 From 575515b28f5e9cca48c6989b44ba964312995be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Martano?= Date: Thu, 15 Aug 2013 18:50:53 -0300 Subject: ZODB now supports Python3. --- docs/narr/project.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ec5d706aa..52f13d5a8 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -49,9 +49,7 @@ The included scaffolds are these: URL mapping via :term:`URL dispatch` and no persistence mechanism. ``zodb`` - URL mapping via :term:`traversal` and persistence via :term:`ZODB`. *Note - that, as of this writing, this scaffold will not run under Python 3, only - under Python 2.* + URL mapping via :term:`traversal` and persistence via :term:`ZODB`. ``alchemy`` URL mapping via :term:`URL dispatch` and persistence via -- cgit v1.2.3 From edfc4f80a1240f6f5f0c41e53078a8f5d305075f Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Thu, 15 Aug 2013 15:57:14 -0700 Subject: prefer the functionish print --- docs/narr/commandline.rst | 6 +++--- docs/narr/events.rst | 6 +++--- docs/narr/extconfig.rst | 4 ++-- docs/narr/hooks.rst | 4 ++-- docs/narr/webob.rst | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 17e5227fa..58b9bdd21 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -538,7 +538,7 @@ representing Pyramid your application configuration as a single argument: from pyramid.paster import bootstrap env = bootstrap('/path/to/my/development.ini') - print env['request'].route_url('home') + print(env['request'].route_url('home')) :func:`pyramid.paster.bootstrap` returns a dictionary containing framework-related information. This dictionary will always contain a @@ -606,7 +606,7 @@ to load instead of ``main``: from pyramid.paster import bootstrap env = bootstrap('/path/to/my/development.ini#another') - print env['request'].route_url('home') + print(env['request'].route_url('home')) The above example specifies the ``another`` ``app``, ``pipeline``, or ``composite`` section of your PasteDeploy configuration file. The ``app`` @@ -643,7 +643,7 @@ the desired request and passing it into :func:`~pyramid.paster.bootstrap`: request = Request.blank('/', base_url='https://example.com/prefix') env = bootstrap('/path/to/my/development.ini#another', request=request) - print env['request'].application_url + print(env['request'].application_url) # will print 'https://example.com/prefix' Now you can readily use Pyramid's APIs for generating URLs: diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 11af89ca6..2accb3dbe 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -26,7 +26,7 @@ subscriber is a function that accepts a single argument named `event`: :linenos: def mysubscriber(event): - print event + print(event) The above is a subscriber that simply prints the event to the console when it's called. @@ -113,10 +113,10 @@ your application like so: :linenos: def handle_new_request(event): - print 'request', event.request + print('request', event.request) def handle_new_response(event): - print 'response', event.response + print('response', event.response) You may configure these functions to be called at the appropriate times by adding the following code to your application's diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 659056952..6587aef92 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -55,7 +55,7 @@ method of the Configurator: :linenos: def mysubscriber(event): - print event.request + print(event.request) config.add_newrequest_subscriber(mysubscriber) @@ -79,7 +79,7 @@ able to install it and subsequently do: :linenos: def mysubscriber(event): - print event.request + print(event.request) from pyramid.config import Configurator config = Configurator() diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 37a74b53a..3a2568775 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -291,7 +291,7 @@ actually execute the function until accessed. return sum(args) def prop(request): - print "getting the property" + print("getting the property") return "the property" config = Configurator() @@ -332,7 +332,7 @@ Here is an example of passing a class to ``Configurator.add_request_method``: # use @property if you don't want to cache the result @reify def prop(self): - print "getting the property" + print("getting the property") return "the property" config = Configurator() diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index c0ca450b1..f0a4b5a0b 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -287,7 +287,7 @@ When such a request reaches a view in your application, the @view_config(renderer='string') def aview(request): - print request.json_body + print(request.json_body) return 'OK' For the above view, printed to the console will be: -- cgit v1.2.3 From d04e2c8e7d12768f92f18ab4771b76492927bb6d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 02:44:39 -0700 Subject: Clean up directions for install Python 2 and 3 and Python extensions on Windows, per feedback from Windows guinea pigs at SFPython Hack Night. --- docs/narr/install.rst | 149 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 35 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index ef5772f79..c1ce64406 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -162,19 +162,19 @@ 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 +:term:`setuptools` or :term:`distribute` 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 +The following command will not display anything if setuptools or distribute 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: +Running the same command will yield the following output if setuptools or +distribute is not yet installed: .. code-block:: text @@ -183,23 +183,27 @@ yet installed: ImportError: No module named setuptools If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools manually. +will need to install setuptools or distribute manually. If you are using a "system" Python (one installed by your OS distributor or a 3rd-party packager such as Fink or MacPorts), you can usually install the -setuptools package by using your system's package manager. If +setuptools or distribute 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 +you will need to install setuptools or distribute "by hand". Installing +setuptools or distribute "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 -~~~~~~~~~~~~~~~~~~~~~ +If you're using Python 2, you'll want to install ``setuptools``. If you're +using Python 3, you'll want to install ``distribute``. Below we tell you how +to do both. + +Installing Setuptools On Python 2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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. +`_ then invoke it using the +Python interpreter into which you want to install setuptools. .. code-block:: text @@ -214,13 +218,35 @@ the script. To remediate this, you may need to do: $ sudo python ez_setup.py +Installing Distribute On Python 3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``setuptools`` doesn't work under Python 3. Instead, you can use +``distribute``, which is a fork of setuptools. To +install it, first download `distribute_setup.py +`_ then invoke it using the +Python interpreter into which you want to install setuptools. + +.. code-block:: text + + $ python3 distribute_setup.py + +Once this command is invoked, distribute 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: + +.. code-block:: text + + $ sudo python3 distribute_setup.py + .. index:: pair: install; virtualenv Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've got setuptools installed, you should install the +Once you've got setuptools or distribute 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. @@ -235,7 +261,7 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Turing-complete. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``setuptools`` into the virtual environment manually, + software such as ``distribute`` into the virtual environment manually, which this guide does not cover. .. code-block:: text @@ -309,50 +335,103 @@ 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 under Python 3. +You can use Pyramid on Windows under Python 2 or under Python 3. Directions +for both versions are included below. -#. Install the most recent `Python 2.7.x or 3.3.x version +Windows Using Python 2 +~~~~~~~~~~~~~~~~~~~~~~ + +#. Download and install the most recent `Python 2.7.x version `_ for your system. -#. Install the `Python for Windows extensions - `_. Make sure to - pick the right download for Python 2.7 or Python 3.3 and install it - using the same Python installation from the previous step. +#. 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 bittedness of build and Python + 2.7 version. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step 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: + `_ and run it using + the ``python`` interpreter of your Python 2.7 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 #. Make a :term:`virtualenv` workspace: .. code-block:: text c:\> set VENV=c:\env - - # modify the command according to the python version, e.g.: - # for Python 2.7: c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% - # for Python 3.3: + + 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. + +#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell + environment wired to use the virtualenv. + +#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies + installed: + + .. code-block:: text + + c:\env> %VENV%\Scripts\easy_install pyramid + +Windows Using Python 3 +~~~~~~~~~~~~~~~~~~~~~~ + +#. Download and install the latest version of `Python 3.x + `_ for your system and which is + supported by Pyramid. + +#. 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 bittedness of build and Python + 3.x version. + +#. Install latest :term:`distribute` distribution into the Python you + obtained/installed/found in the step above: download `distribute_setup.py + `_ and run it using the + ``python`` interpreter of your Python 3.x installation using a command + prompt: + + .. code-block:: text + + # modify the command according to the python version, e.g.: + # for Python 3.2.x: + c:\> c:\Python32\python distribute_setup.py + # for Python 3.3.x: + c:\> c:\Python33\python distribute_setup.py + +#. Install :term:`virtualenv`: + + .. code-block:: text + + # for Python 3.2.x: + c:\> c:\Python32\Scripts\easy_install virtualenv + # for Python 3.3.x: + c:\> c:\Python33\Scripts\easy_install virtualenv + +#. Make a :term:`virtualenv` workspace: + + .. code-block:: text + + c:\> set VENV=c:\env + # for Python 3.2.x: + c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3.x: c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% You can either follow the use of the environment variable, ``%VENV%``, -- cgit v1.2.3 From b35dc8716d2281e9ee7856736d19a45000802c81 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 04:45:21 -0700 Subject: Sphinx: WAAAAAAH! Just shut up and duplicate the link already. --- docs/narr/install.rst | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c1ce64406..eaa9642a8 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -344,11 +344,8 @@ Windows Using Python 2 #. Download and install the most recent `Python 2.7.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 bittedness of build and Python - 2.7 version. +#. Download and install the `Python for Windows extensions (for Python 2.7) `_. + Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 2.7 version. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py @@ -395,11 +392,8 @@ Windows Using Python 3 `_ for your system and which is supported by Pyramid. -#. 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 bittedness of build and Python - 3.x version. +#. Download and install the `Python for Windows extensions (for Python 3.x) `_. + Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 3.x version. #. Install latest :term:`distribute` distribution into the Python you obtained/installed/found in the step above: download `distribute_setup.py -- cgit v1.2.3 From 96645b9b7efb55976d5a87fc3d27982b572e031a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 04:49:08 -0700 Subject: and fix 79 cols --- docs/narr/install.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index eaa9642a8..54109e70f 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -344,8 +344,11 @@ Windows Using Python 2 #. Download and install the most recent `Python 2.7.x version `_ for your system. -#. Download and install the `Python for Windows extensions (for Python 2.7) `_. - Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 2.7 version. +#. Download and install the `Python for Windows extensions (for Python 2.7) + `_. Carefully read + the README.txt file at the end of the list of builds, and follow its + directions. Make sure you get the proper bittedness of build and Python 2.7 + version. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py @@ -392,8 +395,11 @@ Windows Using Python 3 `_ for your system and which is supported by Pyramid. -#. Download and install the `Python for Windows extensions (for Python 3.x) `_. - Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 3.x version. +#. Download and install the `Python for Windows extensions (for Python 3.x) + `_. Carefully read + the README.txt file at the end of the list of builds, and follow its + directions. Make sure you get the proper bittedness of build and Python 3.x + version. #. Install latest :term:`distribute` distribution into the Python you obtained/installed/found in the step above: download `distribute_setup.py -- cgit v1.2.3 From bb0f9b899a45aaa347bf7be3c55bfa78edfeec61 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 23:17:07 -0700 Subject: merge changes from kusut PR#1085 and stevepiercy PR#1084 wrap to 79 columns remove duplicate link of Windows extensions at top of file to prevent early clickage --- docs/narr/install.rst | 369 +++++++++++++++++++------------------------------- 1 file changed, 141 insertions(+), 228 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 54109e70f..e3dc1da2a 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -9,49 +9,50 @@ Installing :app:`Pyramid` Before You Install ------------------ -You will need `Python `_ version 2.6 or better to -run :app:`Pyramid`. +You will need `Python `_ version 2.6 or better to run +:app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.6, - Python 2.7, Python 3.2, and Python 3.3. :app:`Pyramid` does not - run under any version of Python before 2.6. + As of this writing, :app:`Pyramid` has been tested under Python 2.6, Python + 2.7, Python 3.2, and Python 3.3. :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 on :term:`PyPy` (1.9+). +: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+). -: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, so +you need only a Python interpreter that meets the requirements mentioned. For Mac OS X Users ~~~~~~~~~~~~~~~~~~ From `Python.org `_: - Python comes pre-installed on Mac OS X, but due to Apple's release - cycle, it's often one or even two years old. The overwhelming - recommendation of the "MacPython" community is to upgrade your - Python by downloading and installing a newer version from - `the Python standard release page `_. + Python comes pre-installed on Mac OS X, but due to Apple's release cycle, + it's often one or even two years old. The overwhelming recommendation of + the "MacPython" community is to upgrade your Python by downloading and + installing a newer version from `the Python standard release page + `_. -It is recommended to download one of the *installer* versions, unless you prefer to install your Python through a packgage manager (e.g., macports or homebrew) or to build your Python from source. +It is recommended to download one of the *installer* versions, unless you +prefer to install your Python through a packgage manager (e.g., macports or +homebrew) or to build your Python from source. -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. +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. -If you use an installer for your Python, then you can skip to the -section :ref:`installing_unix`. +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 your system doesn't have a Python interpreter, and you're on UNIX, -you can 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. +If your system doesn't have a Python interpreter, and you're on UNIX, you can +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) @@ -59,13 +60,12 @@ UNIX system that has development tools. 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. +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 +.. code-block:: bash $ sudo apt-get install python2.7-dev @@ -82,30 +82,29 @@ invokable via ``python2.7`` from a shell prompt. 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 +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: +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 +.. code-block:: bash $ sudo apt-get install build-essential -On Mac OS X, installing `XCode -`_ has much the same effect. +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: +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 +.. code-block:: bash $ cd ~ $ mkdir tmp @@ -117,9 +116,8 @@ using the following commands: $ ./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. +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) @@ -127,24 +125,21 @@ prompt. 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 `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 `_. +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 +`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. + 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 @@ -154,91 +149,63 @@ extensions `_. 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. +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` or :term:`distribute` is installed. To do so, invoke -``import setuptools`` within the Python interpreter you'd like to run -:app:`Pyramid` under. +: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 or distribute is -already installed: +The following command will not display anything if setuptools is already +installed: -.. code-block:: text +.. code-block:: bash $ python2.7 -c 'import setuptools' -Running the same command will yield the following output if setuptools or -distribute is not yet installed: +Running the same command will yield the following output if setuptools is not +yet installed: -.. code-block:: text +.. code-block:: bash 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 or distribute manually. +will need to install setuptools manually. If you are using a "system" Python (one installed by your OS distributor or a -3rd-party packager such as Fink or MacPorts), you can usually install the -setuptools or distribute 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 or distribute "by hand". Installing -setuptools or distribute "by hand" is always a reasonable thing to do, even -if your package manager already has a pre-chewed version of setuptools for -installation. +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. -If you're using Python 2, you'll want to install ``setuptools``. If you're -using Python 3, you'll want to install ``distribute``. Below we tell you how -to do both. - -Installing Setuptools On Python 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +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. +`_ then invoke +it using the Python interpreter into which you want to install setuptools. -.. code-block:: text +.. code-block:: bash $ python ez_setup.py -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: - -.. code-block:: text - - $ sudo python ez_setup.py - -Installing Distribute On Python 3 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``setuptools`` doesn't work under Python 3. Instead, you can use -``distribute``, which is a fork of setuptools. To -install it, first download `distribute_setup.py -`_ then invoke it using the -Python interpreter into which you want to install setuptools. - -.. code-block:: text - - $ python3 distribute_setup.py - -Once this command is invoked, distribute should be installed on your system. +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: -.. code-block:: text +.. code-block:: bash - $ sudo python3 distribute_setup.py + $ sudo python ez_setup.py .. index:: pair: install; virtualenv @@ -246,9 +213,9 @@ remediate this, you may need to do: Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've got setuptools or distribute 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. +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. .. warning:: @@ -261,18 +228,18 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Turing-complete. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``distribute`` into the virtual environment manually, - which this guide does not cover. + software such as ``setuptools`` into the virtual environment manually, which + this guide does not cover. -.. code-block:: text +.. code-block:: bash $ 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: +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 +.. code-block:: bash $ sudo easy_install virtualenv @@ -286,41 +253,40 @@ 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 +.. code-block:: bash $ export VENV=~/env $ virtualenv --no-site-packages $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. +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. .. warning:: - Using ``--no-site-packages`` when generating your - virtualenv is *very important*. This flag provides the necessary - isolation for running the set of packages required by - :app:`Pyramid`. If you do not specify ``--no-site-packages``, - it's possible that :app:`Pyramid` will not install properly into - the virtualenv, or, even if it does, may not run properly, - depending on the packages you've already got installed into your - Python's "main" site-packages dir. + Using ``--no-site-packages`` when generating your virtualenv is *very + important*. This flag provides the necessary isolation for running the set + of packages required by :app:`Pyramid`. If you do not specify + ``--no-site-packages``, it's possible that :app:`Pyramid` will not install + properly into the virtualenv, or, even if it does, may not run properly, + depending on the packages you've already got installed into your Python's + "main" site-packages dir. .. warning:: *do not* use ``sudo`` to run the - ``virtualenv`` script. It's perfectly acceptable (and desirable) - to create a virtualenv as a normal user. + ``virtualenv`` script. It's perfectly acceptable (and desirable) to create + a virtualenv as a normal user. Installing :app:`Pyramid` Into the Virtual Python Environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -After you've got your virtualenv installed, you may install -:app:`Pyramid` itself using the following commands: +After you've got your virtualenv installed, you may install :app:`Pyramid` +itself using the following commands: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/easy_install pyramid @@ -335,109 +301,56 @@ 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 under Python 3. Directions -for both versions are included below. - -Windows Using Python 2 -~~~~~~~~~~~~~~~~~~~~~~ +You can use Pyramid on Windows under Python 2 or 3. -#. Download and install the most recent `Python 2.7.x version +#. 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 (for Python 2.7) +#. 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 bittedness of build and Python 2.7 + directions. Make sure you get the proper "bittedness" of build and Python version. -#. Install latest :term:`setuptools` distribution into the Python you - obtained/installed/found in the step above: download `ez_setup.py - `_ and run it using - the ``python`` interpreter of your Python 2.7 installation using a - command prompt: +#. 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 + .. code-block:: bash + # 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 - - c:\> c:\Python27\Scripts\easy_install virtualenv - -#. Make a :term:`virtualenv` workspace: - - .. code-block:: text - - c:\> set VENV=c:\env - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %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. - -#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell - environment wired to use the virtualenv. - -#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies - installed: - - .. code-block:: text - - c:\env> %VENV%\Scripts\easy_install pyramid - -Windows Using Python 3 -~~~~~~~~~~~~~~~~~~~~~~ - -#. Download and install the latest version of `Python 3.x - `_ for your system and which is - supported by Pyramid. - -#. Download and install the `Python for Windows extensions (for Python 3.x) - `_. Carefully read - the README.txt file at the end of the list of builds, and follow its - directions. Make sure you get the proper bittedness of build and Python 3.x - version. - -#. Install latest :term:`distribute` distribution into the Python you - obtained/installed/found in the step above: download `distribute_setup.py - `_ and run it using the - ``python`` interpreter of your Python 3.x installation using a command - prompt: - - .. code-block:: text + .. code-block:: bash # modify the command according to the python version, e.g.: - # for Python 3.2.x: - c:\> c:\Python32\python distribute_setup.py - # for Python 3.3.x: - c:\> c:\Python33\python distribute_setup.py - -#. Install :term:`virtualenv`: - - .. code-block:: text - - # for Python 3.2.x: - c:\> c:\Python32\Scripts\easy_install virtualenv - # for Python 3.3.x: + # for Python 2.7: + c:\> c:\Python27\Scripts\easy_install virtualenv + # for Python 3.3: c:\> c:\Python33\Scripts\easy_install virtualenv #. Make a :term:`virtualenv` workspace: - .. code-block:: text + .. code-block:: bash c:\> set VENV=c:\env - # for Python 3.2.x: - c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% - # for Python 3.3.x: + # modify the command according to the python version, e.g.: + # for Python 2.7: + c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3: c:\> c:\Python33\Scripts\virtualenv --no-site-packages %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 :term:`virtualenv`. In that case, + the `set` command can be skipped. If you choose the former approach, ensure + that it's an absolute path. #. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell environment wired to use the virtualenv. @@ -445,7 +358,7 @@ Windows Using Python 3 #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: text + .. code-block:: bash c:\env> %VENV%\Scripts\easy_install pyramid -- cgit v1.2.3 From ca25863d5100535e1b91117b3487b1b3a03e2522 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 23:30:04 -0700 Subject: undoing bash highlighting to just text. bash prepends a $ which makes copy/paste of commands annoying, and for Windows with \ in the path, it is an escape character and does weird colorization. --- docs/narr/install.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index e3dc1da2a..7f549e824 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -65,7 +65,7 @@ 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:: bash +.. code-block:: text $ sudo apt-get install python2.7-dev @@ -93,7 +93,7 @@ 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:: bash +.. code-block:: text $ sudo apt-get install build-essential @@ -104,7 +104,7 @@ 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:: bash +.. code-block:: text $ cd ~ $ mkdir tmp @@ -163,14 +163,14 @@ 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:: bash +.. 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:: bash +.. code-block:: text Traceback (most recent call last): File "", line 1, in @@ -194,7 +194,7 @@ 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:: bash +.. code-block:: text $ python ez_setup.py @@ -203,7 +203,7 @@ 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: -.. code-block:: bash +.. code-block:: text $ sudo python ez_setup.py @@ -231,7 +231,7 @@ setuptools-enabled Python interpreter, use the ``easy_install`` command. software such as ``setuptools`` into the virtual environment manually, which this guide does not cover. -.. code-block:: bash +.. code-block:: text $ easy_install virtualenv @@ -239,7 +239,7 @@ 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:: bash +.. code-block:: text $ sudo easy_install virtualenv @@ -253,7 +253,7 @@ 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:: bash +.. code-block:: text $ export VENV=~/env $ virtualenv --no-site-packages $VENV @@ -286,7 +286,7 @@ Installing :app:`Pyramid` Into the Virtual Python Environment After you've got your virtualenv installed, you may install :app:`Pyramid` itself using the following commands: -.. code-block:: bash +.. code-block:: text $ $VENV/bin/easy_install pyramid @@ -318,7 +318,7 @@ You can use Pyramid on Windows under Python 2 or 3. it using the ``python`` interpreter of your Python 2.7 or 3.3 installation using a command prompt: - .. code-block:: bash + .. code-block:: text # modify the command according to the python version, e.g.: # for Python 2.7: @@ -328,7 +328,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Install `virtualenv`: - .. code-block:: bash + .. code-block:: text # modify the command according to the python version, e.g.: # for Python 2.7: @@ -338,7 +338,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Make a :term:`virtualenv` workspace: - .. code-block:: bash + .. code-block:: text c:\> set VENV=c:\env # modify the command according to the python version, e.g.: @@ -358,7 +358,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: bash + .. code-block:: text c:\env> %VENV%\Scripts\easy_install pyramid -- cgit v1.2.3 From 65c60a85f90f7bf8f97848e7314b6d0e9ecc5599 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 00:48:12 -0700 Subject: restore earlier fixes on latexindex don't make up funny words and use explicit 32- or 64-bit phrase --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 7f549e824..15e9e8699 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -309,7 +309,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. 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 "bittedness" of build and Python + 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 -- cgit v1.2.3 From 2ded59ba248156d92e0f5a8e6c991af93b38384c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 01:26:05 -0700 Subject: remove --no-site-packages and add usage note --- docs/narr/install.rst | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 15e9e8699..d193cbab3 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -256,7 +256,7 @@ you can then create a virtual environment. To do so, invoke the following: .. code-block:: text $ export VENV=~/env - $ virtualenv --no-site-packages $VENV + $ virtualenv $VENV New python executable in /home/foo/env/bin/python Installing setuptools.............done. @@ -267,17 +267,14 @@ it's an absolute path. .. warning:: - Using ``--no-site-packages`` when generating your virtualenv is *very - important*. This flag provides the necessary isolation for running the set - of packages required by :app:`Pyramid`. If you do not specify - ``--no-site-packages``, it's possible that :app:`Pyramid` will not install - properly into the virtualenv, or, even if it does, may not run properly, - depending on the packages you've already got installed into your Python's - "main" site-packages dir. + ``--no-site-packages`` is now the default for virtualenv and can be + omitted. Do not override the default and use ``--system-site-packages`` + unless you know what you are doing. -.. warning:: *do not* use ``sudo`` to run the - ``virtualenv`` script. It's perfectly acceptable (and desirable) to create - a virtualenv as a normal user. +.. warning:: + + *do not* use ``sudo`` to run the ``virtualenv`` script. It's perfectly + acceptable (and desirable) to create a virtualenv as a normal user. Installing :app:`Pyramid` Into the Virtual Python Environment @@ -343,9 +340,9 @@ You can use Pyramid on Windows under Python 2 or 3. c:\> set VENV=c:\env # modify the command according to the python version, e.g.: # for Python 2.7: - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + c:\> c:\Python27\Scripts\virtualenv %VENV% # for Python 3.3: - c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% + c:\> c:\Python33\Scripts\virtualenv %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, -- cgit v1.2.3 From b189a3ed0f44544687e68d0287417c42cd0fdca3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 01:51:59 -0700 Subject: Another crack at the note for venv options --- docs/narr/install.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index d193cbab3..fb67b899b 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -267,9 +267,11 @@ it's an absolute path. .. warning:: - ``--no-site-packages`` is now the default for virtualenv and can be - omitted. Do not override the default and use ``--system-site-packages`` - unless you know what you are doing. + 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. .. warning:: -- cgit v1.2.3 From 8866e256bf640817692cb16ec0ccc4c642a13b7d Mon Sep 17 00:00:00 2001 From: Fabian Neumann Date: Sat, 17 Aug 2013 16:54:28 +0200 Subject: Document the external URL feature. --- docs/narr/urldispatch.rst | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 310c160c0..34014c9c5 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -105,6 +105,7 @@ to using the previous combination of ``add_route`` and ``add_view``. .. _route_pattern_syntax: + Route Pattern Syntax ~~~~~~~~~~~~~~~~~~~~ @@ -754,9 +755,43 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. +:ref:`External routes ` are implicitely static. + .. versionadded:: 1.1 the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` +.. _external_route_narr: + + +External Routes +--------------- + +.. versionadded:: 1.5 + +Route patterns that are valid URLs, are treated as external routes. Like +:ref:`static routes ` they are useful for URL generation +purposes only and are never considered for matching at request time. + +.. code-block:: python + :linenos: + + >>> config = Configurator() + >>> config.add_route('youtube', 'https://youtube.com/watch/{video_id}') + ... + >>> request.route_url('youtube', video_id='oHg5SJYRHA0') + >>> "https://youtube.com/watch/oHg5SJYRHA0" + +All pattern replacements and calls to +:meth:`pyramid.request.Request.route_url` will work as expected. Note that +:meth:`pyramid.request.Request.route_path` will also just return the external +URLs path part. + +.. note:: + + The external URL feature is implemented with a :term:`pregenerator` so you + cannot use both with the same route. + + .. index:: single: redirecting to slash-appended routes -- cgit v1.2.3 From 58d507156b30ac194c99527247078cc5a25cb142 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 17:09:34 +0200 Subject: typo --- docs/narr/urldispatch.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 34014c9c5..045af42eb 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -755,7 +755,7 @@ other non-``name`` and non-``pattern`` arguments to exception to this rule is use of the ``pregenerator`` argument, which is not ignored when ``static`` is ``True``. -:ref:`External routes ` are implicitely static. +:ref:`External routes ` are implicitly static. .. versionadded:: 1.1 the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` -- cgit v1.2.3 From 3bae69780cf5f7d8ff772adc085f3e064853f1a0 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 17:09:36 +0200 Subject: reference the static url route feature --- docs/narr/urldispatch.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 045af42eb..8f03b1080 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -128,6 +128,10 @@ and: /{foo}/bar/baz +If a pattern is a valid URL it won't be ever matched against an incoming +request. Instead it can be useful for generating external URLs. See +:ref:`External routes ` for details. + A pattern segment (an individual item between ``/`` characters in the pattern) may either be a literal string (e.g. ``foo``) *or* it may be a replacement marker (e.g. ``{foo}``) or a certain combination of both. A -- cgit v1.2.3 From 84367e57afc0d5538e02f670834809933d9cab26 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Aug 2013 22:56:54 -0500 Subject: allow pregenerator and route_prefix with external routes --- docs/narr/urldispatch.rst | 5 ----- 1 file changed, 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 8f03b1080..f3513624e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -790,11 +790,6 @@ All pattern replacements and calls to :meth:`pyramid.request.Request.route_path` will also just return the external URLs path part. -.. note:: - - The external URL feature is implemented with a :term:`pregenerator` so you - cannot use both with the same route. - .. index:: single: redirecting to slash-appended routes -- cgit v1.2.3 From d07d167f6dcdc5ef03e8aaca3c953e984a5a5f1a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 20 Aug 2013 10:13:55 -0400 Subject: raise ValueError instead of generating just path when _app_url is provided to request.route_url and the route has an external pattern --- docs/narr/urldispatch.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index f3513624e..62eb89348 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -785,11 +785,12 @@ purposes only and are never considered for matching at request time. >>> request.route_url('youtube', video_id='oHg5SJYRHA0') >>> "https://youtube.com/watch/oHg5SJYRHA0" -All pattern replacements and calls to -:meth:`pyramid.request.Request.route_url` will work as expected. Note that -:meth:`pyramid.request.Request.route_path` will also just return the external -URLs path part. - +Most pattern replacements and calls to +:meth:`pyramid.request.Request.route_url` will work as expected. However, calls +to :meth:`pyramid.request.Request.route_path` against external patterns will +raise an exception, and passing ``_app_url`` to +:meth:`~pyramid.request.Request.route_url` to generate a URL against a route +that has an external pattern will also raise an exception. .. index:: single: redirecting to slash-appended routes -- cgit v1.2.3 From 221fff13b01b3419570630e0da1e617c0ed1a2d7 Mon Sep 17 00:00:00 2001 From: Matthew Wilkes Date: Fri, 23 Aug 2013 15:39:32 +0100 Subject: Fix documentation on using gettext plurals and include examples --- docs/narr/i18n.rst | 58 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 2964686d3..555b06e0f 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -579,18 +579,9 @@ signature: def pluralize(singular, plural, n, domain=None, mapping=None): ... -The ``singular`` and ``plural`` arguments should each be a Unicode -value representing a :term:`message identifier`. ``n`` should be an -integer. ``domain`` should be a :term:`translation domain`, and -``mapping`` should be a dictionary that is used for *replacement -value* interpolation of the translated string. If ``n`` is plural -for the current locale, ``pluralize`` will return a Unicode -translation for the message id ``plural``, otherwise it will return a -Unicode translation for the message id ``singular``. - -The arguments provided as ``singular`` and/or ``plural`` may also be -:term:`translation string` objects, but the domain and mapping -information attached to those objects is ignored. +The simplest case is the ``singular`` and ``plural`` arguments being passed as +unicode literals. This returns the appropriate literal according to the locale +pluralization rules for the number ``n``, and interpolates ``mapping``. .. code-block:: python :linenos: @@ -602,6 +593,49 @@ information attached to those objects is ignored. translated = localizer.pluralize('Item', 'Items', 1, 'mydomain') # ... use translated ... +However, for support of other languages, the ``singular`` argument should +be a Unicode value representing a :term:`message identifier`. In this +case the ``plural`` value is ignored. +``domain`` should be a :term:`translation domain`, and +``mapping`` should be a dictionary that is used for *replacement +value* interpolation of the translated string. + +The value of ``n`` will be used to find the appropriate plural form for the +current language and ``pluralize`` will return a Unicode translation for the +message id ``singular``. The message file must have defined ``singular`` as a +translation with plural forms. + +The argument provided as ``singular`` may be a :term:`translation string` +object, but the domain and mapping information attached is ignored. + +.. code-block:: python + :linenos: + + from pyramid.i18n import get_localizer + + def aview(request): + localizer = get_localizer(request) + num = 1 + translated = localizer.pluralize(_('item_plural', default="${number} items"), + None, num, 'mydomain', mapping={'number':num}) + +The corresponding message catalog must have language plural definitions and +plural alternatives set. + +.. code-block:: text + :linenos: + + "Plural-Forms: nplurals=3; plural=n==0 ? 0 : n==1 ? 1 : 2;" + + msgid "item_plural" + msgid_plural "" + msgstr[0] "No items" + msgstr[1] "${number} item" + msgstr[2] "${number} items" + +More information on complex plurals can be found in the `gettext documentation +`_. + .. index:: single: locale name single: get_locale_name -- cgit v1.2.3 From 330164c3190d92a3e1df89baafba12570d03bd32 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 29 Aug 2013 05:08:53 -0400 Subject: make local_name an attribute of Request, move logic from get_localizer into Request.localizer, fix docs; closes #1099 --- docs/narr/i18n.rst | 77 +++++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 45 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 555b06e0f..b62c16ff0 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -495,7 +495,6 @@ translations will be available to :app:`Pyramid`. .. index:: single: localizer - single: get_localizer single: translation single: pluralization @@ -503,19 +502,17 @@ Using a Localizer ----------------- A :term:`localizer` is an object that allows you to perform translation or -pluralization "by hand" in an application. You may use the -:func:`pyramid.i18n.get_localizer` function to obtain a :term:`localizer`. -This function will return either the localizer object implied by the active -:term:`locale negotiator` or a default localizer object if no explicit locale -negotiator is registered. +pluralization "by hand" in an application. You may use the +:attr:`pyramid.request.Request.localizer` attribute to obtain a +:term:`localizer`. The localizer object will be configured to produce +translations implied by the active :term:`locale negotiator` or a default +localizer object if no explicit locale negotiator is registered. .. code-block:: python :linenos: - from pyramid.i18n import get_localizer - def aview(request): - locale = get_localizer(request) + localizer = request.localizer .. note:: @@ -538,22 +535,20 @@ translation in a view component of an application might look like so: .. code-block:: python :linenos: - from pyramid.i18n import get_localizer from pyramid.i18n import TranslationString ts = TranslationString('Add ${number}', mapping={'number':1}, domain='pyramid') def aview(request): - localizer = get_localizer(request) + localizer = request.localizer translated = localizer.translate(ts) # translation string # ... use translated ... -The :func:`~pyramid.i18n.get_localizer` function will return a -:class:`pyramid.i18n.Localizer` object bound to the locale name -represented by the request. The translation returned from its -:meth:`pyramid.i18n.Localizer.translate` method will depend on the -``domain`` attribute of the provided translation string as well as the +The ``request.localizer`` attribute will be a :class:`pyramid.i18n.Localizer` +object bound to the locale name represented by the request. The translation +returned from its :meth:`pyramid.i18n.Localizer.translate` method will depend +on the ``domain`` attribute of the provided translation string as well as the locale of the localizer. .. note:: @@ -586,10 +581,8 @@ pluralization rules for the number ``n``, and interpolates ``mapping``. .. code-block:: python :linenos: - from pyramid.i18n import get_localizer - def aview(request): - localizer = get_localizer(request) + localizer = request.localizer translated = localizer.pluralize('Item', 'Items', 1, 'mydomain') # ... use translated ... @@ -611,13 +604,13 @@ object, but the domain and mapping information attached is ignored. .. code-block:: python :linenos: - from pyramid.i18n import get_localizer - def aview(request): - localizer = get_localizer(request) + localizer = request.localizer num = 1 - translated = localizer.pluralize(_('item_plural', default="${number} items"), - None, num, 'mydomain', mapping={'number':num}) + translated = localizer.pluralize( + _('item_plural', default="${number} items"), + None, num, 'mydomain', mapping={'number':num} + ) The corresponding message catalog must have language plural definitions and plural alternatives set. @@ -638,7 +631,6 @@ More information on complex plurals can be found in the `gettext documentation .. index:: single: locale name - single: get_locale_name single: negotiate_locale_name .. _obtaining_the_locale_name: @@ -647,25 +639,23 @@ Obtaining the Locale Name for a Request --------------------------------------- You can obtain the locale name related to a request by using the -:func:`pyramid.i18n.get_locale_name` function. +:func:`pyramid.request.Request.locale_name` attribute of the request. .. code-block:: python :linenos: - from pyramid.i18n import get_locale_name - def aview(request): - locale_name = get_locale_name(request) + locale_name = request.locale_name -This returns the locale name negotiated by the currently active -:term:`locale negotiator` or the :term:`default locale name` if the -locale negotiator returns ``None``. You can change the default locale -name by changing the ``pyramid.default_locale_name`` setting; see -:ref:`default_locale_name_setting`. +The locale name of a request is dynamically computed; it will be the locale +name negotiated by the currently active :term:`locale negotiator` or +the :term:`default locale name` if the locale negotiator returns ``None``. +You can change the default locale name by changing the +``pyramid.default_locale_name`` setting; see :ref:`default_locale_name_setting`. -Once :func:`~pyramid.i18n.get_locale_name` is first run, the locale +Once :func:`~pyramid.request.Request.locale_name` is first run, the locale name is stored on the request object. Subsequent calls to -:func:`~pyramid.i18n.get_locale_name` will return the stored locale +:func:`~pyramid.request.Request.locale_name` will return the stored locale name without invoking the :term:`locale negotiator`. To avoid this caching, you can use the :func:`pyramid.i18n.negotiate_locale_name` function: @@ -684,15 +674,13 @@ You can also obtain the locale name related to a request using the .. code-block:: python :linenos: - from pyramid.i18n import get_localizer - def aview(request): - localizer = get_localizer(request) + localizer = request.localizer locale_name = localizer.locale_name Obtaining the locale name as an attribute of a localizer is equivalent -to obtaining a locale name by calling the -:func:`~pyramid.i18n.get_locale_name` function. +to obtaining a locale name by asking for the +:func:`~pyramid.request.Request.locale_name` attribute. .. index:: single: date and currency formatting (i18n) @@ -720,10 +708,9 @@ obtain the locale name for a request to pass to the :linenos: from babel.core import Locale - from pyramid.i18n import get_locale_name def aview(request): - locale_name = get_locale_name(request) + locale_name = request.locale_name locale = Locale(locale_name) .. index:: @@ -1005,8 +992,8 @@ a particular request. A locale negotiator is a bit of code which accepts a request and which returns a :term:`locale name`. It is consulted when :meth:`pyramid.i18n.Localizer.translate` or :meth:`pyramid.i18n.Localizer.pluralize` is invoked. It is also -consulted when :func:`~pyramid.i18n.get_locale_name` or -:func:`~pyramid.i18n.negotiate_locale_name` is invoked. +consulted when :func:`~pyramid.request.Request.locale_name` is accessed or +when :func:`~pyramid.i18n.negotiate_locale_name` is invoked. .. _default_locale_negotiator: -- cgit v1.2.3 From 0a4aed1c8e0a6da9219cccb6f55882d916f49916 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 29 Aug 2013 21:58:48 -0400 Subject: documentation for hybrid url generation --- docs/narr/hybrid.rst | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 1773a6b8c..58d89fc98 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -549,3 +549,83 @@ be invoked when the request URI is ``/abc/bazbuz``, assuming there is no object contained by the root object with the key ``bazbuz``. A different request URI, such as ``/abc/foo/bar``, would invoke the default ``myproject.views.abc`` view. + +.. index:: + pair: hybrid urls; generating + +.. _generating_hybrid_urls: + +Generating Hybrid URLs +---------------------- + +.. versionadded:: 1.5 + +The :meth:`pyramid.request.Request.resource_url` method and the +:meth:`pyramid.request.Request.resource_path` method both accept optional +keyword arguments that make it easier to generate route-prefixed URLs that +contain paths to traversal resources:``route_name`` and ``route_kw``. + +Any route that has a pattern that contains a ``*remainder`` pattern (any +stararg remainder pattern, such as ``*traverse`` or ``*subpath`` or ``*fred``) +can be used as the target name for ``request.resource_url(..., route_name=)`` +and ``request.resource_path(..., route_name=)``. + +For example, let's imagine you have a route defined in your Pyramid application +like so: + +.. code-block:: python + + config.add_route('mysection', '/mysection*traverse') + +If you'd like to generate the URL ``http://example.com/mysection/a/``, you can +use the following incantation, assuming that the variable ``a`` below points to +a resource that is a child of the root with a ``__name__`` of ``a``: + +.. code-block:: python + + request.resource_url(a, route_name='mysection') + +You can generate only the path portion ``/mysection/a/`` assuming the same: + +.. code-block:: python + + request.resource_path(a, route_name='mysection') + +The path is virtual host aware, so if the ``X-Vhm-Root`` environ variable is +present in the request, and it's set to ``/a``, the above call to +``request.resource_url`` would generate ``http://example.com/mysection/`` +and the above call to ``request.resource_path`` would generate ``/mysection/``. +See :ref:`virtual_root_support` for more information. + +If the route you're trying to use needs simple dynamic part values to be filled +in to succesfully generate the URL, you can pass these as the ``route_kw`` +argument to ``resource_url`` and ``resource_path``. For example, assuming that +the route definition is like so: + +.. code-block:: python + + config.add_route('mysection', '/{id}/mysection*traverse') + +You can pass ``route_kw`` in to fill in ``{id}`` above: + +.. code-block:: python + + request.resource_url(a, route_name='mysection', route_kw={'id':'1'}) + +If you pass ``route_kw`` but do not pass ``route_name``, ``route_kw`` will +be ignored. + +All other values that are normally passable to ``resource_path`` and +``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, etc) work +as you might expect in this configuration too. + +If you try to use ``resource_path`` or ``resource_url`` when the ``route_name`` +argument points at a route that does not have a remainder stararg, an error +will not be raised, but the generated URL will not contain any remainder +information either. + +Note that this feature is incompatible with the ``__resource_url__`` feature +(see :ref:`overriding_resource_url_generation`) implemented on resource +objects. Any ``__resource_url__`` supplied by your resource will be ignored +when you pass ``route_name``. + -- cgit v1.2.3 From c29603ed0d8fd0b55789eb8f975c901961864d66 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 29 Aug 2013 23:55:36 -0400 Subject: get rid of remainder_name on route, and just default to passing traverse; add route_remainder_name argument to resource_url --- docs/narr/hybrid.rst | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 58d89fc98..a29ccb2ac 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -563,7 +563,8 @@ Generating Hybrid URLs The :meth:`pyramid.request.Request.resource_url` method and the :meth:`pyramid.request.Request.resource_path` method both accept optional keyword arguments that make it easier to generate route-prefixed URLs that -contain paths to traversal resources:``route_name`` and ``route_kw``. +contain paths to traversal resources:``route_name``, ``route_kw``, and +``route_remainder_name``. Any route that has a pattern that contains a ``*remainder`` pattern (any stararg remainder pattern, such as ``*traverse`` or ``*subpath`` or ``*fred``) @@ -615,15 +616,36 @@ You can pass ``route_kw`` in to fill in ``{id}`` above: If you pass ``route_kw`` but do not pass ``route_name``, ``route_kw`` will be ignored. -All other values that are normally passable to ``resource_path`` and -``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, etc) work -as you might expect in this configuration too. +By default this feature works by calling ``route_url`` under the hood, +and passing the value of the resource path to that function as ``traverse``. +If your route has a different ``*stararg`` remainder name (such as +``*subpath``), you can tell ``resource_url`` or ``resource_path`` to use that +instead of ``traverse`` by passing ``route_remainder_name``. For example, +if you have the following route: + +.. code-block:: python + + config.add_route('mysection', '/mysection*subpath') + +You can fill in the ``*subpath`` value using ``resource_url`` by doing: + +.. code-block:: python + + request.resource_path(a, route_name='mysection', + route_remainder_name='subpath') + +If you pass ``route_remainder_name`` but do not pass ``route_name``, +``route_remainder_name`` will be ignored. If you try to use ``resource_path`` or ``resource_url`` when the ``route_name`` argument points at a route that does not have a remainder stararg, an error will not be raised, but the generated URL will not contain any remainder information either. +All other values that are normally passable to ``resource_path`` and +``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, and +positional elements) work as you might expect in this configuration. + Note that this feature is incompatible with the ``__resource_url__`` feature (see :ref:`overriding_resource_url_generation`) implemented on resource objects. Any ``__resource_url__`` supplied by your resource will be ignored -- cgit v1.2.3 From aa7b06b946b4e8e66818da29e64e9cbccb6ccb10 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 2 Sep 2013 01:03:02 -0400 Subject: move docs section to a more appropriate place --- docs/narr/viewconfig.rst | 59 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 29 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e09fd83ab..76cf1daac 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -465,6 +465,36 @@ configured view. .. versionadded:: 1.4a1 +Inverting Predicate Values +++++++++++++++++++++++++++ + +You can invert the meaning of any predicate value by wrapping it in a call to +:class:`pyramid.config.not_`. + +.. code-block:: python + :linenos: + + from pyramid.config import not_ + + config.add_view( + 'mypackage.views.my_view', + route_name='ok', + request_method=not_('POST') + ) + +The above example will ensure that the view is called if the request method +is *not* ``POST``, at least if no other view is more specific. + +This technique of wrapping a predicate value in ``not_`` can be used anywhere +predicate values are accepted: + +- :meth:`pyramid.config.Configurator.add_view` + +- :meth:`pyramid.view.view_config` + +.. versionadded:: 1.5 + + .. index:: single: view_config decorator @@ -557,35 +587,6 @@ form of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. -Inverting Predicate Values -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can invert the meaning of any predicate value by wrapping it in a call to -:class:`pyramid.config.not_`. - -.. code-block:: python - :linenos: - - from pyramid.config import not_ - - config.add_view( - 'mypackage.views.my_view', - route_name='ok', - request_method=not_('POST') - ) - -The above example will ensure that the view is called if the request method -is *not* ``POST``, at least if no other view is more specific. - -This technique of wrapping a predicate value in ``not_`` can be used anywhere -predicate values are accepted: - -- :meth:`pyramid.config.Configurator.add_view` - -- :meth:`pyramid.view.view_config` - -.. versionadded:: 1.5 - .. index:: single: view_config placement -- cgit v1.2.3 From 44436e1240f497e598de7b316ffaf7b6b8665452 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 3 Sep 2013 18:30:56 -0600 Subject: Removed unnecessary side bar with duplicate content The side-bar contained a duplication of code that was already in the main article. Adding a note instead and removing the side-bar provides the same information without nearly as much duplication. --- docs/narr/traversal.rst | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index a60c5ba56..fb4adff61 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -128,6 +128,12 @@ Here's an example of a simple root factory class: def __init__(self, request): pass +..note:: + For the purpose of understanding traversal, and the contents within + this document, the above Root is an analogue to the default root + factory present in Pyramid. The default root factory is very simple and + not very useful unless using :term:`URL dispatch`. + Here's an example of using this root factory within startup configuration, by passing it to an instance of a :term:`Configurator` named ``config``: @@ -154,28 +160,6 @@ Usually a root factory for a traversal-based application will be more complicated than the above ``Root`` class; in particular it may be associated with a database connection or another persistence mechanism. -.. sidebar:: Emulating the Default Root Factory - - For purposes of understanding the default root factory better, we'll note - that you can emulate the default root factory by using this code as an - explicit root factory in your application setup: - - .. code-block:: python - :linenos: - - class Root(object): - def __init__(self, request): - pass - - config = Configurator(root_factory=Root) - - The default root factory is just a really stupid object that has no - behavior or state. Using :term:`traversal` against an application that - uses the resource tree supplied by the default root resource is not very - interesting, because the default root resource has no children. Its - availability is more useful when you're developing an application using - :term:`URL dispatch`. - .. note:: If the items contained within the resource tree are "persistent" (they -- cgit v1.2.3 From 6ca99b5b42ca13a25a22474c927733d2d16d7cbe Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 23:32:43 -0500 Subject: remove some mako/chameleon renderer docs --- docs/narr/renderers.rst | 179 ++++++------------------------------------------ 1 file changed, 21 insertions(+), 158 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index a2811dbae..212832474 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -365,136 +365,6 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. -.. index:: - pair: renderer; chameleon - -.. _chameleon_template_renderers: - -``*.pt`` or ``*.txt``: Chameleon Template Renderers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Two built-in renderers exist for :term:`Chameleon` templates. - -If the ``renderer`` attribute of a view configuration is an absolute path, a -relative path or :term:`asset specification` which has a final path element -with a filename extension of ``.pt``, the Chameleon ZPT renderer is used. -See :ref:`chameleon_zpt_templates` for more information about ZPT templates. - -If the ``renderer`` attribute of a view configuration is an absolute path or -a :term:`asset specification` which has a final path element with a filename -extension of ``.txt``, the :term:`Chameleon` text renderer is used. See -:ref:`chameleon_text_templates` for more information about Chameleon text -templates. - -The behavior of these renderers is the same, except for the engine -used to render the template. - -When a ``renderer`` attribute that names a template path or :term:`asset -specification` (e.g. ``myproject:templates/foo.pt`` or -``myproject:templates/foo.txt``) is used, the view must return a -:term:`Response` object or a Python *dictionary*. If the view callable with -an associated template returns a Python dictionary, the named template will -be passed the dictionary as its keyword arguments, and the template renderer -implementation will return the resulting rendered template in a response to -the user. If the view callable returns anything but a Response object or a -dictionary, an error will be raised. - -Before passing keywords to the template, the keyword arguments derived from -the dictionary returned by the view are augmented. The callable object -- -whatever object was used to define the view -- will be automatically inserted -into the set of keyword arguments passed to the template as the ``view`` -keyword. If the view callable was a class, the ``view`` keyword will be an -instance of that class. Also inserted into the keywords passed to the -template are ``renderer_name`` (the string used in the ``renderer`` attribute -of the directive), ``renderer_info`` (an object containing renderer-related -information), ``context`` (the context resource of the view used to render -the template), and ``request`` (the request passed to the view used to render -the template). ``request`` is also available as ``req`` in Pyramid 1.3+. - -Here's an example view configuration which uses a Chameleon ZPT renderer: - -.. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='myproject:templates/foo.pt') - -Here's an example view configuration which uses a Chameleon text renderer: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='myproject:templates/foo.txt') - -Views which use a Chameleon renderer can vary response attributes by using -the API of the ``request.response`` attribute. See -:ref:`request_response_attr`. - -.. index:: - pair: renderer; mako - -.. _mako_template_renderers: - -``*.mak`` or ``*.mako``: Mako Template Renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``Mako`` template renderer renders views using a Mako template. When -used, the view must return a Response object or a Python *dictionary*. The -dictionary items will then be used in the global template space. If the view -callable returns anything but a Response object or a dictionary, an error -will be raised. - -When using a ``renderer`` argument to a :term:`view configuration` to specify -a Mako template, the value of the ``renderer`` may be a path relative to the -``mako.directories`` setting (e.g. ``some/template.mak``) or, alternately, -it may be a :term:`asset specification` -(e.g. ``apackage:templates/sometemplate.mak``). Mako templates may -internally inherit other Mako templates using a relative filename or a -:term:`asset specification` as desired. - -Here's an example view configuration which uses a relative path: - -.. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='foo.mak') - -It's important to note that in Mako's case, the 'relative' path name -``foo.mak`` above is not relative to the package, but is relative to the -directory (or directories) configured for Mako via the ``mako.directories`` -configuration file setting. - -The renderer can also be provided in :term:`asset specification` -format. Here's an example view configuration which uses one: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.hello_world', - name='hello', - context='myproject.resources.Hello', - renderer='mypackage:templates/foo.mak') - -The above configuration will use the file named ``foo.mak`` in the -``templates`` directory of the ``mypackage`` package. - -The ``Mako`` template renderer can take additional arguments beyond the -standard ``pyramid.reload_templates`` setting, see the -:ref:`environment_chapter` for additional -:ref:`mako_template_renderer_settings`. - .. index:: single: response headers (from a renderer) single: renderer response headers @@ -739,44 +609,37 @@ ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed to the ``MyJinja2Renderer`` constructor will be the full value that was set as ``renderer=`` in the view configuration. -.. index:: - pair: renderer; changing +Adding a Default Renderer +~~~~~~~~~~~~~~~~~~~~~~~~~ -Changing an Existing Renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can associate more than one filename extension with the same existing -renderer implementation as necessary if you need to use a different file -extension for the same kinds of templates. For example, to associate the -``.zpt`` extension with the Chameleon ZPT renderer factory, use the -:meth:`pyramid.config.Configurator.add_renderer` method: +To associate a *default* renderer with *all* view configurations (even +ones which do not possess a ``renderer`` attribute), pass ``None`` as +the ``name`` attribute to the renderer tag: .. code-block:: python - config.add_renderer('.zpt', 'pyramid.chameleon_zpt.renderer_factory') - -After you do this, :app:`Pyramid` will treat templates ending in both the -``.pt`` and ``.zpt`` filename extensions as Chameleon ZPT templates. - -To change the default mapping in which files with a ``.pt`` extension are -rendered via a Chameleon ZPT page template renderer, use a variation on the -following in your application's startup code: - -.. code-block:: python + config.add_renderer(None, 'mypackage.json_renderer_factory') - config.add_renderer('.pt', 'mypackage.pt_renderer') +.. index:: + pair: renderer; changing -After you do this, the :term:`renderer factory` in -``mypackage.pt_renderer`` will be used to render templates which end -in ``.pt``, replacing the default Chameleon ZPT renderer. +Changing an Existing Renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To associate a *default* renderer with *all* view configurations (even -ones which do not possess a ``renderer`` attribute), pass ``None`` as -the ``name`` attribute to the renderer tag: +Pyramid supports overriding almost every aspect of its setup through its +:ref:`Conflict Resolution ` mechanism. This +means that in most cases overriding a renderer is as simple as using the +:meth:`pyramid.config.Configurator.add_renderer` method to re-define the +template extension. For example, if we'd like to override the ``json`` +extension to specify a new renderer we could do the following: .. code-block:: python - config.add_renderer(None, 'mypackage.json_renderer_factory') + json_renderer = pyramid.renderers.JSON() + config.add_renderer('json', json_renderer) + +After you do this, any views registered with the ``json`` renderer will use +the new renderer. .. index:: pair: renderer; overriding at runtime -- cgit v1.2.3 From b56a6ee9c0c58992df67cdeb021f69d51bcfd26d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 4 Sep 2013 23:36:01 -0500 Subject: change focus from we to you --- docs/narr/renderers.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 212832474..bc96f3d7b 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -630,15 +630,15 @@ Pyramid supports overriding almost every aspect of its setup through its :ref:`Conflict Resolution ` mechanism. This means that in most cases overriding a renderer is as simple as using the :meth:`pyramid.config.Configurator.add_renderer` method to re-define the -template extension. For example, if we'd like to override the ``json`` -extension to specify a new renderer we could do the following: +template extension. For example, if you would like to override the ``.txt`` +extension to specify a new renderer you could do the following: .. code-block:: python json_renderer = pyramid.renderers.JSON() config.add_renderer('json', json_renderer) -After you do this, any views registered with the ``json`` renderer will use +After doing this, any views registered with the ``json`` renderer will use the new renderer. .. index:: -- cgit v1.2.3 From 004d847fe87424f187a920086cb8b9baa8b41b42 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 00:02:51 -0500 Subject: more chameleon builtin references --- docs/narr/renderers.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index bc96f3d7b..dd67c779c 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -67,9 +67,8 @@ When this configuration is added to an application, the ``myproject.views.my_view`` view callable will now use a ``json`` renderer, which renders view return values to a :term:`JSON` response serialization. -Other built-in renderers include renderers which use the :term:`Chameleon` -templating language to render a dictionary to a response. Additional -renderers can be added by developers to the system as necessary. +Pyramid defines several :ref:`built_in_renderers`, and additional renderers +can be added by developers to the system as necessary. See :ref:`adding_and_overriding_renderers`. Views which use a renderer and return a non-Response value can vary non-body -- cgit v1.2.3 From 6f2d0468856b2a3ca84cb22c379196298b2399ea Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 00:35:41 -0500 Subject: add a section mentioning external template bindings --- docs/narr/renderers.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index dd67c779c..21c59c06a 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -364,6 +364,31 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. +Available Add-On Template System Bindings +----------------------------------------- + +The Pylons Project maintains several packages providing bindings to different +templating languages including the following: + ++------------------------------+------------------------------+ +| Template Language | Pyramid Bindings | ++==============================+==============================+ +| Chameleon_ | pyramid_chameleon_ | ++------------------------------+------------------------------+ +| Jinja2_ | pyramid_jinja2_ | ++------------------------------+------------------------------+ +| Mako_ | pyramid_mako_ | ++------------------------------+------------------------------+ + +.. _Chameleon: http://chameleon.readthedocs.org/en/latest/ +.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon + +.. _Jinja2: http://jinja.pocoo.org/docs/ +.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 + +.. _Mako: http://www.makotemplates.org/ +.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako + .. index:: single: response headers (from a renderer) single: renderer response headers -- cgit v1.2.3 From f6f1d1685f09f1ecd3717c90e687a6e3652b4fdc Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:32:41 -0500 Subject: remove the deprecated request.response_* attributes --- docs/narr/renderers.rst | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index a2811dbae..9132606b3 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -556,40 +556,6 @@ For more information on attributes of the request, see the API documentation in :ref:`request_module`. For more information on the API of ``request.response``, see :attr:`pyramid.request.Request.response`. -.. _response_prefixed_attrs: - -Deprecated Mechanism to Vary Attributes of Rendered Responses -------------------------------------------------------------- - -In previous releases of Pyramid (1.0 and before), the ``request.response`` -attribute did not exist. Instead, Pyramid required users to set special -``response_`` -prefixed attributes of the request to influence response -behavior. As of Pyramid 1.1, those request attributes are deprecated and -their use will cause a deprecation warning to be issued when used. Until -their existence is removed completely, we document them below, for benefit of -people with older code bases. - -``response_content_type`` - Defines the content-type of the resulting response, - e.g. ``text/xml``. - -``response_headerlist`` - A sequence of tuples describing header values that should be set in the - response, e.g. ``[('Set-Cookie', 'abc=123'), ('X-My-Header', 'foo')]``. - -``response_status`` - A WSGI-style status code (e.g. ``200 OK``) describing the status of the - response. - -``response_charset`` - The character set (e.g. ``UTF-8``) of the response. - -``response_cache_for`` - A value in seconds which will influence ``Cache-Control`` and ``Expires`` - headers in the returned response. The same can also be achieved by - returning various values in the ``response_headerlist``, this is purely a - convenience. - .. _adding_and_overriding_renderers: Adding and Changing Renderers -- cgit v1.2.3 From bc0a26ac2b75de362a4bf8142b3385788f318f47 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 02:50:15 -0500 Subject: add index for custom template engines --- docs/narr/renderers.rst | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 21c59c06a..8de3cd29d 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -364,6 +364,14 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. +.. index:: + single: template system bindings + single: Chameleon + single: Jinja2 + single: Mako + +.. _available_template_system_bindings: + Available Add-On Template System Bindings ----------------------------------------- -- cgit v1.2.3 From a50494f22bc0e4ee1e2546a192e5a60b0ff46aa3 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 22:46:40 -0500 Subject: remove chameleon and mako template-specific documentation --- docs/narr/templates.rst | 337 +----------------------------------------------- 1 file changed, 1 insertion(+), 336 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 26bb6b6cd..24973f253 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -8,10 +8,6 @@ dynamic data provided by a :term:`view`. :app:`Pyramid` offers a number of ways to perform templating tasks out of the box, and provides add-on templating support through a set of bindings packages. -Out of the box, :app:`Pyramid` provides templating via the :term:`Chameleon` -and :term:`Mako` templating libraries. :term:`Chameleon` provides support for -two different types of templates: :term:`ZPT` templates, and text templates. - Before discussing how built-in templates are used in detail, we'll discuss two ways to render templates within :app:`Pyramid` in general: directly, and via renderer @@ -32,7 +28,7 @@ given templating engine to do so. :app:`Pyramid` provides various APIs that allow you to render templates directly from within a view callable. For example, if there is a -:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named +:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named ``templates`` in your application, you can render the template from within the body of a view callable like so: @@ -383,236 +379,6 @@ The same set of system values are provided to templates rendered via a renderer view configuration as those provided to templates rendered imperatively. See :ref:`renderer_system_values`. - -.. index:: - single: Chameleon ZPT templates - single: ZPT templates (Chameleon) - -.. _chameleon_zpt_templates: - -:term:`Chameleon` ZPT Templates -------------------------------- - -Like :term:`Zope`, :app:`Pyramid` uses :term:`ZPT` (Zope Page -Templates) as its default templating language. However, -:app:`Pyramid` uses a different implementation of the :term:`ZPT` -specification than Zope does: the :term:`Chameleon` templating -engine. The Chameleon engine complies largely with the `Zope Page -Template `_ template -specification. However, it is significantly faster. - -The language definition documentation for Chameleon ZPT-style -templates is available from `the Chameleon website -`_. - -Given a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory -in your application named ``templates``, you can render the template as -a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='templates/foo.pt') - def my_view(request): - return {'foo':1, 'bar':2} - -See also :ref:`built_in_renderers` for more general information about -renderers, including Chameleon ZPT renderers. - -.. index:: - single: ZPT template (sample) - -A Sample ZPT Template -~~~~~~~~~~~~~~~~~~~~~ - -Here's what a simple :term:`Chameleon` ZPT template used under -:app:`Pyramid` might look like: - -.. code-block:: xml - :linenos: - - - - - - ${project} Application - - -

    Welcome to ${project}, an - application generated by the pyramid web - application framework.

    - - - -Note the use of :term:`Genshi` -style ``${replacements}`` above. This -is one of the ways that :term:`Chameleon` ZPT differs from standard -ZPT. The above template expects to find a ``project`` key in the set -of keywords passed in to it via :func:`~pyramid.renderers.render` or -:func:`~pyramid.renderers.render_to_response`. Typical ZPT -attribute-based syntax (e.g. ``tal:content`` and ``tal:replace``) also -works in these templates. - -.. index:: - single: ZPT macros - single: Chameleon ZPT macros - -Using ZPT Macros in :app:`Pyramid` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When a :term:`renderer` is used to render a template, :app:`Pyramid` makes at -least two top-level names available to the template by default: ``context`` -and ``request``. One of the common needs in ZPT-based templates is to use -one template's "macros" from within a different template. In Zope, this is -typically handled by retrieving the template from the ``context``. But the -context in :app:`Pyramid` is a :term:`resource` object, and templates cannot -usually be retrieved from resources. To use macros in :app:`Pyramid`, you -need to make the macro template itself available to the rendered template by -passing the macro template, or even the macro itself, *into* the rendered -template. To do this you can use the :func:`pyramid.renderers.get_renderer` -API to retrieve the macro template, and pass it into the template being -rendered via the dictionary returned by the view. For example, using a -:term:`view configuration` via a :class:`~pyramid.view.view_config` decorator -that uses a :term:`renderer`: - -.. code-block:: python - :linenos: - - from pyramid.renderers import get_renderer - from pyramid.view import view_config - - @view_config(renderer='templates/mytemplate.pt') - def my_view(request): - main = get_renderer('templates/master.pt').implementation() - return {'main':main} - -Where ``templates/master.pt`` might look like so: - -.. code-block:: xml - :linenos: - - - -

    - Hello Fred! -

    -
    - - -And ``templates/mytemplate.pt`` might look like so: - -.. code-block:: xml - :linenos: - - - - Chris - - - - -Using A Chameleon Macro Name Within a Renderer Name -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -At times, you may want to render a macro inside of a Chameleon ZPT template -instead of the full Chameleon ZPT template. To render the content of a -``define-macro`` field inside a Chameleon ZPT template, given a Chameleon -template file named ``foo.pt`` and a macro named ``bar`` defined within it -(e.g. ``
    ...
    ``), you can configure the -template as a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='foo#bar.pt') - def my_view(request): - return {'project':'my project'} - -The above will render only the ``bar`` macro defined within the ``foo.pt`` -template instead of the entire template. - -.. versionadded:: 1.4 - -.. index:: - single: Chameleon text templates - -.. _chameleon_text_templates: - -Templating with :term:`Chameleon` Text Templates ------------------------------------------------- - -:app:`Pyramid` also allows for the use of templates which are -composed entirely of non-XML text via :term:`Chameleon`. To do so, -you can create templates that are entirely composed of text except for -``${name}`` -style substitution points. - -Here's an example usage of a Chameleon text template. Create a file -on disk named ``mytemplate.txt`` in your project's ``templates`` -directory with the following contents: - -.. code-block:: text - - Hello, ${name}! - -Then in your project's ``views.py`` module, you can create a view -which renders this template: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='templates/mytemplate.txt') - def my_view(request): - return {'name':'world'} - -When the template is rendered, it will show: - -.. code-block:: text - - Hello, world! - -See also :ref:`built_in_renderers` for more general information about -renderers, including Chameleon text renderers. - -.. index:: - single: template renderer side effects - -Side Effects of Rendering a Chameleon Template ----------------------------------------------- - -When a Chameleon template is rendered from a file, the templating -engine writes a file in the same directory as the template file itself -as a kind of cache, in order to do less work the next time the -template needs to be read from disk. If you see "strange" ``.py`` -files showing up in your ``templates`` directory (or otherwise -directly "next" to your templates), it is due to this feature. - -If you're using a version control system such as Subversion, you -should configure it to ignore these files. Here's the contents of the -author's ``svn propedit svn:ignore .`` in each of my ``templates`` -directories. - -.. code-block:: text - - *.pt.py - *.txt.py - -Note that I always name my Chameleon ZPT template files with a ``.pt`` -extension and my Chameleon text template files with a ``.txt`` -extension so that these ``svn:ignore`` patterns work. - .. index:: pair: debugging; templates @@ -643,107 +409,6 @@ undefined variable (e.g. ``${wrong}``) might end up looking like this: The output tells you which template the error occurred in, as well as displaying the arguments passed to the template itself. -.. index:: - single: template internationalization - single: internationalization (of templates) - -:term:`Chameleon` Template Internationalization ------------------------------------------------ - -See :ref:`chameleon_translation_strings` for information about -supporting internationalized units of text within :term:`Chameleon` -templates. - -.. index:: - single: Mako - -.. _mako_templates: - -Templating With Mako Templates ------------------------------- - -:term:`Mako` is a templating system written by Mike Bayer. :app:`Pyramid` -has built-in bindings for the Mako templating system. The language -definition documentation for Mako templates is available from `the Mako -website `_. - -To use a Mako template, given a :term:`Mako` template file named ``foo.mak`` -in the ``templates`` subdirectory in your application package named -``mypackage``, you can configure the template as a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='foo.mak') - def my_view(request): - return {'project':'my project'} - -For the above view callable to work, the following setting needs to be -present in the application stanza of your configuration's ``ini`` file: - -.. code-block:: ini - - mako.directories = mypackage:templates - -This lets the Mako templating system know that it should look for templates -in the ``templates`` subdirectory of the ``mypackage`` Python package. See -:ref:`mako_template_renderer_settings` for more information about the -``mako.directories`` setting and other Mako-related settings that can be -placed into the application's ``ini`` file. - -.. index:: - single: Mako template (sample) - -A Sample Mako Template -~~~~~~~~~~~~~~~~~~~~~~ - -Here's what a simple :term:`Mako` template used under :app:`Pyramid` might -look like: - -.. code-block:: xml - :linenos: - - - - ${project} Application - - -

    Welcome to ${project}, an - application generated by the pyramid web framework.

    - - - -This template doesn't use any advanced features of Mako, only the -``${}`` replacement syntax for names that are passed in as -:term:`renderer globals`. See the `the Mako documentation -`_ to use more advanced features. - -Using A Mako def name Within a Renderer Name -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Sometimes you'd like to render a ``def`` inside of a Mako template instead of -the full Mako template. To render a def inside a Mako template, given a -:term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can -configure the template as a :term:`renderer` like so: - -.. code-block:: python - :linenos: - - from pyramid.view import view_config - - @view_config(renderer='foo#bar.mak') - def my_view(request): - return {'project':'my project'} - -The above will render the ``bar`` def from within the ``foo.mak`` template -instead of the entire template. - -.. versionadded:: 1.4 - .. index:: single: automatic reloading of templates single: template automatic reload -- cgit v1.2.3 From 7a60e44961309f5453fba84c7f606af6b19ab096 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 22:57:37 -0500 Subject: whitespace fixes --- docs/narr/templates.rst | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 24973f253..46d836813 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -318,7 +318,9 @@ template renderer: def my_view(request): return {'foo':1, 'bar':2} -.. note:: You do not need to supply the ``request`` value as a key +.. note:: + + You do not need to supply the ``request`` value as a key in the dictionary result returned from a renderer-configured view callable. :app:`Pyramid` automatically supplies this value for you so that the "most correct" system values are provided to @@ -424,9 +426,11 @@ appear immediately without needing to restart the application process. environment so that a change to a template will be automatically detected, and the template will be reloaded on the next rendering. -.. warning:: Auto-template-reload behavior is not recommended for - production sites as it slows rendering slightly; it's - usually only desirable during development. +.. warning:: + + Auto-template-reload behavior is not recommended for + production sites as it slows rendering slightly; it's + usually only desirable during development. In order to turn on automatic reloading of templates, you can use an environment variable, or a configuration file setting. @@ -437,18 +441,18 @@ variable set to ``1``, For example: .. code-block:: text - $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini + $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini To use a setting in the application ``.ini`` file for the same purpose, set the ``pyramid.reload_templates`` key to ``true`` within the application's configuration section, e.g.: .. code-block:: ini - :linenos: + :linenos: - [app:main] - use = egg:MyProject - pyramid.reload_templates = true + [app:main] + use = egg:MyProject + pyramid.reload_templates = true .. index:: single: template system bindings -- cgit v1.2.3 From b9ce00bee0b6f1f5b0174960f2087a418c1488a7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 22:57:46 -0500 Subject: move templating bindings back into the templating chapter --- docs/narr/renderers.rst | 38 +++++--------------------------------- docs/narr/templates.rst | 27 ++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 38 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 8de3cd29d..8afc9c4ab 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -128,6 +128,11 @@ Built-In Renderers Several built-in renderers exist in :app:`Pyramid`. These renderers can be used in the ``renderer`` attribute of view configurations. +.. note:: + + Bindings for officially supported templating languages can be found + at :ref:`available_template_system_bindings`. + .. index:: pair: renderer; string @@ -364,39 +369,6 @@ The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing values to a JSONP renderer too. -.. index:: - single: template system bindings - single: Chameleon - single: Jinja2 - single: Mako - -.. _available_template_system_bindings: - -Available Add-On Template System Bindings ------------------------------------------ - -The Pylons Project maintains several packages providing bindings to different -templating languages including the following: - -+------------------------------+------------------------------+ -| Template Language | Pyramid Bindings | -+==============================+==============================+ -| Chameleon_ | pyramid_chameleon_ | -+------------------------------+------------------------------+ -| Jinja2_ | pyramid_jinja2_ | -+------------------------------+------------------------------+ -| Mako_ | pyramid_mako_ | -+------------------------------+------------------------------+ - -.. _Chameleon: http://chameleon.readthedocs.org/en/latest/ -.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon - -.. _Jinja2: http://jinja.pocoo.org/docs/ -.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 - -.. _Mako: http://www.makotemplates.org/ -.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako - .. index:: single: response headers (from a renderer) single: renderer response headers diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 46d836813..af8f9150a 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -456,16 +456,33 @@ application's configuration section, e.g.: .. index:: single: template system bindings + single: Chameleon single: Jinja2 + single: Mako .. _available_template_system_bindings: Available Add-On Template System Bindings ----------------------------------------- -Jinja2 template bindings are available for :app:`Pyramid` in the -``pyramid_jinja2`` package. You can get the latest release of -this package from the -`Python package index `_ -(pypi). +The Pylons Project maintains several packages providing bindings to different +templating languages including the following: ++------------------------------+------------------------------+ +| Template Language | Pyramid Bindings | ++==============================+==============================+ +| Chameleon_ | pyramid_chameleon_ | ++------------------------------+------------------------------+ +| Jinja2_ | pyramid_jinja2_ | ++------------------------------+------------------------------+ +| Mako_ | pyramid_mako_ | ++------------------------------+------------------------------+ + +.. _Chameleon: http://chameleon.readthedocs.org/en/latest/ +.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon + +.. _Jinja2: http://jinja.pocoo.org/docs/ +.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 + +.. _Mako: http://www.makotemplates.org/ +.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako -- cgit v1.2.3 From f1aaf1577dfeb9e094a5a9d7130984b95531d5cb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:40:27 -0500 Subject: remove some more mako/chameleon references --- docs/narr/templates.rst | 50 ++++++++++++++----------------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index af8f9150a..3e19f7198 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -56,19 +56,8 @@ In this case, this is the directory containing the file that defines the ``sample_view`` function. Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive letter -prefix on Windows. - -.. warning:: - - Only :term:`Chameleon` templates support defining a renderer for a - template relative to the location of the module where the view callable is - defined. Mako templates, and other templating system bindings work - differently. In particular, Mako templates use a "lookup path" as defined - by the ``mako.directories`` configuration file instead of treating - relative paths as relative to the current view module. See - :ref:`mako_templates`. - -The path can alternately be a :term:`asset specification` in the form +prefix on Windows. The path can alternately be a +:term:`asset specification` in the form ``some.dotted.package_name:relative/path``. This makes it possible to address template assets which live in another package. For example: @@ -86,16 +75,9 @@ An asset specification points at a file within a Python *package*. In this case, it points at a file named ``foo.pt`` within the ``templates`` directory of the ``mypackage`` package. Using a asset specification instead of a relative template name is usually -a good idea, because calls to ``render_to_response`` using asset -specifications will continue to work properly if you move the code -containing them around. - -.. note:: - - Mako templating system bindings also respect absolute asset - specifications as an argument to any of the ``render*`` commands. If a - template name defines a ``:`` (colon) character and is not an absolute - path, it is treated as an absolute asset specification. +a good idea, because calls to :func:`~pyramid.renderers.render_to_response` +using asset specifications will continue to work properly if you move the +code containing them around. In the examples above we pass in a keyword argument named ``request`` representing the current :app:`Pyramid` request. Passing a request @@ -143,8 +125,8 @@ import its API functions into your views module, use those APIs to generate a string, then return that string as the body of a :app:`Pyramid` :term:`Response` object. -For example, here's an example of using "raw" `Mako -`_ from within a :app:`Pyramid` :term:`view`: +For example, here's an example of using "raw" Mako_ from within a +:app:`Pyramid` :term:`view`: .. code-block:: python :linenos: @@ -159,10 +141,10 @@ For example, here's an example of using "raw" `Mako return response You probably wouldn't use this particular snippet in a project, because it's -easier to use the Mako renderer bindings which already exist in -:app:`Pyramid`. But if your favorite templating system is not supported as a -renderer extension for :app:`Pyramid`, you can create your own simple -combination as shown above. +easier to use the supported +:ref:`Mako bindings `. But if your +favorite templating system is not supported as a renderer extension for +:app:`Pyramid`, you can create your own simple combination as shown above. .. note:: @@ -277,8 +259,8 @@ You can define more values which will be passed to every template executed as a result of rendering by defining :term:`renderer globals`. What any particular renderer does with these system values is up to the -renderer itself, but most template renderers, including Chameleon and Mako -renderers, make these names available as top-level template variables. +renderer itself, but most template renderers make these names available as +top-level template variables. .. index:: pair: renderer; templates @@ -348,11 +330,7 @@ it possible to address template assets which live in another package. Not just any template from any arbitrary templating system may be used as a renderer. Bindings must exist specifically for :app:`Pyramid` to use a -templating language template as a renderer. Currently, :app:`Pyramid` has -built-in support for two Chameleon templating languages: ZPT and text, and -the Mako templating system. See :ref:`built_in_renderers` for a discussion -of their details. :app:`Pyramid` also supports the use of :term:`Jinja2` -templates as renderers. See :ref:`available_template_system_bindings`. +templating language template as a renderer. .. sidebar:: Why Use A Renderer via View Configuration -- cgit v1.2.3 From 2207ed5c82dfd8c259f6032ff84eb8998be40fa8 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:51:03 -0500 Subject: update the MyProject example app to use pyramid_chameleon --- docs/narr/MyProject/myproject/__init__.py | 1 + docs/narr/MyProject/setup.py | 1 + docs/narr/project.rst | 17 ++++++++++------- 3 files changed, 12 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/__init__.py b/docs/narr/MyProject/myproject/__init__.py index 6c512f52f..ad5ecbc6f 100644 --- a/docs/narr/MyProject/myproject/__init__.py +++ b/docs/narr/MyProject/myproject/__init__.py @@ -5,6 +5,7 @@ def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ config = Configurator(settings=settings) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index 6969c73e7..a23f46c91 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -10,6 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', 'pyramid_debugtoolbar', 'waitress', ] diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 52f13d5a8..f3050f805 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -570,8 +570,8 @@ adding more settings to this section. The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a :app:`Pyramid` -specific setting which is passed into the framework. If it -exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako` -template changes will not require an application restart to be detected. See +exists, and its value is ``true``, supported template changes will not +require an application restart to be detected. See :ref:`reload_templates_section` for more information. .. warning:: The ``pyramid.reload_templates`` option should be turned off for @@ -818,7 +818,7 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Lines 4-11 define a function named ``main`` that returns a :app:`Pyramid` +#. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the :term:`PasteDeploy` framework as a result of running ``pserve``. @@ -826,17 +826,20 @@ also informs Python that the directory which contains it is a *package*. Line 7 creates an instance of a :term:`Configurator`. - Line 8 registers a static view, which will serve up the files from the + Line 8 adds support for Chameleon templating bindings, allowing us to + specify renderers with the ``.pt`` extension. + + Line 9 registers a static view, which will serve up the files from the ``myproject:static`` :term:`asset specification` (the ``static`` directory of the ``myproject`` package). - Line 9 adds a :term:`route` to the configuration. This route is later + Line 10 adds a :term:`route` to the configuration. This route is later used by a view in the ``views`` module. - Line 10 calls ``config.scan()``, which picks up view registrations declared + Line 11 calls ``config.scan()``, which picks up view registrations declared elsewhere in the package (in this case, in the ``views.py`` module). - Line 11 returns a :term:`WSGI` application to the caller of the function + Line 12 returns a :term:`WSGI` application to the caller of the function (Pyramid's pserve). .. index:: -- cgit v1.2.3 From ac681bc83778443bcb70b9c1ea370368044614fb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 5 Sep 2013 23:56:46 -0500 Subject: remove chameleon refs from asset specs --- docs/narr/assets.rst | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 26b3e3a92..b0a8d18b0 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -227,14 +227,14 @@ API to generate them for you. For example: .. code-block:: python :linenos: - from pyramid.chameleon_zpt import render_template_to_response + from pyramid.renderers import render_to_response def my_view(request): css_url = request.static_url('mypackage:assets/1/foo.css') js_url = request.static_url('mypackage:assets/2/foo.js') - return render_template_to_response('templates/my_template.pt', - css_url = css_url, - js_url = js_url) + return render_to_response('templates/my_template.pt', + dict(css_url=css_url, js_url=js_url), + request=request) If the request "application URL" of the running system is ``http://example.com``, the ``css_url`` generated above would be: @@ -336,7 +336,9 @@ your application root as below. from pyramid.static import static_view static_view = static_view('/path/to/static/dir', use_subpath=True) -.. note:: For better cross-system flexibility, use an :term:`asset +.. note:: + + For better cross-system flexibility, use an :term:`asset specification` as the argument to :class:`~pyramid.static.static_view` instead of a physical absolute filesystem path, e.g. ``mypackage:static`` instead of ``/path/to/mypackage/static``. @@ -432,9 +434,9 @@ feature, a :term:`Configurator` API exists named :meth:`pyramid.config.Configurator.override_asset`. This API allows you to *override* the following kinds of assets defined in any Python package: -- Individual :term:`Chameleon` templates. +- Individual template files. -- A directory containing multiple Chameleon templates. +- A directory containing multiple template files. - Individual static files served up by an instance of the ``pyramid.static.static_view`` helper class. @@ -460,8 +462,8 @@ can override a single asset. For example: :linenos: config.override_asset( - to_override='some.package:templates/mytemplate.pt', - override_with='another.package:othertemplates/anothertemplate.pt') + to_override='some.package:templates/mytemplate.pt', + override_with='another.package:othertemplates/anothertemplate.pt') The string value passed to both ``to_override`` and ``override_with`` sent to the ``override_asset`` API is called an :term:`asset specification`. The -- cgit v1.2.3 From fc477b2e4b20ae2788e468e45b2831e774be8ced Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 7 Sep 2013 21:59:41 -0400 Subject: - The ``pyramid.events.NewResponse`` event is now sent **after** response callbacks are executed. It previously executed before response callbacks were executed. Rationale: it's more useful to be able to inspect the response after response callbacks have done their jobs instead of before. Closes #1116. --- docs/narr/hooks.rst | 2 +- docs/narr/subrequest.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 3a2568775..8ffda1a5f 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -514,7 +514,7 @@ callback will be an exception object instead of its default value of ``None``. Response callbacks are called in the order they're added -(first-to-most-recently-added). All response callbacks are called *after* +(first-to-most-recently-added). All response callbacks are called *before* the :class:`~pyramid.events.NewResponse` event is sent. Errors raised by response callbacks are not handled specially. They will be propagated to the caller of the :app:`Pyramid` router application. diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 6437bd0fa..4b4e99d41 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -232,12 +232,12 @@ unconditionally: - Ensures that the user implied by the request passed has the necessary authorization to invoke view callable before calling it. -- causes a :class:`~pyramid.events.NewResponse` event to be sent when the - Pyramid application returns a response. - - Calls any :term:`response callback` functions defined within the subrequest's lifetime if a response is obtained from the Pyramid application. +- causes a :class:`~pyramid.events.NewResponse` event to be sent if a response + is obtained. + - Calls any :term:`finished callback` functions defined within the subrequest's lifetime. -- cgit v1.2.3 From d71acabebb804ebbd37703e78ac9886fcdded827 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 8 Sep 2013 15:15:58 -0600 Subject: Update documentation to reflect the dotted python name --- docs/narr/hooks.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 8ffda1a5f..a7dc3e78b 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1384,9 +1384,11 @@ The first argument to :meth:`pyramid.config.Configurator.add_view_predicate`, the name, is a string representing the name that is expected to be passed to ``view_config`` (or its imperative analogue ``add_view``). -The second argument is a view or route predicate factory. A view or route -predicate factory is most often a class with a constructor (``__init__``), a -``text`` method, a ``phash`` method and a ``__call__`` method. For example: +The second argument is a view or route predicate factory, or a :term:`dotted +Python name` which refers to a view or route predicate factory. A view or +route predicate factory is most often a class with a constructor +(``__init__``), a ``text`` method, a ``phash`` method and a ``__call__`` +method. For example: .. code-block:: python :linenos: -- cgit v1.2.3 From fdf30b3bb6f47d93d2f255a09e75be0c33d54789 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 21:12:10 -0400 Subject: - Removed the ability to pass the following arguments to ``pyramid.config.Configurator.add_route``: `view``, ``view_context``. ``view_for``, ``view_permission``, ``view_renderer``, and ``view_attr``. Using these arguments had been deprecated since Pyramid 1.1. Instead of passing view-related arguments to ``add_route``, use a separate call to ``pyramid.config.Configurator.add_view`` to associate a view with a route using its ``route_name`` argument. Note that this impacts the ``pyramid.config.Configurator.add_static_view`` function too, because it delegates to ``add_route``. --- docs/narr/urldispatch.rst | 7 ------- 1 file changed, 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 62eb89348..61849c3c0 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -399,13 +399,6 @@ process. Examples of route predicate arguments are ``pattern``, ``xhr``, and Other arguments are ``name`` and ``factory``. These arguments represent neither predicates nor view configuration information. -.. warning:: - - Some arguments are view-configuration related arguments, such as - ``view_renderer``. These only have an effect when the route configuration - names a ``view`` and these arguments have been deprecated as of - :app:`Pyramid` 1.1. - .. index:: single: route matching -- cgit v1.2.3 From c6601f77f91dc933ca429d1448f4c6b27857b608 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 8 Sep 2013 22:52:54 -0400 Subject: - The ``renderer_globals_factory`` argument to the ``pyramid.config.Configurator` constructor and its ``setup_registry`` method has been removed. The ``set_renderer_globals_factory`` method of ``pyramid.config.Configurator`` has also been removed. The (internal) ``pyramid.interfaces.IRendererGlobals`` interface was also removed. These arguments, methods and interfaces had been deprecated since 1.1. Use a ``BeforeRender`` event subscriber as documented in the "Hooks" chapter of the Pyramid narrative documentation instead of providing renderer globals values to the configurator. --- docs/narr/advconfig.rst | 1 - docs/narr/hooks.rst | 66 ++-------------------------------------------- docs/narr/introspector.rst | 12 --------- 3 files changed, 2 insertions(+), 77 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 1b8e33de3..d3431e39e 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -302,7 +302,6 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.set_view_mapper`, :meth:`~pyramid.config.Configurator.set_authentication_policy`, :meth:`~pyramid.config.Configurator.set_authorization_policy`, -:meth:`~pyramid.config.Configurator.set_renderer_globals_factory`, :meth:`~pyramid.config.Configurator.set_locale_negotiator`, :meth:`~pyramid.config.Configurator.set_default_permission`, :meth:`~pyramid.config.Configurator.add_traverser`, diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index a7dc3e78b..0c450fad7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -372,10 +372,8 @@ that can be used for this purpose. For example: def add_global(event): event['mykey'] = 'foo' -An object of this type is sent as an event just before a :term:`renderer` is -invoked (but *after* the application-level renderer globals factory added via -:class:`~pyramid.config.Configurator.set_renderer_globals_factory`, if any, -has injected its own keys into the renderer globals dictionary). +An object of this type is sent as an event just before a :term:`renderer` +is invoked. If a subscriber attempts to add a key that already exist in the renderer globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced @@ -417,66 +415,6 @@ your view callable, like so: See the API documentation for the :class:`~pyramid.events.BeforeRender` event interface at :class:`pyramid.interfaces.IBeforeRender`. -Another (deprecated) mechanism which allows event subscribers more control -when adding renderer global values exists in :ref:`adding_renderer_globals`. - -.. index:: - single: adding renderer globals - -.. _adding_renderer_globals: - -Adding Renderer Globals (Deprecated) ------------------------------------- - -.. deprecated:: 1.1 - An alternative mechanism which allows event subscribers to add renderer - global values is documented in :ref:`beforerender_event`. - -Whenever :app:`Pyramid` handles a request to perform a rendering (after a -view with a ``renderer=`` configuration attribute is invoked, or when any of -the methods beginning with ``render`` within the :mod:`pyramid.renderers` -module are called), *renderer globals* can be injected into the *system* -values sent to the renderer. By default, no renderer globals are injected, -and the "bare" system values (such as ``request``, ``context``, ``view``, and -``renderer_name``) are the only values present in the system dictionary -passed to every renderer. - -A callback that :app:`Pyramid` will call every time a renderer is invoked can -be added by passing a ``renderer_globals_factory`` argument to the -constructor of the :term:`configurator`. This callback can either be a -callable object or a :term:`dotted Python name` representing such a callable. - -.. code-block:: python - :linenos: - - def renderer_globals_factory(system): - return {'a': 1} - - config = Configurator( - renderer_globals_factory=renderer_globals_factory) - -Such a callback must accept a single positional argument (notionally named -``system``) which will contain the original system values. It must return a -dictionary of values that will be merged into the system dictionary. See -:ref:`renderer_system_values` for description of the values present in the -system dictionary. - -If you're doing imperative configuration, and you'd rather do it after you've -already constructed a :term:`configurator` it can also be registered via the -:meth:`pyramid.config.Configurator.set_renderer_globals_factory` method: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def renderer_globals_factory(system): - return {'a': 1} - - config = Configurator() - config.set_renderer_globals_factory(renderer_globals_factory) - - .. index:: single: response callback diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index dec22c5b1..3c0a6744f 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -232,18 +232,6 @@ introspectables in categories not described here. The factory object (the resolved ``factory`` argument to ``add_renderer``). -``renderer globals factory`` - - There will be one and only one introspectable in the ``renderer globals - factory`` category. It represents a call to - :meth:`pyramid.config.Configurator.set_renderer_globals_factory`; it will - have the following data. - - ``factory`` - - The factory object (the resolved ``factory`` argument to - ``set_renderer_globals_factory``). - ``routes`` Each introspectable in the ``routes`` category represents a call to -- cgit v1.2.3 From db1efe21c3d9b025883b3ed9b0b897cc3d718c28 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 11 Sep 2013 18:10:18 -0400 Subject: appease --- docs/narr/renderers.rst | 51 ++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index e13e09af3..3059aef35 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -207,13 +207,7 @@ representing the JSON serialization of the return value: The return value needn't be a dictionary, but the return value must contain values serializable by the configured serializer (by default ``json.dumps``). -.. note:: - - Extra arguments can be passed to the serializer by overriding the default - ``json`` renderer. See :class:`pyramid.renderers.JSON` and - :ref:`adding_and_overriding_renderers` for more information. - -You can configure a view to use the JSON renderer by naming ``json`` as the +You can configure a view to use the JSON renderer by naming``json`` as the ``renderer`` argument of a view configuration, e.g. by using :meth:`~pyramid.config.Configurator.add_view`: @@ -234,6 +228,18 @@ using the api of the ``request.response`` attribute. See Serializing Custom Objects ++++++++++++++++++++++++++ +Some objects are not, by default, JSON-serializable (such as datetimes and +other arbitrary Python objects). You can, however, register code that makes +non-serializable objects serializable in two ways: + +- By defining a ``__json__`` method on objects in your application. + +- For objects you don't "own", you can register JSON renderer that knows about + an *adapter* for that kind of object. + +Using a Custom ``__json__`` Method +********************************** + Custom objects can be made easily JSON-serializable in Pyramid by defining a ``__json__`` method on the object's class. This method should return values natively JSON-serializable (such as ints, lists, dictionaries, strings, and @@ -259,6 +265,9 @@ will be the active request object at render time. # the JSON value returned by ``objects`` will be: # [{"x": 1}, {"x": 2}] +Using the ``add_adapter`` Method of a Custom JSON Renderer +********************************************************** + If you aren't the author of the objects being serialized, it won't be possible (or at least not reasonable) to add a custom ``__json__`` method to their classes in order to influence serialization. If the object passed @@ -273,19 +282,21 @@ objects using the registered adapters. A short example follows: from pyramid.renderers import JSON - json_renderer = JSON() - def datetime_adapter(obj, request): - return obj.isoformat() - json_renderer.add_adapter(datetime.datetime, datetime_adapter) - - # then during configuration .... - config = Configurator() - config.add_renderer('json', json_renderer) - -The adapter should accept two arguments: the object needing to be serialized -and ``request``, which will be the current request object at render time. -The adapter should raise a :exc:`TypeError` if it can't determine what to do -with the object. + if __name__ == '__main__': + config = Configurator() + json_renderer = JSON() + def datetime_adapter(obj, request): + return obj.isoformat() + json_renderer.add_adapter(datetime.datetime, datetime_adapter) + config.add_renderer('json', json_renderer) + +The ``add_adapter`` method should accept two arguments: the *class* of the object that you want this adapter to run for (in the example above, +``datetime.datetime``), and the adapter itself. + +The adapter should be a callable. It should accept two arguments: the object +needing to be serialized and ``request``, which will be the current request +object at render time. The adapter should raise a :exc:`TypeError` +if it can't determine what to do with the object. See :class:`pyramid.renderers.JSON` and :ref:`adding_and_overriding_renderers` for more information. -- cgit v1.2.3 From 1e35e04865f5974fe9d31fd2e3079fe339b1b548 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 22 Sep 2013 11:34:39 -0500 Subject: typo --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 76cf1daac..182676b29 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -833,7 +833,7 @@ of this: RESTView, route_name='rest', attr='delete', request_method='DELETE') To reduce the amount of repetition in the ``config.add_view`` statements, we -can move the ``route_name='rest'`` argument to a ``@view_default`` class +can move the ``route_name='rest'`` argument to a ``@view_defaults`` class decorator on the RESTView class: .. code-block:: python -- cgit v1.2.3 From fde65302aee7d6d3ee57af06082fb4ab34e2cda6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 22 Sep 2013 14:29:38 -0500 Subject: try to clarify the docs to avoid "if '__main__'" confusion --- docs/narr/viewconfig.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 182676b29..7c76116f7 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -822,7 +822,7 @@ of this: def delete(self): return Response('delete') - if __name__ == '__main__': + def main(global_config, **settings): config = Configurator() config.add_route('rest', '/rest') config.add_view( @@ -831,6 +831,7 @@ of this: RESTView, route_name='rest', attr='post', request_method='POST') config.add_view( RESTView, route_name='rest', attr='delete', request_method='DELETE') + return config.make_wsgi_app() To reduce the amount of repetition in the ``config.add_view`` statements, we can move the ``route_name='rest'`` argument to a ``@view_defaults`` class @@ -857,12 +858,13 @@ decorator on the RESTView class: def delete(self): return Response('delete') - if __name__ == '__main__': + def main(global_config, **settings): config = Configurator() config.add_route('rest', '/rest') config.add_view(RESTView, attr='get', request_method='GET') config.add_view(RESTView, attr='post', request_method='POST') config.add_view(RESTView, attr='delete', request_method='DELETE') + return config.make_wsgi_app() :class:`pyramid.view.view_defaults` accepts the same set of arguments that :class:`pyramid.view.view_config` does, and they have the same meaning. Each -- cgit v1.2.3 From c5a467b86b96d2cb0b4eda13134dac7edb68d0ec Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 22 Sep 2013 14:29:38 -0500 Subject: try to clarify the docs to avoid "if '__main__'" confusion --- docs/narr/viewconfig.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 182676b29..7c76116f7 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -822,7 +822,7 @@ of this: def delete(self): return Response('delete') - if __name__ == '__main__': + def main(global_config, **settings): config = Configurator() config.add_route('rest', '/rest') config.add_view( @@ -831,6 +831,7 @@ of this: RESTView, route_name='rest', attr='post', request_method='POST') config.add_view( RESTView, route_name='rest', attr='delete', request_method='DELETE') + return config.make_wsgi_app() To reduce the amount of repetition in the ``config.add_view`` statements, we can move the ``route_name='rest'`` argument to a ``@view_defaults`` class @@ -857,12 +858,13 @@ decorator on the RESTView class: def delete(self): return Response('delete') - if __name__ == '__main__': + def main(global_config, **settings): config = Configurator() config.add_route('rest', '/rest') config.add_view(RESTView, attr='get', request_method='GET') config.add_view(RESTView, attr='post', request_method='POST') config.add_view(RESTView, attr='delete', request_method='DELETE') + return config.make_wsgi_app() :class:`pyramid.view.view_defaults` accepts the same set of arguments that :class:`pyramid.view.view_config` does, and they have the same meaning. Each -- cgit v1.2.3 From ae5f2b9da9583114f3f5a6f08497e5a248e3e960 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Fri, 27 Sep 2013 20:47:28 -0500 Subject: Docs: Make clear that installation is into the virtual enviornment. --- docs/narr/project.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index f3050f805..602f15fef 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -193,10 +193,10 @@ Elided output from a run of this command on UNIX is shown below: ... Finished processing dependencies for MyProject==0.0 -This will install a :term:`distribution` representing your project into the -interpreter's library set so it can be found by ``import`` statements and by -other console scripts such as ``pserve``, ``pshell``, ``proutes`` and -``pviews``. +This will install a :term:`distribution` representing your project +into the virtual environment interpreter's library set so it can be +found by ``import`` statements and by other console scripts such as +``pserve``, ``pshell``, ``proutes`` and ``pviews``. .. index:: single: running tests -- cgit v1.2.3 From 08bf6fa20e9593c14f5870f392cf7d01665f52f8 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 27 Sep 2013 23:52:20 -0600 Subject: Add note about C extensions There was some confusion regarding the output of easy_install pyramid when the Python header files were not installed, these errors are harmless however adding a simple note would have stopped a lot of frustration. --- docs/narr/install.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index fb67b899b..6260c36f2 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -25,6 +25,10 @@ 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. +Certain :app:`Pyramid` dependencies can optionally use C Python extensions, +if a compiler or Python headers are unavailable the dependency will fall back +to using pure Python instead. + For Mac OS X Users ~~~~~~~~~~~~~~~~~~ @@ -292,6 +296,13 @@ itself using the following commands: The ``easy_install`` command will take longer than the previous ones to complete, as it downloads and installs a number of dependencies. +.. note:: + + If you see any errors related to failing to compile the C extensions, 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 -- cgit v1.2.3 From 994261c9104c174624fb7655508acad453023a5b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 28 Sep 2013 01:23:43 -0500 Subject: minor tweaks to language --- docs/narr/install.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 6260c36f2..f3f736df6 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -25,9 +25,9 @@ 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. -Certain :app:`Pyramid` dependencies can optionally use C Python extensions, -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. For Mac OS X Users ~~~~~~~~~~~~~~~~~~ @@ -298,10 +298,10 @@ complete, as it downloads and installs a number of dependencies. .. note:: - If you see any errors related to failing to compile the C extensions, 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. + 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 -- cgit v1.2.3 From 2323103debf8487d0a0a1ec27580e502d46989e3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 28 Sep 2013 02:19:27 -0700 Subject: Add versioning to branch master --- docs/narr/install.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index f3f736df6..e419a8b20 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -289,9 +289,9 @@ Installing :app:`Pyramid` Into the Virtual Python Environment After you've got your virtualenv installed, you may install :app:`Pyramid` itself using the following commands: -.. code-block:: text - - $ $VENV/bin/easy_install pyramid +.. parsed-literal:: + + $ $VENV/bin/easy_install "pyramid==\ |release|\ " The ``easy_install`` command will take longer than the previous ones to complete, as it downloads and installs a number of dependencies. @@ -368,9 +368,9 @@ You can use Pyramid on Windows under Python 2 or 3. #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: text - - c:\env> %VENV%\Scripts\easy_install pyramid + .. parsed-literal:: + + c:\\env> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ " What Gets Installed ------------------- -- cgit v1.2.3 From bc3de3f5499e39e67e29b6678503f3a14be0b08c Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 1 Oct 2013 00:14:12 -0500 Subject: Docs: project.rst: Match parenthesis & fix punctuation. --- docs/narr/project.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 602f15fef..fc3cac009 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -974,9 +974,9 @@ named ``views`` instead of within a single ``views.py`` file, you might: - *Move* the existing ``views.py`` file to a file inside the new ``views`` directory named, say, ``blog.py``. -- Create a file within the new ``views`` directory named ``__init__.py`` (it - can be empty, this just tells Python that the ``views`` directory is a - *package*. +- Create a file within the new ``views`` directory named ``__init__.py``. (It + can be empty. This just tells Python that the ``views`` directory is a + *package*.) You can then continue to add view callable functions to the ``blog.py`` module, but you can also add other ``.py`` files which contain view callable -- cgit v1.2.3 From 128d9d6cd92ddd50dfcdf14b12cc94a0902c0df1 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 1 Oct 2013 00:22:20 -0500 Subject: Docs: project.rst: Note that asset specs must be fully qualifed when moving views into a sub-package. --- docs/narr/project.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index fc3cac009..1b98271fb 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -971,13 +971,16 @@ named ``views`` instead of within a single ``views.py`` file, you might: - Create a ``views`` directory inside your ``myproject`` package directory (the same directory which holds ``views.py``). -- *Move* the existing ``views.py`` file to a file inside the new ``views`` - directory named, say, ``blog.py``. - - Create a file within the new ``views`` directory named ``__init__.py``. (It can be empty. This just tells Python that the ``views`` directory is a *package*.) +- *Move* the existing ``views.py`` file to a file inside the new ``views`` + directory named, say, ``blog.py``. The template :term:`asset + specification`s in ``blog.py`` must now be fully qualified with the + project's package name (``myproject:templates/blog.pt``) since the + ``templates`` directory remains in the ``myproject`` package. + You can then continue to add view callable functions to the ``blog.py`` module, but you can also add other ``.py`` files which contain view callable functions to the ``views`` directory. As long as you use the -- cgit v1.2.3 From ac7d1752e071fb7dadbfbf7f4bd1efadd3052b4f Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 1 Oct 2013 00:44:16 -0500 Subject: Docs: project.rst: Make the sentence more better. --- docs/narr/project.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 1b98271fb..e5da3b5c5 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -976,10 +976,10 @@ named ``views`` instead of within a single ``views.py`` file, you might: *package*.) - *Move* the existing ``views.py`` file to a file inside the new ``views`` - directory named, say, ``blog.py``. The template :term:`asset + directory named, say, ``blog.py``. Because the ``templates`` directory + remains in the ``myproject`` package the template :term:`asset specification`s in ``blog.py`` must now be fully qualified with the - project's package name (``myproject:templates/blog.pt``) since the - ``templates`` directory remains in the ``myproject`` package. + project's package name (``myproject:templates/blog.pt``). You can then continue to add view callable functions to the ``blog.py`` module, but you can also add other ``.py`` files which contain view callable -- cgit v1.2.3 From 1a76ed41b133ea73c7d40997c6f564fd72d7273e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 1 Oct 2013 00:48:53 -0700 Subject: Add comma --- docs/narr/project.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index e5da3b5c5..4c19982d6 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -144,7 +144,7 @@ contains no space characters, so it's wise to *avoid* a path that contains i.e. ``My Documents``. As a result, the author, when he uses Windows, just puts his projects in ``C:\projects``. -.. warning:: +.. warning:: You’ll need to avoid using ``pcreate`` to create a project with the same name as a Python standard library component. In particular, this means you @@ -977,7 +977,7 @@ named ``views`` instead of within a single ``views.py`` file, you might: - *Move* the existing ``views.py`` file to a file inside the new ``views`` directory named, say, ``blog.py``. Because the ``templates`` directory - remains in the ``myproject`` package the template :term:`asset + remains in the ``myproject`` package, the template :term:`asset specification`s in ``blog.py`` must now be fully qualified with the project's package name (``myproject:templates/blog.pt``). @@ -1028,7 +1028,7 @@ server. Waitress is a server that is suited for development and light production usage. It's not the fastest nor the most featureful WSGI server. Instead, its main feature is that it works on all platforms that Pyramid needs to run on, making it a good choice as a default server from the -perspective of Pyramid's developers. +perspective of Pyramid's developers. Any WSGI server is capable of running a :app:`Pyramid` application. But we suggest you stick with the default server for development, and that you wait -- cgit v1.2.3 From f24ac4c471a458aec0cde232925c8fab652bafcc Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 11:31:47 -0500 Subject: Docs: project.rst: Eliminate reduncency and better explain renderer. --- docs/narr/project.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 602f15fef..09e07ee6d 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -871,18 +871,17 @@ specification` that specifies the ``mytemplate.pt`` file within the ``templates`` directory of the ``myproject`` package. The asset specification could have also been specified as ``myproject:templates/mytemplate.pt``; the leading package name and colon is -optional. The template file it actually points to is a :term:`Chameleon` ZPT -template file. +optional. The template file pointed to is a :term:`Chameleon` ZPT +template file (``templates/my_template.pt``). This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` class representing the browser's request to our server. -This view returns a dictionary. When this view is invoked, a -:term:`renderer` converts the dictionary returned by the view into HTML, and -returns the result as the :term:`response`. This view is configured to -invoke a renderer which uses a :term:`Chameleon` ZPT template -(``templates/my_template.pt``). +This view is configured to invoke a :term;`renderer` on a template. The +dictionary the view returns (on line 6) provides the value the renderer +substitutes into the template when generating HTML. The renderer then +returns the HTML in a :term:`response`. See :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. -- cgit v1.2.3 From 77edee7e91356f4f0f1d12c2dd159965b0576109 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 11:33:50 -0500 Subject: Docs: project.rst: Emphasize key takeaway; use dicts to supply values to templates. --- docs/narr/project.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 09e07ee6d..359fb31d3 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -878,6 +878,8 @@ This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` class representing the browser's request to our server. +.. note:: Dictionaries (typically) provide values to :term:`template`s. + This view is configured to invoke a :term;`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer substitutes into the template when generating HTML. The renderer then -- cgit v1.2.3 From 68d16988404aec339fde1df7822c783d3ea23af6 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 11:35:34 -0500 Subject: Docs: renderers.rst: Explain typical renderer usage. --- docs/narr/renderers.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 3059aef35..235dbaf83 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -49,10 +49,14 @@ Writing View Callables Which Use a Renderer ------------------------------------------- As we've seen, a view callable needn't always return a Response object. -Instead, it may return an arbitrary Python object, with the expectation -that a :term:`renderer` will convert that object into a response instance on -your behalf. Some renderers use a templating system; other renderers use -object serialization techniques. +Instead, it may return an arbitrary Python object, with the expectation that +a :term:`renderer` will convert that object into a response instance on your +behalf. Some renderers use a templating system; other renderers use object +serialization techniques. Because renderers inject variable data into some +output (otherwise a static Response object could be returned) the renderer +must have some means of identifying the data and mapping its transformation +into the desired output. Often, as the means of providing this mapping, the +object supplied to the renderer is a Python dictionary. View configuration can vary the renderer associated with a view callable via the ``renderer`` attribute. For example, this call to -- cgit v1.2.3 From 190b5644c473286f8066c9eb430c567dfdeb4913 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 13:36:05 -0500 Subject: Docs: sessions.rst: Explain example. --- 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 358977089..eafa9dbf9 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -99,6 +99,10 @@ example: else: return Response('Fred was not in the session') +The first time this view is invoked produces ``Fred was not in the +session``. Subsequent invocations produce ``Fred was in the +session``. + You can use a session much like a Python dictionary. It supports all dictionary methods, along with some extra attributes, and methods. -- cgit v1.2.3 From 66be39bf656a2840931603bc959e38ff95e53164 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 2 Oct 2013 15:35:24 -0400 Subject: - Removed mention of ``pyramid_beaker`` from docs. Beaker is no longer maintained. Point people at ``pyramid_redis_sessions`` instead. --- docs/narr/sessions.rst | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 358977089..f8279b0a5 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -146,8 +146,6 @@ Some gotchas: you've changed sessioning data. .. index:: - single: pyramid_beaker - single: Beaker single: pyramid_redis_sessions single: session factory (alternates) @@ -156,20 +154,11 @@ Some gotchas: Using Alternate Session Factories --------------------------------- -At the time of this writing, exactly two alternate session factories -exist. - -The first is named ``pyramid_redis_sessions``. It can be downloaded from PyPI. +At the time of this writing, exactly one project-endorsed alternate session +factory exists named``pyramid_redis_sessions``. It can be downloaded from PyPI. It uses Redis as a backend. It is the recommended persistent session solution at the time of this writing. -The second is named ``pyramid_beaker``. This is a session factory that uses the -`Beaker `_ library as a backend. Beaker has -support for file-based sessions, database based sessions, and encrypted -cookie-based sessions. See `the pyramid_beaker documentation -`_ for more -information about ``pyramid_beaker``. - .. index:: single: session factory (custom) -- cgit v1.2.3 From b31cdc5beb173716235a026d264dafde12fea109 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 14:47:01 -0500 Subject: Docs: sessions.rst: Sessions only work when the client cooperates. --- docs/narr/sessions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index eafa9dbf9..db1e0ea20 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -101,7 +101,8 @@ example: The first time this view is invoked produces ``Fred was not in the session``. Subsequent invocations produce ``Fred was in the -session``. +session``, assuming of course that the client side maintains the +session's identity across multiple requests. You can use a session much like a Python dictionary. It supports all dictionary methods, along with some extra attributes, and methods. -- cgit v1.2.3 From 5bf27497638ad607f0e42feb10145cd6720b74d3 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 15:20:59 -0500 Subject: Docs: Make statements more concreate regards renderers getting data from dictionaries. --- docs/narr/project.rst | 2 +- docs/narr/renderers.rst | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9a1ba190d..61b6ae316 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -878,7 +878,7 @@ This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` class representing the browser's request to our server. -.. note:: Dictionaries (typically) provide values to :term:`template`s. +.. note:: Dictionaries provide values to :term:`template`s. This view is configured to invoke a :term;`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 235dbaf83..4046c67fa 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -52,11 +52,9 @@ As we've seen, a view callable needn't always return a Response object. Instead, it may return an arbitrary Python object, with the expectation that a :term:`renderer` will convert that object into a response instance on your behalf. Some renderers use a templating system; other renderers use object -serialization techniques. Because renderers inject variable data into some -output (otherwise a static Response object could be returned) the renderer -must have some means of identifying the data and mapping its transformation -into the desired output. Often, as the means of providing this mapping, the -object supplied to the renderer is a Python dictionary. +serialization techniques. In practice, renderers obtain application data +values from Python dictionaries so, in practice, view callables which use +renderers return Python dictionaries. View configuration can vary the renderer associated with a view callable via the ``renderer`` attribute. For example, this call to -- cgit v1.2.3 From 47e13e042c270f9ffb3ac86b294e89ec4b1fef6a Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Wed, 2 Oct 2013 15:27:32 -0500 Subject: Docs: project.rst: Fix markup failure just introduced. --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 61b6ae316..2acc81e17 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -880,7 +880,7 @@ This view callable function is handed a single piece of information: the .. note:: Dictionaries provide values to :term:`template`s. -This view is configured to invoke a :term;`renderer` on a template. The +This view is configured to invoke a :term:`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer substitutes into the template when generating HTML. The renderer then returns the HTML in a :term:`response`. -- cgit v1.2.3 From 4122733091d0204b22d7acedfdf985caed17f93f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 2 Oct 2013 17:29:39 -0400 Subject: get rid of note that appears to be explained in the next para --- docs/narr/project.rst | 2 -- 1 file changed, 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 2acc81e17..bfd00d3a0 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -878,8 +878,6 @@ This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` class representing the browser's request to our server. -.. note:: Dictionaries provide values to :term:`template`s. - This view is configured to invoke a :term:`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer substitutes into the template when generating HTML. The renderer then -- cgit v1.2.3 From ab2fedf7adaec0a56a69beed35312c88d7961c6c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 2 Oct 2013 17:47:17 -0400 Subject: fix the docs build and get rid of stray references to Beaker --- docs/narr/project.rst | 2 +- docs/narr/sessions.rst | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index bfd00d3a0..9451f41b1 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -977,7 +977,7 @@ named ``views`` instead of within a single ``views.py`` file, you might: - *Move* the existing ``views.py`` file to a file inside the new ``views`` directory named, say, ``blog.py``. Because the ``templates`` directory remains in the ``myproject`` package, the template :term:`asset - specification`s in ``blog.py`` must now be fully qualified with the + specification` values in ``blog.py`` must now be fully qualified with the project's package name (``myproject:templates/blog.pt``). You can then continue to add view callable functions to the ``blog.py`` diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index f4da5d82a..649d22bd2 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -159,10 +159,10 @@ Some gotchas: Using Alternate Session Factories --------------------------------- -At the time of this writing, exactly one project-endorsed alternate session -factory exists named``pyramid_redis_sessions``. It can be downloaded from PyPI. -It uses Redis as a backend. It is the recommended persistent session solution -at the time of this writing. +At the time of this writing, exactly one project-endorsed alternate session +factory exists named :term:`pyramid_redis_sessions`. It can be downloaded from +PyPI. It uses the Redis database as a backend. It is the recommended +persistent session solution at the time of this writing. .. index:: single: session factory (custom) -- cgit v1.2.3 From 96188ac4b74cb1e67cb95afdb9519ecd8934d688 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 2 Oct 2013 18:56:56 -0400 Subject: rearrange the fix --- docs/narr/traversal.rst | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index fb4adff61..454bb5620 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -128,12 +128,6 @@ Here's an example of a simple root factory class: def __init__(self, request): pass -..note:: - For the purpose of understanding traversal, and the contents within - this document, the above Root is an analogue to the default root - factory present in Pyramid. The default root factory is very simple and - not very useful unless using :term:`URL dispatch`. - Here's an example of using this root factory within startup configuration, by passing it to an instance of a :term:`Configurator` named ``config``: @@ -152,13 +146,15 @@ refer to a root factory defined in a different module. If no :term:`root factory` is passed to the :app:`Pyramid` :term:`Configurator` constructor, or if the ``root_factory`` value -specified is ``None``, a *default* root factory is used. The default +specified is ``None``, a :term:`default root factory` is used. The default root factory always returns a resource that has no child resources; it is effectively empty. Usually a root factory for a traversal-based application will be more -complicated than the above ``Root`` class; in particular it may be -associated with a database connection or another persistence mechanism. +complicated than the above ``Root`` class; in particular it may be associated +with a database connection or another persistence mechanism. The above +``Root`` class is analogous to the default root factory present in Pyramid. The +default root factory is very simple and not very useful. .. note:: -- cgit v1.2.3 From 1f7a00346411033d935bf931c206b585353f8be4 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Sat, 5 Oct 2013 00:37:09 -0500 Subject: Docs: Link from renderer narrative docs to example render_to_response call, and index the example. More fully explain the 2 examples, one with render_to_response call and one without. --- docs/narr/introduction.rst | 11 +++++++++-- docs/narr/renderers.rst | 10 ++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 032f4be6b..8c2acf95c 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -321,7 +321,14 @@ assertion instead that the view returns "the right stuff" in the dictionary it returns. You can write "real" unit tests instead of functionally testing all of your views. -For example, instead of: +.. index:: + pair: renderer; explicitly calling + pair: view renderer; explictly calling + +.. _example_render_to_response_call: + +For example, instead of returning a ``Response`` object from a +``render_to_response`` call: .. code-block:: python :linenos: @@ -332,7 +339,7 @@ For example, instead of: return render_to_response('myapp:templates/mytemplate.pt', {'a':1}, request=request) -You can do this: +You can return a Python dictionary: .. code-block:: python :linenos: diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 4046c67fa..b86f7298b 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -56,10 +56,12 @@ serialization techniques. In practice, renderers obtain application data values from Python dictionaries so, in practice, view callables which use renderers return Python dictionaries. -View configuration can vary the renderer associated with a view callable via -the ``renderer`` attribute. For example, this call to -:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` renderer -with a view callable: +View callables can :ref:`explicitly call +` renderers but, typically, view +configuration declares the renderer used to render a view callable's +results. This is done with the ``renderer`` attribute. For example, +this call to :meth:`~pyramid.config.Configurator.add_view` associates +the ``json`` renderer with a view callable: .. code-block:: python -- cgit v1.2.3 From cabaa67149f95796aac35a19313ca543064a7a0b Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Sat, 5 Oct 2013 00:56:39 -0500 Subject: Docs: project.rst: Hilight that dictionaries provide values to templates. --- docs/narr/project.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9451f41b1..8788977c7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -878,6 +878,8 @@ This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` class representing the browser's request to our server. +.. note:: Dictionaries provide values to :term:`template`\s. + This view is configured to invoke a :term:`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer substitutes into the template when generating HTML. The renderer then -- cgit v1.2.3 From a8cb84e04a81bcfd0236c3ff534919bb555e7ed3 Mon Sep 17 00:00:00 2001 From: BauhausSP Date: Sun, 6 Oct 2013 21:08:14 +0100 Subject: Fixed an example "from pyramid.view import view_config" instead of "from pyramid.view. import view_config" --- docs/narr/upgrading.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index ca6dc565b..64343ca3e 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -150,7 +150,7 @@ do things the newer way: .. code-block:: python :linenos: - from pyramid.view. import view_config + from pyramid.view import view_config from pyramid.static import static_view myview = static_view('static', 'static', use_subpath=True) -- cgit v1.2.3 From 0f5e17a983ecb97bb0bdeb169ac775886c9e15fe Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 09:53:06 -0500 Subject: Docs: project.rst: Utilize sidebars for out-of-band text. --- docs/narr/project.rst | 58 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 24 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 8788977c7..622f40d69 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -210,6 +210,12 @@ Python interpreter from the :term:`virtualenv` you created during :ref:`installing_chapter` (the ``python`` command that lives in the ``bin`` directory of your virtualenv). +.. sidebar:: Verbose Testing + + The ``-q`` option is passed to the ``setup.py test`` command to limit the + output to a stream of dots. If you don't pass ``-q``, you'll see more + verbose test result output (which normally isn't very useful). + On UNIX: .. code-block:: text @@ -243,12 +249,6 @@ Here's sample output from a test run on UNIX: OK -.. note:: - - The ``-q`` option is passed to the ``setup.py test`` command to limit the - output to a stream of dots. If you don't pass ``-q``, you'll see more - verbose test result output (which normally isn't very useful). - The tests themselves are found in the ``tests.py`` module in your ``pcreate`` generated project. Within a project generated by the ``starter`` scaffold, a single sample test exists. @@ -684,6 +684,14 @@ use a different version control system, you may need to install a setuptools add-on such as ``setuptools-git`` or ``setuptools-hg`` for this behavior to work properly. +.. sidebar:: Python's ``setup.py`` + + ``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 `_. + .. index:: single: setup.py @@ -694,14 +702,6 @@ The ``setup.py`` file is a :term:`setuptools` setup file. It is meant to be run directly from the command line to perform a variety of functions, such as testing, packaging, and distributing your application. -.. note:: - - ``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 `_. - Our generated ``setup.py`` looks like this: .. literalinclude:: MyProject/setup.py @@ -857,6 +857,26 @@ and which returns a :term:`response`. :language: python :linenos: +.. sidebar:: Fully Interactive Development + + Because our ``development.ini`` has a ``pyramid.reload_templates = + true`` directive indicating that templates should be reloaded when + they change, you won't need to restart the application server to + see changes you make to templates. During development, this is + handy. If this directive had been ``false`` (or if the directive + did not exist), you would need to restart the application server + for each template change. For production applications, you should + set your project's ``pyramid.reload_templates`` to ``false`` to + increase template rendering speed. + + Pyramid can also dynamically reload changed Python files. For more + on this see :ref:`reloading_code` above. + + The :ref:`debug_toolbar` provides interactive access to your + application's internals and, should an exception occur, allows + interactive access to traceback execution stack frames from the + Python interpreter. + Lines 4-6 define and register a :term:`view callable` named ``my_view``. The function named ``my_view`` is decorated with a ``view_config`` decorator (which is processed by the ``config.scan()`` line in our ``__init__.py``). @@ -888,16 +908,6 @@ returns the HTML in a :term:`response`. See :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. -.. note:: Because our ``development.ini`` has a ``pyramid.reload_templates = - true`` directive indicating that templates should be reloaded when - they change, you won't need to restart the application server to - see changes you make to templates. During development, this is - handy. If this directive had been ``false`` (or if the directive - did not exist), you would need to restart the application server - for each template change. For production applications, you should - set your project's ``pyramid.reload_templates`` to ``false`` to increase - the speed at which templates may be rendered. - .. index:: single: static directory -- cgit v1.2.3 From 5276ce567b1c04e3d4cadcfb7f41b135296b1d39 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 09:55:07 -0500 Subject: Docs: project.rst: Move note that tempates get values from dictionaries down a paragraph. --- 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 622f40d69..fc1d473ac 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -898,13 +898,13 @@ This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` class representing the browser's request to our server. -.. note:: Dictionaries provide values to :term:`template`\s. - This view is configured to invoke a :term:`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer substitutes into the template when generating HTML. The renderer then returns the HTML in a :term:`response`. +.. note:: Dictionaries provide values to :term:`template`\s. + See :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. -- cgit v1.2.3 From daefb5f5009166ac9fbc3ba7fb6498d093620eec Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 10:12:14 -0500 Subject: Doc: introduction.rst: Broaden debug toolbar feature description to include other interactive development features. --- docs/narr/introduction.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 032f4be6b..64cce407a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -176,8 +176,13 @@ static file server in production without changing any code. Example: :ref:`static_assets_section`. -Debug Toolbar -~~~~~~~~~~~~~ +Fully Interactive Development +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When developing a Pyramid application a variety of interactive features are +available. Pyramid will automatically utilize changed templates when +rendering pages and automatically restart the application to incorporate +changed python code. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 6461f60320106b5114bb7f226959c7d7f2995ec2 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 11:26:22 -0500 Subject: Docs: introduction.rst: Improve wording. --- docs/narr/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 64cce407a..816199038 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -179,10 +179,10 @@ Example: :ref:`static_assets_section`. Fully Interactive Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When developing a Pyramid application a variety of interactive features are -available. Pyramid will automatically utilize changed templates when -rendering pages and automatically restart the application to incorporate -changed python code. +When developing a Pyramid application a variety of interactive +features are available. Pyramid can automatically utilize changed +templates when rendering pages and automatically restart the +application to incorporate changed python code. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 70b05dfaea547fea328a7054acd921f02be34a87 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 16:06:15 -0500 Subject: Docs: renders.rst: Use punctuation to make sentence simpler. --- docs/narr/renderers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b86f7298b..49f834ecb 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -57,7 +57,7 @@ values from Python dictionaries so, in practice, view callables which use renderers return Python dictionaries. View callables can :ref:`explicitly call -` renderers but, typically, view +` renderers; but typically view configuration declares the renderer used to render a view callable's results. This is done with the ``renderer`` attribute. For example, this call to :meth:`~pyramid.config.Configurator.add_view` associates -- cgit v1.2.3 From 77497acef17d5e5996ac231bf8ac9b679b291316 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 16:10:18 -0500 Subject: Docs: renders.rst: Break sentence into two to simplify. --- docs/narr/renderers.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 49f834ecb..b542e42a2 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -57,11 +57,12 @@ values from Python dictionaries so, in practice, view callables which use renderers return Python dictionaries. View callables can :ref:`explicitly call -` renderers; but typically view -configuration declares the renderer used to render a view callable's -results. This is done with the ``renderer`` attribute. For example, -this call to :meth:`~pyramid.config.Configurator.add_view` associates -the ``json`` renderer with a view callable: +` renderers, but they typically +don't. Instead view configuration declares the renderer used to +render a view callable's results. This is done with the ``renderer`` +attribute. For example, this call to +:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` +renderer with a view callable: .. code-block:: python -- cgit v1.2.3 From 0681d5798574d5f3ed644bf56086208c8571e0b9 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 16:12:27 -0500 Subject: Docs: renders.rst: Make sentences short per IRC chat with committers. --- docs/narr/renderers.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index b542e42a2..7c25386f5 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -56,13 +56,11 @@ serialization techniques. In practice, renderers obtain application data values from Python dictionaries so, in practice, view callables which use renderers return Python dictionaries. -View callables can :ref:`explicitly call -` renderers, but they typically -don't. Instead view configuration declares the renderer used to -render a view callable's results. This is done with the ``renderer`` -attribute. For example, this call to -:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` -renderer with a view callable: +View callables can :ref:`explicitly call ` +renderers. Typically view configuration declares the renderer used to render +a view callable's results. This is done with the ``renderer`` attribute. +For example, this call to :meth:`~pyramid.config.Configurator.add_view` +associates the ``json`` renderer with a view callable: .. code-block:: python -- cgit v1.2.3 From a26d09f291bdf4f9c7853b1dbfc9643a678a7b94 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 16:29:31 -0500 Subject: Docs: renders.rst: Make sentences that everybody's happy with. --- docs/narr/renderers.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 7c25386f5..740c81555 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -57,10 +57,11 @@ values from Python dictionaries so, in practice, view callables which use renderers return Python dictionaries. View callables can :ref:`explicitly call ` -renderers. Typically view configuration declares the renderer used to render -a view callable's results. This is done with the ``renderer`` attribute. -For example, this call to :meth:`~pyramid.config.Configurator.add_view` -associates the ``json`` renderer with a view callable: +renderers, but typically don't. Instead view configuration declares the +renderer used to render a view callable's results. This is done with the +``renderer`` attribute. For example, this call to +:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` +renderer with a view callable: .. code-block:: python -- cgit v1.2.3 From 56170f30f6cd1d4268d9e5b0cd24a75c645ab0ca Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 21:00:26 -0500 Subject: Docs: project.rst: Reword template reload note per Steve Piercy's suggestions. Take care to retain the thought that the defaults setup by the scaffold cause automatic template reload. This patch should be applied before the docs_dict_note branch. --- docs/narr/project.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9451f41b1..0de46c806 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -886,15 +886,16 @@ returns the HTML in a :term:`response`. See :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. -.. note:: Because our ``development.ini`` has a ``pyramid.reload_templates = - true`` directive indicating that templates should be reloaded when - they change, you won't need to restart the application server to - see changes you make to templates. During development, this is - handy. If this directive had been ``false`` (or if the directive - did not exist), you would need to restart the application server - for each template change. For production applications, you should - set your project's ``pyramid.reload_templates`` to ``false`` to increase - the speed at which templates may be rendered. +.. note:: ``development.ini`` has a setting that controls how templates are + reloaded: ``pyramid.reload_templates``. + + - A setting of ``True`` (as in the scaffold ``development.ini``) + automatically reloads changed templates without a server restart. This + is convenient while developing but slows template rendering speed. + + - A setting of ``False`` (the default) requires a server restart to + integrate template changes. Production applications should set + ``pyramid.reload_templates = False``. .. index:: single: static directory -- cgit v1.2.3 From 8e1e6914945a5a3d05f49f0e32b7152182b23767 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 22:20:26 -0500 Subject: Docs: introduction.rst: Note that printf() works. --- docs/narr/introduction.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 9ec26f276..b60934ebb 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -182,7 +182,8 @@ Fully Interactive Development When developing a Pyramid application a variety of interactive features are available. Pyramid can automatically utilize changed templates when rendering pages and automatically restart the -application to incorporate changed python code. +application to incorporate changed python code. Plain old ``printf()`` +calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 5ded35a5d057eb6188d6f80c47593ec934833d47 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 7 Oct 2013 21:32:14 -0700 Subject: - straighten out difference between content and its presentation, re: admonitions of note, seealse, sidebar --- docs/narr/project.rst | 79 +++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 46 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index b4397c09b..fcce9fac4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -146,7 +146,7 @@ puts his projects in ``C:\projects``. .. warning:: - You’ll need to avoid using ``pcreate`` to create a project with the same + You'll need to avoid using ``pcreate`` to create a project with the same name as a Python standard library component. In particular, this means you should avoid using the names ``site`` or ``test``, both of which conflict with Python standard library packages. You should also avoid @@ -210,12 +210,6 @@ Python interpreter from the :term:`virtualenv` you created during :ref:`installing_chapter` (the ``python`` command that lives in the ``bin`` directory of your virtualenv). -.. sidebar:: Verbose Testing - - The ``-q`` option is passed to the ``setup.py test`` command to limit the - output to a stream of dots. If you don't pass ``-q``, you'll see more - verbose test result output (which normally isn't very useful). - On UNIX: .. code-block:: text @@ -253,6 +247,12 @@ The tests themselves are found in the ``tests.py`` module in your ``pcreate`` generated project. Within a project generated by the ``starter`` scaffold, a single sample test exists. +.. note:: + + The ``-q`` option is passed to the ``setup.py test`` command to limit the + output to a stream of dots. If you don't pass ``-q``, you'll see more + verbose test result output (which normally isn't very useful). + .. index:: single: running an application single: pserve @@ -684,14 +684,6 @@ use a different version control system, you may need to install a setuptools add-on such as ``setuptools-git`` or ``setuptools-hg`` for this behavior to work properly. -.. sidebar:: Python's ``setup.py`` - - ``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 `_. - .. index:: single: setup.py @@ -702,6 +694,14 @@ The ``setup.py`` file is a :term:`setuptools` setup file. It is meant to be run directly from the command line to perform a variety of functions, such as testing, packaging, and distributing your application. +.. note:: + + ``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 `_. + Our generated ``setup.py`` looks like this: .. literalinclude:: MyProject/setup.py @@ -857,26 +857,6 @@ and which returns a :term:`response`. :language: python :linenos: -.. sidebar:: Fully Interactive Development - - Because our ``development.ini`` has a ``pyramid.reload_templates = - true`` directive indicating that templates should be reloaded when - they change, you won't need to restart the application server to - see changes you make to templates. During development, this is - handy. If this directive had been ``false`` (or if the directive - did not exist), you would need to restart the application server - for each template change. For production applications, you should - set your project's ``pyramid.reload_templates`` to ``false`` to - increase template rendering speed. - - Pyramid can also dynamically reload changed Python files. For more - on this see :ref:`reloading_code` above. - - The :ref:`debug_toolbar` provides interactive access to your - application's internals and, should an exception occur, allows - interactive access to traceback execution stack frames from the - Python interpreter. - Lines 4-6 define and register a :term:`view callable` named ``my_view``. The function named ``my_view`` is decorated with a ``view_config`` decorator (which is processed by the ``config.scan()`` line in our ``__init__.py``). @@ -905,20 +885,27 @@ returns the HTML in a :term:`response`. .. note:: Dictionaries provide values to :term:`template`\s. -See :ref:`views_which_use_a_renderer` for more information about how views, -renderers, and templates relate and cooperate. - .. note:: ``development.ini`` has a setting that controls how templates are - reloaded: ``pyramid.reload_templates``. - - - A setting of ``True`` (as in the scaffold ``development.ini``) - automatically reloads changed templates without a server restart. This - is convenient while developing but slows template rendering speed. - - - A setting of ``False`` (the default) requires a server restart to - integrate template changes. Production applications should set + reloaded, ``pyramid.reload_templates``. + + - When set to ``True`` (as in the scaffold ``development.ini``) changed + templates automatically reload without a server restart. This is + convenient while developing, but slows template rendering speed. + + - When set to ``False`` (the default value), changing templates requires + a server restart to reload them. Production applications should use ``pyramid.reload_templates = False``. +.. seealso:: See also :ref:`views_which_use_a_renderer` for more information + about how views, renderers, and templates relate and cooperate. + +.. seealso:: Pyramid can also dynamically reload changed Python files. For + more on this see :ref:`reloading_code`. + +.. seealso:: The :ref:`debug_toolbar` provides interactive access to your + application's internals and, should an exception occur, allows interactive + access to traceback execution stack frames from the Python interpreter. + .. index:: single: static directory -- cgit v1.2.3 From d84407421d1830ed726bcc280b3de112aca701e7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 7 Oct 2013 21:40:10 -0700 Subject: wrap to 79 --- docs/narr/introduction.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b60934ebb..ece720a97 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -179,11 +179,11 @@ Example: :ref:`static_assets_section`. Fully Interactive Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When developing a Pyramid application a variety of interactive -features are available. Pyramid can automatically utilize changed -templates when rendering pages and automatically restart the -application to incorporate changed python code. Plain old ``printf()`` -calls used for debugging can display to a console. +When developing a Pyramid application, several interactive features are +available. Pyramid can automatically utilize changed templates when rendering +pages and automatically restart the application to incorporate changed python +code. Plain old ``printf()`` calls used for debugging can display to a +console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and @@ -790,7 +790,7 @@ automate some of the tedium away: for method in ('GET', 'POST', 'HEAD'): view = getattr(module, 'xhr_%s_view' % method, None) if view is not None: - config.add_view(view, route_name='xhr_route', xhr=True, + config.add_view(view, route_name='xhr_route', xhr=True, permission='view', request_method=method) config = Configurator() -- cgit v1.2.3 From 716bdf37573ee8ef295ac1d01a1e8ff96c4c0f43 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 7 Oct 2013 21:55:30 -0700 Subject: - use clearer subject --- docs/narr/project.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index fcce9fac4..8b7c24725 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -984,9 +984,9 @@ named ``views`` instead of within a single ``views.py`` file, you might: can be empty. This just tells Python that the ``views`` directory is a *package*.) -- *Move* the existing ``views.py`` file to a file inside the new ``views`` - directory named, say, ``blog.py``. Because the ``templates`` directory - remains in the ``myproject`` package, the template :term:`asset +- *Move* the content from the existing ``views.py`` file to a file inside the + new ``views`` directory named, say, ``blog.py``. Because the ``templates`` + directory remains in the ``myproject`` package, the template :term:`asset specification` values in ``blog.py`` must now be fully qualified with the project's package name (``myproject:templates/blog.pt``). -- cgit v1.2.3 From eb3b27df0a35088f631680d7f467680662f17bac Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 8 Oct 2013 06:17:13 -0500 Subject: Docs: project.rst: Printf()s can be used for debugging. Output goes to the server console. The main point of the second sentence is to setup the reader with mental context for the 3rd sentence, so that the 3rd sentence sinks in. Likewise, the parenthetical in the second sentence about server startup messages gives the reader some clue as to what the rest of the sentence it talking about. I suspect that some readers won't know what a console is, and the rest will be confused by a server run on a console. --- docs/narr/project.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 8b7c24725..a454573f0 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -259,6 +259,8 @@ single sample test exists. single: reload single: startup +.. _running_the_project_application: + Running The Project Application ------------------------------- @@ -600,6 +602,8 @@ 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. +.. _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 @@ -885,6 +889,14 @@ returns the HTML in a :term:`response`. .. note:: Dictionaries provide values to :term:`template`\s. +.. note:: When the application is run with the scaffold's :ref:`default + development.ini ` configuration :ref:`logging is setup + ` to aid debugging. Should an exception be raised, + uncaught tracebacks are displayed, after the startup messages, on :ref:`the + console running the server `. + Conveniently, ``printf()``\s inserted into the application for debugging + also send output to this console. + .. note:: ``development.ini`` has a setting that controls how templates are reloaded, ``pyramid.reload_templates``. -- cgit v1.2.3 From fd99b0e53835dd7463986c4d705e8de06be7dbe6 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 8 Oct 2013 09:16:10 -0500 Subject: Docs: project.rst: Oops, print(), not printf(). --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index a454573f0..9a15649d7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -894,7 +894,7 @@ returns the HTML in a :term:`response`. ` to aid debugging. Should an exception be raised, uncaught tracebacks are displayed, after the startup messages, on :ref:`the console running the server `. - Conveniently, ``printf()``\s inserted into the application for debugging + Conveniently, ``print()``\s inserted into the application for debugging also send output to this console. .. note:: ``development.ini`` has a setting that controls how templates are -- cgit v1.2.3 From 2004173e4f1614b8eb9cc3534ec3117c736ff009 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 8 Oct 2013 09:37:39 -0500 Subject: Docs: introduction.rst: Beaker -> Redis. --- docs/narr/introduction.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index ece720a97..4e705b8b1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -418,12 +418,12 @@ Sessions Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-party Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. +Pyramid also allows you to plug in your own sessioning system by creating some +code that adheres to a documented interface. Currently there is a binding +package for the third-party Redis sessioning system that does exactly this. +But if you have a specialized need (perhaps you want to store your session data +in MongoDB), you can. You can even switch between implementations without +changing your application code. Example: :ref:`sessions_chapter`. -- cgit v1.2.3 From 4bc489d00bcb6013db1e9da00c3c16809eeb90fc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2013 11:17:18 -0700 Subject: print() not printf() --- docs/narr/introduction.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index ece720a97..bb2d85e94 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -180,10 +180,9 @@ Fully Interactive Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When developing a Pyramid application, several interactive features are -available. Pyramid can automatically utilize changed templates when rendering +available. Pyramid can automatically utilize changed templates when rendering pages and automatically restart the application to incorporate changed python -code. Plain old ``printf()`` calls used for debugging can display to a -console. +code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 6db4eb3a5fe625918c52b40ed669f1b55343abf9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 14 Oct 2013 12:42:17 +0200 Subject: add note about custom args to python when using command-line scripts --- docs/narr/commandline.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 58b9bdd21..0984b4daf 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -474,6 +474,17 @@ input 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 +------------------------------------------------------------ + +.. versionadded:: 1.5 + +Each of Pyramid's console scripts (``pserve``, ``pviews``, etc) can be run +directly using ``python -m``, allowing custom arguments to be sent to the +python interpreter at runtime. For example:: + + python -3 -m pyramid.scripts.pserve development.ini + Showing All Installed Distributions and their Versions ------------------------------------------------------ -- cgit v1.2.3 From 1034327081839902e691236f60b2a85f74bbc4e3 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Oct 2013 16:29:32 -0500 Subject: update old ptweens output --- docs/narr/commandline.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 58b9bdd21..a04b38ae3 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -387,12 +387,12 @@ explicit tweens defined in its ``development.ini`` file: Implicit Tween Chain (not used) - Position Name Alias - -------- ---- ----- - - - INGRESS - 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory pdbt - 1 pyramid.tweens.excview_tween_factory excview - - - MAIN + Position Name + -------- ---- + - INGRESS + 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory + 1 pyramid.tweens.excview_tween_factory + - MAIN Here's the application configuration section of the ``development.ini`` used by the above ``ptweens`` command which reports that the explicit tween chain -- cgit v1.2.3 From 3acee31f86bcde8abbb4e63715afc5ca67976eaf Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 17 Oct 2013 13:32:49 -0500 Subject: fix documentation for csrf checking --- docs/narr/sessions.rst | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 649d22bd2..f33bc6132 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -363,25 +363,27 @@ 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. -Using the ``session.check_csrf_token`` Method -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Checking CSRF Tokens Manually +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In request handling code, you can check the presence and validity of a CSRF -token with ``session.check_csrf_token(request)``. If the token is valid, -it will return True, otherwise it will raise ``HTTPBadRequest``. +token with :func:`pyramid.session.check_csrf_token(request)``. If the token is +valid, it will return ``True``, otherwise it will raise ``HTTPBadRequest``. +Optionally, you can specify ``raises=False`` to have the check return ``False`` +instead of raising an exception. By default, it checks for a GET or POST parameter named ``csrf_token`` or a header named ``X-CSRF-Token``. .. code-block:: python - def myview(request): - session = request.session + from pyramid.session import check_csrf_token + def myview(request): # Require CSRF Token - session.check_csrf_token(request): + check_csrf_token(request) - ... + # ... .. index:: single: session.new_csrf_token -- cgit v1.2.3 From 8df7a71d99bbeb7819e8a2752012d51202669aa6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Oct 2013 01:30:58 -0500 Subject: update the docs --- docs/narr/sessions.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 358977089..1d914f9ea 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -43,24 +43,23 @@ limitations: It is digitally signed, however, and thus its data cannot easily be tampered with. -You can configure this session factory in your :app:`Pyramid` -application by using the ``session_factory`` argument to the -:class:`~pyramid.config.Configurator` class: +You can configure this session factory in your :app:`Pyramid` application +by using the :meth:`pyramid.config.Configurator.set_session_factory`` method. .. code-block:: python :linenos: - from pyramid.session import UnencryptedCookieSessionFactoryConfig - my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') - + from pyramid.session import SignedCookieSessionFactory + my_session_factory = SignedCookieSessionFactory('itsaseekreet') + from pyramid.config import Configurator - config = Configurator(session_factory = my_session_factory) + config = Configurator() + config.set_session_factory(my_session_factory) .. warning:: - Note the very long, very explicit name for - ``UnencryptedCookieSessionFactoryConfig``. It's trying to tell you that - this implementation is, by default, *unencrypted*. You should not use it + By default the :func:`~pyramid.session.SignedCookieSessionFactory` + implementation is *unencrypted*. You should not use it when you keep sensitive information in the session object, as the information can be easily read by both users of your application and third parties who have access to your users' network traffic. And if you use this -- cgit v1.2.3 From 777112d521e337fefc2e0c217add7ac283d087b3 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 19 Oct 2013 03:48:01 -0500 Subject: link to the public renderer interfaces --- docs/narr/renderers.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 740c81555..4f8c4bf77 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -480,8 +480,11 @@ Adding a New Renderer You may add a new renderer by creating and registering a :term:`renderer factory`. -A renderer factory implementation is typically a class with the -following interface: +A renderer factory implementation should conform to the +:class:`pyramid.interfaces.IRendererFactory` interface. It should be capable +of creating an object that conforms to the +:class:`pyramid.interfaces.IRenderer` interface. A typical class that follows +this setup is as follows: .. code-block:: python :linenos: -- cgit v1.2.3 From e521f14cc4d986c2ad400abff3d6cb7ff784b775 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 19 Oct 2013 15:57:33 -0400 Subject: add admonishment against secret sharing --- docs/narr/security.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 6517fedf8..9884bb1dc 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -669,3 +669,31 @@ following interface: After you do so, you can pass an instance of such a class into the :class:`~pyramid.config.Configurator.set_authorization_policy` method at configuration time to use it. + +.. _admonishment_against_secret_sharing: + +Admomishment Against Secret-Sharing +----------------------------------- + +A "secret" is required by various components of Pyramid. For example, the +:term:`authentication policy` below uses a secret value ``seekrit``:: + + authn_policy = AuthTktAuthenticationPolicy('seekrit', hashalg='sha512') + +A :term:`session factory` also requires a secret:: + + my_session_factory = SignedCookieSessionFactory('itsaseekreet') + +It is tempting to use the same secret for multiple Pyramid subsystems. For +example, you might be tempted to use the value ``seekrit`` as the secret for +both the authentication policy and the session factory defined above. This is +a bad idea, because in both cases, these secrets are used to sign the payload +of the data. + +If you use the same secret for two different parts of your application for +signing purposes, it may allow an attacker to get his chosen plaintext signed, +which would allow the attacker to control the content of the payload. Re-using +a secret across two different subsystems might drop the security of signing to +zero. Keys should not be re-used across different contexts where an attacker +has the possibility of providing a chosen plaintext. + -- cgit v1.2.3 From 94360dffe85332733f35f2fb3ab32de3fedd787e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 19 Oct 2013 16:00:40 -0400 Subject: mon --- docs/narr/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 9884bb1dc..e85ed823a 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -672,7 +672,7 @@ configuration time to use it. .. _admonishment_against_secret_sharing: -Admomishment Against Secret-Sharing +Admonishment Against Secret-Sharing ----------------------------------- A "secret" is required by various components of Pyramid. For example, the -- cgit v1.2.3 From 3c2f95e8049bbd45b144d454daa68005361828b2 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Thu, 24 Oct 2013 23:52:42 +0100 Subject: Security APIs on pyramid.request.Request The pyramid.security Authorization API function has_permission is made available on the request. The pyramid.security Authentication API functions are now available as properties (unauthenticated_userid, authenticated_userid, effective_principals) and methods (remember_userid, forget_userid) on pyramid.request.Request. Backwards compatibility: For each of the APIs moved to request method or property, the original API in the pyramid.security module proxies to the request. Reworked tests to check module level b/c wrappers call through to mixins for each API. Tests that check no reg on request now do the right thing. Use a response callback to set the request headers for forget_userid and remember_userid. Update docs. Attempt to improve a documentation section referencing the pyramid.security.has_permission function in docs/narr/resources.rst Ensures backwards compatiblity for `pyramid.security.forget` and `pyramid.security.remember`. --- docs/narr/resources.rst | 12 ++++++------ docs/narr/security.rst | 4 ++-- docs/narr/testing.rst | 2 +- docs/narr/viewconfig.rst | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index b1bb611e5..34d75f2cc 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -201,7 +201,7 @@ location-aware resources. These APIs include (but are not limited to) :func:`~pyramid.traversal.resource_path`, :func:`~pyramid.traversal.resource_path_tuple`, or :func:`~pyramid.traversal.traverse`, :func:`~pyramid.traversal.virtual_root`, -and (usually) :func:`~pyramid.security.has_permission` and +and (usually) :meth:`~pyramid.request.Request.has_permission` and :func:`~pyramid.security.principals_allowed_by_permission`. In general, since so much :app:`Pyramid` infrastructure depends on @@ -695,10 +695,10 @@ The APIs provided by :ref:`location_module` are used against resources. These can be used to walk down a resource tree, or conveniently locate one resource "inside" another. -Some APIs in :ref:`security_module` accept a resource object as a parameter. -For example, the :func:`~pyramid.security.has_permission` API accepts a +Some APIs on the :class:`pyramid.request.Request` accept a resource object as a parameter. +For example, the :meth:`~pyramid.request.Request.has_permission` API accepts a resource object as one of its arguments; the ACL is obtained from this -resource or one of its ancestors. Other APIs in the :mod:`pyramid.security` -module also accept :term:`context` as an argument, and a context is always a -resource. +resource or one of its ancestors. Other security related APIs on the +:class:`pyramid.request.Request` class also accept :term:`context` as an argument, +and a context is always a resource. diff --git a/docs/narr/security.rst b/docs/narr/security.rst index e85ed823a..9e6fb6c82 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -550,7 +550,7 @@ also contain security debugging information in its body. Debugging Imperative Authorization Failures ------------------------------------------- -The :func:`pyramid.security.has_permission` API is used to check +The :meth:`pyramid.request.Request.has_permission` API is used to check security within view functions imperatively. It returns instances of objects that are effectively booleans. But these objects are not raw ``True`` or ``False`` objects, and have information attached to them @@ -563,7 +563,7 @@ one of :data:`pyramid.security.ACLAllowed`, ``msg`` attribute, which is a string indicating why the permission was denied or allowed. Introspecting this information in the debugger or via print statements when a call to -:func:`~pyramid.security.has_permission` fails is often useful. +:meth:`~pyramid.request.Request.has_permission` fails is often useful. .. index:: single: authentication policy (creating) diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 88d6904c7..3f5d5ae6c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -229,7 +229,7 @@ function. otherwise it would fail when run normally. Without doing anything special during a unit test, the call to -:func:`~pyramid.security.has_permission` in this view function will always +:meth:`~pyramid.request.Request.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts normally, it will populate a :term:`application registry` using :term:`configuration declaration` calls made against a :term:`Configurator`. But if this diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 7c76116f7..e5a2c1ade 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -435,7 +435,7 @@ configured view. If specified, this value should be a :term:`principal` identifier or a sequence of principal identifiers. If the - :func:`pyramid.security.effective_principals` method indicates that every + :meth:`pyramid.request.Request.effective_principals` method indicates that every principal named in the argument list is present in the current request, this predicate will return True; otherwise it will return False. For example: ``effective_principals=pyramid.security.Authenticated`` or -- cgit v1.2.3 From a91c19837f5ce579ce2a5bf68ddee30cfaebe034 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 30 Oct 2013 20:19:23 -0400 Subject: note deprecation --- docs/narr/threadlocals.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst index a90ee4905..afe56de3e 100644 --- a/docs/narr/threadlocals.rst +++ b/docs/narr/threadlocals.rst @@ -29,17 +29,16 @@ of a thread local or a global is usually just a way to avoid passing some value around between functions, which is itself usually a very bad idea, at least if code readability counts as an important concern. -For historical reasons, however, thread local variables are indeed -consulted by various :app:`Pyramid` API functions. For example, -the implementation of the :mod:`pyramid.security` function named -:func:`~pyramid.security.authenticated_userid` retrieves the thread -local :term:`application registry` as a matter of course to find an +For historical reasons, however, thread local variables are indeed consulted by +various :app:`Pyramid` API functions. For example, the implementation of the +:mod:`pyramid.security` function named +:func:`~pyramid.security.authenticated_userid` (deprecated as of 1.5) retrieves +the thread local :term:`application registry` as a matter of course to find an :term:`authentication policy`. It uses the -:func:`pyramid.threadlocal.get_current_registry` function to -retrieve the application registry, from which it looks up the -authentication policy; it then uses the authentication policy to -retrieve the authenticated user id. This is how :app:`Pyramid` -allows arbitrary authentication policies to be "plugged in". +:func:`pyramid.threadlocal.get_current_registry` function to retrieve the +application registry, from which it looks up the authentication policy; it then +uses the authentication policy to retrieve the authenticated user id. This is +how :app:`Pyramid` allows arbitrary authentication policies to be "plugged in". When they need to do so, :app:`Pyramid` internals use two API functions to retrieve the :term:`request` and :term:`application -- cgit v1.2.3 From 3bd1fa5dd792d639615e5125b73caef8c65a0a30 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 30 Oct 2013 20:28:53 -0400 Subject: new api --- docs/narr/testing.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 3f5d5ae6c..5a5bf8fad 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -214,11 +214,10 @@ function. .. code-block:: python :linenos: - from pyramid.security import has_permission from pyramid.httpexceptions import HTTPForbidden def view_fn(request): - if not has_permission('edit', request.context, request): + if request.has_permission('edit'): raise HTTPForbidden return {'greeting':'hello'} @@ -229,15 +228,16 @@ function. otherwise it would fail when run normally. Without doing anything special during a unit test, the call to -:meth:`~pyramid.request.Request.has_permission` in this view function will always -return a ``True`` value. When a :app:`Pyramid` application starts normally, -it will populate a :term:`application registry` using :term:`configuration -declaration` calls made against a :term:`Configurator`. But if this -application registry is not created and populated (e.g. by initializing the -configurator with an authorization policy), like when you invoke application -code via a unit test, :app:`Pyramid` API functions will tend to either fail -or return default results. So how do you test the branch of the code in this -view function that raises :exc:`~pyramid.httpexceptions.HTTPForbidden`? +:meth:`~pyramid.request.Request.has_permission` in this view function will +always return a ``True`` value. When a :app:`Pyramid` application starts +normally, it will populate a :term:`application registry` using +:term:`configuration declaration` calls made against a :term:`Configurator`. +But if this application registry is not created and populated (e.g. by +initializing the configurator with an authorization policy), like when you +invoke application code via a unit test, :app:`Pyramid` API functions will tend +to either fail or return default results. So how do you test the branch of the +code in this view function that raises +:exc:`~pyramid.httpexceptions.HTTPForbidden`? The testing API provided by :app:`Pyramid` allows you to simulate various application registry registrations for use under a unit testing framework @@ -287,12 +287,12 @@ Its third line registers a "dummy" "non-permissive" authorization policy using the :meth:`~pyramid.config.Configurator.testing_securitypolicy` method, which is a special helper method for unit testing. -We then create a :class:`pyramid.testing.DummyRequest` object which simulates -a WebOb request object API. A :class:`pyramid.testing.DummyRequest` is a -request object that requires less setup than a "real" :app:`Pyramid` request. -We call the function being tested with the manufactured request. When the -function is called, :func:`pyramid.security.has_permission` will call the -"dummy" authentication policy we've registered through +We then create a :class:`pyramid.testing.DummyRequest` object which simulates a +WebOb request object API. A :class:`pyramid.testing.DummyRequest` is a request +object that requires less setup than a "real" :app:`Pyramid` request. We call +the function being tested with the manufactured request. When the function is +called, :meth:`pyramid.request.Request.has_permission` will call the "dummy" +authentication policy we've registered through :meth:`~pyramid.config.Configurator.testing_securitypolicy`, which denies access. We check that the view function raises a :exc:`~pyramid.httpexceptions.HTTPForbidden` error. -- cgit v1.2.3 From daa0964624bb4d2818cad62351418c09a7326b5a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 11 Nov 2013 23:23:58 -0600 Subject: easiest commit ever --- docs/narr/paste.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index 3427b6d53..f1fb70869 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -87,7 +87,7 @@ configuration object and *returns* an instance of our application. .. _defaults_section_of_pastedeploy_file: -``[DEFAULTS]`` Section of a PasteDeploy ``.ini`` File +``[DEFAULT]`` Section of a PasteDeploy ``.ini`` File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can add a ``[DEFAULT]`` section to your PasteDeploy ``.ini`` file. Such -- cgit v1.2.3 From 04e6bf670e3968864fd858e3d3fa310d601a2420 Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sat, 16 Nov 2013 00:31:48 +0200 Subject: Enhanced the narrative documentation for tweens. --- docs/narr/hooks.rst | 87 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 19 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 0c450fad7..b26a46272 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -963,8 +963,8 @@ For full details, please read the `Venusian documentation .. _registering_tweens: -Registering "Tweens" --------------------- +Registering Tweens +------------------ .. versionadded:: 1.2 Tweens @@ -976,23 +976,76 @@ feature that may be used by Pyramid framework extensions, to provide, for example, Pyramid-specific view timing support bookkeeping code that examines exceptions before they are returned to the upstream WSGI application. Tweens behave a bit like :term:`WSGI` :term:`middleware` but they have the benefit of -running in a context in which they have access to the Pyramid -:term:`application registry` as well as the Pyramid rendering machinery. +running in a context in which they have access to the Pyramid :term:`request`, +:term:`response` and :term:`application registry` as well as the Pyramid +rendering machinery. -Creating a Tween Factory -~~~~~~~~~~~~~~~~~~~~~~~~ +Creating a Tween +~~~~~~~~~~~~~~~~ -To make use of tweens, you must construct a "tween factory". A tween factory +To create a tween, you must write a "tween factory". A tween factory must be a globally importable callable which accepts two arguments: ``handler`` and ``registry``. ``handler`` will be the either the main Pyramid request handling function or another tween. ``registry`` will be the Pyramid :term:`application registry` represented by this Configurator. A -tween factory must return a tween when it is called. +tween factory must return the tween (a callable object) when it is called. -A tween is a callable which accepts a :term:`request` object and returns -a :term:`response` object. +A tween is called with a single argument, ``request``, which is the +:term:`request` created by Pyramid's router when it receives a WSGI request. +A tween should return a :term:`response`, usually the one generated by the +downstream Pyramid application. -Here's an example of a tween factory: +You can write the tween factory as a simple closure-returning function: + +.. code-block:: python + :linenos: + + def simple_tween_factory(handler, registry): + # one-time configuration code goes here + + def simple_tween(request): + # code to be executed for each request before + # the actual application code goes here + + response = handler(request) + + # code to be executed for each request after + # the actual application code goes here + + return response + + return handler + +Alternatively, the tween factory can be a class with the ``__call__`` magic method: + +.. code-block:: python + :linenos: + + class simple_tween_factory(object): + def __init__(handler, registry): + self.handler = handler + self.registry = registry + + # one-time configuration code goes here + + def __call__(self, request): + # code to be executed for each request before + # the actual application code goes here + + response = self.handler(request) + + # code to be executed for each request after + # the actual application code goes here + + return response + +The closure style performs slightly better and enables you to conditionally +omit the tween from the request processing pipeline (see the following timing +tween example), whereas the class style makes it easier to have shared mutable +state, and it allows subclassing. + +Here's a complete example of a tween that logs the time spent processing each +request: .. code-block:: python :linenos: @@ -1022,12 +1075,6 @@ Here's an example of a tween factory: # handler return handler -If you remember, a tween is an object which accepts a :term:`request` object -and which returns a :term:`response` argument. The ``request`` argument to a -tween will be the request created by Pyramid's router when it receives a WSGI -request. The response object will be generated by the downstream Pyramid -application and it should be returned by the tween. - In the above example, the tween factory defines a ``timing_tween`` tween and returns it if ``asbool(registry.settings.get('do_timing'))`` is true. It otherwise simply returns the handler it was given. The ``registry.settings`` @@ -1132,8 +1179,10 @@ Allowable values for ``under`` or ``over`` (or both) are: fallbacks if the desired tween is not included, as well as compatibility with multiple other tweens. -Effectively, ``under`` means "closer to the main Pyramid application than", -``over`` means "closer to the request ingress than". +Effectively, ``over`` means "closer to the request ingress than" and +``under`` means "closer to the main Pyramid application than". +You can think of an onion with outer layers over the inner layers, +the application being under all the layers at the center. For example, the following call to :meth:`~pyramid.config.Configurator.add_tween` will attempt to place the -- cgit v1.2.3 From a0ef135f2ad6e4425eec7ffcc0839b605347c346 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Nov 2013 05:06:38 -0500 Subject: 80 chars --- docs/narr/hooks.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b26a46272..84dd2143c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1016,7 +1016,8 @@ You can write the tween factory as a simple closure-returning function: return handler -Alternatively, the tween factory can be a class with the ``__call__`` magic method: +Alternatively, the tween factory can be a class with the ``__call__`` magic +method: .. code-block:: python :linenos: -- cgit v1.2.3 From 392a6c7df93b67d6889680133fda0f744970d61f Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 00:11:37 +0200 Subject: Removed extra indentation from some examples (:linenos: should be indented with the same indentation as the rest of the code block) --- docs/narr/events.rst | 6 +++--- docs/narr/extending.rst | 2 +- docs/narr/hooks.rst | 20 ++++++++++---------- docs/narr/hybrid.rst | 2 +- docs/narr/i18n.rst | 8 ++++---- docs/narr/introduction.rst | 6 +++--- docs/narr/introspector.rst | 4 ++-- docs/narr/logging.rst | 2 +- docs/narr/resources.rst | 2 +- docs/narr/scaffolding.rst | 2 +- docs/narr/upgrading.rst | 4 ++-- docs/narr/urldispatch.rst | 10 +++++----- docs/narr/vhosting.rst | 4 ++-- docs/narr/views.rst | 2 +- 14 files changed, 37 insertions(+), 37 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 2accb3dbe..50484761d 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -172,7 +172,7 @@ track of the information that subscribers will need. Here are some example custom event classes: .. code-block:: python - :linenos: + :linenos: class DocCreated(object): def __init__(self, doc, request): @@ -196,7 +196,7 @@ also use custom events with :ref:`subscriber predicates event with a decorator: .. code-block:: python - :linenos: + :linenos: from pyramid.events import subscriber from .events import DocCreated @@ -215,7 +215,7 @@ To fire your custom events use the accessed as ``request.registry.notify``. For example: .. code-block:: python - :linenos: + :linenos: from .events import DocCreated diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index a60a49fea..8462a9da7 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -234,7 +234,7 @@ For example, if the original application has the following ``configure_views`` configuration method: .. code-block:: python - :linenos: + :linenos: def configure_views(config): config.add_view('theoriginalapp.views.theview', name='theview') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 84dd2143c..14009a094 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -363,7 +363,7 @@ and modify the set of :term:`renderer globals` before they are passed to a that can be used for this purpose. For example: .. code-block:: python - :linenos: + :linenos: from pyramid.events import subscriber from pyramid.events import BeforeRender @@ -998,7 +998,7 @@ downstream Pyramid application. You can write the tween factory as a simple closure-returning function: .. code-block:: python - :linenos: + :linenos: def simple_tween_factory(handler, registry): # one-time configuration code goes here @@ -1020,7 +1020,7 @@ Alternatively, the tween factory can be a class with the ``__call__`` magic method: .. code-block:: python - :linenos: + :linenos: class simple_tween_factory(object): def __init__(handler, registry): @@ -1049,7 +1049,7 @@ Here's a complete example of a tween that logs the time spent processing each request: .. code-block:: python - :linenos: + :linenos: # in a module named myapp.tweens @@ -1101,7 +1101,7 @@ Here's an example of registering a tween factory as an "implicit" tween in a Pyramid application: .. code-block:: python - :linenos: + :linenos: from pyramid.config import Configurator config = Configurator() @@ -1135,7 +1135,7 @@ chain (the tween generated by the very last tween factory added) as its request handler function. For example: .. code-block:: python - :linenos: + :linenos: from pyramid.config import Configurator @@ -1379,7 +1379,7 @@ route predicate factory is most often a class with a constructor method. For example: .. code-block:: python - :linenos: + :linenos: class ContentTypePredicate(object): def __init__(self, val, config): @@ -1442,7 +1442,7 @@ with a subscriber that subscribes to the :class:`pyramid.events.NewRequest` event type. .. code-block:: python - :linenos: + :linenos: class RequestPathStartsWith(object): def __init__(self, val, config): @@ -1471,7 +1471,7 @@ previously registered ``request_path_startswith`` predicate in a call to :meth:`~pyramid.config.Configurator.add_subscriber`: .. code-block:: python - :linenos: + :linenos: # define a subscriber in your code @@ -1487,7 +1487,7 @@ Here's the same subscriber/predicate/event-type combination used via :class:`~pyramid.events.subscriber`. .. code-block:: python - :linenos: + :linenos: from pyramid.events import subscriber diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index a29ccb2ac..4a3258d35 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -63,7 +63,7 @@ An application that uses only traversal will have view configuration declarations that look like this: .. code-block:: python - :linenos: + :linenos: # config is an instance of pyramid.config.Configurator diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index b62c16ff0..c9b782c08 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -309,7 +309,7 @@ In particular, add the ``Babel`` and ``lingua`` distributions to the application's ``setup.py`` file: .. code-block:: python - :linenos: + :linenos: setup(name="mypackage", # ... @@ -370,7 +370,7 @@ file of a ``pcreate`` -generated :app:`Pyramid` application has stanzas in it that look something like the following: .. code-block:: ini - :linenos: + :linenos: [compile_catalog] directory = myproject/locale @@ -398,7 +398,7 @@ that you'd like the domain of your translations to be ``mydomain`` instead, change the ``setup.cfg`` file stanzas to look like so: .. code-block:: ini - :linenos: + :linenos: [compile_catalog] directory = myproject/locale @@ -1041,7 +1041,7 @@ if no locale can be determined. Here's an implementation of a simple locale negotiator: .. code-block:: python - :linenos: + :linenos: def my_locale_negotiator(request): locale_name = request.params.get('my_locale') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a9c5fdfbd..8acbab3a0 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -336,7 +336,7 @@ For example, instead of returning a ``Response`` object from a ``render_to_response`` call: .. code-block:: python - :linenos: + :linenos: from pyramid.renderers import render_to_response @@ -347,7 +347,7 @@ For example, instead of returning a ``Response`` object from a You can return a Python dictionary: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config @@ -827,7 +827,7 @@ Here's an example of using Pyramid's introspector from within a view callable: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config from pyramid.response import Response diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 3c0a6744f..a7bde4cf7 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -24,7 +24,7 @@ Here's an example of using Pyramid's introspector from within a view callable: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config from pyramid.response import Response @@ -100,7 +100,7 @@ its ``__getitem__``, ``get``, ``keys``, ``values``, or ``items`` methods. For example: .. code-block:: python - :linenos: + :linenos: route_intr = introspector.get('routes', 'edit_user') pattern = route_intr['pattern'] diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index b3bfb8a1e..75428d513 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -179,7 +179,7 @@ file, simply create a logger object using the ``__name__`` builtin and call methods on it. .. code-block:: python - :linenos: + :linenos: import logging log = logging.getLogger(__name__) diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 34d75f2cc..f3ff1dc4c 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -83,7 +83,7 @@ works against resource instances. Here's a sample resource tree, represented by a variable named ``root``: .. code-block:: python - :linenos: + :linenos: class Resource(dict): pass diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 534b2caf4..9952b6818 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -112,7 +112,7 @@ want to have extension scaffolds that can work across Pyramid 1.0.X, 1.1.X, defining your scaffold template: .. code-block:: python - :linenos: + :linenos: try: # pyramid 1.0.X # "pyramid.paster.paste_script..." doesn't exist past 1.0.X diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index 64343ca3e..eb3194a65 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -137,7 +137,7 @@ In the above case, it's line #3 in the ``myproj.views`` module (``from pyramid.view import static``) that is causing the problem: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config @@ -148,7 +148,7 @@ The deprecation warning tells me how to fix it, so I can change the code to do things the newer way: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 61849c3c0..96ee5758e 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -492,7 +492,7 @@ The simplest route declaration which configures a route match to *directly* result in a particular view callable being invoked: .. code-block:: python - :linenos: + :linenos: config.add_route('idea', 'site/{id}') config.add_view('mypackage.views.site_view', route_name='idea') @@ -901,7 +901,7 @@ Details of the route matching decision for a particular request to the which you started the application from. For example: .. code-block:: text - :linenos: + :linenos: $ PYRAMID_DEBUG_ROUTEMATCH=true $VENV/bin/pserve development.ini Starting server in PID 13586. @@ -1060,7 +1060,7 @@ A custom route predicate may also *modify* the ``match`` dictionary. For instance, a predicate might do some type conversion of values: .. code-block:: python - :linenos: + :linenos: def integers(*segment_names): def predicate(info, request): @@ -1086,7 +1086,7 @@ To avoid the try/except uncertainty, the route pattern can contain regular expressions specifying requirements for that marker. For instance: .. code-block:: python - :linenos: + :linenos: def integers(*segment_names): def predicate(info, request): @@ -1128,7 +1128,7 @@ name. The ``pattern`` attribute is the route pattern. An example of using the route in a set of route predicates: .. code-block:: python - :linenos: + :linenos: def twenty_ten(info, request): if info['route'].name in ('ymd', 'ym', 'y'): diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index d37518052..53f6888b3 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -109,7 +109,7 @@ An example of an Apache ``mod_proxy`` configuration that will host the is below: .. code-block:: apache - :linenos: + :linenos: NameVirtualHost *:80 @@ -130,7 +130,7 @@ For a :app:`Pyramid` application running under :term:`mod_wsgi`, the same can be achieved using ``SetEnv``: .. code-block:: apache - :linenos: + :linenos: SetEnv HTTP_X_VHM_ROOT /cms diff --git a/docs/narr/views.rst b/docs/narr/views.rst index b2dd549ce..a746eb043 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -536,7 +536,7 @@ The following types work as view callables in this style: e.g.: .. code-block:: python - :linenos: + :linenos: from pyramid.response import Response -- cgit v1.2.3 From bd897bbcfd936d36ad9877a2f00792454767b7fb Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 01:02:29 +0200 Subject: Fixed indentation issues --- docs/narr/scaffolding.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 9952b6818..f924d0d62 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -39,9 +39,9 @@ named ``__init__.py`` with something like the following: from pyramid.scaffolds import PyramidTemplate - class CoolExtensionTemplate(PyramidTemplate): - _template_dir = 'coolextension_scaffold' - summary = 'My cool extension' + class CoolExtensionTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool extension' Once this is done, within the ``scaffolds`` directory, create a template directory. Our example used a template directory named @@ -89,7 +89,7 @@ For example: [pyramid.scaffold] coolextension=coolextension.scaffolds:CoolExtensionTemplate """ - ) + ) Run your distribution's ``setup.py develop`` or ``setup.py install`` command. After that, you should be able to see your scaffolding template -- cgit v1.2.3 From fab44e1e402efbf37fc58875974e9ae42827446e Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 19:08:18 +0200 Subject: Should return the simple_tween here, not the handler. --- 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 14009a094..f2542f1d7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1014,7 +1014,7 @@ You can write the tween factory as a simple closure-returning function: return response - return handler + return simple_tween Alternatively, the tween factory can be a class with the ``__call__`` magic method: -- cgit v1.2.3 From 5431138583ee9d4382c1fe6dd0fb706ed514a4bf Mon Sep 17 00:00:00 2001 From: Matthew Wilkes Date: Tue, 10 Dec 2013 20:29:28 +0000 Subject: Use new pluralize calling convention recognised by Lingua 1.7 --- docs/narr/i18n.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index c9b782c08..5f50ca212 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -607,10 +607,8 @@ object, but the domain and mapping information attached is ignored. def aview(request): localizer = request.localizer num = 1 - translated = localizer.pluralize( - _('item_plural', default="${number} items"), - None, num, 'mydomain', mapping={'number':num} - ) + translated = localizer.pluralize('item_plural', '${number} items', + num, 'mydomain', mapping={'number':num}) The corresponding message catalog must have language plural definitions and plural alternatives set. -- cgit v1.2.3 From 3687465ab87b82b83b7ffa2f216425136d71ebec Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 30 Dec 2013 02:49:18 -0800 Subject: grammar fixes --- docs/narr/templates.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 3e19f7198..00fc21634 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -38,8 +38,8 @@ within the body of a view callable like so: from pyramid.renderers import render_to_response def sample_view(request): - return render_to_response('templates/foo.pt', - {'foo':1, 'bar':2}, + return render_to_response('templates/foo.pt', + {'foo':1, 'bar':2}, request=request) The ``sample_view`` :term:`view callable` function above returns a @@ -56,7 +56,7 @@ In this case, this is the directory containing the file that defines the ``sample_view`` function. Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive letter -prefix on Windows. The path can alternately be a +prefix on Windows. The path can alternately be an :term:`asset specification` in the form ``some.dotted.package_name:relative/path``. This makes it possible to address template assets which live in another package. For example: @@ -73,11 +73,11 @@ address template assets which live in another package. For example: An asset specification points at a file within a Python *package*. In this case, it points at a file named ``foo.pt`` within the -``templates`` directory of the ``mypackage`` package. Using a +``templates`` directory of the ``mypackage`` package. Using an asset specification instead of a relative template name is usually a good idea, because calls to :func:`~pyramid.renderers.render_to_response` using asset specifications will continue to work properly if you move the -code containing them around. +code containing them to another location. In the examples above we pass in a keyword argument named ``request`` representing the current :app:`Pyramid` request. Passing a request @@ -94,8 +94,8 @@ Every view must return a :term:`response` object, except for views which use a :term:`renderer` named via view configuration (which we'll see shortly). The :func:`pyramid.renderers.render_to_response` function is a shortcut function that actually returns a response -object. This allows the example view above to simply return the result -of its call to ``render_to_response()`` directly. +object. This allows the example view above to simply return the result +of its call to ``render_to_response()`` directly. Obviously not all APIs you might call to get response data will return a response object. For example, you might render one or more templates to @@ -111,8 +111,8 @@ as the body of the response: from pyramid.response import Response def sample_view(request): - result = render('mypackage:templates/foo.pt', - {'foo':1, 'bar':2}, + result = render('mypackage:templates/foo.pt', + {'foo':1, 'bar':2}, request=request) response = Response(result) return response @@ -194,7 +194,7 @@ of :func:`~pyramid.renderers.render` (a string): def sample_view(request): result = render('mypackage:templates/foo.pt', - {'foo':1, 'bar':2}, + {'foo':1, 'bar':2}, request=request) response = Response(result) response.content_type = 'text/plain' @@ -241,7 +241,7 @@ These values are provided to the template: The renderer name used to perform the rendering, e.g. ``mypackage:templates/foo.pt``. -``renderer_info`` +``renderer_info`` An object implementing the :class:`pyramid.interfaces.IRendererInfo` interface. Basically, an object with the following attributes: ``name``, ``package`` and ``type``. @@ -273,7 +273,7 @@ Templates Used as Renderers via Configuration An alternative to using :func:`~pyramid.renderers.render_to_response` to render templates manually in your view callable code, is to specify the template as a :term:`renderer` in your -*view configuration*. This can be done with any of the +*view configuration*. This can be done with any of the templating languages supported by :app:`Pyramid`. To use a renderer via view configuration, specify a template -- cgit v1.2.3 From 41cd98df2eea454a43af37cc2cf070a2ea275af9 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Fri, 3 Jan 2014 23:18:40 -0500 Subject: changed project image refs --- docs/narr/project-debug.png | Bin 153807 -> 106878 bytes docs/narr/project.png | Bin 128727 -> 91662 bytes 2 files changed, 0 insertions(+), 0 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project-debug.png b/docs/narr/project-debug.png index d13a91736..4f8e441ef 100644 Binary files a/docs/narr/project-debug.png and b/docs/narr/project-debug.png differ diff --git a/docs/narr/project.png b/docs/narr/project.png index fc00ec086..5d46df0dd 100644 Binary files a/docs/narr/project.png and b/docs/narr/project.png differ -- cgit v1.2.3 From 59882984b368f8e0c81411283a121359083099e0 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Fri, 3 Jan 2014 23:29:35 -0500 Subject: updated myproject docs --- docs/narr/project.rst | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index d7292d187..f1bee9efd 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -487,23 +487,24 @@ structure: .. code-block:: text MyProject/ - |-- CHANGES.txt - |-- development.ini - |-- MANIFEST.in - |-- myproject - | |-- __init__.py - | |-- static - | | |-- favicon.ico - | | |-- logo.png - | | `-- pylons.css - | |-- templates - | | `-- mytemplate.pt - | |-- tests.py - | `-- views.py - |-- production.ini - |-- README.txt - |-- setup.cfg - `-- setup.py + ├── CHANGES.txt + ├── MANIFEST.in + ├── README.txt + ├── development.ini + ├── myproject + │   ├── __init__.py + │   ├── static + │   │   ├── pyramid-16x16.png + │   │   ├── pyramid.png + │   │   ├── theme.css + │   │   └── theme.min.css + │   ├── templates + │   │   └── mytemplate.pt + │   ├── tests.py + │   └── views.py + ├── production.ini + ├── setup.cfg + └── setup.py The ``MyProject`` :term:`Project` --------------------------------- -- cgit v1.2.3 From 7bffb5889cddec7ed8eea505004c30d01513c767 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Fri, 3 Jan 2014 23:29:50 -0500 Subject: modified MyProject src --- docs/narr/MyProject/development.ini | 22 +- docs/narr/MyProject/myproject/static/favicon.ico | Bin 1406 -> 0 bytes docs/narr/MyProject/myproject/static/footerbg.png | Bin 333 -> 0 bytes docs/narr/MyProject/myproject/static/headerbg.png | Bin 203 -> 0 bytes docs/narr/MyProject/myproject/static/ie6.css | 8 - docs/narr/MyProject/myproject/static/middlebg.png | Bin 2797 -> 0 bytes docs/narr/MyProject/myproject/static/pylons.css | 372 --------------------- .../MyProject/myproject/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../MyProject/myproject/static/pyramid-small.png | Bin 7044 -> 0 bytes docs/narr/MyProject/myproject/static/pyramid.png | Bin 33055 -> 12901 bytes docs/narr/MyProject/myproject/static/theme.css | 152 +++++++++ docs/narr/MyProject/myproject/static/theme.min.css | 1 + .../MyProject/myproject/static/transparent.gif | Bin 49 -> 0 bytes .../MyProject/myproject/templates/mytemplate.pt | 132 ++++---- docs/narr/MyProject/production.ini | 16 +- docs/narr/MyProject/setup.py | 1 - 16 files changed, 245 insertions(+), 459 deletions(-) delete mode 100644 docs/narr/MyProject/myproject/static/favicon.ico delete mode 100644 docs/narr/MyProject/myproject/static/footerbg.png delete mode 100644 docs/narr/MyProject/myproject/static/headerbg.png delete mode 100644 docs/narr/MyProject/myproject/static/ie6.css delete mode 100644 docs/narr/MyProject/myproject/static/middlebg.png delete mode 100644 docs/narr/MyProject/myproject/static/pylons.css create mode 100644 docs/narr/MyProject/myproject/static/pyramid-16x16.png delete mode 100644 docs/narr/MyProject/myproject/static/pyramid-small.png create mode 100644 docs/narr/MyProject/myproject/static/theme.css create mode 100644 docs/narr/MyProject/myproject/static/theme.min.css delete mode 100644 docs/narr/MyProject/myproject/static/transparent.gif (limited to 'docs/narr') diff --git a/docs/narr/MyProject/development.ini b/docs/narr/MyProject/development.ini index 84e08c2d0..a9a26e56b 100644 --- a/docs/narr/MyProject/development.ini +++ b/docs/narr/MyProject/development.ini @@ -1,3 +1,8 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + [app:main] use = egg:MyProject @@ -6,15 +11,26 @@ 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 +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main host = 0.0.0.0 port = 6543 -# Begin logging configuration +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### [loggers] keys = root, myproject @@ -42,5 +58,3 @@ formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/docs/narr/MyProject/myproject/static/favicon.ico b/docs/narr/MyProject/myproject/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/narr/MyProject/myproject/static/favicon.ico and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/footerbg.png b/docs/narr/MyProject/myproject/static/footerbg.png deleted file mode 100644 index 1fbc873da..000000000 Binary files a/docs/narr/MyProject/myproject/static/footerbg.png and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/headerbg.png b/docs/narr/MyProject/myproject/static/headerbg.png deleted file mode 100644 index 0596f2020..000000000 Binary files a/docs/narr/MyProject/myproject/static/headerbg.png and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/ie6.css b/docs/narr/MyProject/myproject/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/narr/MyProject/myproject/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} -#wrap{display:table;height:100%} diff --git a/docs/narr/MyProject/myproject/static/middlebg.png b/docs/narr/MyProject/myproject/static/middlebg.png deleted file mode 100644 index 2369cfb7d..000000000 Binary files a/docs/narr/MyProject/myproject/static/middlebg.png and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/pylons.css b/docs/narr/MyProject/myproject/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/narr/MyProject/myproject/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -ul, menu, dir -{ - display: block; - list-style-type: disc; - margin: 1em 0; - padding-left: 40px; -} - -ol -{ - display: block; - list-style-type: decimal-leading-zero; - margin: 1em 0; - padding-left: 40px; -} - -li -{ - display: list-item; -} - -ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl -{ - margin-top: 0; - margin-bottom: 0; -} - -ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir -{ - list-style-type: circle; -} - -ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir -{ - list-style-type: square; -} - -.hidden -{ - display: none; -} - -p -{ - line-height: 1.5em; -} - -h1 -{ - font-size: 1.75em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h2 -{ - font-size: 1.5em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h3 -{ - font-size: 1.25em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h4 -{ - font-size: 1em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -html, body -{ - width: 100%; - height: 100%; -} - -body -{ - margin: 0; - padding: 0; - background-color: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 url(footerbg.png) repeat-x 0 top; - position: relative; - margin-top: -40px; - clear: both; -} - -.header, .footer -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.wrapper -{ - width: 100%; -} - -#top, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.top, .top-small, .middle, .bottom -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.top -{ - padding-top: 40px; -} - -.top-small -{ - padding-top: 10px; -} - -#middle -{ - width: 100%; - height: 100px; - background: url(middlebg.png) repeat-x; - border-top: 2px solid #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#left -{ - width: 350px; - float: left; - padding-right: 25px; -} - -#right -{ - width: 350px; - float: right; - padding-left: 25px; -} - -.align-left -{ - text-align: left; -} - -.align-right -{ - text-align: right; -} - -.align-center -{ - text-align: center; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -ul.links li -{ - list-style-type: none; - font-size: 14px; -} - -form -{ - border-style: none; -} - -fieldset -{ - border-style: none; -} - -input -{ - color: #222; - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 12px; - line-height: 16px; -} - -input[type=text], input[type=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/narr/MyProject/myproject/static/pyramid-16x16.png b/docs/narr/MyProject/myproject/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/narr/MyProject/myproject/static/pyramid-16x16.png differ diff --git a/docs/narr/MyProject/myproject/static/pyramid-small.png b/docs/narr/MyProject/myproject/static/pyramid-small.png deleted file mode 100644 index a5bc0ade7..000000000 Binary files a/docs/narr/MyProject/myproject/static/pyramid-small.png and /dev/null differ diff --git a/docs/narr/MyProject/myproject/static/pyramid.png b/docs/narr/MyProject/myproject/static/pyramid.png index 347e05549..4ab837be9 100644 Binary files a/docs/narr/MyProject/myproject/static/pyramid.png and b/docs/narr/MyProject/myproject/static/pyramid.png differ diff --git a/docs/narr/MyProject/myproject/static/theme.css b/docs/narr/MyProject/myproject/static/theme.css new file mode 100644 index 000000000..be50ad420 --- /dev/null +++ b/docs/narr/MyProject/myproject/static/theme.css @@ -0,0 +1,152 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a { + color: #ffffff; +} +.starter-template .links ul li a:hover { + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/narr/MyProject/myproject/static/theme.min.css b/docs/narr/MyProject/myproject/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/narr/MyProject/myproject/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file diff --git a/docs/narr/MyProject/myproject/static/transparent.gif b/docs/narr/MyProject/myproject/static/transparent.gif deleted file mode 100644 index 0341802e5..000000000 Binary files a/docs/narr/MyProject/myproject/static/transparent.gif and /dev/null differ diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 0fccba624..d1af4f42c 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -1,76 +1,66 @@ - - - - The Pyramid Web Framework - - - - - - - - - - -
    -
    -
    -
    pyramid
    -
    -
    -
    -
    -

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

    -
    -
    -
    -
    -
    -

    Search documentation

    -
    - - -
    + + + + + + + + + + + Starter Template for The Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +

    Pyramid starter template

    +

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

    +
    +
    +
    +
    +
    -
    -
    - - + + + + + + + diff --git a/docs/narr/MyProject/production.ini b/docs/narr/MyProject/production.ini index 3396125f2..9eae9e03f 100644 --- a/docs/narr/MyProject/production.ini +++ b/docs/narr/MyProject/production.ini @@ -1,3 +1,8 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + [app:main] use = egg:MyProject @@ -7,12 +12,19 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main host = 0.0.0.0 port = 6543 -# Begin logging configuration +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### [loggers] keys = root, myproject @@ -40,5 +52,3 @@ formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index a23f46c91..8c019af51 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -40,4 +40,3 @@ setup(name='MyProject', main = myproject:main """, ) - -- cgit v1.2.3 From df6065fb1c3724649ac6e75cfcabc273ef6fd0d9 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 19 Jan 2014 16:46:24 -0600 Subject: update narrative docs about iterable decorator argument --- docs/narr/viewconfig.rst | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index e5a2c1ade..84fde3f01 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -217,7 +217,21 @@ Non-Predicate Arguments decorator function will be called with the view callable as a single argument. The view callable it is passed will accept ``(context, request)``. The decorator must return a replacement view callable which - also accepts ``(context, request)``. + also accepts ``(context, request)``. The ``decorator`` may also be an + iterable of decorators, in which case they will be applied one after the + other to the view, in reverse order. For example:: + + @view_config(..., decorator=(decorator2, decorator1)) + def myview(request): + ... + + Is similar to doing:: + + @view_config(...) + @decorator2 + @decorator1 + def myview(request): + ... ``mapper`` A Python object or :term:`dotted Python name` which refers to a :term:`view -- cgit v1.2.3 From 0dd16dd2abf25e3f1a1e73ff6a3e206ed9a18fd9 Mon Sep 17 00:00:00 2001 From: amitvmane Date: Thu, 23 Jan 2014 21:56:45 +0530 Subject: Update project.rst Document fix for issue 1226 --- docs/narr/project.rst | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index f1bee9efd..cab7cbec7 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -74,6 +74,11 @@ In :ref:`installing_chapter` we called the virtualenv directory ``env``; the following commands assume that our current working directory is the ``env`` directory. +The below command uses the ``pcreate`` command to create a project with the +``starter`` scaffold. + +For example, + On UNIX: .. code-block:: text @@ -85,21 +90,7 @@ Or on Windows: .. code-block:: text > %VENV%\Scripts\pcreate -s starter MyProject - -The above command uses the ``pcreate`` command to create a project with the -``starter`` scaffold. To use a different scaffold, such as -``alchemy``, you'd just change the ``-s`` argument value. For example, -on UNIX: - -.. code-block:: text - - $ $VENV/bin/pcreate -s alchemy MyProject - -Or on Windows: - -.. code-block:: text - - > %VENV%\Scripts\pcreate -s alchemy MyProject + Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: -- cgit v1.2.3 From cf8bff6f0176f955bf61fb9832b7ec6da888cd33 Mon Sep 17 00:00:00 2001 From: amitvmane Date: Thu, 23 Jan 2014 22:12:00 +0530 Subject: Update project.rst Updated text as per feedback from Michael M. Thanks. --- docs/narr/project.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index cab7cbec7..eb12f67ef 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -74,11 +74,9 @@ In :ref:`installing_chapter` we called the virtualenv directory ``env``; the following commands assume that our current working directory is the ``env`` directory. -The below command uses the ``pcreate`` command to create a project with the +The below example uses the ``pcreate`` command to create a project with the ``starter`` scaffold. -For example, - On UNIX: .. code-block:: text -- cgit v1.2.3 From b5655e2e35c6fc57dd54684b1c71b1e11f672a14 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Sun, 9 Feb 2014 23:13:27 -0500 Subject: Apply change from #1221 manually. Avoid the unintentional slight in OPs commit message. --- docs/narr/startup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 1affa1758..7b4a7ea08 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -123,7 +123,7 @@ Here's a high-level time-ordered overview of what happens when you press populated by other methods run against the Configurator. The router is a WSGI application. -#. A :class:`~pyramid.events.ApplicationCreated` event is emitted (see +#. An :class:`~pyramid.events.ApplicationCreated` event is emitted (see :ref:`events_chapter` for more information about events). #. Assuming there were no errors, the ``main`` function in ``myproject`` -- cgit v1.2.3 From 5ac519452613b7bd5df22293c2ccb3b9c3597ef4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 10 Feb 2014 01:10:05 -0600 Subject: - Update list of session packages - Update Quick Tour section on sessions - Closes PR #1150 --- docs/narr/sessions.rst | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index fb5035373..8da743a01 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -158,10 +158,24 @@ Some gotchas: Using Alternate Session Factories --------------------------------- -At the time of this writing, exactly one project-endorsed alternate session -factory exists named :term:`pyramid_redis_sessions`. It can be downloaded from -PyPI. It uses the Redis database as a backend. It is the recommended -persistent session solution at the time of this writing. +The following session factories exist at the time of this writing. + +======================= ======= ============================= +Session Factory Backend Description +======================= ======= ============================= +pyramid_redis_sessions_ Redis_ Server-side session library + for Pyramid, using Redis for + storage. +pyramid_beaker_ Beaker_ Session factory for Pyramid + backed by the Beaker + sessioning system. +======================= ======= ============================= + +.. _pyramid_redis_sessions: https://pypi.python.org/pypi/pyramid_redis_sessions +.. _Redis: http://redis.io/ + +.. _pyramid_beaker: https://pypi.python.org/pypi/pyramid_beaker +.. _Beaker: http://beaker.readthedocs.org/en/latest/ .. index:: single: session factory (custom) -- cgit v1.2.3 From 2033eeb3602f330930585678aac926749b9c22f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 10 Feb 2014 03:22:33 -0600 Subject: - Garden PR #1121 --- docs/narr/advconfig.rst | 8 ++++++-- docs/narr/environment.rst | 38 ++++++++++++++++++++++++++++++-------- docs/narr/events.rst | 6 +++++- docs/narr/hellotraversal.rst | 10 +++++----- docs/narr/introduction.rst | 29 ++++++++++++++++++++++------- docs/narr/project.rst | 19 +++++++++++++------ docs/narr/resources.rst | 7 +++++-- docs/narr/security.rst | 18 +++++++++++++----- docs/narr/templates.rst | 6 +++++- docs/narr/testing.rst | 6 ++++-- docs/narr/urldispatch.rst | 5 +++-- docs/narr/viewconfig.rst | 5 +++-- 12 files changed, 114 insertions(+), 43 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index d3431e39e..9ceaaa495 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -158,8 +158,12 @@ use :meth:`pyramid.config.Configurator.include`: Using :meth:`~pyramid.config.Configurator.include` instead of calling the function directly provides a modicum of automated conflict resolution, with the configuration statements you define in the calling code overriding those -of the included function. See also :ref:`automatic_conflict_resolution` and -:ref:`including_configuration`. +of the included function. + +.. seealso:: + + See also :ref:`automatic_conflict_resolution` and + :ref:`including_configuration`. Using ``config.commit()`` +++++++++++++++++++++++++ diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index f0c0c18fe..412635f08 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -59,8 +59,11 @@ third-party template rendering extensions. Reloading Assets ---------------- -Don't cache any asset file data when this value is true. See -also :ref:`overriding_assets_section`. +Don't cache any asset file data when this value is true. + +.. seealso:: + + See also :ref:`overriding_assets_section`. +---------------------------------+-----------------------------+ | Environment Variable Name | Config File Setting Name | @@ -79,7 +82,11 @@ Debugging Authorization ----------------------- Print view authorization failure and success information to stderr -when this value is true. See also :ref:`debug_authorization_section`. +when this value is true. + +.. seealso:: + + See also :ref:`debug_authorization_section`. +---------------------------------+-----------------------------------+ | Environment Variable Name | Config File Setting Name | @@ -94,7 +101,11 @@ Debugging Not Found Errors -------------------------- Print view-related ``NotFound`` debug messages to stderr -when this value is true. See also :ref:`debug_notfound_section`. +when this value is true. + +.. seealso:: + + See also :ref:`debug_notfound_section`. +---------------------------------+------------------------------+ | Environment Variable Name | Config File Setting Name | @@ -109,7 +120,11 @@ Debugging Route Matching ------------------------ Print debugging messages related to :term:`url dispatch` route matching when -this value is true. See also :ref:`debug_routematch_section`. +this value is true. + +.. seealso:: + + See also :ref:`debug_routematch_section`. +---------------------------------+--------------------------------+ | Environment Variable Name | Config File Setting Name | @@ -128,7 +143,11 @@ Preventing HTTP Caching Prevent the ``http_cache`` view configuration argument from having any effect globally in this process when this value is true. No http caching-related response headers will be set by the Pyramid ``http_cache`` view configuration -feature when this is true. See also :ref:`influencing_http_caching`. +feature when this is true. + +.. seealso:: + + See also :ref:`influencing_http_caching`. +---------------------------------+----------------------------------+ | Environment Variable Name | Config File Setting Name | @@ -173,8 +192,11 @@ Default Locale Name -------------------- The value supplied here is used as the default locale name when a -:term:`locale negotiator` is not registered. See also -:ref:`localization_deployment_settings`. +:term:`locale negotiator` is not registered. + +.. seealso:: + + See also :ref:`localization_deployment_settings`. +---------------------------------+-----------------------------------+ | Environment Variable Name | Config File Setting Name | diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 50484761d..09caac898 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -44,7 +44,7 @@ Configuring an Event Listener Imperatively You can imperatively configure a subscriber function to be called for some event type via the :meth:`~pyramid.config.Configurator.add_subscriber` -method (see also :term:`Configurator`): +method: .. code-block:: python :linenos: @@ -63,6 +63,10 @@ The first argument to subscriber function (or a :term:`dotted Python name` which refers to a subscriber callable); the second argument is the event type. +.. seealso:: + + See also :term:`Configurator`. + Configuring an Event Listener Using a Decorator ----------------------------------------------- diff --git a/docs/narr/hellotraversal.rst b/docs/narr/hellotraversal.rst index 142c24f54..0a93b8f16 100644 --- a/docs/narr/hellotraversal.rst +++ b/docs/narr/hellotraversal.rst @@ -60,10 +60,10 @@ A more complicated application could have many types of resources, with different view callables defined for each type, and even multiple views for each type. -See Also ---------- +.. seealso:: -Full technical details may be found in :doc:`traversal`. - -For more about *why* you might use traversal, see :doc:`muchadoabouttraversal`. + Full technical details may be found in :doc:`traversal`. + + For more about *why* you might use traversal, see + :doc:`muchadoabouttraversal`. diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8acbab3a0..a37d74c9b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -121,7 +121,9 @@ ways. .. literalinclude:: helloworld.py -See also :ref:`firstapp_chapter`. +.. seealso:: + + See also :ref:`firstapp_chapter`. Decorator-based configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -271,7 +273,9 @@ Here's a few views defined as methods of a class instead: def view_two(self): return Response('two') -See also :ref:`view_config_placement`. +.. seealso:: + + See also :ref:`view_config_placement`. .. _intro_asset_specs: @@ -572,7 +576,10 @@ For example: config.include('pyramid_exclog') config.include('some.other.guys.package', route_prefix='/someotherguy') -See also :ref:`including_configuration` and :ref:`building_an_extensible_app` +.. seealso:: + + See also :ref:`including_configuration` and + :ref:`building_an_extensible_app`. Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -730,7 +737,9 @@ Pyramid defaults to explicit behavior, because it's the most generally useful, but provides hooks that allow you to adapt the framework to localized aesthetic desires. -See also :ref:`using_iresponse`. +.. seealso:: + + See also :ref:`using_iresponse`. "Global" response object ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -748,7 +757,9 @@ section," you say. Fine. Be that way: response.content_type = 'text/plain' return response -See also :ref:`request_response_attr`. +.. seealso:: + + See also :ref:`request_response_attr`. Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -811,7 +822,9 @@ it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the :meth:`~pyramid.config.Configurator.include` method against your code. -See also :ref:`add_directive`. +.. seealso:: + + See also :ref:`add_directive`. Programmatic Introspection ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -839,7 +852,9 @@ callable: route_intr = introspector.get('routes', route_name) return Response(str(route_intr['pattern'])) -See also :ref:`using_introspection`. +.. seealso:: + + See also :ref:`using_introspection`. Python 3 Compatibility ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index eb12f67ef..62b91de0e 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -898,15 +898,22 @@ returns the HTML in a :term:`response`. a server restart to reload them. Production applications should use ``pyramid.reload_templates = False``. -.. seealso:: See also :ref:`views_which_use_a_renderer` for more information +.. seealso:: + + See also :ref:`views_which_use_a_renderer` for more information about how views, renderers, and templates relate and cooperate. -.. seealso:: Pyramid can also dynamically reload changed Python files. For - more on this see :ref:`reloading_code`. +.. seealso:: + + Pyramid can also dynamically reload changed Python files. See also + :ref:`reloading_code`. + +.. seealso:: -.. seealso:: The :ref:`debug_toolbar` provides interactive access to your - application's internals and, should an exception occur, allows interactive - access to traceback execution stack frames from the Python interpreter. + See also the :ref:`debug_toolbar`, which provides interactive access to + your application's internals and, should an exception occur, allows + interactive access to traceback execution stack frames from the Python + interpreter. .. index:: single: static directory diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index f3ff1dc4c..6139154ff 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -673,8 +673,11 @@ Calling ``find_interface(b, Thing2)`` will return the ``b`` resource. The second argument to find_interface may also be a :term:`interface` instead of a class. If it is an interface, each resource in the lineage is checked to see if the resource implements the specificed interface (instead of seeing -if the resource is of a class). See also -:ref:`resources_which_implement_interfaces`. +if the resource is of a class). + +.. seealso:: + + See also :ref:`resources_which_implement_interfaces`. .. index:: single: resource API functions diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 9e6fb6c82..8db23a33b 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -113,9 +113,11 @@ authorization policies, it is an error to configure a Pyramid application with an authentication policy but without the authorization policy or vice versa. If you do this, you'll receive an error at application startup time. -See also the :mod:`pyramid.authorization` and -:mod:`pyramid.authentication` modules for alternate implementations -of authorization and authentication policies. +.. seealso:: + + See also the :mod:`pyramid.authorization` and + :mod:`pyramid.authentication` modules for alternate implementations of + authorization and authentication policies. .. index:: single: permissions @@ -495,8 +497,14 @@ is said to be *location-aware*. Location-aware objects define an ``__parent__`` attribute which points at their parent object. The root object's ``__parent__`` is ``None``. -See :ref:`location_module` for documentations of functions which use -location-awareness. See also :ref:`location_aware`. +.. seealso:: + + See also :ref:`location_module` for documentations of functions which use + location-awareness. + +.. seealso:: + + See also :ref:`location_aware`. .. index:: single: forbidden view diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 00fc21634..038dd2594 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -320,7 +320,11 @@ template renderer: in Chameleon, not in Mako templates. Similar renderer configuration can be done imperatively. See -:ref:`views_which_use_a_renderer`. See also :ref:`built_in_renderers`. +:ref:`views_which_use_a_renderer`. + +.. seealso:: + + See also :ref:`built_in_renderers`. Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 5a5bf8fad..e001ad81c 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -319,8 +319,10 @@ registering resources at paths, registering event listeners, registering views and view permissions, and classes representing "dummy" implementations of a request and a resource. -See also the various methods of the :term:`Configurator` documented in -:ref:`configuration_module` that begin with the ``testing_`` prefix. +.. seealso:: + + See also the various methods of the :term:`Configurator` documented in + :ref:`configuration_module` that begin with the ``testing_`` prefix. .. index:: single: integration tests diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 96ee5758e..87a962a9a 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -1183,9 +1183,10 @@ still easily do it by wrapping it in classmethod call. Same will work with staticmethod, just use ``staticmethod`` instead of ``classmethod``. +.. seealso:: -See also :class:`pyramid.interfaces.IRoute` for more API documentation about -route objects. + See also :class:`pyramid.interfaces.IRoute` for more API documentation + about route objects. .. index:: single: route factory diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 84fde3f01..adc53bd11 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -118,8 +118,9 @@ Non-Predicate Arguments ``renderer`` Denotes the :term:`renderer` implementation which will be used to construct - a :term:`response` from the associated view callable's return value. (see - also :ref:`renderers_chapter`). + a :term:`response` from the associated view callable's return value. + + .. seealso:: See also :ref:`renderers_chapter`. This is either a single string term (e.g. ``json``) or a string implying a path or :term:`asset specification` (e.g. ``templates/views.pt``) naming a -- cgit v1.2.3 From 407b335ed9954c042377fd2e060c36edcd07cf60 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 27 Feb 2014 23:45:24 -0500 Subject: add support for using an absolute path to override an asset fixes #1229 --- docs/narr/assets.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index b0a8d18b0..fec55ce7c 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -526,3 +526,6 @@ files. Any software which uses the :func:`pkg_resources.get_resource_string` APIs will obtain an overridden file 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. -- cgit v1.2.3 From e4dc7443ddf8e5e3d861c66e0cef565a6d907789 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 20:07:59 +0200 Subject: Update documentation for Lingua 2 --- docs/narr/i18n.rst | 182 ++++++++++++++--------------------------------------- 1 file changed, 48 insertions(+), 134 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 5f50ca212..31b63664b 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -245,88 +245,69 @@ GNU gettext uses three types of files in the translation framework, A ``.po`` file is turned into a machine-readable binary file, which is the ``.mo`` file. Compiling the translations to machine code - makes the localized program run faster. + makes the localized program start faster. The tools for working with :term:`gettext` translation files related to a -:app:`Pyramid` application is :term:`Babel` and :term:`Lingua`. Lingua is a -Babel extension that provides support for scraping i18n references out of -Python and Chameleon files. +:app:`Pyramid` application are :term:`Lingua` and :term:`Gettext`. Lingua +can scrape i18n references out of Python and Chameleon files and create +the ``.pot`` file. Gettext includes tools to update a ``.po`` file from +an updated ``.pot`` file and to compile ``.po`` files to ``.mo`` files. .. index:: - single: Babel + single: Gettext single: Lingua .. _installing_babel: -Installing Babel and Lingua -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Installing Lingua and Gettext +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In order for the commands related to working with ``gettext`` translation -files to work properly, you will need to have :term:`Babel` and -:term:`Lingua` installed into the same environment in which :app:`Pyramid` is +files to work properly, you will need to have :term:`Lingua` and +:term:`Gettext` installed into the same environment in which :app:`Pyramid` is installed. Installation on UNIX ++++++++++++++++++++ -If the :term:`virtualenv` into which you've installed your :app:`Pyramid` -application lives in ``/my/virtualenv``, you can install Babel and Lingua -like so: +Gettext is often already installed on UNIX systems. You can check if it is +installed by testing if the ``msgfmt`` command is available. If it is not +available you can install it through the packaging system from your OS; +the package name is almost always ``gettext``. For example on a Debian or +Ubuntu system run this command: .. code-block:: text - $ cd /my/virtualenv - $ $VENV/bin/easy_install Babel lingua + $ sudo apt-get install gettext -Installation on Windows -+++++++++++++++++++++++ - -If the :term:`virtualenv` into which you've installed your :app:`Pyramid` -application lives in ``C:\my\virtualenv``, you can install Babel and Lingua +Installing Lingua is done with the Python packaging tools. If the +:term:`virtualenv` into which you've installed your :app:`Pyramid` application +lives in ``/my/virtualenv``, you can install Lingua like so: .. code-block:: text - C> %VENV%\Scripts\easy_install Babel lingua + $ cd /my/virtualenv + $ $VENV/bin/pip install lingua -.. index:: - single: Babel; message extractors - single: Lingua +Installation on Windows ++++++++++++++++++++++++ -Changing the ``setup.py`` -+++++++++++++++++++++++++ +There are several ways to install Gettext on Windows: it is included in the +`Cygwin `_ collection, or you can use the `installer +from the GnuWin32 `_ +or compile it yourself. Make sure the installation path is added to your +``$PATH``. -You need to add a few boilerplate lines to your application's ``setup.py`` -file in order to properly generate :term:`gettext` files from your -application. -.. note:: See :ref:`project_narr` to learn about the - composition of an application's ``setup.py`` file. +Installing Lingua is done with the Python packaging tools. If the +:term:`virtualenv` into which you've installed your :app:`Pyramid` application +lives in ``C:\my\virtualenv``, you can install Lingua like so: -In particular, add the ``Babel`` and ``lingua`` distributions to the -``install_requires`` list and insert a set of references to :term:`Babel` -*message extractors* within the call to :func:`setuptools.setup` inside your -application's ``setup.py`` file: +.. code-block:: text -.. code-block:: python - :linenos: + C> %VENV%\Scripts\pip install lingua - setup(name="mypackage", - # ... - install_requires = [ - # ... - 'Babel', - 'lingua', - ], - message_extractors = { '.': [ - ('**.py', 'lingua_python', None ), - ('**.pt', 'lingua_xml', None ), - ]}, - ) - -The ``message_extractors`` stanza placed into the ``setup.py`` file causes -the :term:`Babel` message catalog extraction machinery to also consider -``*.pt`` files when doing message id extraction. .. index:: pair: extracting; messages @@ -336,90 +317,20 @@ the :term:`Babel` message catalog extraction machinery to also consider Extracting Messages from Code and Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once Babel and Lingua are installed and your application's ``setup.py`` file -has the correct message extractor references, you may extract a message -catalog template from the code and :term:`Chameleon` templates which reside -in your :app:`Pyramid` application. You run a ``setup.py`` command to -extract the messages: +Once Lingua is installed you may extract a message catalog template from the +code and :term:`Chameleon` templates which reside in your :app:`Pyramid` +application. You run a ``pot-create`` command to extract the messages: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives $ mkdir -p myapplication/locale - $ $VENV/bin/python setup.py extract_messages + $ $VENT/bin/pot-create src > myapplication/locale/myapplication.pot The message catalog ``.pot`` template will end up in: ``myapplication/locale/myapplication.pot``. -.. index:: - single: translation domains - -Translation Domains -+++++++++++++++++++ - -The name ``myapplication`` above in the filename ``myapplication.pot`` -denotes the :term:`translation domain` of the translations that must -be performed to localize your application. By default, the -translation domain is the :term:`project` name of your -:app:`Pyramid` application. - -To change the translation domain of the extracted messages in your project, -edit the ``setup.cfg`` file of your application, The default ``setup.cfg`` -file of a ``pcreate`` -generated :app:`Pyramid` application has stanzas in it -that look something like the following: - -.. code-block:: ini - :linenos: - - [compile_catalog] - directory = myproject/locale - domain = MyProject - statistics = true - - [extract_messages] - add_comments = TRANSLATORS: - output_file = myproject/locale/MyProject.pot - width = 80 - - [init_catalog] - domain = MyProject - input_file = myproject/locale/MyProject.pot - output_dir = myproject/locale - - [update_catalog] - domain = MyProject - input_file = myproject/locale/MyProject.pot - output_dir = myproject/locale - previous = true - -In the above example, the project name is ``MyProject``. To indicate -that you'd like the domain of your translations to be ``mydomain`` -instead, change the ``setup.cfg`` file stanzas to look like so: - -.. code-block:: ini - :linenos: - - [compile_catalog] - directory = myproject/locale - domain = mydomain - statistics = true - - [extract_messages] - add_comments = TRANSLATORS: - output_file = myproject/locale/mydomain.pot - width = 80 - - [init_catalog] - domain = mydomain - input_file = myproject/locale/mydomain.pot - output_dir = myproject/locale - - [update_catalog] - domain = mydomain - input_file = myproject/locale/mydomain.pot - output_dir = myproject/locale - previous = true .. index:: pair: initializing; message catalog @@ -432,15 +343,17 @@ Once you've extracted messages into a ``.pot`` file (see in the ``.pot`` file, you need to generate at least one ``.po`` file. A ``.po`` file represents translations of a particular set of messages to a particular locale. Initialize a ``.po`` file for a specific -locale from a pre-generated ``.pot`` template by using the ``setup.py -init_catalog`` command: +locale from a pre-generated ``.pot`` template by using the ``msginit`` +command: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $VENV/bin/python setup.py init_catalog -l es + $ cd myapplication/locale + $ mkdir -p es/LC_MESSAGES + $ msginit -l es es/LC_MESSAGES/myapplication.po -By default, the message catalog ``.po`` file will end up in: +This will create a new the message catalog ``.po`` file will in: ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. @@ -465,12 +378,13 @@ files based on changes to the ``.pot`` file, so that the new and changed messages can also be translated or re-translated. First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. -Then use the ``setup.py update_catalog`` command. +Then use the ``msgmerge`` command. .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $VENV/bin/python setup.py update_catalog + $ cd myapplication/locale + $ msgmerge --update es/LC_MESSAGES/myapplication.po myapplication.pot .. index:: pair: compiling; message catalog @@ -481,12 +395,12 @@ Compiling a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Finally, to prepare an application for performing actual runtime -translations, compile ``.po`` files to ``.mo`` files: +translations, compile ``.po`` files to ``.mo`` files use the ``msgfmt``: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ $VENV/bin/python setup.py compile_catalog + $ msgfmt myapplication/locale/*/LC_MESSAGES/*.po This will create a ``.mo`` file for each ``.po`` file in your application. As long as the :term:`translation directory` in which -- cgit v1.2.3 From cfaec8b63b271e141789244ad276d3045e00a2a8 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 21:01:43 +0200 Subject: Keep using easy_install. --- docs/narr/i18n.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 31b63664b..122f33130 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -288,7 +288,7 @@ like so: .. code-block:: text $ cd /my/virtualenv - $ $VENV/bin/pip install lingua + $ $VENV/bin/easy_install lingua Installation on Windows +++++++++++++++++++++++ @@ -306,7 +306,7 @@ lives in ``C:\my\virtualenv``, you can install Lingua like so: .. code-block:: text - C> %VENV%\Scripts\pip install lingua + C> %VENV%\Scripts\easy_install lingua .. index:: -- cgit v1.2.3 From d3a70e5e656eea3f527b56e9f03b6f754731dc4a Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 21:04:57 +0200 Subject: Fix $VENT typo --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 122f33130..50e5a6817 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -325,7 +325,7 @@ application. You run a ``pot-create`` command to extract the messages: $ cd /place/where/myapplication/setup.py/lives $ mkdir -p myapplication/locale - $ $VENT/bin/pot-create src > myapplication/locale/myapplication.pot + $ $VENV/bin/pot-create src > myapplication/locale/myapplication.pot The message catalog ``.pot`` template will end up in: -- cgit v1.2.3 From c1cbf085fbf4e0280481acfbf1e9b6b0f8692cbd Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 21:07:24 +0200 Subject: Remove lingua references from setup.cfg description. --- 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 62b91de0e..3631a9782 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -760,8 +760,8 @@ Our generated ``setup.cfg`` looks like this: :language: guess :linenos: -The values in the default setup file allow various commonly-used -internationalization commands and testing commands to work more smoothly. +The values in the default setup file make the testing commands to work more +smoothly. .. index:: single: package -- cgit v1.2.3 From 0a4433df3711755170396090d8daa69bfaef76f9 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 21:09:34 +0200 Subject: Always mention the msg* commands come from Gettext --- docs/narr/i18n.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 50e5a6817..1de2c8941 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -250,8 +250,9 @@ GNU gettext uses three types of files in the translation framework, The tools for working with :term:`gettext` translation files related to a :app:`Pyramid` application are :term:`Lingua` and :term:`Gettext`. Lingua can scrape i18n references out of Python and Chameleon files and create -the ``.pot`` file. Gettext includes tools to update a ``.po`` file from -an updated ``.pot`` file and to compile ``.po`` files to ``.mo`` files. +the ``.pot`` file. Gettext includes ``msgmerge`` tool to update a ``.po`` file +from an updated ``.pot`` file and ``msgfmt`` to compile ``.po`` files to +``.mo`` files. .. index:: single: Gettext @@ -344,7 +345,7 @@ in the ``.pot`` file, you need to generate at least one ``.po`` file. A ``.po`` file represents translations of a particular set of messages to a particular locale. Initialize a ``.po`` file for a specific locale from a pre-generated ``.pot`` template by using the ``msginit`` -command: +command from Gettext: .. code-block:: text @@ -378,7 +379,7 @@ files based on changes to the ``.pot`` file, so that the new and changed messages can also be translated or re-translated. First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. -Then use the ``msgmerge`` command. +Then use the ``msgmerge`` command from Gettext. .. code-block:: text @@ -395,7 +396,8 @@ Compiling a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Finally, to prepare an application for performing actual runtime -translations, compile ``.po`` files to ``.mo`` files use the ``msgfmt``: +translations, compile ``.po`` files to ``.mo`` files use the ``msgfmt`` +command from Gettext: .. code-block:: text -- cgit v1.2.3 From 832c2e8967fa1904fb1a0d3e5d707a11c32aa543 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 21:49:44 +0200 Subject: Remove Babel from all setup.cfg files --- docs/narr/MyProject/setup.cfg | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/setup.cfg b/docs/narr/MyProject/setup.cfg index 332e80a60..229a686f8 100644 --- a/docs/narr/MyProject/setup.cfg +++ b/docs/narr/MyProject/setup.cfg @@ -4,24 +4,3 @@ nocapture = 1 cover-package = myproject with-coverage = 1 cover-erase = 1 - -[compile_catalog] -directory = myproject/locale -domain = MyProject -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = myproject/locale/MyProject.pot -width = 80 - -[init_catalog] -domain = MyProject -input_file = myproject/locale/MyProject.pot -output_dir = myproject/locale - -[update_catalog] -domain = MyProject -input_file = myproject/locale/MyProject.pot -output_dir = myproject/locale -previous = true -- cgit v1.2.3 From eab0eb5068754da33123d5a7bc3faf025a3fc14e Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 22:04:47 +0200 Subject: Drop setup.cfg from scaffolds Since setup.cfg is no longer needed for Babel, and no scaffold or documentation references nose there is no need to keep them. --- docs/narr/MyProject/setup.cfg | 6 ------ docs/narr/project.rst | 22 ---------------------- 2 files changed, 28 deletions(-) delete mode 100644 docs/narr/MyProject/setup.cfg (limited to 'docs/narr') diff --git a/docs/narr/MyProject/setup.cfg b/docs/narr/MyProject/setup.cfg deleted file mode 100644 index 229a686f8..000000000 --- a/docs/narr/MyProject/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = myproject -with-coverage = 1 -cover-erase = 1 diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 3631a9782..39e55706f 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -492,7 +492,6 @@ structure: │   ├── tests.py │   └── views.py ├── production.ini - ├── setup.cfg └── setup.py The ``MyProject`` :term:`Project` @@ -515,9 +514,6 @@ describe, run, and test your application. #. ``production.ini`` is a :term:`PasteDeploy` configuration file that can be used to execute your application in a production configuration. -#. ``setup.cfg`` is a :term:`setuptools` configuration file used by - ``setup.py``. - #. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files should be included in a source distribution of the package when ``python setup.py sdist`` is run. @@ -745,24 +741,6 @@ This will create a tarball of your application in a ``dist`` subdirectory named ``MyProject-0.1.tar.gz``. You can send this tarball to other people who want to install and use your application. -.. index:: - single: setup.cfg - -``setup.cfg`` -~~~~~~~~~~~~~ - -The ``setup.cfg`` file is a :term:`setuptools` configuration file. It -contains various settings related to testing and internationalization: - -Our generated ``setup.cfg`` looks like this: - -.. literalinclude:: MyProject/setup.cfg - :language: guess - :linenos: - -The values in the default setup file make the testing commands to work more -smoothly. - .. index:: single: package -- cgit v1.2.3 From c3ef4170b195f08f9563256a3cbdd614d786acef Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 8 Apr 2014 17:51:30 -0400 Subject: make pdf build again --- docs/narr/project.rst | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 39e55706f..0ada1a379 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -476,23 +476,23 @@ structure: .. code-block:: text MyProject/ - ├── CHANGES.txt - ├── MANIFEST.in - ├── README.txt - ├── development.ini - ├── myproject - │   ├── __init__.py - │   ├── static - │   │   ├── pyramid-16x16.png - │   │   ├── pyramid.png - │   │   ├── theme.css - │   │   └── theme.min.css - │   ├── templates - │   │   └── mytemplate.pt - │   ├── tests.py - │   └── views.py - ├── production.ini - └── setup.py + |-- CHANGES.txt + |-- development.ini + |-- MANIFEST.in + |-- myproject + | |-- __init__.py + | |-- static + | | |-- pyramid-16x16.png + | | |-- pyramid.png + | | |-- theme.css + | | `-- theme.min.css + | |-- templates + | | `-- mytemplate.pt + | |-- tests.py + | `-- views.py + |-- production.ini + |-- README.txt + `-- setup.py The ``MyProject`` :term:`Project` --------------------------------- -- cgit v1.2.3 From f0398e9e32d8fee1b0f46eef0ffcc814d7e6efb0 Mon Sep 17 00:00:00 2001 From: Nina Zakharenko Date: Mon, 14 Apr 2014 14:46:11 -0400 Subject: Update python installation instructions for mac osx. --- docs/narr/install.rst | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index e419a8b20..89791115f 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -32,20 +32,32 @@ dependency will fall back to using pure Python instead. For Mac OS X Users ~~~~~~~~~~~~~~~~~~ -From `Python.org `_: +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. - Python comes pre-installed on Mac OS X, but due to Apple's release cycle, - it's often one or even two years old. The overwhelming recommendation of - the "MacPython" community is to upgrade your Python by downloading and - installing a newer version from `the Python standard release page - `_. +You can install the latest version of Python for Mac using the `homebrew `_ package manager. -It is recommended to download one of the *installer* versions, unless you -prefer to install your Python through a packgage manager (e.g., macports or -homebrew) or to build your Python from source. +To install homebrew: -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. +.. code-block:: text + + $ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)" + +Then update the homebrew package index. + +.. code-block:: text + + $ brew update & brew doctor + +If the message says you're ready to brew, install the latest python2 or python3 using: + +.. code-block:: text + + $ brew install python + $ brew install python3 + +Alternatively, you can install it via the binaries on the `python.org `_ site. If you use an installer for your Python, then you can skip to the section :ref:`installing_unix`. -- cgit v1.2.3 From 836894d87eb2b1127b69f7eed70b770460f913ca Mon Sep 17 00:00:00 2001 From: Nina Zakharenko Date: Mon, 14 Apr 2014 16:07:23 -0400 Subject: Update the documentation for Python installation on OSX. Binaries are primary method. --- docs/narr/install.rst | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 89791115f..c0f633686 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -33,32 +33,19 @@ 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. +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. -You can install the latest version of Python for Mac using the `homebrew `_ package manager. +You can install the latest verion of Python for OSX from the binaries on +`python.org `_. -To install homebrew: - -.. code-block:: text - - $ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)" - -Then update the homebrew package index. - -.. code-block:: text - - $ brew update & brew doctor - -If the message says you're ready to brew, install the latest python2 or python3 using: +Alternatively, you can use the `homebrew `_ package manager. .. code-block:: text $ brew install python $ brew install python3 -Alternatively, you can install it via the binaries on the `python.org `_ site. - If you use an installer for your Python, then you can skip to the section :ref:`installing_unix`. -- cgit v1.2.3 From 8af14089b511723912063bb1b8f1471378d4a0ba Mon Sep 17 00:00:00 2001 From: Nina Zakharenko Date: Mon, 14 Apr 2014 16:20:04 -0400 Subject: Change OSX to Mac OS X --- docs/narr/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c0f633686..54984e6a2 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -36,7 +36,7 @@ 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. -You can install the latest verion of Python for OSX from the binaries on +You can install the latest verion of Python for Mac OS X from the binaries on `python.org `_. Alternatively, you can use the `homebrew `_ package manager. -- cgit v1.2.3 From abab3574569d39eeea5459eaad102eb6c7b2d7ef Mon Sep 17 00:00:00 2001 From: Nina Zakharenko Date: Mon, 14 Apr 2014 16:44:32 -0400 Subject: adding comments for python versions --- docs/narr/install.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 54984e6a2..4ccf65c65 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -43,7 +43,10 @@ Alternatively, you can use the `homebrew `_ package manager. .. code-block:: text + # for python 2.7 $ brew install python + + # for python 3.4 $ brew install python3 If you use an installer for your Python, then you can skip to the section -- cgit v1.2.3 From a51a5627b0dda868f467588c464215d6f74a0958 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 14 Apr 2014 16:46:59 -0400 Subject: clarify python version support --- 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 e419a8b20..a6ae7df60 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, and Python 3.3. :app:`Pyramid` does not run under any - version of Python before 2.6. + 2.7, Python 3.2, Python 3.3, Python 3.4 and PyPy 2.2. :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 ac16ec2f722dcdaa45d0389ad87952bd6be6e389 Mon Sep 17 00:00:00 2001 From: westurner Date: Tue, 15 Apr 2014 01:28:03 -0500 Subject: DOC: Response.content_type defaults to text/html --- docs/narr/webob.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index f0a4b5a0b..6a331e4bf 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -408,6 +408,8 @@ Here are some highlights: The content type *not* including the ``charset`` parameter. Typical use: ``response.content_type = 'text/html'``. + Default value: ``response.content_type = 'text/html'``. + ``response.charset``: The ``charset`` parameter of the content-type, it also informs encoding in ``response.unicode_body``. @@ -466,9 +468,12 @@ argument to the class; e.g.: from pyramid.response import Response response = Response(body='hello world!', content_type='text/plain') -The status defaults to ``'200 OK'``. The content_type does not default to -anything, though if you subclass :class:`pyramid.response.Response` and set -``default_content_type`` you can override this behavior. +The status defaults to ``'200 OK'``. + +The value of content_type defaults to +``webob.response.Response.default_content_type``; which is `text/html`. +You can subclass :class:`pyramid.response.Response` and set +``default_content_type`` to override this behavior. .. index:: single: exception responses -- cgit v1.2.3 From cef139b9c2f163694968ae5b7efe7eae07e72c04 Mon Sep 17 00:00:00 2001 From: bobby Date: Wed, 23 Apr 2014 23:04:00 -0700 Subject: Typo found in second Declarative code block There were two import statements for Configurator. I removed the second import statement in the "__main__" since most of the documentation declares all imports on the top of the source. modified: configuration.rst --- docs/narr/configuration.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index f7a69d613..52615533d 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -114,7 +114,6 @@ in a package and its subpackages. For example: return Response('Hello') if __name__ == '__main__': - from pyramid.config import Configurator config = Configurator() config.scan() app = config.make_wsgi_app() -- cgit v1.2.3 From 6541717478e958143b73256f113cf709ebaa40d6 Mon Sep 17 00:00:00 2001 From: Fenton Travers Date: Thu, 24 Apr 2014 14:03:49 -0700 Subject: Replaced non-ascii copyright character with HTML equivalent. --- docs/narr/MyProject/myproject/templates/mytemplate.pt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index d1af4f42c..e6b00a145 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -50,7 +50,7 @@
    -- cgit v1.2.3 From 306c298d897acb5b751fa7dc0b8081b48007686f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 1 May 2014 13:34:17 -0500 Subject: fix #1253 --- docs/narr/viewconfig.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index adc53bd11..a0feef8d7 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -295,11 +295,14 @@ configured view. *This is an advanced feature, not often used by "civilians"*. ``request_method`` - This value can be a string (typically ``"GET"``, ``"POST"``, ``"PUT"``, - ``"DELETE"``, or ``"HEAD"``) representing an HTTP ``REQUEST_METHOD``. A view - declaration with this argument ensures that the view will only be called - when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the - WSGI environment) string matches the supplied value. + This value can be either a string (such as ``"GET"``, ``"POST"``, + ``"PUT"``, ``"DELETE"``, ``"HEAD"`` or ``"OPTIONS"``) representing an + HTTP ``REQUEST_METHOD``, or a tuple containing one or more of these + strings. A view declaration with this argument ensures that the + view will only be called when the ``method`` attribute of the + request (aka the ``REQUEST_METHOD`` of the WSGI environment) matches + a supplied value. Note that use of ``"GET"`` also implies that the + view will respond to ``"HEAD"`` as of Pyramid 1.4. If ``request_method`` is not supplied, the view will be invoked regardless of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. -- cgit v1.2.3 From fbcce774fb33b57673c99f9e82058c507e212611 Mon Sep 17 00:00:00 2001 From: synthomat Date: Tue, 13 May 2014 13:29:56 +0200 Subject: Update hooks.rst 'self' param was omitted in the constructor of simple_tween_factory class --- 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 f2542f1d7..94be31bbc 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1023,7 +1023,7 @@ method: :linenos: class simple_tween_factory(object): - def __init__(handler, registry): + def __init__(self, handler, registry): self.handler = handler self.registry = registry -- cgit v1.2.3 From 739fbc26639a06900a8638d0e5de7441e41ff810 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Fri, 16 May 2014 10:32:42 -0500 Subject: Docs: narr/templates.rst: Doc default extensions of each template system. --- docs/narr/templates.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 038dd2594..cd13afde8 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -450,15 +450,15 @@ Available Add-On Template System Bindings The Pylons Project maintains several packages providing bindings to different templating languages including the following: -+------------------------------+------------------------------+ -| Template Language | Pyramid Bindings | -+==============================+==============================+ -| Chameleon_ | pyramid_chameleon_ | -+------------------------------+------------------------------+ -| Jinja2_ | pyramid_jinja2_ | -+------------------------------+------------------------------+ -| Mako_ | pyramid_mako_ | -+------------------------------+------------------------------+ ++---------------------------+----------------------------+--------------------+ +| Template Language | Pyramid Bindings | Default Extensions | ++===========================+============================+====================+ +| Chameleon_ | pyramid_chameleon_ | .pt, .txt | ++---------------------------+----------------------------+--------------------+ +| Jinja2_ | pyramid_jinja2_ | .jinja2 | ++---------------------------+----------------------------+--------------------+ +| Mako_ | pyramid_mako_ | .mak, .mako | ++---------------------------+----------------------------+--------------------+ .. _Chameleon: http://chameleon.readthedocs.org/en/latest/ .. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon -- cgit v1.2.3 From e858454e9cc375a633bfb7b39bdd4391f79e2531 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Fri, 16 May 2014 17:18:00 -0500 Subject: Docs: narr/templates.rst: Link template bindings to pyramid docs. --- docs/narr/templates.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index cd13afde8..460cda8ee 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -461,10 +461,13 @@ templating languages including the following: +---------------------------+----------------------------+--------------------+ .. _Chameleon: http://chameleon.readthedocs.org/en/latest/ -.. _pyramid_chameleon: https://pypi.python.org/pypi/pyramid_chameleon +.. _pyramid_chameleon: + http://docs.pylonsproject.org/projects/pyramid-chameleon/en/latest/ .. _Jinja2: http://jinja.pocoo.org/docs/ -.. _pyramid_jinja2: https://pypi.python.org/pypi/pyramid_jinja2 +.. _pyramid_jinja2: + http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/ .. _Mako: http://www.makotemplates.org/ -.. _pyramid_mako: https://pypi.python.org/pypi/pyramid_mako +.. _pyramid_mako: + http://docs.pylonsproject.org/projects/pyramid-mako/en/latest/ -- cgit v1.2.3 From d194f3df5b5941251a36e0e7d535eaf0d633dd1b Mon Sep 17 00:00:00 2001 From: flibustenet Date: Sun, 18 May 2014 11:26:48 +0200 Subject: Draw attention that tweens instances are unique and shared between threads Forgetting that tween instance are not instantiated for each request leads to threads issues difficult to detect --- docs/narr/hooks.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 94be31bbc..91392ce7a 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1017,7 +1017,8 @@ You can write the tween factory as a simple closure-returning function: return simple_tween Alternatively, the tween factory can be a class with the ``__call__`` magic -method: +method (the instance will be unique, be aware that it will be shared +between threads): .. code-block:: python :linenos: -- cgit v1.2.3 From bf669af7f10ec81280fd8dbee43e414fa75457c5 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 21 May 2014 11:03:13 -0500 Subject: clarify tween thread-safety --- docs/narr/hooks.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 91392ce7a..fe7749cac 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -985,7 +985,7 @@ Creating a Tween To create a tween, you must write a "tween factory". A tween factory must be a globally importable callable which accepts two arguments: -``handler`` and ``registry``. ``handler`` will be the either the main +``handler`` and ``registry``. ``handler`` will be either the main Pyramid request handling function or another tween. ``registry`` will be the Pyramid :term:`application registry` represented by this Configurator. A tween factory must return the tween (a callable object) when it is called. @@ -995,6 +995,11 @@ A tween is called with a single argument, ``request``, which is the A tween should return a :term:`response`, usually the one generated by the downstream Pyramid application. +The tween factory will be shared between requests and is used to create one +tween per-request. Shared mutable state on the factory itself needs to be +carefully handled, and should be avoided unless you are willing to handle +the race conditions that may arise. + You can write the tween factory as a simple closure-returning function: .. code-block:: python @@ -1017,8 +1022,7 @@ You can write the tween factory as a simple closure-returning function: return simple_tween Alternatively, the tween factory can be a class with the ``__call__`` magic -method (the instance will be unique, be aware that it will be shared -between threads): +method: .. code-block:: python :linenos: -- cgit v1.2.3 From 2c096b0a8b7a83f5ded54a3fd6c048cd5f01b9a4 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 21 May 2014 12:20:56 -0500 Subject: oops, re-clarify that tweens should not have mutable state --- docs/narr/hooks.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index fe7749cac..4da36e730 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -995,11 +995,6 @@ A tween is called with a single argument, ``request``, which is the A tween should return a :term:`response`, usually the one generated by the downstream Pyramid application. -The tween factory will be shared between requests and is used to create one -tween per-request. Shared mutable state on the factory itself needs to be -carefully handled, and should be avoided unless you are willing to handle -the race conditions that may arise. - You can write the tween factory as a simple closure-returning function: .. code-block:: python @@ -1045,6 +1040,10 @@ method: return response +You should avoid mutating any state on the tween instance. The tween is +invoked once per request and any shared mutable state needs to be carefully +handled to avoid any race conditions. + The closure style performs slightly better and enables you to conditionally omit the tween from the request processing pipeline (see the following timing tween example), whereas the class style makes it easier to have shared mutable -- cgit v1.2.3 From 7dd856ffed7df4bec637c29f4529cabc07e5e191 Mon Sep 17 00:00:00 2001 From: LiJunjie Date: Mon, 16 Jun 2014 14:36:30 +0800 Subject: Correct handler name for logger_wsgi --- docs/narr/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 75428d513..71029bb33 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -377,7 +377,7 @@ FileHandler to the list of handlers (named ``accesslog``), and ensure that the [logger_wsgi] level = INFO - handlers = handler_accesslog + handlers = accesslog qualname = wsgi propagate = 0 -- cgit v1.2.3 From 3f87c228c920edbb85a85f3332a5340063e49b11 Mon Sep 17 00:00:00 2001 From: Kamal Gill Date: Mon, 2 Jun 2014 13:51:09 -0700 Subject: Fix path to pshell --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 3cabbd8f4..4f16617c4 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -146,7 +146,7 @@ name ``main`` as a section name: .. code-block:: text - $ $VENV/bin starter/development.ini#main + $ $VENV/bin/pshell starter/development.ini#main Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. -- cgit v1.2.3 From 7a479d270d654f61fca00f8a27b64fd2bf99d35d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 13 Jul 2014 23:39:38 -0400 Subject: remove lie --- docs/narr/templates.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 460cda8ee..4c1364493 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -316,8 +316,7 @@ template renderer: we're using a Chameleon renderer, it means "relative to the directory in which the file which defines the view configuration lives". In this case, this is the directory containing the file that defines the ``my_view`` - function. View-configuration-relative asset specifications work only - in Chameleon, not in Mako templates. + function. Similar renderer configuration can be done imperatively. See :ref:`views_which_use_a_renderer`. -- cgit v1.2.3 From a8eb53fb79981e1b6fb93af3c80a6bdbae7f9d8f Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Mon, 14 Jul 2014 11:13:28 -0400 Subject: Narrative scifi. --- docs/narr/assets.rst | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index b0a8d18b0..a2976de22 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -286,6 +286,71 @@ the application is being run in development or in production (use a different suggestion for a pattern; any setting name other than ``media_location`` could be used. +.. _cache_busting: + +Cache Busting +------------- + +In order to maximize performance of a web application, you generally want to +limit the number of times a particular client requests the same static asset. +Ideally a client would cache a particular static asset "forever", requiring +it to be sent to the client a single time. The HTTP protocol allows you to +send headers with an HTTP response that can instruct a client to cache a +particular asset for an amount of time. As long as the client has a copy of +the asset in its cache and that cache hasn't expired, the client will use the +cached copy rather than request a new copy from the server. The drawback to +sending cache headers to the client for a static asset is that at some point +the static asset may change, and then you'll want the client to load a new copy +of the asset. Under normal circumstances you'd just need to wait for the +client's cached copy to expire before they get the new version of the static +resource. + +A commonly used workaround to this problem is a technique known as "cache +busting". Cache busting schemes generally involve generating a URL for a +static asset that changes when the static asset changes. This way headers can +be sent along with the static asset instructing the client to cache the asset +for a very long time. When a static asset is changed, the URL used to refer to +it in a web page also changes, so the client sees it as a new resource and +requests a copy, 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, `cache_bust` to +:meth:`~pyramid.config.Configurator.add_static_view`: + +.. code-block:: python + :linenos: + + # config is an instance of pyramid.config.Configurator + config.add_static_view(name='static', path='mypackage:folder/static', + cache_bust='md5') + +Supplying the `cache_bust` argument instructs :app:`Pyramid` to add a query +string to URLs generated for this static view which includes the md5 checksum +of the static file being served: + +.. code-block:: python + :linenos: + + js_url = request.static_url('mypackage:folder/static/js/myapp.js') + # Returns: 'http://www.example.com/static/js/myapp.js?md5=c9658b3c0a314a1ca21e5988e662a09e` + +When the asset changes, so will its md5 checksum, and therefore so will its +URL. Supplying the `cache_bust` argument also causes the static view to set +headers instructing clients to cache the asset for ten years, unless the +`max_cache_age` argument is also passed, in which case that value is used. + +.. note:: + + `md5` is currently the only possible value for the `cache_bust` argument to + :meth:`~pyramid.config.Configurator.add_static_view`. + +.. note:: + + md5 checksums are cached in RAM so if you change a static resource without + restarting your application, you may still generate URLs with a stale md5 + checksum. + .. index:: single: static assets view -- cgit v1.2.3 From 5e61602652b2963ee0ef2df30ac81f29c42d3415 Mon Sep 17 00:00:00 2001 From: Alexey Torkhov Date: Mon, 14 Jul 2014 22:49:59 +0400 Subject: Update i18n.rst To set output file for pot-create -o flag should be used, not redirect. --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 1de2c8941..cb2cd049c 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -326,7 +326,7 @@ application. You run a ``pot-create`` command to extract the messages: $ cd /place/where/myapplication/setup.py/lives $ mkdir -p myapplication/locale - $ $VENV/bin/pot-create src > myapplication/locale/myapplication.pot + $ $VENV/bin/pot-create -o myapplication/locale/myapplication.pot src The message catalog ``.pot`` template will end up in: -- cgit v1.2.3 From 4fcbd9e5351bb7ec417cb10ba89dc3af2a6ef9a7 Mon Sep 17 00:00:00 2001 From: Alexey Torkhov Date: Tue, 15 Jul 2014 12:35:13 +0400 Subject: Update i18n.rst msgfmt produces 'messages.mo' file in current dir by default, it needs -o to specify destination. Also, added ref to adding a translation directory. --- docs/narr/i18n.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index cb2cd049c..6bfbc5136 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -402,11 +402,11 @@ command from Gettext: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ msgfmt myapplication/locale/*/LC_MESSAGES/*.po + $ msgfmt -o myapplication/locale/es/LC_MESSAGES/myapplication.mo myapplication/locale/es/LC_MESSAGES/myapplication.po This will create a ``.mo`` file for each ``.po`` file in your application. As long as the :term:`translation directory` in which -the ``.mo`` file ends up in is configured into your application, these +the ``.mo`` file ends up in is configured into your application (see :ref:`adding_a_translation_directory`), these translations will be available to :app:`Pyramid`. .. index:: -- cgit v1.2.3 From faaed6c7cffb453aed823b80f4169e87bfbc8026 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 16 Jul 2014 10:28:47 -0500 Subject: remove mako docs that should be in pyramid_mako package --- docs/narr/environment.rst | 148 ---------------------------------------------- 1 file changed, 148 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 412635f08..7bac12ea7 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -13,7 +13,6 @@ single: reload settings single: default_locale_name single: environment variables - single: Mako environment settings single: ini file settings single: PasteDeploy settings @@ -396,153 +395,6 @@ Is equivalent to using the following statements in your configuration code: It is fine to use both or either form. -.. _mako_template_renderer_settings: - -Mako Template Render Settings ------------------------------ - -Mako derives additional settings to configure its template renderer that -should be set when using it. Many of these settings are optional and only need -to be set if they should be different from the default. The Mako Template -Renderer uses a subclass of Mako's `template lookup -`_ and accepts -several arguments to configure it. - -Mako Directories -~~~~~~~~~~~~~~~~ - -The value(s) supplied here are passed in as the template directories. They -should be in :term:`asset specification` format, for example: -``my.package:templates``. - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.directories`` | -| | -| | -| | -+-----------------------------+ - -Mako Module Directory -~~~~~~~~~~~~~~~~~~~~~ - -The value supplied here tells Mako where to store compiled Mako templates. If -omitted, compiled templates will be stored in memory. This value should be an -absolute path, for example: ``%(here)s/data/templates`` would use a directory -called ``data/templates`` in the same parent directory as the INI file. - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.module_directory`` | -| | -| | -| | -+-----------------------------+ - -Mako Input Encoding -~~~~~~~~~~~~~~~~~~~ - -The encoding that Mako templates are assumed to have. By default this is set -to ``utf-8``. If you wish to use a different template encoding, this value -should be changed accordingly. - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.input_encoding`` | -| | -| | -| | -+-----------------------------+ - -Mako Error Handler -~~~~~~~~~~~~~~~~~~ - -A callable (or a :term:`dotted Python name` which names a callable) which is -called whenever Mako compile or runtime exceptions occur. The callable is -passed the current context as well as the exception. If the callable returns -True, the exception is considered to be handled, else it is re-raised after -the function completes. Is used to provide custom error-rendering functions. - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.error_handler`` | -| | -| | -| | -+-----------------------------+ - -Mako Default Filters -~~~~~~~~~~~~~~~~~~~~ - -List of string filter names that will be applied to all Mako expressions. - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.default_filters`` | -| | -| | -| | -+-----------------------------+ - -Mako Import -~~~~~~~~~~~ - -String list of Python statements, typically individual "import" lines, which -will be placed into the module level preamble of all generated Python modules. - - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.imports`` | -| | -| | -| | -+-----------------------------+ - - -Mako Strict Undefined -~~~~~~~~~~~~~~~~~~~~~ - -``true`` or ``false``, representing the "strict undefined" behavior of Mako -(see `Mako Context Variables -`_). By -default, this is ``false``. - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.strict_undefined`` | -| | -| | -| | -+-----------------------------+ - -Mako Preprocessor -~~~~~~~~~~~~~~~~~ - -.. versionadded:: 1.1 - -A callable (or a :term:`dotted Python name` which names a callable) which is -called to preprocess the source before the template is called. The callable -will be passed the full template source before it is parsed. The return -result of the callable will be used as the template source code. - - -+-----------------------------+ -| Config File Setting Name | -+=============================+ -| ``mako.preprocessor`` | -| | -| | -| | -+-----------------------------+ - Examples -------- -- cgit v1.2.3 From b4245a312bfe7f99080d46c1f9814f2c5da2cbf1 Mon Sep 17 00:00:00 2001 From: nick knouf Date: Tue, 15 Jul 2014 17:04:07 -0400 Subject: Updating to current msginit syntax --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 6bfbc5136..95f663584 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -352,7 +352,7 @@ command from Gettext: $ cd /place/where/myapplication/setup.py/lives $ cd myapplication/locale $ mkdir -p es/LC_MESSAGES - $ msginit -l es es/LC_MESSAGES/myapplication.po + $ msginit -l es -o es/LC_MESSAGES/myapplication.po This will create a new the message catalog ``.po`` file will in: -- cgit v1.2.3 From f729a1e7f1efc27a6df1ae0eaca7fdffdd86ec2f Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Thu, 17 Jul 2014 16:04:28 -0400 Subject: Write the documentation. --- docs/narr/assets.rst | 72 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 13 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index a2976de22..97d473761 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -315,7 +315,7 @@ requests a copy, 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, `cache_bust` to +assets by passing the optional argument, ``cachebuster`` to :meth:`~pyramid.config.Configurator.add_static_view`: .. code-block:: python @@ -323,27 +323,22 @@ assets by passing the optional argument, `cache_bust` to # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='mypackage:folder/static', - cache_bust='md5') + cachebuster=True) -Supplying the `cache_bust` argument instructs :app:`Pyramid` to add a query -string to URLs generated for this static view which includes the md5 checksum -of the static file being served: +Setting the ``cachebuster`` argument instructs :app:`Pyramid` to use a cache +busting scheme which adds the md5 checksum for a static asset as a path segment +in the asset's URL: .. code-block:: python :linenos: js_url = request.static_url('mypackage:folder/static/js/myapp.js') - # Returns: 'http://www.example.com/static/js/myapp.js?md5=c9658b3c0a314a1ca21e5988e662a09e` + # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js` When the asset changes, so will its md5 checksum, and therefore so will its -URL. Supplying the `cache_bust` argument also causes the static view to set +URL. Supplying the ``cachebuster`` argument also causes the static view to set headers instructing clients to cache the asset for ten years, unless the -`max_cache_age` argument is also passed, in which case that value is used. - -.. note:: - - `md5` is currently the only possible value for the `cache_bust` argument to - :meth:`~pyramid.config.Configurator.add_static_view`. +``max_cache_age`` argument is also passed, in which case that value is used. .. note:: @@ -351,6 +346,57 @@ headers instructing clients to cache the asset for ten years, unless the restarting your application, you may still generate URLs with a stale md5 checksum. +Customizing the Cache Buster +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Revisiting from the previous section: + +.. code-block:: python + :linenos: + + # config is an instance of pyramid.config.Configurator + config.add_static_view(name='static', path='mypackage:folder/static', + cachebuster=True) + +Setting ``cachebuster`` to ``True`` instructs :app:`Pyramid` to use a default +cache busting implementation that should work for many situations. The +``cachebuster`` may be set to any object that implements the interface, +:class:`~pyramid.interfaces.ICacheBuster`. The above configuration is exactly +equivalent to: + +.. code-block:: python + :linenos: + + from pyramid.static import ( + Md5AssetTokenGenerator, + PathSegmentCacheBuster) + + # config is an instance of pyramid.config.Configurator + cachebuster = PathSegmentCacheBuster(Md5AssetTokenGenerator()) + config.add_static_view(name='static', path='mypackage:folder/static', + cachebuster=cachebuster) + +:app:`Pyramid` includes two ready to use cache buster implementations: +:class:`~pyramid.static.PathSegmentCacheBuster`, which inserts an asset token +in the path portion of the asset's URL, and +:class:`~pyramid.static.QueryStringCacheBuster`, which adds an asset token to +the query string of the asset's URL. Both of these classes have constructors +which accept a token generator function as an argument, allowing for the way a +token is generated to be decoupled from the way it is inserted into a URL. +:app:`Pyramid` provides a single asset token generator, +:meth:`~pyramid.static.Md5AssetTokenGenerator`. + +In order to implement your own cache buster, see the +:class:`~pyramid.interfaces.ICacheBuster` interface and the existing +implementations in the :mod:`~pyramid.static` module. + +.. note:: + + Many HTTP caching proxy implementations will fail to cache any URL which + has a query string. For this reason, you should probably prefer + :class:`~pyramid.static.PathSegementCacheBuster` to + :class:`~pyramid.static.QueryStringCacheBuster`. + .. index:: single: static assets view -- cgit v1.2.3 From 002da7991f4433e5fd5a07489038a6bd2720a526 Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Thu, 17 Jul 2014 16:10:52 -0400 Subject: Add index entry. --- docs/narr/assets.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 97d473761..642211f5b 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -286,6 +286,9 @@ the application is being run in development or in production (use a different suggestion for a pattern; any setting name other than ``media_location`` could be used. +.. index:: + single: Cache Busting + .. _cache_busting: Cache Busting -- cgit v1.2.3 From aa96dda157d39c57c0d2fe8399db0b2175fa83d2 Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Fri, 18 Jul 2014 17:18:56 -0400 Subject: Take mcdonc's advice. This should be easier for users to understand. --- docs/narr/assets.rst | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 642211f5b..7987d03a6 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -370,28 +370,18 @@ equivalent to: .. code-block:: python :linenos: - from pyramid.static import ( - Md5AssetTokenGenerator, - PathSegmentCacheBuster) + from pyramid.static import PathSegmentCacheBuster # config is an instance of pyramid.config.Configurator - cachebuster = PathSegmentCacheBuster(Md5AssetTokenGenerator()) config.add_static_view(name='static', path='mypackage:folder/static', - cachebuster=cachebuster) + cachebuster=PathSegmentCacheBuster()) :app:`Pyramid` includes two ready to use cache buster implementations: :class:`~pyramid.static.PathSegmentCacheBuster`, which inserts an asset token in the path portion of the asset's URL, and :class:`~pyramid.static.QueryStringCacheBuster`, which adds an asset token to -the query string of the asset's URL. Both of these classes have constructors -which accept a token generator function as an argument, allowing for the way a -token is generated to be decoupled from the way it is inserted into a URL. -:app:`Pyramid` provides a single asset token generator, -:meth:`~pyramid.static.Md5AssetTokenGenerator`. - -In order to implement your own cache buster, see the -:class:`~pyramid.interfaces.ICacheBuster` interface and the existing -implementations in the :mod:`~pyramid.static` module. +the query string of the asset's URL. Both of these classes generate md5 +checksums as asset tokens. .. note:: @@ -400,6 +390,29 @@ implementations in the :mod:`~pyramid.static` module. :class:`~pyramid.static.PathSegementCacheBuster` to :class:`~pyramid.static.QueryStringCacheBuster`. +In order to implement your own cache buster, you can write your own class from +scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` +interface. Alternatively you may choose to subclass one of the existing +implementations. One of the most likely scenarios is you'd want to change the +way the asset token is generated. To do this just subclass an existing +implementation and replace the :meth:`~pyramid.interfaces.ICacheBuster.token` +method. Here is an example which just uses a global setting for the asset +token: + +.. code-block:: python + :linenos: + + from pyramid.static import PathSegmentCacheBuster + + class MyCacheBuster(PathSegmentCacheBuster): + + def __init__(self, config): + # config is an instance of pyramid.config.Configurator + self._token = config.registry.settings['myapp.cachebust_token'] + + def token(self, pathspec): + return self._token + .. index:: single: static assets view -- cgit v1.2.3 From 6596304446f8369dfbcf264d143fe85d75832dba Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Mon, 21 Jul 2014 16:46:35 -0400 Subject: Add 'prevent_cachebuster' setting. --- docs/narr/assets.rst | 11 ++++++++++- docs/narr/environment.rst | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 7987d03a6..fea3fae48 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -349,6 +349,15 @@ headers instructing clients to cache the asset for ten years, unless the restarting your application, you may still generate URLs with a stale md5 checksum. +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 +``PYRAMID_PREVENT_CACHEBUSTER`` environment variable or the +``pyramid.prevent_cachebuster`` configuration value to a true value. + Customizing the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -387,7 +396,7 @@ checksums as asset tokens. Many HTTP caching proxy implementations will fail to cache any URL which has a query string. For this reason, you should probably prefer - :class:`~pyramid.static.PathSegementCacheBuster` to + :class:`~pyramid.static.PathSegmentCacheBuster` to :class:`~pyramid.static.QueryStringCacheBuster`. In order to implement your own cache buster, you can write your own class from diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 412635f08..7e2f19278 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -158,6 +158,26 @@ feature when this is true. | | | +---------------------------------+----------------------------------+ +Preventing Cache Busting +------------------------ + +Prevent the ``cachebuster`` static view configuration argument from having any +effect globally in this process when this value is true. No cache buster will +be configured or used when this is true. + +.. seealso:: + + See also :ref:`cache_busting`. + ++---------------------------------+----------------------------------+ +| Environment Variable Name | Config File Setting Name | ++=================================+==================================+ +| ``PYRAMID_PREVENT_CACHEBUSTER`` | ``pyramid.prevent_cachebuster`` | +| | or ``prevent_cachebuster`` | +| | | +| | | ++---------------------------------+----------------------------------+ + Debugging All ------------- -- cgit v1.2.3 From 15b979413c700fbc289328b25aaa4ba1c4cbdda9 Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Thu, 24 Jul 2014 17:13:08 -0400 Subject: cachebuster -> cachebust --- docs/narr/assets.rst | 20 ++++++++++---------- docs/narr/environment.rst | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index fea3fae48..7fb0ec40b 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -318,7 +318,7 @@ requests a copy, 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, ``cachebuster`` to +assets by passing the optional argument, ``cachebust`` to :meth:`~pyramid.config.Configurator.add_static_view`: .. code-block:: python @@ -326,9 +326,9 @@ assets by passing the optional argument, ``cachebuster`` to # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='mypackage:folder/static', - cachebuster=True) + cachebust=True) -Setting the ``cachebuster`` argument instructs :app:`Pyramid` to use a cache +Setting the ``cachebust`` argument instructs :app:`Pyramid` to use a cache busting scheme which adds the md5 checksum for a static asset as a path segment in the asset's URL: @@ -339,7 +339,7 @@ in the asset's URL: # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js` When the asset changes, so will its md5 checksum, and therefore so will its -URL. Supplying the ``cachebuster`` argument also causes the static view to set +URL. Supplying the ``cachebust`` argument also causes the static view to set headers instructing clients to cache the asset for ten years, unless the ``max_cache_age`` argument is also passed, in which case that value is used. @@ -355,8 +355,8 @@ 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 -``PYRAMID_PREVENT_CACHEBUSTER`` environment variable or the -``pyramid.prevent_cachebuster`` configuration value to a true value. +``PYRAMID_PREVENT_CACHEBUST`` environment variable or the +``pyramid.prevent_cachebust`` configuration value to a true value. Customizing the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -368,11 +368,11 @@ Revisiting from the previous section: # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='mypackage:folder/static', - cachebuster=True) + cachebust=True) -Setting ``cachebuster`` to ``True`` instructs :app:`Pyramid` to use a default +Setting ``cachebust`` to ``True`` instructs :app:`Pyramid` to use a default cache busting implementation that should work for many situations. The -``cachebuster`` may be set to any object that implements the interface, +``cachebust`` may be set to any object that implements the interface, :class:`~pyramid.interfaces.ICacheBuster`. The above configuration is exactly equivalent to: @@ -383,7 +383,7 @@ equivalent to: # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='mypackage:folder/static', - cachebuster=PathSegmentCacheBuster()) + cachebust=PathSegmentCacheBuster()) :app:`Pyramid` includes two ready to use cache buster implementations: :class:`~pyramid.static.PathSegmentCacheBuster`, which inserts an asset token diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 7e2f19278..a81ad19af 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -161,7 +161,7 @@ feature when this is true. Preventing Cache Busting ------------------------ -Prevent the ``cachebuster`` static view configuration argument from having any +Prevent the ``cachebust`` static view configuration argument from having any effect globally in this process when this value is true. No cache buster will be configured or used when this is true. @@ -172,8 +172,8 @@ be configured or used when this is true. +---------------------------------+----------------------------------+ | Environment Variable Name | Config File Setting Name | +=================================+==================================+ -| ``PYRAMID_PREVENT_CACHEBUSTER`` | ``pyramid.prevent_cachebuster`` | -| | or ``prevent_cachebuster`` | +| ``PYRAMID_PREVENT_CACHEBUST`` | ``pyramid.prevent_cachebust`` | +| | or ``prevent_cachebust`` | | | | | | | +---------------------------------+----------------------------------+ -- cgit v1.2.3 From f674a8f691d260d44e0f76e3afecfb15484c45b9 Mon Sep 17 00:00:00 2001 From: Chris Rossi Date: Mon, 28 Jul 2014 17:26:11 -0400 Subject: Mo' features, mo' problems. --- docs/narr/assets.rst | 87 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 25 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 7fb0ec40b..33677988d 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -379,25 +379,19 @@ equivalent to: .. code-block:: python :linenos: - from pyramid.static import PathSegmentCacheBuster + from pyramid.static import PathSegmentMd5CacheBuster # config is an instance of pyramid.config.Configurator config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=PathSegmentCacheBuster()) + cachebust=PathSegmentMd5CacheBuster()) -:app:`Pyramid` includes two ready to use cache buster implementations: -:class:`~pyramid.static.PathSegmentCacheBuster`, which inserts an asset token -in the path portion of the asset's URL, and -:class:`~pyramid.static.QueryStringCacheBuster`, which adds an asset token to -the query string of the asset's URL. Both of these classes generate md5 -checksums as asset tokens. - -.. note:: - - Many HTTP caching proxy implementations will fail to cache any URL which - has a query string. For this reason, you should probably prefer - :class:`~pyramid.static.PathSegmentCacheBuster` to - :class:`~pyramid.static.QueryStringCacheBuster`. +:app:`Pyramid` includes a handful of ready to use cache buster implementations: +:class:`~pyramid.static.PathSegmentMd5CacheBuster`, which inserts an md5 +checksum token in the path portion of the asset's URL, +:class:`~pyramid.static.QueryStringMd5CacheBuster`, which adds an md5 checksum +token to the query string of the asset's URL, and +:class:`~pyramid.static.QueryStringConstantCacheBuster`, which adds an +arbitrary token you provide to the query string of the asset's URL. In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` @@ -405,22 +399,65 @@ interface. Alternatively you may choose to subclass one of the existing implementations. One of the most likely scenarios is you'd want to change the way the asset token is generated. To do this just subclass an existing implementation and replace the :meth:`~pyramid.interfaces.ICacheBuster.token` -method. Here is an example which just uses a global setting for the asset -token: +method. Here is an example which just uses Git to get the hash of the +currently checked out code: .. code-block:: python :linenos: - - from pyramid.static import PathSegmentCacheBuster - class MyCacheBuster(PathSegmentCacheBuster): - - def __init__(self, config): - # config is an instance of pyramid.config.Configurator - self._token = config.registry.settings['myapp.cachebust_token'] + import os + import subprocess + from pyramid.static import PathSegmentMd5CacheBuster + + class GitCacheBuster(PathSegmentMd5CacheBuster): + """ + Assuming your code is installed as a Git checkout, as opposed to as an + egg 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): + here = os.path.dirname(os.path.abspath(__file__)) + self.sha1 = subprocess.check_output( + ['git', 'rev-parse', 'HEAD'], + cwd=here).strip() def token(self, pathspec): - return self._token + return self.sha1 + +Choosing a Cache Buster +~~~~~~~~~~~~~~~~~~~~~~~ + +The default cache buster implementation, +:class:`~pyramid.static.PathSegmentMd5CacheBuster`, works very well assuming +that you're using :app:`Pyramid` to serve your static assets. The md5 checksum +is fine grained enough that browsers should only request new versions of +specific assets that have changed. Many caching HTTP proxies will fail to +cache a resource if the URL contains a query string. In general, therefore, +you should prefer a cache busting strategy which modifies the path segment to +a strategy which adds a query string. + +It is possible, however, that your static assets are being served by another +web server or externally on a CDN. In these cases modifying the path segment +for a static asset URL would cause the external service to fail to find the +asset, causing your customer to get a 404. In these cases you would need to +fall back to a cache buster which adds a query string. It is even possible +that there isn't a copy of your static assets available to the :app:`Pyramid` +application, so a cache busting implementation that generates md5 checksums +would fail since it can't access the assets. In such a case, +:class:`~pyramid.static.QueryStringConstantCacheBuster` is a reasonable +fallback. 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', + cachebust=QueryStringConstantCacheBuster(str(time.time()))) .. index:: single: static assets view -- cgit v1.2.3 From 6b88bdf7680151345debec0c8651f164a149a53a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 28 Jul 2014 21:06:34 -0400 Subject: add versionadded notes --- docs/narr/assets.rst | 2 ++ docs/narr/environment.rst | 2 ++ 2 files changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 33677988d..95863848b 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -294,6 +294,8 @@ could be used. Cache Busting ------------- +.. versionadded:: 1.6 + In order to maximize performance of a web application, you generally want to limit the number of times a particular client requests the same static asset. Ideally a client would cache a particular static asset "forever", requiring diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index a81ad19af..e1171d710 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -165,6 +165,8 @@ Prevent the ``cachebust`` static view configuration argument from having any effect globally in this process when this value is true. No cache buster will be configured or used when this is true. +.. versionadded:: 1.6 + .. seealso:: See also :ref:`cache_busting`. -- cgit v1.2.3 From 1a768e3d45594d2458c379bcd55d6f1478ef3281 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Fri, 8 Aug 2014 23:22:24 -0500 Subject: Link to .ini file description in configuration chapter. The Startup chapter describes a Pyramid application's .ini file. This is now a seealso in the Configuration chapter. --- docs/narr/configuration.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index 52615533d..f7fa94daf 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -17,6 +17,10 @@ plugging application code that you've written into :app:`Pyramid` is also referred to within this documentation as "configuration"; you are configuring :app:`Pyramid` to call the code that makes up your application. +.. seealso:: + For information on ``.ini`` files for Pyramid applications see the + :ref:`startup_chapter` chapter. + There are two ways to configure a :app:`Pyramid` application: :term:`imperative configuration` and :term:`declarative configuration`. Both are described below. -- cgit v1.2.3 From ad76ef6ab78847ef86abf97868a32e9604aaab7e Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Fri, 8 Aug 2014 23:28:13 -0500 Subject: Link to logging configuration in the Startup chapter. The Startup chapter describes the application's .ini file. The Logging chapter describes how to configure logging with the .ini file. --- docs/narr/logging.rst | 9 +++++++++ docs/narr/startup.rst | 7 +++++++ 2 files changed, 16 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 71029bb33..783fca932 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -294,6 +294,15 @@ use the :term:`pyramid_exclog` package. Details about its configuration are in its `documentation `_. +.. index:: + single: TransLogger + single: middleware; TransLogger + pair: configuration; middleware + single: settings; middleware + pair: .ini; middleware + +.. _request_logging_with_pastes_translogger: + Request Logging with Paste's TransLogger ---------------------------------------- diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index 7b4a7ea08..cd44e0ee3 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -139,6 +139,13 @@ Here's a high-level time-ordered overview of what happens when you press 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. There, in :ref:`request_logging_with_pastes_translogger`, + you will also find an example of how to configure + :term:`middleware` to add pre-packaged functionality to your + application. + .. index:: pair: settings; deployment single: custom settings -- cgit v1.2.3 From 4a63f6ac8f19d21eebf23bd8c9f833f2b676287b Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Fri, 8 Aug 2014 23:30:04 -0500 Subject: Add index entries for .ini files vis settings. --- docs/narr/logging.rst | 5 +++++ docs/narr/startup.rst | 1 + 2 files changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 783fca932..68da0813c 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -16,6 +16,11 @@ how to send log messages to loggers that you've configured. a third-party scaffold which does not create these files, the configuration information in this chapter may not be applicable. +.. index: + pair: settings; logging + pair: .ini; logging + pair: logging; configuration + .. _logging_config: Logging Configuration diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index cd44e0ee3..a1a23ed52 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -19,6 +19,7 @@ console. .. index:: single: startup process + pair: settings; .ini The Startup Process ------------------- -- cgit v1.2.3 From dcc6b4aceb140a5b6e03b1d3b0f32d925cbe879c Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Sun, 10 Aug 2014 21:31:01 -0500 Subject: Some improvements to the paste.translogger related docs. Synchronizes with Waitress docs. --- docs/narr/logging.rst | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 71029bb33..8f6c74fd4 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -297,12 +297,14 @@ in its `documentation Request Logging with Paste's TransLogger ---------------------------------------- -Paste provides the `TransLogger -`_ :term:`middleware` for -logging requests using the `Apache Combined Log Format -`_. TransLogger combined -with a FileHandler can be used to create an ``access.log`` file similar to -Apache's. +The term:`WSGI` design is modular. Waitress logs error conditions, debugging +output, etc., but not web traffic. For web traffic logging Paste provides the +`TransLogger `_ +:term:`middleware`. TransLogger produces logs in the `Apache Combined Log +Format `_. But +TransLogger does not write to files, the Python logging system must be +configured to do this. The Python FileHandler_ logging handler can be used +alongside TransLogger to create an ``access.log`` file similar to Apache's. Like any standard :term:`middleware` with a Paste entry point, TransLogger can be configured to wrap your application using ``.ini`` file syntax. First, @@ -343,10 +345,12 @@ function of your project's ``__init__`` file: app = TransLogger(app, setup_console_handler=False) return app -TransLogger will automatically setup a logging handler to the console when -called with no arguments, so it 'just works' in environments that don't -configure logging. Since we've configured our own logging handlers, we need -to disable that option via ``setup_console_handler = False``. + +.. note:: + TransLogger will automatically setup a logging handler to the console when + called with no arguments, so it 'just works' in environments that don't + configure logging. Since our logging handlers are configured we disable + the automation via ``setup_console_handler = False``. With the filter in place, TransLogger's logger (named the ``wsgi`` logger) will propagate its log messages to the parent logger (the root logger), sending @@ -361,9 +365,9 @@ its output to the console when we request a page: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6" -To direct TransLogger to an ``access.log`` FileHandler, we need to add that -FileHandler to the list of handlers (named ``accesslog``), and ensure that the -``wsgi`` logger is configured and uses this handler accordingly: +To direct TransLogger to an ``access.log`` FileHandler, we need the following +to add a FileHandler (named ``accesslog``) to the list of handlers, and ensure +that the ``wsgi`` logger is configured and uses this handler accordingly: .. code-block:: ini @@ -395,7 +399,7 @@ directs its records only to the ``accesslog`` handler. Finally, there's no need to use the ``generic`` formatter with TransLogger as TransLogger itself provides all the information we need. We'll use a formatter that passes-through the log messages as is. Add a new formatter -called ``accesslog`` by include the following in your configuration file: +called ``accesslog`` by including the following in your configuration file: .. code-block:: ini @@ -405,7 +409,9 @@ called ``accesslog`` by include the following in your configuration file: [formatter_accesslog] format = %(message)s -Then wire this new ``accesslog`` formatter into the FileHandler: + +Finally alter the existing configuration to wire this new +``accesslog`` formatter into the FileHandler: .. code-block:: ini -- cgit v1.2.3 From 81719b800cfea1c6fd68427ea1d9c0a2f3e6c1dd Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 12 Aug 2014 21:56:26 -0500 Subject: Docs: Make clear that a userid need not be a principal. --- docs/narr/security.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 8db23a33b..57d7ac38f 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -611,9 +611,9 @@ that implements the following interface: def effective_principals(self, request): """ Return a sequence representing the effective principals - including the userid and any groups belonged to by the current - user, including 'system' groups such as - ``pyramid.security.Everyone`` and + typically including the userid and any groups belonged to + by the current user, always including 'system' groups such + as ``pyramid.security.Everyone`` and ``pyramid.security.Authenticated``. """ def remember(self, request, principal, **kw): -- cgit v1.2.3 From c7afe4e43ab19a5e8274988fe8dd004c04c160a1 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 12 Aug 2014 22:10:03 -0500 Subject: Security: Change "principal" argument in security.remember() to "userid". Make the change througout the authentication policies, etc. as well. --- docs/narr/security.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 57d7ac38f..16718cfa4 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -104,9 +104,9 @@ For example: The above configuration enables a policy which compares the value of an "auth ticket" cookie passed in the request's environment which contains a reference -to a single :term:`principal` against the principals present in any -:term:`ACL` found in the resource tree when attempting to call some -:term:`view`. +to a single :term:`userid` and matches that userid's principals against the +principals present in any :term:`ACL` found in the resource tree when +attempting to call some :term:`view`. While it is possible to mix and match different authentication and authorization policies, it is an error to configure a Pyramid application @@ -616,11 +616,11 @@ that implements the following interface: as ``pyramid.security.Everyone`` and ``pyramid.security.Authenticated``. """ - def remember(self, request, principal, **kw): + def remember(self, request, userid, **kw): """ Return a set of headers suitable for 'remembering' the - principal named ``principal`` when set in a response. An - individual authentication policy and its consumers can decide - on the composition and meaning of **kw. """ + userid named ``userid`` when set in a response. An + individual authentication policy and its consumers can + decide on the composition and meaning of **kw. """ def forget(self, request): """ Return a set of headers suitable for 'forgetting' the -- cgit v1.2.3 From dc324784193a577bc039dcddb0651ef5ec9e6f57 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 12 Aug 2014 22:12:25 -0500 Subject: Docs: Make "userid" link to the glossary term. --- docs/narr/security.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 16718cfa4..f3879d0ba 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -595,19 +595,21 @@ that implements the following interface: """ An object representing a Pyramid authentication policy. """ def authenticated_userid(self, request): - """ Return the authenticated userid or ``None`` if no - authenticated userid can be found. This method of the policy - should ensure that a record exists in whatever persistent store is - used related to the user (the user should not have been deleted); - if a record associated with the current id does not exist in a - persistent store, it should return ``None``.""" + """ Return the authenticated :term:`userid` or ``None`` if + no authenticated userid can be found. This method of the + policy should ensure that a record exists in whatever + persistent store is used related to the user (the user + should not have been deleted); if a record associated with + the current id does not exist in a persistent store, it + should return ``None``.""" def unauthenticated_userid(self, request): - """ Return the *unauthenticated* userid. This method performs the - same duty as ``authenticated_userid`` but is permitted to return the - userid based only on data present in the request; it needn't (and - shouldn't) check any persistent store to ensure that the user record - related to the request userid exists.""" + """ Return the *unauthenticated* userid. This method + performs the same duty as ``authenticated_userid`` but is + permitted to return the userid based only on data present + in the request; it needn't (and shouldn't) check any + persistent store to ensure that the user record related to + the request userid exists.""" def effective_principals(self, request): """ Return a sequence representing the effective principals -- cgit v1.2.3 From a0cba72fb9925a1476ebf0848fa6ae07bbea5840 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 12 Aug 2014 22:33:48 -0500 Subject: Docs: Include the concept of credentials in the high level security overview. --- docs/narr/security.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index f3879d0ba..29c62d9f3 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -13,6 +13,11 @@ authorization system can use the credentials in the :term:`request` along with the :term:`context` resource to determine if access will be allowed. Here's how it works at a high level: +- A user may or may not have previously visited the application and + supplied authentication credentials, including a :term:`userid`. If + so, the application may have called + :func:`pyramid.security.remember` to remember these. + - A :term:`request` is generated when a user visits the application. - Based on the request, a :term:`context` resource is located through @@ -25,7 +30,9 @@ allowed. Here's how it works at a high level: context as well as other attributes of the request. - If an :term:`authentication policy` is in effect, it is passed the - request; it returns some number of :term:`principal` identifiers. + request. Based on the request and the remembered (or lack of) + :term:`userid` and related credentials it returns some number of + :term:`principal` identifiers. - If an :term:`authorization policy` is in effect and the :term:`view configuration` associated with the view callable that was found has -- cgit v1.2.3 From 6bedf31e5275c2f2a33051a547aa1dc722aafa97 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 12 Aug 2014 23:05:35 -0500 Subject: Docs: Add resource tree into security overview. --- docs/narr/security.rst | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 29c62d9f3..e6bbff44e 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -20,6 +20,12 @@ allowed. Here's how it works at a high level: - A :term:`request` is generated when a user visits the application. +- If an :term:`authorization policy` is in effect the application uses + the request and it's :term:`root factory` to create a :ref:`resource tree + ` of :term:`contexts `. The resource + tree maps contexts to URLs and within the contexts the application + puts declarations which authorize access. + - Based on the request, a :term:`context` resource is located through :term:`resource location`. A context is located differently depending on whether the application uses :term:`traversal` or :term:`URL dispatch`, but -- cgit v1.2.3 From 03e95958a9c2b9042e55bc55e4cdb193649857ef Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 12 Aug 2014 23:42:20 -0500 Subject: Docs: Switched first 2 paragraphs of security overview. --- docs/narr/security.rst | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index e6bbff44e..203962751 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -6,8 +6,18 @@ Security ======== -:app:`Pyramid` provides an optional declarative authorization system -that can prevent a :term:`view` from being invoked based on an +:app:`Pyramid` provides an optional, declarative, security system. +Security in :app:`Pyramid`, unlike many systems, cleanly and explicitly +separates authentication and authorization. Authentication is merely the +mechanism by which credentials provided in the :term:`request` are +resolved to one or more :term:`principal` identifiers. These identifiers +represent the users and groups in effect during the request. +Authorization then determines access based on the :term:`principal` +identifiers, the :term:`view callable` being invoked, and the +:term:`context` resource. + +The :app:`Pyramid` authorization system +can prevent a :term:`view` from being invoked based on an :term:`authorization policy`. Before a view is invoked, the authorization system can use the credentials in the :term:`request` along with the :term:`context` resource to determine if access will be @@ -54,14 +64,6 @@ allowed. Here's how it works at a high level: - If the authorization policy denies access, the view callable is not invoked; instead the :term:`forbidden view` is invoked. -Security in :app:`Pyramid`, unlike many systems, cleanly and explicitly -separates authentication and authorization. Authentication is merely the -mechanism by which credentials provided in the :term:`request` are -resolved to one or more :term:`principal` identifiers. These identifiers -represent the users and groups in effect during the request. -Authorization then determines access based on the :term:`principal` -identifiers, the :term:`view callable` being invoked, and the -:term:`context` resource. Authorization is enabled by modifying your application to include an :term:`authentication policy` and :term:`authorization policy`. -- cgit v1.2.3 From fe83c6bfdab16818cb434d95a09bd6510b43aa24 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 13 Aug 2014 10:48:22 -0500 Subject: some tweaks to the usage of userid in the docs --- docs/narr/security.rst | 69 ++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 30 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 203962751..2dc0c76af 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -7,14 +7,14 @@ Security ======== :app:`Pyramid` provides an optional, declarative, security system. -Security in :app:`Pyramid`, unlike many systems, cleanly and explicitly -separates authentication and authorization. Authentication is merely the -mechanism by which credentials provided in the :term:`request` are -resolved to one or more :term:`principal` identifiers. These identifiers -represent the users and groups in effect during the request. -Authorization then determines access based on the :term:`principal` -identifiers, the :term:`view callable` being invoked, and the -:term:`context` resource. +Security in :app:`Pyramid` is separated into authentication and +authorization. The two systems communicate via :term:`principal` +identifiers. Authentication is merely the mechanism by which credentials +provided in the :term:`request` are resolved to one or more +:term:`principal` identifiers. These identifiers represent the users and +groups that are in effect during the request. Authorization then determines +access based on the :term:`principal` identifiers, the requested +:term:`permission`, and a :term:`context`. The :app:`Pyramid` authorization system can prevent a :term:`view` from being invoked based on an @@ -30,12 +30,6 @@ allowed. Here's how it works at a high level: - A :term:`request` is generated when a user visits the application. -- If an :term:`authorization policy` is in effect the application uses - the request and it's :term:`root factory` to create a :ref:`resource tree - ` of :term:`contexts `. The resource - tree maps contexts to URLs and within the contexts the application - puts declarations which authorize access. - - Based on the request, a :term:`context` resource is located through :term:`resource location`. A context is located differently depending on whether the application uses :term:`traversal` or :term:`URL dispatch`, but @@ -46,9 +40,9 @@ allowed. Here's how it works at a high level: context as well as other attributes of the request. - If an :term:`authentication policy` is in effect, it is passed the - request. Based on the request and the remembered (or lack of) - :term:`userid` and related credentials it returns some number of - :term:`principal` identifiers. + request. It will return some number of :term:`principal` identifiers. + To do this, the policy would need to determine the authenticated + :term:`userid` present in the request. - If an :term:`authorization policy` is in effect and the :term:`view configuration` associated with the view callable that was found has @@ -64,7 +58,6 @@ allowed. Here's how it works at a high level: - If the authorization policy denies access, the view callable is not invoked; instead the :term:`forbidden view` is invoked. - Authorization is enabled by modifying your application to include an :term:`authentication policy` and :term:`authorization policy`. :app:`Pyramid` comes with a variety of implementations of these @@ -119,9 +112,10 @@ For example: The above configuration enables a policy which compares the value of an "auth ticket" cookie passed in the request's environment which contains a reference -to a single :term:`userid` and matches that userid's principals against the -principals present in any :term:`ACL` found in the resource tree when -attempting to call some :term:`view`. +to a single :term:`userid` and matches that userid's +:term:`principals ` against the principals present in any +:term:`ACL` found in the resource tree when attempting to call some +:term:`view`. While it is possible to mix and match different authentication and authorization policies, it is an error to configure a Pyramid application @@ -616,7 +610,9 @@ that implements the following interface: persistent store is used related to the user (the user should not have been deleted); if a record associated with the current id does not exist in a persistent store, it - should return ``None``.""" + should return ``None``. + + """ def unauthenticated_userid(self, request): """ Return the *unauthenticated* userid. This method @@ -624,24 +620,37 @@ that implements the following interface: permitted to return the userid based only on data present in the request; it needn't (and shouldn't) check any persistent store to ensure that the user record related to - the request userid exists.""" + the request userid exists. + + This method is intended primarily a helper to assist the + ``authenticated_userid`` method in pulling credentials out + of the request data, abstracting away the specific headers, + query strings, etc that are used to authenticate the request. + + """ def effective_principals(self, request): """ Return a sequence representing the effective principals - typically including the userid and any groups belonged to - by the current user, always including 'system' groups such + typically including the :term:`userid` and any groups belonged + to by the current user, always including 'system' groups such as ``pyramid.security.Everyone`` and - ``pyramid.security.Authenticated``. """ + ``pyramid.security.Authenticated``. + + """ def remember(self, request, userid, **kw): """ Return a set of headers suitable for 'remembering' the - userid named ``userid`` when set in a response. An + :term:`userid` named ``userid`` when set in a response. An individual authentication policy and its consumers can - decide on the composition and meaning of **kw. """ - + decide on the composition and meaning of **kw. + + """ + def forget(self, request): """ Return a set of headers suitable for 'forgetting' the - current user on subsequent requests. """ + current user on subsequent requests. + + """ After you do so, you can pass an instance of such a class into the :class:`~pyramid.config.Configurator.set_authentication_policy` method -- cgit v1.2.3 From ddc745ff6497a5c08c44e2fc8f722ad0034948dc Mon Sep 17 00:00:00 2001 From: Tim Tisdall Date: Thu, 14 Aug 2014 10:31:22 -0400 Subject: remove unnecessary use of `get_current_registry()` - We have a request object, so get the current registry properly through it. - make use of the built-in `aslist` function for parsing the result --- docs/narr/i18n.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 95f663584..3313f8dad 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -792,9 +792,11 @@ Then as a part of the code of a custom :term:`locale negotiator`: .. code-block:: python :linenos: - from pyramid.threadlocal import get_current_registry - settings = get_current_registry().settings - languages = settings['available_languages'].split() + from pyramid.settings import aslist + + def my_locale_negotiator(request): + languages = aslist(request.registry.settings['available_languages']) + # ... This is only a suggestion. You can create your own "available languages" configuration scheme as necessary. -- cgit v1.2.3 From c4c45446f79d6647aa6a90fc1f45def1319f7ac2 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Wed, 10 Sep 2014 11:15:21 -0600 Subject: Change helloworld to myapp Fix a typo in the documentation. Closes #1408 --- docs/narr/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 71029bb33..74d9f260e 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -242,7 +242,7 @@ level is set to ``INFO``, whereas the application's log level is set to [logger_myapp] level = DEBUG handlers = - qualname = helloworld + qualname = myapp All of the child loggers of the ``myapp`` logger will inherit the ``DEBUG`` level unless they're explicitly set differently. Meaning the ``myapp.views``, -- cgit v1.2.3 From 555969e05458b2e19305fd0a4f15ac3d27d3a90c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 11 Nov 2014 00:50:29 -0800 Subject: fix grammar --- docs/narr/i18n.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 3313f8dad..3c804a158 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -354,7 +354,7 @@ command from Gettext: $ mkdir -p es/LC_MESSAGES $ msginit -l es -o es/LC_MESSAGES/myapplication.po -This will create a new the message catalog ``.po`` file will in: +This will create a new message catalog ``.po`` file in: ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. -- cgit v1.2.3 From b542a4d723e5e994f693884618878186b94fa51c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 17 Nov 2014 01:10:11 -0600 Subject: improve the docs for absolute path overrides --- docs/narr/assets.rst | 65 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 74708ff3e..fc908c2b4 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -276,15 +276,62 @@ to put static media on a separate webserver during production (if the ``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is a URL), while keeping static media package-internal and served by the development webserver during development (if the ``name`` argument to -:meth:`~pyramid.config.Configurator.add_static_view` is a URL prefix). To -create such a circumstance, we suggest using the -:attr:`pyramid.registry.Registry.settings` API in conjunction with a setting -in the application ``.ini`` file named ``media_location``. Then set the -value of ``media_location`` to either a prefix or a URL depending on whether -the application is being run in development or in production (use a different -``.ini`` file for production than you do for development). This is just a -suggestion for a pattern; any setting name other than ``media_location`` -could be used. +:meth:`~pyramid.config.Configurator.add_static_view` is a URL prefix). + +For example, we may define a :ref:`custom setting ` +named ``media_location`` which we can set to an external URL in production +when our assets are hosted on a CDN. + +.. code-block:: python + :linenos: + + media_location = settings.get('media_location', 'static') + + config = Configurator(settings=settings) + config.add_static_view(path='myapp:static', name=media_location) + +Now we can optionally define the setting in our ini file: + +.. code-block:: ini + :linenos: + + # production.ini + [app:main] + use = egg:myapp#main + + media_location = http://static.example.com/ + +It is also possible to serve assets that live outside of the source by +referring to an absolute path on the filesystem. There are two ways to +accomplish this. + +First, :meth:`~pyramid.config.Configurator.add_static_view` +supports taking an absolute path directly instead of an asset spec. This works +as expected, looking in the file or folder of files and serving them up at +some URL within your application or externally. Unfortunately, this technique +has a drawback that it is not possible to use the +:meth:`~pyramid.request.Request.static_url` method to generate URLs, since it +works based on an asset spec. + +The second approach, available in Pyramid 1.6+, uses the asset overriding +APIs described in the :ref:`overriding_assets_section` section. It is then +possible to configure a "dummy" package which then serves its file or folder +from an absolute path. + +.. code-block:: python + + config.add_static_view(path='myapp:static_images', name='static') + config.override_asset(to_override='myapp:static_images/', + override_with='/abs/path/to/images/') + +From this configuration it is now possible to use +:meth:`~pyramid.request.Request.static_url` to generate URLs to the data +in the folder by doing something like +``request.static_url('myapp:static_images/foo.png')``. While it is not +necessary that the ``static_images`` file or folder actually exist in the +``myapp`` package, it is important that the ``myapp`` portion points to a +valid package. If the folder does exist then the overriden folder is given +priority if the file's name exists in both locations. .. index:: single: Cache Busting -- cgit v1.2.3 From 370862eb748f74dacee6b2bb1a5a2e35f865018a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 22 Nov 2014 23:31:50 -0800 Subject: add request processing diagram to docs/narr/router.rst --- docs/narr/router.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index ac3deefdc..745c2faa1 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -9,6 +9,9 @@ Request Processing ================== +.. image:: ../_static/pyramid_router.svg + :alt: Request Processing + Once a :app:`Pyramid` application is up and running, it is ready to accept requests and return responses. What happens from the time a :term:`WSGI` request enters a :app:`Pyramid` application through to the point that -- cgit v1.2.3 From 138706a24bd8e7051c60942c2789d8c16b4ca2ed Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 19 Nov 2014 23:06:17 +0000 Subject: Include code examples for integration and functional tests in docs #1001 Wrap lines as per convention. --- docs/narr/MyProject/myproject/tests.py | 37 +++++++++ docs/narr/MyProject/setup.py | 45 +++++++---- docs/narr/testing.rst | 142 +++++++++++++++------------------ 3 files changed, 131 insertions(+), 93 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/MyProject/myproject/tests.py b/docs/narr/MyProject/myproject/tests.py index 64dcab1d5..8c60407e5 100644 --- a/docs/narr/MyProject/myproject/tests.py +++ b/docs/narr/MyProject/myproject/tests.py @@ -15,3 +15,40 @@ class ViewTests(unittest.TestCase): request = testing.DummyRequest() info = my_view(request) 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 + app = main({}) + from webtest import TestApp + self.testapp = TestApp(app) + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue('Pyramid' in res.body) diff --git a/docs/narr/MyProject/setup.py b/docs/narr/MyProject/setup.py index 8c019af51..9f34540a7 100644 --- a/docs/narr/MyProject/setup.py +++ b/docs/narr/MyProject/setup.py @@ -1,30 +1,42 @@ -import os +"""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 f: - README = f.read() -with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() -requires = [ +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() + + +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='', @@ -32,11 +44,10 @@ setup(name='MyProject', packages=find_packages(), include_package_data=True, zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="myproject", + install_requires=REQUIRES, + tests_require=TESTS_REQUIRE, + test_suite='myproject', entry_points="""\ [paste.app_factory] main = myproject:main - """, - ) + """) diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index e001ad81c..3620f5e11 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -128,8 +128,9 @@ functions accepts various arguments that influence the environment of the test. See the :ref:`testing_module` API for information about the extra arguments supported by these functions. -If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something -other than ``None`` during the course of a single test, you can pass a +If you also want to make :func:`~pyramid.threadlocal.get_current_request` +return something other than ``None`` during the course of a single test, you +can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within the ``setUp`` method of your test: @@ -333,66 +334,49 @@ Creating Integration Tests -------------------------- In :app:`Pyramid`, a *unit test* typically relies on "mock" or "dummy" -implementations to give the code under test only enough context to run. +implementations to give the code under test enough context to run. "Integration testing" implies another sort of testing. In the context of a -:app:`Pyramid` integration test, the test logic tests the functionality of -some code *and* its integration with the rest of the :app:`Pyramid` +:app:`Pyramid` integration test, the test logic exercises the functionality of +the code under test *and* its integration with the rest of the :app:`Pyramid` framework. -In :app:`Pyramid` applications that are plugins to Pyramid, you can create an -integration test by including its ``includeme`` function via -:meth:`pyramid.config.Configurator.include` in the test's setup code. This -causes the entire :app:`Pyramid` environment to be set up and torn down as if -your application was running "for real". This is a heavy-hammer way of -making sure that your tests have enough context to run properly, and it tests -your code's integration with the rest of :app:`Pyramid`. +Creating an integration test for a :app:`Pyramid` application usually means +invoking the application's ``includeme`` function via +:meth:`pyramid.config.Configurator.include` within the test's setup code. This +causes the entire :app:`Pyramid` environment to be set up, simulating what +happens when your application is run "for real". This is a heavy-hammer way of +making sure that your tests have enough context to run properly, and tests your +code's integration with the rest of :app:`Pyramid`. -Let's demonstrate this by showing an integration test for a view. The below -test assumes that your application's package name is ``myapp``, and that -there is a ``views`` module in the app with a function with the name -``my_view`` in it that returns the response 'Welcome to this application' -after accessing some values that require a fully set up environment. +.. seealso:: -.. code-block:: python - :linenos: + See more information about :app:`Pyramid`'s ``includme`` function. - import unittest +Let's demonstrate this by showing an integration test for a view. - from pyramid import testing +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``: - class ViewIntegrationTests(unittest.TestCase): - def setUp(self): - """ This sets up the application registry with the - registrations your application declares in its ``includeme`` - function. - """ - import myapp - self.config = testing.setUp() - self.config.include('myapp') + .. literalinclude:: MyProject/myproject/views.py + :linenos: + :lines: 1-6 + :language: python - def tearDown(self): - """ Clear out the application registry """ - testing.tearDown() +You'd then create a ``tests`` module within your ``myproject`` package, +containing the following test code: - def test_my_view(self): - from myapp.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)))) - -Unless you cannot avoid it, you should prefer writing unit tests that use the -:class:`~pyramid.config.Configurator` API to set up the right "mock" -registrations rather than creating an integration test. Unit tests will run -faster (because they do less for each test) and the result of a unit test is -usually easier to make assertions about. + .. 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 +test) and are usually easier to reason about. .. index:: single: functional tests @@ -404,34 +388,40 @@ Creating Functional Tests Functional tests test your literal application. -The below test assumes that your application's package name is ``myapp``, and -that there is a view that returns an HTML body when the root URL is invoked. -It further assumes that you've added a ``tests_require`` dependency on the -``WebTest`` package within your ``setup.py`` file. :term:`WebTest` is a -functional testing package written by Ian Bicking. +In Pyramid, functional tests are typically written using the :term:`WebTest` +package, which provides APIs for invoking HTTP(S) requests to your application. -.. code-block:: python - :linenos: +Regardless of which testing :term:`package` you use, ensure to add a +``tests_require`` dependency on that package to to your application's +``setup.py`` file: - import unittest + .. literalinclude:: MyProject/setup.py + :linenos: + :emphasize-lines: 26-28,48 + :language: python - class FunctionalTests(unittest.TestCase): - def setUp(self): - from myapp import main - app = main({}) - from webtest import TestApp - self.testapp = TestApp(app) - - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertTrue('Pyramid' in res.body) - -When this test is run, each test creates a "real" WSGI application using the -``main`` function in your ``myapp.__init__`` module and uses :term:`WebTest` -to wrap that WSGI application. It assigns the result to ``self.testapp``. -In the test named ``test_root``, we use the testapp's ``get`` method to -invoke the root URL. We then assert that the returned HTML has the string -``Pyramid`` in it. +Assuming 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: + + .. literalinclude:: MyProject/myproject/views.py + :linenos: + :language: python + +Then the following example functional test (shown below) demonstrates invoking +the :term:`view` shown above: + + .. literalinclude:: MyProject/myproject/tests.py + :linenos: + :pyobject: FunctionalTests + :language: python + +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`` +method is used to invoke the root URL. Finally, an assertion is made that the +returned HTML contains the text ``MyProject``. See the :term:`WebTest` documentation for further information about the methods available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From 9c94e129f1bbb753317deba7ea5f790db13e0709 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Tue, 25 Nov 2014 20:59:18 +0000 Subject: Tweak seealso for the includeme function. --- docs/narr/testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index 3620f5e11..ecda57489 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -351,7 +351,7 @@ code's integration with the rest of :app:`Pyramid`. .. seealso:: - See more information about :app:`Pyramid`'s ``includme`` function. + See also :ref:`including_configuration` Let's demonstrate this by showing an integration test for a view. -- cgit v1.2.3 From 3408269bd291b771efef8e54f039038fc5b59a26 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 1 Dec 2014 13:40:39 -0800 Subject: - rename pyramid_router.svg to pyramid_request_processing.svg to be consistent with its content - add source files for future modifications --- docs/narr/router.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 745c2faa1..e82b66801 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -9,7 +9,7 @@ Request Processing ================== -.. image:: ../_static/pyramid_router.svg +.. image:: ../_static/pyramid_request_processing.svg :alt: Request Processing Once a :app:`Pyramid` application is up and running, it is ready to accept -- cgit v1.2.3 From 29e7a7d80149e84b844b68f093a7676ba9e400ee Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 1 Dec 2014 13:45:01 -0800 Subject: replace router.png with pyramid_router.svg and make design consistent --- docs/narr/router.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index e82b66801..693217a6b 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -119,7 +119,8 @@ request enters a :app:`Pyramid` application through to the point that #. The :term:`thread local` stack is popped. -.. image:: router.png +.. image:: ../_static/pyramid_router.svg + :alt: Pyramid Router This is a very high-level overview that leaves out various details. For more detail about subsystems invoked by the :app:`Pyramid` router such as -- cgit v1.2.3 From bb60b86feeea7cfbb531460b22ad40f211562708 Mon Sep 17 00:00:00 2001 From: Zack Marvel Date: Wed, 10 Dec 2014 01:25:11 -0500 Subject: Revise URL Dispatch documentation to use config.scan() in Examples 1, 2, and 3 In response to #600. --- docs/narr/urldispatch.rst | 57 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 87a962a9a..2fd971917 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -495,17 +495,20 @@ result in a particular view callable being invoked: :linenos: config.add_route('idea', 'site/{id}') - config.add_view('mypackage.views.site_view', route_name='idea') + config.scan() When a route configuration with a ``view`` attribute is added to the system, and an incoming request matches the *pattern* of the route configuration, the :term:`view callable` named as the ``view`` attribute of the route configuration will be invoked. -In the case of the above example, when the URL of a request matches -``/site/{id}``, the view callable at the Python dotted path name -``mypackage.views.site_view`` will be called with the request. In other -words, we've associated a view callable directly with a route pattern. +Recall that ``config.scan`` is equivalent to calling ``config.add_view``, +because the ``@view_config`` decorator in ``mypackage.views``, shown below, +maps the route name to the matching view callable. In the case of the above +example, when the URL of a request matches ``/site/{id}``, the view callable at +the Python dotted path name ``mypackage.views.site_view`` will be called with +the request. In other words, we've associated a view callable directly with a +route pattern. When the ``/site/{id}`` route pattern matches during a request, the ``site_view`` view callable is invoked with that request as its sole @@ -519,8 +522,10 @@ The ``mypackage.views`` module referred to above might look like so: .. code-block:: python :linenos: + from pyramid.view import view_config from pyramid.response import Response + @view_config(route_name='idea') def site_view(request): return Response(request.matchdict['id']) @@ -542,11 +547,30 @@ add to your application: config.add_route('idea', 'ideas/{idea}') config.add_route('user', 'users/{user}') config.add_route('tag', 'tags/{tag}') + config.scan() + +Here is an example of a corresponding ``mypackage.views`` module: - config.add_view('mypackage.views.idea_view', route_name='idea') - config.add_view('mypackage.views.user_view', route_name='user') - config.add_view('mypackage.views.tag_view', route_name='tag') +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + @view_config(route_name='idea') + def idea_view(request): + return Response(request.matchdict['id']) + + @view_config(route_name='user') + def user_view(request): + user = request.matchdict['user'] + return Response(u'The user is {}.'.format(user)) + + @view_config(route_name='tag') + def tag_view(request): + tag = request.matchdict['tag'] + return Response(u'The tag is {}.'.format(tag)) + The above configuration will allow :app:`Pyramid` to service URLs in these forms: @@ -596,7 +620,7 @@ An example of using a route with a factory: :linenos: config.add_route('idea', 'ideas/{idea}', factory='myproject.resources.Idea') - config.add_view('myproject.views.idea_view', route_name='idea') + config.scan() The above route will manufacture an ``Idea`` resource as a :term:`context`, assuming that ``mypackage.resources.Idea`` resolves to a class that accepts a @@ -610,7 +634,20 @@ request in its ``__init__``. For example: pass In a more complicated application, this root factory might be a class -representing a :term:`SQLAlchemy` model. +representing a :term:`SQLAlchemy` model. The view ``mypackage.views.idea_view`` +might look like this: + +.. code-block:: python + :linenos: + + @view_config(route_name='idea') + def idea_view(request): + idea = request.context + return Response(idea) + +Here, ``request.context`` is an instance of ``Idea``. If indeed the resource +object is a SQLAlchemy model, you do not even have to perform a query in the +view callable, since you have access to the resource via ``request.context``. See :ref:`route_factories` for more details about how to use route factories. -- cgit v1.2.3 From 2711913daac645dc1960074d6c5121c8fb49b772 Mon Sep 17 00:00:00 2001 From: Adrian Teng Date: Wed, 17 Dec 2014 00:06:27 +0000 Subject: Add documentation on handling CORS pre-flights --- docs/narr/webob.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 6a331e4bf..7d459a1f5 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -310,6 +310,10 @@ Python's ``urllib2`` instead of a Javascript AJAX request: req = urllib2.Request('http://localhost:6543/', json_payload, headers) resp = urllib2.urlopen(req) +If you are doing Cross-origin resource sharing (CORS), then the standard requires the browser to do a pre-flight HTTP OPTIONS request. The easiest way to handling this is adding an extra ``view_config`` for the same route, with ``request_method`` set to ``OPTIONS``, and setting the desired response header before returning. You can find examples of response headers here_. + +.. _here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests + .. index:: single: cleaning up after request -- cgit v1.2.3 From 2660f5053de5383aacf4ceff3d4e05d7e73f1635 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 16 Dec 2014 19:54:03 -0500 Subject: 79 cols --- docs/narr/webob.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 7d459a1f5..0eb070b06 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -310,7 +310,11 @@ Python's ``urllib2`` instead of a Javascript AJAX request: req = urllib2.Request('http://localhost:6543/', json_payload, headers) resp = urllib2.urlopen(req) -If you are doing Cross-origin resource sharing (CORS), then the standard requires the browser to do a pre-flight HTTP OPTIONS request. The easiest way to handling this is adding an extra ``view_config`` for the same route, with ``request_method`` set to ``OPTIONS``, and setting the desired response header before returning. You can find examples of response headers here_. +If you are doing Cross-origin resource sharing (CORS), then the standard +requires the browser to do a pre-flight HTTP OPTIONS request. The easiest way +to handling this is adding an extra ``view_config`` for the same route, with +``request_method`` set to ``OPTIONS``, and setting the desired response header +before returning. You can find examples of response headers here_. .. _here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests -- cgit v1.2.3 From 8c54a34d5d3211537b8705b04ae8662274641828 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 26 Dec 2014 02:32:58 -0800 Subject: - adding back .png file because PDF cannot include and build SVG files. Also renamed images to use a 'imagename.*' wildcard so that the correct format is chosen. See http://stackoverflow.com/questions/6473660/using-sphinx-docs-how-can-i-specify-png-image-formats-for-html-builds-and-pdf-im --- docs/narr/router.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 693217a6b..6f90c70cc 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -9,7 +9,7 @@ Request Processing ================== -.. image:: ../_static/pyramid_request_processing.svg +.. image:: ../_static/pyramid_request_processing.* :alt: Request Processing Once a :app:`Pyramid` application is up and running, it is ready to accept @@ -119,7 +119,7 @@ request enters a :app:`Pyramid` application through to the point that #. The :term:`thread local` stack is popped. -.. image:: ../_static/pyramid_router.svg +.. image:: ../_static/pyramid_router.* :alt: Pyramid Router This is a very high-level overview that leaves out various details. For more -- cgit v1.2.3 From c569571bdb6e8c001ab0bc11777a2e0cca72d2fb Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 27 Dec 2014 01:55:25 -0600 Subject: add action-order documentation --- docs/narr/extconfig.rst | 99 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 6587aef92..c4d3e0250 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -215,13 +215,110 @@ registers an action with a higher order than the passed to it, that a route by this name was already registered by ``add_route``, and if such a route has not already been registered, it's a configuration error (a view that names a nonexistent route via its -``route_name`` parameter will never be called). +``route_name`` parameter will never be called). As of Pyramid 1.6 it is +possible for one action to invoke another. See :ref:`ordering_actions` for +more information. ``introspectables`` is a sequence of :term:`introspectable` objects. You can pass a sequence of introspectables to the :meth:`~pyramid.config.Configurator.action` method, which allows you to augment Pyramid's configuration introspection system. +.. _ordering_actions: + +Ordering Actions +---------------- + +In Pyramid every :term:`action` has an inherent ordering relative to other +actions. The logic within actions is deferred until a call to +:meth:`pyramid.config.Configurator.commit` (which is automatically invoked by +:meth:`pyramid.config.Configurator.make_wsgi_app`). This means you may call +``config.add_view(route_name='foo')`` **before** +``config.add_route('foo', '/foo')`` because nothing actually happens until +commit-time when conflicts are resolved, actions are ordered and executed. + +By default, almost every action in Pyramid has an ``order`` of ``0``. Every +action within the same order-level will be executed in the order it was called. +This means that if an action must be reliably executed before or after another +action, the ``order`` must be defined explicitly to make this work. For +example, views are dependent on routes being defined. Thus the action created +by :meth:`pyramid.config.Configurator.add_route` has an ``order`` of +:const:`pyramid.interfaces.PHASE2_CONFIG`. + +Pre-defined Phases +~~~~~~~~~~~~~~~~~~ + +:const:`pyramid.interfaces.PHASE1_CONFIG` + +- :meth:`pyramid.config.Configurator.add_renderer` +- :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.set_authorization_policy` +- :meth:`pyramid.config.Configurator.set_default_permission` +- :meth:`pyramid.config.Configurator.set_view_mapper` + +:const:`pyramid.interfaces.PHASE2_CONFIG` + +- :meth:`pyramid.config.Configurator.add_route` +- :meth:`pyramid.config.Configurator.set_authentication_policy` + +``0`` + +- The default for all builtin or custom directives unless otherwise specified. + +Calling Actions From Actions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.6 + +Pyramid's configurator allows actions to be added during a commit-cycle as +long as they are added to the current or a later ``order`` phase. This means +that your custom action can defer decisions until commit-time and then do +things like invoke :meth:`pyramid.config.Configurator.add_route`. It can also +provide better conflict detection if your addon needs to call more than one +other action. + +For example, let's make an addon that invokes ``add_route`` and ``add_view``, +but we want it to conflict with any other call to our addon: + +.. code-block:: python + :linenos: + + from pyramid.interfaces import PHASE1_CONFIG + + PHASE0_CONFIG = PHASE1_CONFIG - 10 + + def includeme(config): + config.add_directive(add_auto_route, 'add_auto_route') + + def add_auto_route(config, name, view): + def register(): + config.add_view(route_name=name, view=view) + config.add_route(name, '/' + name) + config.action(('auto route', name), register, order=PHASE0_CONFIG) + +Now someone else can use your addon and be informed if there is a conflict +between this route and another, or two calls to ``add_auto_route``. +Notice how we had to invoke our action **before** ``add_view`` or +``add_route``. If we tried to invoke this afterward, the subsequent calls to +``add_view`` and ``add_route`` would cause conflicts because that phase had +already been executed, and the configurator cannot go back in time to add more +views during that commit-cycle. + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def main(global_config, **settings): + config = Configurator() + config.include('auto_route_addon') + config.add_auto_route('foo', my_view) + + def my_view(request): + return request.response + .. _introspection: Adding Configuration Introspection -- cgit v1.2.3 From 1236dec0dcfd916bca4e233587f86baa8d2418a8 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Sat, 27 Dec 2014 00:18:23 -0800 Subject: Add the `set_response_factory` API --- docs/narr/hooks.rst | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4da36e730..f557527bb 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -354,6 +354,68 @@ We attach and cache an object named ``extra`` to the ``request`` object. .. _beforerender_event: +.. index:: + single: response factory + +.. _changing_the_response_factory: + +Changing the Response Factory +---------------------------- + +Whenever :app:`Pyramid` returns a response from a view it creates a +:term:`response` object. By default, an instance of the +:class:`pyramid.response.Response` class is created to represent the response +object. + +The class (aka "factory") that :app:`Pyramid` uses to create a response object +instance can be changed by passing a ``response_factory`` argument to the +constructor of the :term:`configurator`. This argument can be either a +callable or a :term:`dotted Python name` representing a callable. + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + class MyResponse(Response): + pass + + config = Configurator(response_factory=MyResponse) + +If you're doing imperative configuration, and you'd rather do it after you've +already constructed a :term:`configurator` it can also be registered via the +:meth:`pyramid.config.Configurator.set_response_factory` method: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + + class MyResponse(Response): + pass + + config = Configurator() + config.set_response_factory(MyRequest) + +If you are already using a custom ```request_factory`` you can also set the +``ResponseClass`` on your :class:`pyramid.request.Request`: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + from pyramid.request import Request + + class MyResponse(Response): + pass + + class MyRequest(Request): + ResponseClass = MyResponse + + config = Configurator() + Using The Before Render Event ----------------------------- -- cgit v1.2.3 From e8a666655b5365a0adde32f2bd387b0d42690384 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Sat, 27 Dec 2014 00:23:18 -0800 Subject: basic docs cleanup --- 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 f557527bb..4702c09b0 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -360,7 +360,7 @@ We attach and cache an object named ``extra`` to the ``request`` object. .. _changing_the_response_factory: Changing the Response Factory ----------------------------- +------------------------------- Whenever :app:`Pyramid` returns a response from a view it creates a :term:`response` object. By default, an instance of the -- cgit v1.2.3 From 807e941787e157db882fcd95e13f5cafb7ebde7f Mon Sep 17 00:00:00 2001 From: John Anderson Date: Sat, 27 Dec 2014 13:33:39 -0800 Subject: Added a version added flag --- docs/narr/hooks.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4702c09b0..689ce9dc2 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -362,6 +362,8 @@ We attach and cache an object named ``extra`` to the ``request`` object. Changing the Response Factory ------------------------------- +.. versionadded:: 1.6 + Whenever :app:`Pyramid` returns a response from a view it creates a :term:`response` object. By default, an instance of the :class:`pyramid.response.Response` class is created to represent the response -- cgit v1.2.3 From 32cb805132e8149a276a8c65fdfa961384e8254e Mon Sep 17 00:00:00 2001 From: John Anderson Date: Thu, 1 Jan 2015 15:03:56 -0800 Subject: Mkae the response factory a factory that takes a request --- docs/narr/hooks.rst | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 689ce9dc2..e250c2d7e 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -369,10 +369,10 @@ Whenever :app:`Pyramid` returns a response from a view it creates a :class:`pyramid.response.Response` class is created to represent the response object. -The class (aka "factory") that :app:`Pyramid` uses to create a response object -instance can be changed by passing a ``response_factory`` argument to the -constructor of the :term:`configurator`. This argument can be either a -callable or a :term:`dotted Python name` representing a callable. +The factory that :app:`Pyramid` uses to create a response object instance can be +changed by passing a ``response_factory`` argument to the constructor of the +:term:`configurator`. This argument can be either a callable or a +:term:`dotted Python name` representing a callable. .. code-block:: python :linenos: @@ -382,7 +382,7 @@ callable or a :term:`dotted Python name` representing a callable. class MyResponse(Response): pass - config = Configurator(response_factory=MyResponse) + config = Configurator(response_factory=lambda r: MyResponse()) If you're doing imperative configuration, and you'd rather do it after you've already constructed a :term:`configurator` it can also be registered via the @@ -398,25 +398,8 @@ already constructed a :term:`configurator` it can also be registered via the pass config = Configurator() - config.set_response_factory(MyRequest) - -If you are already using a custom ```request_factory`` you can also set the -``ResponseClass`` on your :class:`pyramid.request.Request`: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - from pyramid.response import Response - from pyramid.request import Request - - class MyResponse(Response): - pass - - class MyRequest(Request): - ResponseClass = MyResponse + config.set_response_factory(lambda r: MyResponse()) - config = Configurator() Using The Before Render Event ----------------------------- -- cgit v1.2.3 From 22c836ecbc6f10c4851d88017243f91e469016aa Mon Sep 17 00:00:00 2001 From: John Anderson Date: Thu, 1 Jan 2015 22:17:13 -0800 Subject: Updated the docs to talk about `--format` --- docs/narr/commandline.rst | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 4f16617c4..02bb6138e 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -312,24 +312,49 @@ For example: :linenos: $ $VENV/bin/proutes development.ini - Name Pattern View - ---- ------- ---- - home / - home2 / - another /another None - static/ static/*subpath - catchall /*subpath - -``proutes`` generates a table with three columns: *Name*, *Pattern*, + Name Pattern View + ---- ------- ---- + debugtoolbar /_debug_toolbar/*subpath * + __static/ /static/*subpath dummy_starter:static/ * + __static2/ /static2/*subpath /var/www/static/ * + __pdt_images/ /pdt_images/*subpath pyramid_debugtoolbar:static/img/ * + a / * + no_view_attached / * + route_and_view_attached / app1.standard_views.route_and_view_attached * + method_conflicts /conflicts app1.standard_conflicts + multiview /multiview app1.standard_views.multiview GET,PATCH + not_post /not_post app1.standard_views.multview !POST,* + +``proutes`` generates a table with three columns: *Name*, *Pattern*, *Method*, and *View*. The items listed in the Name column are route names, the items listed in the Pattern column are route patterns, and the items listed in the View column are representations of the view callable that will be invoked when a request matches the associated -route pattern. The view column may show ``None`` if no associated view +route pattern. The view column may show ```` if no associated view callable could be found. If no routes are configured within your application, nothing will be printed to the console when ``proutes`` is executed. +It is convenient when using the ``proutes`` often to configure which columns +and the order you would like to view them. To facilitate this, ``proutes`` will +look for a special ``[proutes]`` section in your INI file and use those as +defaults. + +For example you may remove request method and place the view first: + +.. code-block:: text + :linenos: + + [proutes] + format = view + name + pattern + +If you want to temporarily configure the columns and order there is the +``--format` which is a comma separated list of columns you want to include. The +current available formats are ``name``, ``pattern``, ``view``, and ``method``. + + .. index:: pair: tweens; printing single: ptweens -- cgit v1.2.3 From 83a400a3cd121fe65d33e796c28a199b35ab67e5 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Thu, 1 Jan 2015 22:25:25 -0800 Subject: Terminated the highlight on ``format`` --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 02bb6138e..aca0ff425 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -351,7 +351,7 @@ For example you may remove request method and place the view first: pattern If you want to temporarily configure the columns and order there is the -``--format` which is a comma separated list of columns you want to include. The +``--format`` which is a comma separated list of columns you want to include. The current available formats are ``name``, ``pattern``, ``view``, and ``method``. -- cgit v1.2.3 From ef2a4abb2850af8d21995f04e9f30e6a8949ff9d Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Wed, 7 Jan 2015 14:42:27 +0200 Subject: Fix "pyramid" spelling --- docs/narr/hybrid.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 4a3258d35..1c324d22b 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -453,7 +453,7 @@ commonly in route declarations that look like this: .. code-block:: python :linenos: - from pryamid.static import static_view + from pyramid.static import static_view www = static_view('mypackage:static', use_subpath=True) -- cgit v1.2.3 From b6ad615549fb52c40f55760027bffbdd1a919aa1 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Wed, 7 Jan 2015 14:44:27 +0200 Subject: Fix "add_subscriber" spelling --- docs/narr/introspector.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index a7bde4cf7..0ff1615d1 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -121,7 +121,7 @@ introspectables in categories not described here. ``subscriber`` The subscriber callable object (the resolution of the ``subscriber`` - argument passed to ``add_susbcriber``). + argument passed to ``add_subscriber``). ``interfaces`` @@ -137,12 +137,12 @@ introspectables in categories not described here. ``predicates`` The predicate objects created as the result of passing predicate arguments - to ``add_susbcriber`` + to ``add_subscriber`` ``derived_predicates`` Wrappers around the predicate objects created as the result of passing - predicate arguments to ``add_susbcriber`` (to be used when predicates take + predicate arguments to ``add_subscriber`` (to be used when predicates take only one value but must be passed more than one). ``response adapters`` -- cgit v1.2.3 From 99d7c44610ad56bac0e90ba119b003ef11b2eb5a Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Wed, 7 Jan 2015 14:51:45 +0200 Subject: Fix rendering --- docs/narr/sessions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 8da743a01..f20a36d81 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -44,7 +44,7 @@ It is digitally signed, however, and thus its data cannot easily be tampered with. You can configure this session factory in your :app:`Pyramid` application -by using the :meth:`pyramid.config.Configurator.set_session_factory`` method. +by using the :meth:`pyramid.config.Configurator.set_session_factory` method. .. code-block:: python :linenos: @@ -380,7 +380,7 @@ Checking CSRF Tokens Manually ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In request handling code, you can check the presence and validity of a CSRF -token with :func:`pyramid.session.check_csrf_token(request)``. If the token is +token with ``pyramid.session.check_csrf_token(request)``. If the token is valid, it will return ``True``, otherwise it will raise ``HTTPBadRequest``. Optionally, you can specify ``raises=False`` to have the check return ``False`` instead of raising an exception. -- cgit v1.2.3 From 77db3c2c000d7209d1c486585d7227181e2a4286 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Wed, 7 Jan 2015 15:00:06 +0200 Subject: Fix typos in configuration introspection documentation --- docs/narr/introspector.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 0ff1615d1..8caba522c 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -450,9 +450,9 @@ introspectables in categories not described here. The :class:`pyramid.interfaces.IRendererInfo` object which represents this template's renderer. -``view mapper`` +``view mappers`` - Each introspectable in the ``permissions`` category represents a call to + Each introspectable in the ``view mappers`` category represents a call to :meth:`pyramid.config.Configurator.add_view` that has an explicit ``mapper`` argument to *or* a call to :meth:`pyramid.config.Configurator.set_view_mapper`; each will have @@ -481,8 +481,8 @@ introspectables in categories not described here. ``translation directories`` - Each introspectable in the ``asset overrides`` category represents an - individual element in a ``specs`` argument passed to + Each introspectable in the ``translation directories`` category represents + an individual element in a ``specs`` argument passed to :meth:`pyramid.config.Configurator.add_translation_dirs`; each will have the following data. @@ -511,7 +511,7 @@ introspectables in categories not described here. ``type`` - ``implict`` or ``explicit`` as a string. + ``implicit`` or ``explicit`` as a string. ``under`` -- cgit v1.2.3 From 3702ab07e835a06f30abf5ceb626f81114115062 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Wed, 7 Jan 2015 15:09:26 +0200 Subject: Fix typo --- 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 e250c2d7e..5bba0d143 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -777,7 +777,7 @@ If you want to implement your own Response object instead of using the :class:`pyramid.response.Response` object in any capacity at all, you'll have to make sure the object implements every attribute and method outlined in :class:`pyramid.interfaces.IResponse` and you'll have to ensure that it uses -``zope.interface.implementer(IResponse)`` as a class decoratoror. +``zope.interface.implementer(IResponse)`` as a class decorator. .. code-block:: python :linenos: -- cgit v1.2.3 From 47e85294779814f14e02327eb4d378197bbaeb29 Mon Sep 17 00:00:00 2001 From: Pavlo Kapyshin Date: Wed, 7 Jan 2015 19:10:31 +0200 Subject: Provide a ref to check_csrf_token --- docs/narr/sessions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index f20a36d81..5c103405a 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -380,7 +380,7 @@ Checking CSRF Tokens Manually ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In request handling code, you can check the presence and validity of a CSRF -token with ``pyramid.session.check_csrf_token(request)``. If the token is +token with :func:`pyramid.session.check_csrf_token`. If the token is valid, it will return ``True``, otherwise it will raise ``HTTPBadRequest``. Optionally, you can specify ``raises=False`` to have the check return ``False`` instead of raising an exception. -- cgit v1.2.3 From 8b5000f44cddd24df111c8a1d2ff65ee6d37afbb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 22 Jan 2015 02:46:09 -0800 Subject: move index and reference down to proper section so that docs will build on master again --- docs/narr/hooks.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 5bba0d143..17cae2c67 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -348,12 +348,6 @@ We attach and cache an object named ``extra`` to the ``request`` object. >>> request.extra.prop the property -.. index:: - single: before render event - single: adding renderer globals - -.. _beforerender_event: - .. index:: single: response factory @@ -400,6 +394,11 @@ already constructed a :term:`configurator` it can also be registered via the config = Configurator() config.set_response_factory(lambda r: MyResponse()) +.. index:: + single: before render event + single: adding renderer globals + +.. _beforerender_event: Using The Before Render Event ----------------------------- -- cgit v1.2.3 From 0e4dcf9f85babd94dcd9fc59513d257b4aba8d40 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 22 Jan 2015 03:46:27 -0800 Subject: apply changes from #1538 and #1539 --- docs/narr/logging.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index c16673ae6..921883091 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -254,16 +254,15 @@ level unless they're explicitly set differently. Meaning the ``myapp.views``, ``myapp.models`` (and all your app's modules') loggers by default have an effective level of ``DEBUG`` too. -For more advanced filtering, the logging module provides a `Filter -`_ object; however it cannot be used -directly from the configuration file. +For more advanced filtering, the logging module provides a +:class:`logging.Filter` object; however it cannot be used directly from the +configuration file. -Advanced Configuration +Advanced Configuration ---------------------- -To capture log output to a separate file, use a `FileHandler -`_ (or a `RotatingFileHandler -`_): +To capture log output to a separate file, use :class:`logging.FileHandler` (or +:class:`logging.handlers.RotatingFileHandler`): .. code-block:: ini @@ -317,8 +316,9 @@ output, etc., but not web traffic. For web traffic logging Paste provides the :term:`middleware`. TransLogger produces logs in the `Apache Combined Log Format `_. But TransLogger does not write to files, the Python logging system must be -configured to do this. The Python FileHandler_ logging handler can be used -alongside TransLogger to create an ``access.log`` file similar to Apache's. +configured to do this. The Python :class:`logging.FileHandler` logging +handler can be used alongside TransLogger to create an ``access.log`` file +similar to Apache's. Like any standard :term:`middleware` with a Paste entry point, TransLogger can be configured to wrap your application using ``.ini`` file syntax. First, -- cgit v1.2.3 From b8ba0f1ed25b118aeb05accb23d872b3a72dc548 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Thu, 22 Jan 2015 07:29:02 -0800 Subject: Make more ways to configure [proutes] section --- docs/narr/commandline.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index aca0ff425..3dcb092e2 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -350,6 +350,17 @@ For example you may remove request method and place the view first: name pattern +You can also separate the formats with commas or spaces: + +.. code-block:: text + :linenos: + + [proutes] + format = view name pattern + + [proutes] + format = view, name, pattern + If you want to temporarily configure the columns and order there is the ``--format`` which is a comma separated list of columns you want to include. The current available formats are ``name``, ``pattern``, ``view``, and ``method``. -- cgit v1.2.3 From c7bf2744f332c0294d8d673d21b56f5edacb2eae Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 27 Jan 2015 14:51:58 -0600 Subject: fix count --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 3dcb092e2..1fe2d9278 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -325,7 +325,7 @@ For example: multiview /multiview app1.standard_views.multiview GET,PATCH not_post /not_post app1.standard_views.multview !POST,* -``proutes`` generates a table with three columns: *Name*, *Pattern*, *Method*, +``proutes`` generates a table with four columns: *Name*, *Pattern*, *Method*, and *View*. The items listed in the Name column are route names, the items listed in the Pattern column are route patterns, and the items listed in the View column are representations of the -- cgit v1.2.3 From 5de795938f4ec23c53cd4678021e36a72d3188cb Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sat, 7 Feb 2015 01:06:29 -0700 Subject: Document the factory requires a positional argument --- docs/narr/hooks.rst | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 17cae2c67..8e6cf8343 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -368,6 +368,9 @@ changed by passing a ``response_factory`` argument to the constructor of the :term:`configurator`. This argument can be either a callable or a :term:`dotted Python name` representing a callable. +The factory takes a single positional argument, which is a :term:`Request` +object. The argument may be the value ``None``. + .. code-block:: python :linenos: -- cgit v1.2.3 From da5f5f9ea02c2c9830c7ae016547d2bedd0e0171 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 7 Feb 2015 02:38:54 -0600 Subject: move the IResponseFactory into the public api --- docs/narr/hooks.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 8e6cf8343..4fd7670b9 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -364,12 +364,12 @@ Whenever :app:`Pyramid` returns a response from a view it creates a object. The factory that :app:`Pyramid` uses to create a response object instance can be -changed by passing a ``response_factory`` argument to the constructor of the -:term:`configurator`. This argument can be either a callable or a -:term:`dotted Python name` representing a callable. +changed by passing a :class:`pyramid.interfaces.IResponseFactory` argument to +the constructor of the :term:`configurator`. This argument can be either a +callable or a :term:`dotted Python name` representing a callable. The factory takes a single positional argument, which is a :term:`Request` -object. The argument may be the value ``None``. +object. The argument may be ``None``. .. code-block:: python :linenos: -- cgit v1.2.3 From 780889f18d17b86fc12625166a245c7f9947cbe6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 01:05:04 -0600 Subject: remove the token from the ICacheBuster api This exposes the QueryStringCacheBuster and PathSegmentCacheBuster public APIs alongside the md5-variants. These should be more cleanly subclassed by people wishing to extend their implementations. --- docs/narr/assets.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index fc908c2b4..d6bc8cbb8 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -446,19 +446,20 @@ In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` interface. Alternatively you may choose to subclass one of the existing implementations. One of the most likely scenarios is you'd want to change the -way the asset token is generated. To do this just subclass an existing -implementation and replace the :meth:`~pyramid.interfaces.ICacheBuster.token` -method. Here is an example which just uses Git to get the hash of the -currently checked out code: +way the asset token is generated. To do this just subclass either +:class:`~pyramid.static.PathSegmentCacheBuster` or +:class:`~pyramid.static.QueryStringCacheBuster` and define a +``tokenize(pathspec)`` method. Here is an example which just uses Git to get +the hash of the currently checked out code: .. code-block:: python :linenos: import os import subprocess - from pyramid.static import PathSegmentMd5CacheBuster + from pyramid.static import PathSegmentCacheBuster - class GitCacheBuster(PathSegmentMd5CacheBuster): + class GitCacheBuster(PathSegmentCacheBuster): """ Assuming your code is installed as a Git checkout, as opposed to as an egg from an egg repository like PYPI, you can use this cachebuster to @@ -470,7 +471,7 @@ currently checked out code: ['git', 'rev-parse', 'HEAD'], cwd=here).strip() - def token(self, pathspec): + def tokenize(self, pathspec): return self.sha1 Choosing a Cache Buster -- cgit v1.2.3 From 568a025d3156ee1e7bdf92e14c9eba7390c1dd26 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 18:58:53 -0600 Subject: expose public config phases in pyramid.config --- docs/narr/extconfig.rst | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index c4d3e0250..c805f1572 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -243,12 +243,17 @@ This means that if an action must be reliably executed before or after another action, the ``order`` must be defined explicitly to make this work. For example, views are dependent on routes being defined. Thus the action created by :meth:`pyramid.config.Configurator.add_route` has an ``order`` of -:const:`pyramid.interfaces.PHASE2_CONFIG`. +:const:`pyramid.config.PHASE2_CONFIG`. Pre-defined Phases ~~~~~~~~~~~~~~~~~~ -:const:`pyramid.interfaces.PHASE1_CONFIG` +:const:`pyramid.config.PHASE0_CONFIG` + +- This phase is reserved for developers who want to execute actions prior + to Pyramid's core directives. + +:const:`pyramid.config.PHASE1_CONFIG` - :meth:`pyramid.config.Configurator.add_renderer` - :meth:`pyramid.config.Configurator.add_route_predicate` @@ -258,12 +263,12 @@ Pre-defined Phases - :meth:`pyramid.config.Configurator.set_default_permission` - :meth:`pyramid.config.Configurator.set_view_mapper` -:const:`pyramid.interfaces.PHASE2_CONFIG` +:const:`pyramid.config.PHASE2_CONFIG` - :meth:`pyramid.config.Configurator.add_route` - :meth:`pyramid.config.Configurator.set_authentication_policy` -``0`` +:const:`pyramid.config.PHASE3_CONFIG` - The default for all builtin or custom directives unless otherwise specified. @@ -285,9 +290,7 @@ but we want it to conflict with any other call to our addon: .. code-block:: python :linenos: - from pyramid.interfaces import PHASE1_CONFIG - - PHASE0_CONFIG = PHASE1_CONFIG - 10 + from pyramid.config import PHASE0_CONFIG def includeme(config): config.add_directive(add_auto_route, 'add_auto_route') -- cgit v1.2.3 From c0063b33e3b570120aab09b7d0a0adcf31c8705c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 19:01:15 -0600 Subject: fix odd sentence --- docs/narr/extconfig.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index c805f1572..47f2fcb46 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -235,7 +235,8 @@ actions. The logic within actions is deferred until a call to :meth:`pyramid.config.Configurator.make_wsgi_app`). This means you may call ``config.add_view(route_name='foo')`` **before** ``config.add_route('foo', '/foo')`` because nothing actually happens until -commit-time when conflicts are resolved, actions are ordered and executed. +commit-time. During a commit cycle conflicts are resolved, actions are ordered +and executed. By default, almost every action in Pyramid has an ``order`` of ``0``. Every action within the same order-level will be executed in the order it was called. -- cgit v1.2.3 From bba15920ee77a626c2ea3636d9d3b4f8d571afa6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 19:02:14 -0600 Subject: avoid saying order=0, instead say PHASE3_CONFIG --- docs/narr/extconfig.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 47f2fcb46..d17842bf2 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -238,8 +238,9 @@ actions. The logic within actions is deferred until a call to commit-time. During a commit cycle conflicts are resolved, actions are ordered and executed. -By default, almost every action in Pyramid has an ``order`` of ``0``. Every -action within the same order-level will be executed in the order it was called. +By default, almost every action in Pyramid has an ``order`` of +:const:`pyramid.config.PHASE3_CONFIG`. Every action within the same order-level +will be executed in the order it was called. This means that if an action must be reliably executed before or after another action, the ``order`` must be defined explicitly to make this work. For example, views are dependent on routes being defined. Thus the action created -- cgit v1.2.3 From 0bf2fded1a5dfa1614120c989f1d051908fa0b56 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 19:03:13 -0600 Subject: fix syntax --- docs/narr/extconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index d17842bf2..a61eca7b7 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -295,7 +295,7 @@ but we want it to conflict with any other call to our addon: from pyramid.config import PHASE0_CONFIG def includeme(config): - config.add_directive(add_auto_route, 'add_auto_route') + config.add_directive('add_auto_route', add_auto_route) def add_auto_route(config, name, view): def register(): -- cgit v1.2.3 From 3c163b212a6848c1d45916073d6a60a9020ea5c1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 21:08:58 -0600 Subject: reword a small part to clarify what's happening with view_config --- docs/narr/urldispatch.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 2fd971917..ca6a55164 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -502,9 +502,10 @@ and an incoming request matches the *pattern* of the route configuration, the :term:`view callable` named as the ``view`` attribute of the route configuration will be invoked. -Recall that ``config.scan`` is equivalent to calling ``config.add_view``, -because the ``@view_config`` decorator in ``mypackage.views``, shown below, -maps the route name to the matching view callable. In the case of the above +Recall that the ``@view_config`` is equivalent to calling ``config.add_view``, +because the ``config.scan()`` call will import ``mypackage.views``, shown +below, and execute ``config.add_view`` under the hood. Each view then maps the +route name to the matching view callable. In the case of the above example, when the URL of a request matches ``/site/{id}``, the view callable at the Python dotted path name ``mypackage.views.site_view`` will be called with the request. In other words, we've associated a view callable directly with a -- cgit v1.2.3 From 459493929a92b14a986ba387bdabd3c551ddee72 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 21:14:49 -0600 Subject: grammar --- docs/narr/security.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 2dc0c76af..a02f65660 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -653,7 +653,7 @@ that implements the following interface: """ After you do so, you can pass an instance of such a class into the -:class:`~pyramid.config.Configurator.set_authentication_policy` method +:class:`~pyramid.config.Configurator.set_authentication_policy` method at configuration time to use it. .. index:: -- cgit v1.2.3 From df966ac2f5c6fc230db920d945be4a6567521e40 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 17 Feb 2015 21:45:56 -0600 Subject: enhance security docs with an example of subclassing a builtin policy --- docs/narr/security.rst | 58 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index a02f65660..75f4dc7c5 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -341,9 +341,7 @@ third argument is a permission or sequence of permission names. A principal is usually a user id, however it also may be a group id if your authentication system provides group information and the effective :term:`authentication policy` policy is written to respect group information. -For example, the -:class:`pyramid.authentication.RepozeWho1AuthenticationPolicy` respects group -information if you configure it with a ``callback``. +See :ref:`extending_default_authentication_policies`. Each ACE in an ACL is processed by an authorization policy *in the order dictated by the ACL*. So if you have an ACL like this: @@ -582,6 +580,60 @@ denied or allowed. Introspecting this information in the debugger or via print statements when a call to :meth:`~pyramid.request.Request.has_permission` fails is often useful. +.. index:: + single: authentication policy (extending) + +.. _extending_default_authentication_policies: + +Extending Default Authentication Policies +----------------------------------------- + +Pyramid ships with some builtin authentication policies for use in your +applications. See :mod:`pyramid.authentication` for the available +policies. They differ on their mechanisms for tracking authentication +credentials between requests, however they all interface with your +application in mostly the same way. + +Above you learned about :ref:`assigning_acls`. Each :term:`principal` used +in the :term:`ACL` is matched against the list returned from +:meth:`pyramid.interfaces.IAuthenticationPolicy.effective_principals`. +Similarly, :meth:`pyramid.request.Request.authenticated_userid` maps to +:meth:`pyramid.interfaces.IAuthenticationPolicy.authenticated_userid`. + +You may control these values by subclassing the default authentication +policies. For example, below we subclass the +:class:`pyramid.authentication.AuthTktAuthenticationPolicy` and define +extra functionality to query our database before confirming that the +:term:`userid` is valid in order to avoid blindly trusting the value in the +cookie (what if the cookie is still valid but the user has deleted their +account?). We then use that :term:`userid` to augment the +``effective_principals`` with information about groups and other state for +that user. + +.. code-block:: python + :linenos: + + from pyramid.authentication import AuthTktAuthenticationPolicy + + class MyAuthenticationPolicy(AuthTktAuthenticationPolicy): + def authenticated_userid(self, request): + userid = self.unauthenticated_userid(request) + if userid: + if request.verify_userid_is_still_valid(userid): + return userid + + def effective_principals(self, request): + principals = [Everyone] + userid = self.authenticated_userid(request) + if userid: + principals += [Authenticated, str(userid)] + return principals + +In most instances ``authenticated_userid`` and ``effective_principals`` are +application-specific whereas ``unauthenticated_userid``, ``remember`` and +``forget`` are generic and focused on transport/serialization of data +between consecutive requests. + .. index:: single: authentication policy (creating) -- cgit v1.2.3 From 12b6f58956a50a0ad8e6d9971a0248d8f7997122 Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Sun, 15 Mar 2015 15:18:51 -0400 Subject: Allow passing a custom redirect class for appending slashes --- docs/narr/urldispatch.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index ca6a55164..fa3e734fe 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -842,7 +842,9 @@ route. When configured, along with at least one other route in your application, this view will be invoked if the value of ``PATH_INFO`` does not already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash matches any route's pattern. In this case it does an HTTP redirect to the -slash-appended ``PATH_INFO``. +slash-appended ``PATH_INFO``. In addition you may pass anything that implements +:class:`pyramid.interfaces.IResponse` which will then be used in place of the +default class (:class:`pyramid.httpexceptions.HTTPFound`). Let's use an example. If the following routes are configured in your application: -- cgit v1.2.3 From 610b6edef76168e6a499871be10ba9ea5ea6aa6d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 26 Mar 2015 11:54:30 -0500 Subject: fix out of date match_param docs --- docs/narr/viewconfig.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index a0feef8d7..d5203c6ba 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -325,7 +325,7 @@ configured view. ``match_param`` This param may be either a single string of the format "key=value" or a - dict of key/value pairs. + tuple containing one or more of these strings. This argument ensures that the view will only be called when the :term:`request` has key/value pairs in its :term:`matchdict` that equal @@ -334,8 +334,8 @@ configured view. hand side of the expression (``edit``) for the view to "match" the current request. - If the ``match_param`` is a dict, every key/value pair must match for the - predicate to pass. + If the ``match_param`` is a tuple, every key/value pair must match + for the predicate to pass. If ``match_param`` is not supplied, the view will be invoked without consideration of the keys and values in ``request.matchdict``. -- cgit v1.2.3 From 109792709bf90eddf85eaaed1743b5cbb1faa34e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 16 May 2015 16:12:35 -0700 Subject: cherrypick from 1.5 --- docs/narr/install.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index a825b61b9..0f114a9c7 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -33,11 +33,11 @@ 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. +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. You can install the latest verion of Python for Mac OS X from the binaries on -`python.org `_. +`python.org `_. Alternatively, you can use the `homebrew `_ package manager. -- cgit v1.2.3 From 6e0f02a1e2d6fdece760f5ce1e61850b9514897d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 27 May 2015 10:29:21 -0500 Subject: add an example decorator showing a response being used unconditionally --- docs/narr/viewconfig.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index d5203c6ba..fc5ae6dc6 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -234,6 +234,21 @@ Non-Predicate Arguments def myview(request): ... + All view callables in the decorator chain must return a response object + implementing :class:`pyramid.interfaces.IResponse` or raise an exception: + + .. code-block:: python + + def log_timer(wrapped): + def wrapper(context, request): + start = time.time() + response = wrapped(context, request) + duration = time.time() - start + response.headers['X-View-Time'] = '%.3f' % (duration,) + log.info('view took %.3f seconds', duration) + return response + return wrapper + ``mapper`` A Python object or :term:`dotted Python name` which refers to a :term:`view mapper`, or ``None``. By default it is ``None``, which indicates that the -- cgit v1.2.3 From 7cb892010592f52cb754c428f648390043ac75a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20Gy=C3=B6rgy?= Date: Sat, 30 May 2015 16:15:11 +0200 Subject: Added notes on check_csrf view predicate. Also it is an add_view parameter, not add_route. --- docs/narr/sessions.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 5c103405a..f37cc3c7d 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -56,7 +56,7 @@ by using the :meth:`pyramid.config.Configurator.set_session_factory` method. config = Configurator() config.set_session_factory(my_session_factory) -.. warning:: +.. warning:: By default the :func:`~pyramid.session.SignedCookieSessionFactory` implementation is *unencrypted*. You should not use it @@ -112,7 +112,7 @@ Extra attributes: An integer timestamp indicating the time that this session was created. ``new`` - A boolean. If ``new`` is True, this session is new. Otherwise, it has + A boolean. If ``new`` is True, this session is new. Otherwise, it has been constituted from data that was already serialized. Extra methods: @@ -225,7 +225,7 @@ method: request.session.flash('mymessage') The ``flash()`` method appends a message to a flash queue, creating the queue -if necessary. +if necessary. ``flash()`` accepts three arguments: @@ -406,7 +406,7 @@ Checking CSRF Tokens With A View Predicate 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_route`. +See :meth:`pyramid.config.Configurator.add_view`. .. code-block:: python @@ -414,6 +414,12 @@ See :meth:`pyramid.config.Configurator.add_route`. def myview(request): ... +.. note:: + A mismatch of csrf token is treated like any other predicate miss, and the + 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`. + Using the ``session.new_csrf_token`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From d5923976b090e3538d9e655d72361cbfab6a250a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 31 May 2015 11:48:55 -0700 Subject: - update testing and templating remarks - grammar, punctuation, 79-column rewrapping, case corrections --- docs/narr/introduction.rst | 165 +++++++++++++++++++++++---------------------- docs/narr/sessions.rst | 2 +- 2 files changed, 84 insertions(+), 83 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a37d74c9b..2d3cd23e9 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -65,11 +65,11 @@ Openness .. _what_makes_pyramid_unique: -What Makes Pyramid Unique +What makes Pyramid unique ------------------------- Understandably, people don't usually want to hear about squishy engineering -principles, they want to hear about concrete stuff that solves their +principles; they want to hear about concrete stuff that solves their problems. With that in mind, what would make someone want to use Pyramid instead of one of the many other web frameworks available today? What makes Pyramid unique? @@ -78,13 +78,13 @@ This is a hard question to answer, because there are lots of excellent choices, and it's actually quite hard to make a wrong choice, particularly in the Python web framework market. But one reasonable answer is this: you can write very small applications in Pyramid without needing to know a lot. -"What?", you say, "that can't possibly be a unique feature, lots of other web +"What?", you say. "That can't possibly be a unique feature. Lots of other web frameworks let you do that!" Well, you're right. But unlike many other systems, you can also write very large applications in Pyramid if you learn a little more about it. Pyramid will allow you to become productive quickly, -and will grow with you; it won't hold you back when your application is small +and will grow with you. It won't hold you back when your application is small, and it won't get in your way when your application becomes large. "Well -that's fine," you say, "lots of other frameworks let me write large apps +that's fine," you say. "Lots of other frameworks let me write large apps, too." Absolutely. But other Python web frameworks don't seamlessly let you do both. They seem to fall into two non-overlapping categories: frameworks for "small apps" and frameworks for "big apps". The "small app" frameworks @@ -95,15 +95,15 @@ in a "small framework" and "big apps" in a "big framework". You can't really know to what size every application will eventually grow. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -frameworks for small and large applications is just false; a well-designed +frameworks for small and large applications is just false. A well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework. To this end, Pyramid provides a set of features that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some -combination of these features; Pyramid of course actually stole many of them +combination of these features. Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful a la carte without +them in one place, documented appropriately, and useful *à la carte* without necessarily paying for the entire banquet. These are detailed below. Single-file applications @@ -143,14 +143,14 @@ decorators to localize the configuration. For example: return Response('fred') However, unlike some other systems, using decorators for Pyramid -configuration does not make your application difficult to extend, test or +configuration does not make your application difficult to extend, test, or reuse. The :class:`~pyramid.view.view_config` decorator, for example, does not actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation; you don't need to understand the -framework to test your own code, you just behave as if the decorator is not +testing it is a "WYSIWYG" operation. You don't need to understand the +framework to test your own code. You just behave as if the decorator is not there. You can also instruct Pyramid to ignore some decorators, or use completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager: you detect and activate them +Pyramid decorators are inert instead of eager. You detect and activate them with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. @@ -171,24 +171,24 @@ Static file serving Pyramid is perfectly willing to serve static files itself. It won't make you use some external web server to do that. You can even serve more than one set of static files in a single Pyramid web application (e.g. ``/static`` and -``/static2``). You can also, optionally, place your files on an external web -server and ask Pyramid to help you generate URLs to those files, so you can -use Pyramid's internal fileserving while doing development, and a faster -static file server in production without changing any code. +``/static2``). You can optionally place your files on an external web +server and ask Pyramid to help you generate URLs to those files. This let's +you use Pyramid's internal file serving while doing development, and a faster +static file server in production, without changing any code. Example: :ref:`static_assets_section`. -Fully Interactive Development +Fully interactive development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When developing a Pyramid application, several interactive features are available. Pyramid can automatically utilize changed templates when rendering -pages and automatically restart the application to incorporate changed python +pages and automatically restart the application to incorporate changed Python code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -allows you access to framework data such as the routes configured, the last +allows you access to framework data, such as the routes configured, the last renderings performed, the current set of packages installed, SQLAlchemy queries run, logging data, and various other facts. When an exception occurs, you can use its interactive debugger to poke around right in your @@ -201,16 +201,16 @@ Debugging settings Pyramid has debugging settings that allow you to print Pyramid runtime information to the console when things aren't behaving as you're expecting. -For example, you can turn on "debug_notfound", which prints an informative +For example, you can turn on ``debug_notfound``, which prints an informative message to the console every time a URL does not match any view. You can -turn on "debug_authorization", which lets you know why a view execution was +turn on ``debug_authorization``, which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. There are also a number of commands that you can invoke within a Pyramid -environment that allow you to introspect the configuration of your system: +environment that allow you to introspect the configuration of your system. ``proutes`` shows all configured routes for an application in the order -they'll be evaluated for matching; ``pviews`` shows all configured views for +they'll be evaluated for matching. ``pviews`` shows all configured views for any given URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. @@ -224,8 +224,8 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation - +Examples: +http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -233,13 +233,13 @@ Class-based and function-based views Pyramid has a structured, unified concept of a :term:`view callable`. View callables can be functions, methods of classes, or even instances. When you add a new view callable, you can choose to make it a function or a method -of a class; in either case, Pyramid treats it largely the same way. You can -change your mind later, and move code between methods of classes and +of a class. In either case Pyramid treats it largely the same way. You can +change your mind later and move code between methods of classes and functions. A collection of similar view callables can be attached to a single class as methods, if that floats your boat, and they can share initialization code as necessary. All kinds of views are easy to understand -and use and operate similarly. There is no phony distinction between them; -they can be used for the same purposes. +and use, and operate similarly. There is no phony distinction between them. +They can be used for the same purposes. Here's a view callable defined as a function: @@ -283,10 +283,10 @@ Asset specifications ~~~~~~~~~~~~~~~~~~~~ Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +a file or directory name, e.g., ``MyPackage:static/index.html``. Use of these specifications is omnipresent in Pyramid. An asset specification can refer to a template, a translation directory, or any other package-bound static -resource. This makes a system built on Pyramid extensible, because you don't +resource. This makes a system built on Pyramid extensible because you don't have to rely on globals ("*the* static directory") or lookup schemes ("*the* ordered set of template directories") to address your files. You can move files around as necessary, and include other packages that may not share your @@ -325,10 +325,9 @@ If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a dictionary, and Pyramid will take care of converting that dictionary to a Response using a template on your behalf. This makes the view easier to -test, because you don't have to parse HTML in your tests; just make an -assertion instead that the view returns "the right stuff" in the dictionary -it returns. You can write "real" unit tests instead of functionally testing -all of your views. +test, because you don't have to parse HTML in your tests; instead just make an +assertion that the view returns "the right stuff" in the dictionary. You can +write "real" unit tests instead of functionally testing all of your views. .. index:: pair: renderer; explicitly calling @@ -394,7 +393,7 @@ Built-in internationalization Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files -and templates. Pyramid allows for a plurality of message catalog via the use +and templates. Pyramid allows for a plurality of message catalogs via the use of translation domains: you can create a system that has its own translations without conflict with other translations in other domains. @@ -445,7 +444,7 @@ useless without requirements and goals, but if you need speed, Pyramid will almost certainly never be your application's bottleneck; at least no more than Python will be a bottleneck. -Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ +Example: http://blog.curiasolutions.com/pages/the-great-web-framework-shootout.html Exception views ~~~~~~~~~~~~~~~ @@ -469,11 +468,11 @@ No singletons ~~~~~~~~~~~~~ Pyramid is written in such a way that it requires your application to have -exactly zero "singleton" data structures. Or, put another way, Pyramid +exactly zero "singleton" data structures. Or put another way, Pyramid doesn't require you to construct any "mutable globals". Or put even a different way, an import of a Pyramid application needn't have any "import-time side effects". This is esoteric-sounding, but if you've ever -tried to cope with parameterizing a Django "settings.py" file for multiple +tried to cope with parameterizing a Django ``settings.py`` file for multiple installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous @@ -494,7 +493,7 @@ is the most basic thing you can do with a view predicate. You can also associate views with other request parameters such as the elements in the query string, the Accept header, whether the request is an XHR request or not, and lots of other things. This feature allows you to keep your -individual views "clean"; they won't need much conditional logic, so they'll +individual views clean. They won't need much conditional logic, so they'll be easier to test. Example: :ref:`view_configuration_parameters`. @@ -505,10 +504,10 @@ Transaction management Pyramid's :term:`scaffold` system renders projects that include a *transaction management* system, stolen from Zope. When you use this transaction management system, you cease being responsible for committing -your data anymore. Instead, Pyramid takes care of committing: it commits at +your data anymore. Instead Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great -thing. If, instead of managing your transactions in a centralized place, you +thing. If instead of managing your transactions in a centralized place you sprinkle ``session.commit`` calls in your application logic itself, you can wind up in a bad place. Wherever you manually commit data to your database, it's likely that some of your other code is going to run *after* your commit. @@ -521,8 +520,8 @@ who also care about data integrity. Either the request completes successfully, and all changes are committed, or it does not, and all changes are aborted. -Also, Pyramid's transaction management system allows you to synchronize -commits between multiple databases, and allows you to do things like +Pyramid's transaction management system allows you to synchronize +commits between multiple databases. It also allows you to do things like conditionally send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements @@ -534,13 +533,14 @@ Configuration conflict detection When a system is small, it's reasonably easy to keep it all in your head. But when systems grow large, you may have hundreds or thousands of configuration statements which add a view, add a route, and so forth. -Pyramid's configuration system keeps track of your configuration statements, -and if you accidentally add two that are identical, or Pyramid can't make + +Pyramid's configuration system keeps track of your configuration statements. +If you accidentally add two that are identical, or Pyramid can't make sense out of what it would mean to have both statements active at the same -time, it will complain loudly at startup time. It's not dumb though: it will +time, it will complain loudly at startup time. It's not dumb though. It will automatically resolve conflicting configuration statements on its own if you -use the configuration :meth:`~pyramid.config.Configurator.include` system: -"more local" statements are preferred over "less local" ones. This allows +use the configuration :meth:`~pyramid.config.Configurator.include` system. +"More local" statements are preferred over "less local" ones. This allows you to intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. @@ -552,15 +552,15 @@ Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be -performed by included packages including the addition of views, routes, +performed by included packages, including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's configuration in your own, overriding or adding new views and routes to it. This has the potential to allow you to create a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the -``include`` statement with a ``route_prefix``; the new application will live -within your application at a URL prefix. It's not a big deal, and requires +``include`` statement with a ``route_prefix``. The new application will live +within your application at an URL prefix. It's not a big deal, and requires little up-front engineering effort. For example: @@ -603,8 +603,8 @@ Traversal :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to create a tree of resources, each of which can be addressed by one or more URLs. Each of those resources can have one or more *views* associated with -it. If your data isn't naturally treelike (or you're unwilling to create a -treelike representation of your data), you aren't going to find traversal +it. If your data isn't naturally treelike, or you're unwilling to create a +treelike representation of your data, you aren't going to find traversal very useful. However, traversal is absolutely fantastic for sites that need to be arbitrarily extensible: it's a lot easier to add a node to a tree than it is to shoehorn a route into an ordered list of other routes, or to create @@ -635,7 +635,7 @@ View response adapters A lot is made of the aesthetics of what *kinds* of objects you're allowed to return from view callables in various frameworks. In a previous section in -this document we showed you that, if you use a :term:`renderer`, you can +this document, we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on :term:`Response` object. But some frameworks allow you to return strings or tuples from view callables. When frameworks allow for this, code looks @@ -826,7 +826,7 @@ within a function called when another user uses the See also :ref:`add_directive`. -Programmatic Introspection +Programmatic introspection ~~~~~~~~~~~~~~~~~~~~~~~~~~ If you're building a large system that other users may plug code into, it's @@ -856,7 +856,7 @@ callable: See also :ref:`using_introspection`. -Python 3 Compatibility +Python 3 compatibility ~~~~~~~~~~~~~~~~~~~~~~ Pyramid and most of its add-ons are Python 3 compatible. If you develop a @@ -871,11 +871,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 and PyPy 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.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. Example: http://jenkins.pylonsproject.org/ @@ -883,15 +883,15 @@ Support ~~~~~~~ It's our goal that no Pyramid question go unanswered. Whether you ask a -question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're -likely to get a reasonably prompt response. We don't tolerate "support +question on IRC, on the Pylons-discuss mailing list, or on StackOverflow, +you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow users in our various official support channels. We try to keep it well-lit and new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at -http://groups.google.com/group/pylons-discuss/ . +http://groups.google.com/group/pylons-discuss/. Documentation ~~~~~~~~~~~~~ @@ -900,12 +900,12 @@ It's a constant struggle, but we try to maintain a balance between completeness and new-user-friendliness in the official narrative Pyramid documentation (concrete suggestions for improvement are always appreciated, by the way). We also maintain a "cookbook" of recipes, which are usually -demonstrations of common integration scenarios, too specific to add to the +demonstrations of common integration scenarios too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The rest of this documentation and the cookbook at -http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . +Example: The Pyramid Cookbook at +http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/. .. index:: single: Pylons Project @@ -934,25 +934,26 @@ in July of 2008. At the end of 2010, we changed the name of as :app:`Pyramid` in November of that year. :app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version -1.0) and :term:`Django`. As a result, :app:`Pyramid` borrows several +1.0), and :term:`Django`. As a result, :app:`Pyramid` borrows several concepts and features from each, combining them into a unique web framework. Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. -Like Zope applications, :app:`Pyramid` applications can be easily extended: -if you obey certain constraints, the application you produce can be reused, +Like Zope applications, :app:`Pyramid` applications can be easily extended. +If you obey certain constraints, the application you produce can be reused, modified, re-integrated, or extended by third-party developers without forking the original application. The concepts of :term:`traversal` and declarative security in :app:`Pyramid` were pioneered first in Zope. The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the -:term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons -version 1.0, :app:`Pyramid` is mostly policy-free. It makes no -assertions about which database you should use, and its built-in -templating facilities are included only for convenience. In essence, -it only supplies a mechanism to map URLs to :term:`view` code, along -with a set of conventions for calling those views. You are free to -use third-party components that fit your needs in your applications. +:term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons version +1.0, :app:`Pyramid` is mostly policy-free. It makes no assertions about which +database you should use. Pyramid no longer has built-in templating facilities +as of version 1.5a2, but instead officially supports bindings for templating +languages, including Chameleon, Jinja2, and Mako. In essence, it only +supplies a mechanism to map URLs to :term:`view` code, along with a set of +conventions for calling those views. You are free to use third-party +components that fit your needs in your applications. The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be by Django. :app:`Pyramid` has a documentation culture more like Django's @@ -967,15 +968,15 @@ declarations are used for this purpose. Out of the box, Pyramid supports imperative and decorator-based configuration; :term:`ZCML` may be used via an add-on package named ``pyramid_zcml``. -Also unlike :term:`Zope` and unlike other "full-stack" frameworks such +Also unlike :term:`Zope` and other "full-stack" frameworks such as :term:`Django`, :app:`Pyramid` makes no assumptions about which persistence mechanisms you should use to build an application. Zope applications are typically reliant on :term:`ZODB`; :app:`Pyramid` allows you to build :term:`ZODB` applications, but it has no reliance on the ZODB software. Likewise, :term:`Django` tends to assume that you want to store your application's data in a relational database. -:app:`Pyramid` makes no such assumption; it allows you to use a -relational database but doesn't encourage or discourage the decision. +:app:`Pyramid` makes no such assumption, allowing you to use a +relational database, and neither encouraging nor discouraging the decision. Other Python web frameworks advertise themselves as members of a class of web frameworks named `model-view-controller @@ -987,7 +988,7 @@ frameworks, :app:`Pyramid` also generally fits into this class. The :app:`Pyramid` authors believe that the MVC pattern just doesn't really fit the web very well. In a :app:`Pyramid` application, there is a - resource tree, which represents the site structure, and views, which tend + resource tree which represents the site structure, and views which tend to present the data stored in the resource tree and a user-defined "domain model". However, no facility provided *by the framework* actually necessarily maps to the concept of a "controller" or "model". So if you diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index f37cc3c7d..916c6c1f6 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -415,7 +415,7 @@ See :meth:`pyramid.config.Configurator.add_view`. ... .. note:: - A mismatch of csrf token is treated like any other predicate miss, and the + A mismatch of CSRF token is treated like any other predicate miss, and the 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`. -- cgit v1.2.3 From 1395f5485c4155a67f4ca0e18507387e02c985d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiss=20Gy=C3=B6rgy?= Date: Sat, 6 Jun 2015 14:40:16 +0200 Subject: More idiomatic code --- docs/narr/viewconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index fc5ae6dc6..46b2c4f76 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -119,7 +119,7 @@ Non-Predicate Arguments ``renderer`` Denotes the :term:`renderer` implementation which will be used to construct a :term:`response` from the associated view callable's return value. - + .. seealso:: See also :ref:`renderers_chapter`. This is either a single string term (e.g. ``json``) or a string implying a @@ -1020,7 +1020,7 @@ there's a ``should_cache`` GET or POST variable: @view_config(http_cache=3600) def view(request): response = Response() - if not 'should_cache' in request.params: + if 'should_cache' not in request.params: response.cache_control.prevent_auto = True return response -- cgit v1.2.3 From f866fa68ffcac3e200e4d530f8c157e5848e60b0 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 6 Jun 2015 15:02:47 -0700 Subject: cherry pick 1.6-branch to master --- docs/narr/assets.rst | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index d6bc8cbb8..fc02b3f7d 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -512,6 +512,93 @@ time at start up as a cachebust token: .. index:: single: static assets view +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. + +* Process the files by using a precompiler which rewrites URLs to their final + cache busted form. + +* Templatize JS and CSS, and call ``request.static_url()`` inside their + template code. + +* Pass static URL references to CSS and JavaScript via other means. + +Below are some simple approaches for CSS and JS programming which consider +asset cache busting. These approaches do not require additional tools or +packages. + +Relative cache busted URLs in CSS ++++++++++++++++++++++++++++++++++ + +Consider a CSS file ``/static/theme/css/site.css`` which contains the +following CSS code. + +.. code-block:: css + + body { + background: url(/static/theme/img/background.jpg); + } + +Any changes to ``background.jpg`` would not appear to the visitor because the +URL path is not cache busted as it is. Instead we would have to construct an +URL to the background image with the default ``PathSegmentCacheBuster`` cache +busting mechanism:: + + https://site/static/1eeb262c717/theme/img/background.jpg + +Every time the image is updated, the URL would need to be changed. It is not +practical to write this non-human readable URL into a CSS file. + +However, the CSS file itself is cache busted and is located under the path for +static assets. This lets us use relative references in our CSS to cache bust +the image. + +.. code-block:: css + + body { + background: url(../img/background.jpg); + } + +The browser would interpret this as having the CSS file hash in URL:: + + https://site/static/ab234b262c71/theme/css/../img/background.jpg + +The downside of this approach is that if the background image changes, one +needs to bump the CSS file. The CSS file hash change signals the caches that +the relative URL to the image in the CSS has been changed. When updating CSS +and related image assets, updates usually happen hand in hand, so this does +not add extra effort to theming workflow. + +Passing cache busted URLs to JavaScript ++++++++++++++++++++++++++++++++++++++++ + +For JavaScript, one can pass static asset URLs as function arguments or +globals. The globals can be generated in page template code, having access to +the ``request.static_url()`` function. + +Below is a simple example of passing a cached busted image URL in the Jinja2 +template language. Put the following code into the ```` section of the +relevant page. + +.. code-block:: html + + + +Then in your main ``site.js`` file put the following code. + +.. code-block:: javascript + + var image = new Image(window.assets.backgroundImage); + .. _advanced_static: Advanced: Serving Static Assets Using a View Callable -- cgit v1.2.3 From 8447260de970629be01de821e43e9ea33e4405a0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Jul 2015 01:44:01 -0400 Subject: fix for #1846, incorrect pointers to nonexistent webob properties --- docs/narr/webob.rst | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index 0eb070b06..f82cf6fbe 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -191,25 +191,21 @@ of them. Here are a couple that might be useful: this for subrequests, or testing. .. index:: - single: request (and unicode) - single: unicode (and the request) + single: request (and text/unicode) + single: unicode and text (and the request) -Unicode -+++++++ +Text (Unicode) +++++++++++++++ -Many of the properties in the request object will return unicode -values if the request encoding/charset is provided. The client *can* +Many of the properties of the request object will be text values (``unicode`` +under Python 2 or ``str`` under Python 3) if the request encoding/charset is +provided. If it is provided, the values in ``req.POST``, ``req.GET``, +``req.params``, and ``req.cookies`` will contain text. The client *can* indicate the charset with something like ``Content-Type: -application/x-www-form-urlencoded; charset=utf8``, but browsers seldom -set this. You can set the charset with ``req.charset = 'utf8'``, or -during instantiation with ``Request(environ, charset='utf8')``. If -you subclass ``Request`` you can also set ``charset`` as a class-level -attribute. - -If it is set, then ``req.POST``, ``req.GET``, ``req.params``, and -``req.cookies`` will contain unicode strings. Each has a -corresponding ``req.str_*`` (e.g., ``req.str_POST``) that is always -a ``str``, and never unicode. +application/x-www-form-urlencoded; charset=utf8``, but browsers seldom set +this. You can reset the charset of an existing request with ``newreq = +req.decode('utf-8')``, or during instantiation with ``Request(environ, +charset='utf8')``. .. index:: single: multidict (WebOb) @@ -404,7 +400,7 @@ A response object has three fundamental parts: ``response.app_iter``: An iterable (such as a list or generator) that will produce the content of the response. This is also accessible as - ``response.body`` (a string), ``response.unicode_body`` (a + ``response.body`` (a string), ``response.text`` (a unicode object, informed by ``response.charset``), and ``response.body_file`` (a file-like object; writing to it appends to ``app_iter``). @@ -420,7 +416,7 @@ Here are some highlights: ``response.charset``: The ``charset`` parameter of the content-type, it also informs - encoding in ``response.unicode_body``. + encoding in ``response.text``. ``response.content_type_params`` is a dictionary of all the parameters. -- cgit v1.2.3 From d229631e690021222143b72c47fc9a9706a92467 Mon Sep 17 00:00:00 2001 From: David Beitey Date: Thu, 23 Jul 2015 14:00:27 +1000 Subject: Use correct cache argument in cache busting doco Minor correction; it's ``cache_max_age`` rather than ``max_cache_age``. --- 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 fc02b3f7d..1beabe8de 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -390,7 +390,7 @@ in the asset's URL: When the asset changes, so will its md5 checksum, 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 -``max_cache_age`` argument is also passed, in which case that value is used. +``cache_max_age`` argument is also passed, in which case that value is used. .. note:: -- cgit v1.2.3 From bb494a32d77b4f36473bece91cfaf8cf17c4bc07 Mon Sep 17 00:00:00 2001 From: Alexandre Conrad Date: Mon, 24 Aug 2015 20:42:26 -0700 Subject: document +dot+ for dotfiles in scaffolds --- docs/narr/scaffolding.rst | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index f924d0d62..4fcdeb537 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -57,6 +57,11 @@ As you create files and directories within the template directory, note that: have that string replaced with the value of the ``var`` variable provided to the scaffold. +- Files that start with a dot (e.g., ``.env``) are ignored and will not be + copied over to the destination directory. If you want to include a file with + a leading dot then you must replace the dot with ``+dot+`` (e.g., + ``+dot+env``). + Otherwise, files and directories which live in the template directory will be copied directly without modification to the ``pcreate`` output location. -- cgit v1.2.3 From 82862ba554ff97932b5f6745c8e6b022dcdfe18c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 1 Sep 2015 02:42:05 -0700 Subject: - add pylonswebframework to intersphinx config, sort entries so they can be found (meh! 79 char columns) - replace final pylonshq reference with RTD reference --- docs/narr/i18n.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 3c804a158..8d81418d9 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -219,10 +219,9 @@ by creating various kinds of gettext files. The steps a developer must take to work with :term:`gettext` :term:`message catalog` files within a :app:`Pyramid` application are very similar to the steps a :term:`Pylons` - developer must take to do the same. See the `Pylons - internationalization documentation - `_ - for more information. + developer must take to do the same. See the :ref:`Pylons + Internationalization and Localization documentation + ` for more information. GNU gettext uses three types of files in the translation framework, ``.pot`` files, ``.po`` files and ``.mo`` files. -- cgit v1.2.3 From cb92023e9d0ddb56d20dcc445a5e028fec581342 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Sun, 6 Sep 2015 15:26:35 -0700 Subject: Use entry points for pshell --- docs/narr/commandline.rst | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 1fe2d9278..89df13ce4 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -288,6 +288,40 @@ specifically invoke one of your choice with the ``-p choice`` or $ $VENV/bin/pshell -p ipython | bpython | python development.ini#MyProject +Alternative Shells +~~~~~~~~~~~~~~~~~~ +If you want to use a shell that isn't supported out of the box you can introduce +a new shell by registering an entrypoint in your setup.py: + +.. code-block:: python + + setup( + entry_points = """\ + [pyramid.pshell] + myshell=my_app.ptpython_shell_factory + """ + ) + +and then your shell factory should return a function that accepts two arguments, +``env`` and ``help``, this would look like this: + +.. code-block:: python + + def ptpython_shell_factory(): + try: + from ptpython.repl import embed + def PTPShell(banner, **kwargs): + print(banner) + return embed(**kwargs) + except ImportError: + return None + + def shell(env, help): + PTPShell(banner=help, locals=env) + + return shell + + .. index:: pair: routes; printing single: proutes -- cgit v1.2.3 From 509ca0fd906304b7fc672fcc7cb7a59527f1ba86 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 12 Sep 2015 05:19:46 -0700 Subject: Fix possessive form, from PR by @uralbash --- docs/narr/viewconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 46b2c4f76..484350b31 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -108,7 +108,7 @@ Non-Predicate Arguments function) to obtain a response. The ``attr`` value allows you to vary the method attribute used to obtain the response. For example, if your view was a class, and the class has a method named ``index`` and you wanted to - use this method instead of the class' ``__call__`` method to return the + use this method instead of the class's ``__call__`` method to return the response, you'd say ``attr="index"`` in the view configuration for the view. This is most useful when the view definition is a class. -- cgit v1.2.3 From 02801e33f5a11d069921e1a16933a0225fad45bc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 1 Oct 2015 13:43:54 -0700 Subject: wrap to 79 chars --- docs/narr/i18n.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 8d81418d9..7b6903d01 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -403,10 +403,11 @@ command from Gettext: $ cd /place/where/myapplication/setup.py/lives $ msgfmt -o myapplication/locale/es/LC_MESSAGES/myapplication.mo myapplication/locale/es/LC_MESSAGES/myapplication.po -This will create a ``.mo`` file for each ``.po`` file in your -application. As long as the :term:`translation directory` in which -the ``.mo`` file ends up in is configured into your application (see :ref:`adding_a_translation_directory`), these -translations will be available to :app:`Pyramid`. +This will create a ``.mo`` file for each ``.po`` file in your application. As +long as the :term:`translation directory` in which the ``.mo`` file ends up in +is configured into your application (see +:ref:`adding_a_translation_directory`), these translations will be available +to :app:`Pyramid`. .. index:: single: localizer -- cgit v1.2.3 From cbd2b039e5c57df5f17ef543c52056bc983f8ccf Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 4 Oct 2015 02:14:38 -0700 Subject: grammar, rst heading underline fixes --- docs/narr/firstapp.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index e73ef66ac..ee7511770 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -4,7 +4,7 @@ .. _firstapp_chapter: Creating Your First :app:`Pyramid` Application -================================================= +============================================== In this chapter, we will walk through the creation of a tiny :app:`Pyramid` application. After we're finished creating the application, we'll explain in @@ -52,7 +52,7 @@ done by the wsgiref server we've used to serve this application. It logs an Press ``Ctrl-C`` (or ``Ctrl-Break`` on Windows) to stop the application. Now that we have a rudimentary understanding of what the application does, -let's examine it piece-by-piece. +let's examine it piece by piece. Imports ~~~~~~~ @@ -129,7 +129,7 @@ defined imports and function definitions, placed within the confines of an :linenos: :lines: 9-15 -Let's break this down piece-by-piece. +Let's break this down piece by piece. Configurator Construction ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -145,7 +145,7 @@ line. For example, if the file named ``helloworld.py`` contains the entire script body, the code within the ``if`` statement will only be invoked when ``python helloworld.py`` is executed from the command line. -Using the ``if`` clause is necessary -- or at least best practice -- because +Using the ``if`` clause is necessary—or at least best practice—because code in a Python ``.py`` file may be eventually imported via the Python ``import`` statement by another ``.py`` file. ``.py`` files that are imported by other ``.py`` files are referred to as *modules*. By using the @@ -170,7 +170,7 @@ Adding Configuration :linenos: :lines: 11-12 -First line above calls the :meth:`pyramid.config.Configurator.add_route` +The first line above calls the :meth:`pyramid.config.Configurator.add_route` method, which registers a :term:`route` to match any URL path that begins with ``/hello/`` followed by a string. @@ -220,7 +220,7 @@ WSGI Application Serving Finally, we actually serve the application to requestors by starting up a WSGI server. We happen to use the :mod:`wsgiref` ``make_server`` server maker for this purpose. We pass in as the first argument ``'0.0.0.0'``, -which means "listen on all TCP interfaces." By default, the HTTP server +which means "listen on all TCP interfaces". By default, the HTTP server listens only on the ``127.0.0.1`` interface, which is problematic if you're running the server on a remote system and you wish to access it with a web browser from a local system. We also specify a TCP port number to listen on, -- cgit v1.2.3 From 87ae607687f94ef73a9a4a24409515cc08a2db91 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 4 Oct 2015 04:08:33 -0700 Subject: grammar (cherry picked from commit 961dcb8) (cherry picked from commit eb74c4d) --- docs/narr/configuration.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index f7fa94daf..c1457fce5 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -57,7 +57,7 @@ applications, configured imperatively: We won't talk much about what this application does yet. Just note that the "configuration' statements take place underneath the ``if __name__ == '__main__':`` stanza in the form of method calls on a :term:`Configurator` -object (e.g. ``config.add_view(...)``). These statements take place one +object (e.g., ``config.add_view(...)``). These statements take place one after the other, and are executed in order, so the full power of Python, including conditionals, can be employed in this mode of configuration. @@ -133,7 +133,7 @@ instance method. Once scanning is invoked, and :term:`configuration decoration` is found by the scanner, a set of calls are made to a :term:`Configurator` on your -behalf: these calls replace the need to add imperative configuration +behalf. These calls replace the need to add imperative configuration statements that don't live near the code being configured. The combination of :term:`configuration decoration` and the invocation of a @@ -151,6 +151,6 @@ Summary ------- There are two ways to configure a :app:`Pyramid` application: declaratively -and imperatively. You can choose the mode you're most comfortable with; both -are completely equivalent. Examples in this documentation will use both +and imperatively. You can choose the mode with which you're most comfortable; +both are completely equivalent. Examples in this documentation will use both modes interchangeably. -- cgit v1.2.3 From 609a999c2d743252906c257dbc83bc3e9e30c946 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Oct 2015 03:03:26 -0700 Subject: - grammar - heading underlines - update images and text for debug toolbar --- docs/narr/project-debug.png | Bin 106878 -> 202464 bytes docs/narr/project-show-toolbar.png | Bin 0 -> 11050 bytes docs/narr/project.png | Bin 91662 -> 133242 bytes docs/narr/project.rst | 87 +++++++++++++++++++------------------ 4 files changed, 44 insertions(+), 43 deletions(-) create mode 100644 docs/narr/project-show-toolbar.png (limited to 'docs/narr') diff --git a/docs/narr/project-debug.png b/docs/narr/project-debug.png index 4f8e441ef..0a703dead 100644 Binary files a/docs/narr/project-debug.png and b/docs/narr/project-debug.png differ diff --git a/docs/narr/project-show-toolbar.png b/docs/narr/project-show-toolbar.png new file mode 100644 index 000000000..89b838f64 Binary files /dev/null and b/docs/narr/project-show-toolbar.png differ diff --git a/docs/narr/project.png b/docs/narr/project.png index 5d46df0dd..e1afd97d4 100644 Binary files a/docs/narr/project.png and b/docs/narr/project.png differ diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 0ada1a379..76c56157a 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1,7 +1,7 @@ .. _project_narr: Creating a :app:`Pyramid` Project -==================================== +================================= As we saw in :ref:`firstapp_chapter`, it's possible to create a :app:`Pyramid` application completely manually. However, it's usually more @@ -12,8 +12,8 @@ A project is a directory that contains at least one Python :term:`package`. You'll use a scaffold to create a project, and you'll create your application logic within a package that lives inside the project. Even if your application is extremely simple, it is useful to place code that drives the -application within a package, because: 1) a package is more easily extended -with new code and 2) an application that lives inside a package can also be +application within a package, because (1) a package is more easily extended +with new code, and (2) an application that lives inside a package can also be distributed more easily than one which does not live within a package. :app:`Pyramid` comes with a variety of scaffolds that you can use to generate @@ -32,24 +32,24 @@ as part of Pyramid. .. _additional_paster_scaffolds: Scaffolds Included with :app:`Pyramid` ------------------------------------------------- +-------------------------------------- The convenience scaffolds included with :app:`Pyramid` differ from each other on a number of axes: - the persistence mechanism they offer (no persistence mechanism, - :term:`ZODB`, or :term:`SQLAlchemy`). + :term:`ZODB`, or :term:`SQLAlchemy`) - the mechanism they use to map URLs to code (:term:`traversal` or :term:`URL - dispatch`). + dispatch`) The included scaffolds are these: ``starter`` - URL mapping via :term:`URL dispatch` and no persistence mechanism. + URL mapping via :term:`URL dispatch` and no persistence mechanism ``zodb`` - URL mapping via :term:`traversal` and persistence via :term:`ZODB`. + URL mapping via :term:`traversal` and persistence via :term:`ZODB` ``alchemy`` URL mapping via :term:`URL dispatch` and persistence via @@ -70,7 +70,7 @@ the ``pcreate`` command installed within the virtualenv. We'll choose the ``starter`` scaffold for this purpose. When we invoke ``pcreate``, it will create a directory that represents our project. -In :ref:`installing_chapter` we called the virtualenv directory ``env``; the +In :ref:`installing_chapter` we called the virtualenv directory ``env``. The following commands assume that our current working directory is the ``env`` directory. @@ -89,7 +89,6 @@ Or on Windows: > %VENV%\Scripts\pcreate -s starter MyProject - Here's sample output from a run of ``pcreate`` on UNIX for a project we name ``MyProject``: @@ -129,8 +128,8 @@ server" directory, and you don't need to put it within a virtualenv directory. The author uses Linux mainly, and tends to put project directories which he creates within his ``~/projects`` directory. On Windows, it's a good idea to put project directories within a directory that -contains no space characters, so it's wise to *avoid* a path that contains -i.e. ``My Documents``. As a result, the author, when he uses Windows, just +contains no space characters, so it's wise to *avoid* a path that contains, +i.e., ``My Documents``. As a result, the author, when he uses Windows, just puts his projects in ``C:\projects``. .. warning:: @@ -185,13 +184,13 @@ Elided output from a run of this command on UNIX is shown below: This will install a :term:`distribution` representing your project into the virtual environment interpreter's library set so it can be found by ``import`` statements and by other console scripts such as -``pserve``, ``pshell``, ``proutes`` and ``pviews``. +``pserve``, ``pshell``, ``proutes``, and ``pviews``. .. index:: single: running tests single: tests (running) -Running The Tests For Your Application +Running the Tests for Your Application -------------------------------------- To run unit tests for your application, you should invoke them using the @@ -250,7 +249,7 @@ single sample test exists. .. _running_the_project_application: -Running The Project Application +Running the Project Application ------------------------------- Once a project is installed for development, you can run the application it @@ -285,10 +284,10 @@ 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/``. +``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 @@ -309,19 +308,20 @@ portion of the ``development.ini`` file. For example, you can change the section to ``port = 8080`` to run the server on port 8080 instead of port 6543. -You can shut down a server started this way by pressing ``Ctrl-C``. +You can shut down a server started this way by pressing ``Ctrl-C`` (or +``Ctrl-Break`` on Windows). The default server used to run your Pyramid application when a project is created from a scaffold is named :term:`Waitress`. This server is what prints the ``serving on...`` line when you run ``pserve``. It's a good idea -to use this server during development, because it's very simple. It can also +to use this server during development because it's very simple. It can also be used for light production. Setting your application up under a different server is not advised until you've done some development work under the default server, particularly if you're not yet experienced with Python web development. Python web server setup can be complex, and you should get some confidence that your application works in a default environment before trying to optimize it or make it "more like production". It's awfully easy to get -sidetracked trying to set up a nondefault server for hours without actually +sidetracked trying to set up a non-default server for hours without actually starting to do any development. One of the nice things about Python web servers is that they're largely interchangeable, so if your application works under the default server, it will almost certainly work under any other @@ -392,25 +392,26 @@ generated ``starter`` application in a browser. The Debug Toolbar ~~~~~~~~~~~~~~~~~ -If you click on the image shown at the right hand top of the page ("^DT"), -you'll be presented with a debug toolbar that provides various niceties while -you're developing. This image will float above every HTML page served by -:app:`Pyramid` while you develop an application, and allows you show the -toolbar as necessary. Click on ``Hide`` to hide the toolbar and show the -image again. +.. image:: project-show-toolbar.png + +If you click on the :app:`Pyramid` logo at the top right of the page, a new +target window will open to present a debug toolbar that provides various +niceties while you're developing. This logo will float above every HTML +page served by :app:`Pyramid` while you develop an application, and allows +you to show the toolbar as necessary. .. image:: project-debug.png -If you don't see the debug toolbar image on the right hand top of the page, -it means you're browsing from a system that does not have debugging access. -By default, for security reasons, only a browser originating from -``localhost`` (``127.0.0.1``) can see the debug toolbar. To allow your -browser on a remote system to access the server, add a line within the -``[app:main]`` section of the ``development.ini`` file in the form -``debugtoolbar.hosts = X.X.X.X``. For example, if your Pyramid application -is running on a remote system, and you're browsing from a host with the IP -address ``192.168.1.1``, you'd add something like this to enable the toolbar -when your system contacts Pyramid: +If you don't see the Pyramid logo on the top right of the page, it means +you're browsing from a system that does not have debugging access. By +default, for security reasons, only a browser originating from ``localhost`` +(``127.0.0.1``) can see the debug toolbar. To allow your browser on a +remote system to access the server, add a line within the ``[app:main]`` +section of the ``development.ini`` file in the form ``debugtoolbar.hosts = X +.X.X.X``. For example, if your Pyramid application is running on a remote +system, and you're browsing from a host with the IP address ``192.168.1.1``, +you'd add something like this to enable the toolbar when your system +contacts Pyramid: .. code-block:: ini @@ -450,9 +451,9 @@ Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: Then restart the application to see that the toolbar has been turned off. Note that if you comment out the ``pyramid_debugtoolbar`` line, the ``#`` -*must* be in the first column. If you put it anywhere else, -and then attempt to restart the application, -you'll receive an error that ends something like this: +*must* be in the first column. If you put it anywhere else, and then +attempt to restart the application, you'll receive an error that ends +something like this: .. code-block:: text @@ -610,7 +611,7 @@ implementations. single: production.ini ``production.ini`` -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~ The ``production.ini`` file is a :term:`PasteDeploy` configuration file with a purpose much like that of ``development.ini``. However, it disables the @@ -942,7 +943,7 @@ unit tests. .. _modifying_package_structure: Modifying Package Structure ----------------------------- +--------------------------- It is best practice for your application's code layout to not stray too much from accepted Pyramid scaffold defaults. If you refrain from changing -- cgit v1.2.3 From 058e904ce255bb5d4dded8d051655724c3e85514 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Oct 2015 04:20:46 -0700 Subject: - grammar - heading underlines - update images and text for debug toolbar --- docs/narr/project.rst | 80 ++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 76c56157a..d8312b4ea 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -470,7 +470,7 @@ which contains a Python :term:`package`. The package is *also* named ``myproject``, but it's lowercased; the scaffold generates a project which contains a package that shares its name except for case. -All :app:`Pyramid` ``pcreate`` -generated projects share a similar structure. +All :app:`Pyramid` ``pcreate``-generated projects share a similar structure. The ``MyProject`` project we've generated has the following directory structure: @@ -542,7 +542,7 @@ The generated ``development.ini`` file looks like so: :linenos: This file contains several sections including ``[app:main]``, -``[server:main]`` and several other sections related to logging +``[server:main]``, and several other sections related to logging configuration. The ``[app:main]`` section represents configuration for your :app:`Pyramid` @@ -554,11 +554,11 @@ to the function named ``main`` in our package's ``__init__.py`` module. You can provide startup-time configuration parameters to your application by adding more settings to this section. -.. note:: See :ref:`pastedeploy_entry_points` for more information about the +.. seealso:: See :ref:`pastedeploy_entry_points` for more information about the meaning of the ``use = egg:MyProject`` value in this section. The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a -:app:`Pyramid` -specific setting which is passed into the framework. If it +:app:`Pyramid`-specific setting which is passed into the framework. If it exists, and its value is ``true``, supported template changes will not require an application restart to be detected. See :ref:`reload_templates_section` for more information. @@ -571,9 +571,10 @@ The ``pyramid.includes`` setting in the ``[app:main]`` section tells Pyramid to "include" configuration from another package. In this case, the line ``pyramid.includes = pyramid_debugtoolbar`` tells Pyramid to include configuration from the ``pyramid_debugtoolbar`` package. This turns on a -debugging panel in development mode which will be shown on the right hand -side of the screen. Including the debug toolbar will also make it possible -to interactively debug exceptions when an error occurs. +debugging panel in development mode which can be opened by clicking on the +:app:`Pyramid` logo on the top right of the screen. Including the debug +toolbar will also make it possible to interactively debug exceptions when an +error occurs. Various other settings may exist in this section having to do with debugging or influencing runtime behavior of a :app:`Pyramid` application. See @@ -597,14 +598,14 @@ and ``# End logging configuration`` represent Python's standard library 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 sends application logging output to the standard error output -of your terminal. For more information about logging configuration, see +``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`. See the :term:`PasteDeploy` documentation for more information about other types of things you can put into this ``.ini`` file, such as other -applications, :term:`middleware` and alternate :term:`WSGI` server +applications, :term:`middleware`, and alternate :term:`WSGI` server implementations. .. index:: @@ -736,7 +737,7 @@ For fun, you can try this command now: .. code-block:: text - $ python setup.py sdist + $ $VENV/bin/python setup.py sdist This will create a tarball of your application in a ``dist`` subdirectory named ``MyProject-0.1.tar.gz``. You can send this tarball to other people @@ -765,11 +766,10 @@ The ``myproject`` :term:`package` lives inside the ``MyProject`` #. A ``views.py`` module, which contains view code for the application. -These are purely conventions established by the scaffold: -:app:`Pyramid` doesn't insist that you name things in any particular way. -However, it's generally a good idea to follow Pyramid standards for naming, -so that other Pyramid developers can get up to speed quickly on your code -when you need help. +These are purely conventions established by the scaffold. :app:`Pyramid` +doesn't insist that you name things in any particular way. However, it's +generally a good idea to follow Pyramid standards for naming, so that other +Pyramid developers can get up to speed quickly on your code when you need help. .. index:: single: __init__.py @@ -839,13 +839,13 @@ The view_config decorator asserts that this view be found when a route will match when a visitor visits the root URL. The view_config decorator also names a ``renderer``, which in this case is a template that will be used to render the result of the view callable. This particular view -declaration points at ``templates/mytemplate.pt``, which is a :term:`asset +declaration points at ``templates/mytemplate.pt``, which is an :term:`asset specification` that specifies the ``mytemplate.pt`` file within the ``templates`` directory of the ``myproject`` package. The asset specification could have also been specified as ``myproject:templates/mytemplate.pt``; the leading package name and colon is -optional. The template file pointed to is a :term:`Chameleon` ZPT -template file (``templates/my_template.pt``). +optional. The template file pointed to is a :term:`Chameleon` ZPT template +file (``templates/my_template.pt``). This view callable function is handed a single piece of information: the :term:`request`. The *request* is an instance of the :term:`WebOb` @@ -859,7 +859,7 @@ returns the HTML in a :term:`response`. .. note:: Dictionaries provide values to :term:`template`\s. .. note:: When the application is run with the scaffold's :ref:`default - development.ini ` configuration :ref:`logging is set up + development.ini ` configuration, :ref:`logging is set up ` to aid debugging. If an exception is raised, uncaught tracebacks are displayed after the startup messages on :ref:`the console running the server `. Also @@ -869,7 +869,7 @@ returns the HTML in a :term:`response`. .. note:: ``development.ini`` has a setting that controls how templates are reloaded, ``pyramid.reload_templates``. - - When set to ``True`` (as in the scaffold ``development.ini``) changed + - When set to ``True`` (as in the scaffold ``development.ini``), changed templates automatically reload without a server restart. This is convenient while developing, but slows template rendering speed. @@ -906,7 +906,7 @@ template. It includes CSS and images. ``templates/mytemplate.pt`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The single :term:`Chameleon` template that exists in the project. Its +This is the single :term:`Chameleon` template that exists in the project. Its contents are too long to show here, but it displays a default page when rendered. It is referenced by the call to ``@view_config`` as the ``renderer`` of the ``my_view`` view callable in the ``views.py`` file. See @@ -926,12 +926,13 @@ The ``tests.py`` module includes unit tests for your application. .. literalinclude:: MyProject/myproject/tests.py :language: python + :lines: 1-18 :linenos: This sample ``tests.py`` file has a single unit test defined within it. This test is executed when you run ``python setup.py test``. You may add more tests here as you build your application. You are not required to write -tests to use :app:`Pyramid`, this file is simply provided as convenience and +tests to use :app:`Pyramid`. This file is simply provided for convenience and example. See :ref:`testing_chapter` for more information about writing :app:`Pyramid` @@ -963,7 +964,8 @@ adding a single file for each view. If your project package name was ``myproject`` and you wanted to arrange all your views in a Python subpackage within the ``myproject`` :term:`package` -named ``views`` instead of within a single ``views.py`` file, you might: +named ``views`` instead of within a single ``views.py`` file, you might do the +following. - Create a ``views`` directory inside your ``myproject`` package directory (the same directory which holds ``views.py``). @@ -982,8 +984,8 @@ You can then continue to add view callable functions to the ``blog.py`` module, but you can also add other ``.py`` files which contain view callable functions to the ``views`` directory. As long as you use the ``@view_config`` directive to register views in conjunction with -``config.scan()`` they will be picked up automatically when the application -is restarted. +``config.scan()``, they will be picked up automatically when the application is +restarted. Using the Interactive Shell --------------------------- @@ -998,22 +1000,22 @@ See :ref:`interactive_shell` for more details. What Is This ``pserve`` Thing ----------------------------- -The code generated by an :app:`Pyramid` scaffold assumes that you will be -using the ``pserve`` command to start your application while you do -development. ``pserve`` is a command that reads a :term:`PasteDeploy` -``.ini`` file (e.g. ``development.ini``) and configures a server to serve a -Pyramid application based on the data in the file. +The code generated by a :app:`Pyramid` scaffold assumes that you will be using +the ``pserve`` command to start your application while you do development. +``pserve`` is a command that reads a :term:`PasteDeploy` ``.ini`` file (e.g., +``development.ini``), and configures a server to serve a :app:`Pyramid` +application based on the data in the file. ``pserve`` is by no means the only way to start up and serve a :app:`Pyramid` application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to -run a :app:`Pyramid` application is purely conventional based on the output -of its scaffolding. But we strongly recommend using ``pserve`` while -developing your application, because many other convenience introspection -commands (such as ``pviews``, ``prequest``, ``proutes`` and others) are also -implemented in terms of configuration availability of this ``.ini`` file -format. It also configures Pyramid logging and provides the ``--reload`` -switch for convenient restarting of the server when code changes. +run a :app:`Pyramid` application is purely conventional based on the output of +its scaffolding. But we strongly recommend using ``pserve`` while developing +your application because many other convenience introspection commands (such as +``pviews``, ``prequest``, ``proutes``, and others) are also implemented in +terms of configuration availability of this ``.ini`` file format. It also +configures Pyramid logging and provides the ``--reload``switch for convenient +restarting of the server when code changes. .. _alternate_wsgi_server: -- cgit v1.2.3 From 02503c54ca0bdc32aaaf177c3626b4fbe1bf6ce6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Oct 2015 04:20:46 -0700 Subject: - grammar, wrapping to 79 columns --- docs/narr/startup.rst | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index a1a23ed52..b8d3bfac9 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -13,9 +13,8 @@ you'll see something much like this show up on the console: serving on 0.0.0.0:6543 view at 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. +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. .. index:: single: startup process @@ -42,14 +41,14 @@ Here's a high-level time-ordered overview of what happens when you press #. The framework finds a section named either ``[app:main]``, ``[pipeline:main]``, or ``[composite:main]`` in the ``.ini`` file. This section represents the configuration of a :term:`WSGI` application that - will be served. If you're using a simple application (e.g. + will be served. If you're using a simple application (e.g., ``[app:main]``), the application's ``paste.app_factory`` :term:`entry point` will be named on the ``use=`` line within the section's - configuration. If, instead of a simple application, you're using a WSGI - :term:`pipeline` (e.g. a ``[pipeline:main]`` section), the application + configuration. If instead of a simple application, you're using a WSGI + :term:`pipeline` (e.g., a ``[pipeline:main]`` section), the application named on the "last" element will refer to your :app:`Pyramid` application. If instead of a simple application or a pipeline, you're using a - "composite" (e.g. ``[composite:main]``), refer to the documentation for + "composite" (e.g., ``[composite:main]``), refer to the documentation for that particular composite to understand how to make it refer to your :app:`Pyramid` application. In most cases, a Pyramid application built from a scaffold will have a single ``[app:main]`` section in it, and this @@ -60,7 +59,7 @@ Here's a high-level time-ordered overview of what happens when you press system for this application. See :ref:`logging_config` for more information. -#. The application's *constructor* named by the entry point reference on the +#. The application's *constructor* named by the entry point referenced on the ``use=`` line of the section representing your :app:`Pyramid` application is passed the key/value parameters mentioned within the section in which it's defined. The constructor is meant to return a :term:`router` @@ -78,14 +77,13 @@ Here's a high-level time-ordered overview of what happens when you press Note that the constructor function accepts a ``global_config`` argument, which is a dictionary of key/value pairs mentioned in the ``[DEFAULT]`` - section of an ``.ini`` file - (if :ref:`[DEFAULT] ` is present). - It also accepts a ``**settings`` argument, which collects - another set of arbitrary key/value pairs. The arbitrary key/value pairs - received by this function in ``**settings`` will be composed of all the - key/value pairs that are present in the ``[app:main]`` section (except for - the ``use=`` setting) when this function is called by when you run - ``pserve``. + section of an ``.ini`` file (if :ref:`[DEFAULT] + ` is present). It also accepts a + ``**settings`` argument, which collects another set of arbitrary + key/value pairs. The arbitrary key/value pairs received by this function in + ``**settings`` will be composed of all the key/value pairs that are + present in the ``[app:main]`` section (except for the ``use=`` setting) + when this function is called when you run ``pserve``. Our generated ``development.ini`` file looks like so: @@ -95,7 +93,7 @@ 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), + 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', @@ -141,11 +139,10 @@ Here's a high-level time-ordered overview of what happens when you press to receive requests. .. seealso:: - Logging configuration is described in the :ref:`logging_chapter` - chapter. There, in :ref:`request_logging_with_pastes_translogger`, - you will also find an example of how to configure - :term:`middleware` to add pre-packaged functionality to your - application. + Logging configuration is described in the :ref:`logging_chapter` chapter. + There, in :ref:`request_logging_with_pastes_translogger`, you will also + find an example of how to configure :term:`middleware` to add + pre-packaged functionality to your application. .. index:: pair: settings; deployment -- cgit v1.2.3 From c2913465ba64532b05d77508aa8a847c9e1af8d9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Oct 2015 04:20:46 -0700 Subject: - neutral gender, grammar, rewrapping --- docs/narr/router.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 6f90c70cc..7037afcec 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -17,12 +17,12 @@ requests and return responses. What happens from the time a :term:`WSGI` request enters a :app:`Pyramid` application through to the point that :app:`Pyramid` hands off a response back to WSGI for upstream processing? -#. A user initiates a request from his browser to the hostname and port +#. A user initiates a request from their browser to the hostname and port number of the WSGI server used by the :app:`Pyramid` application. #. The WSGI server used by the :app:`Pyramid` application passes the WSGI - environment to the ``__call__`` method of the :app:`Pyramid` - :term:`router` object. + environment to the ``__call__`` method of the :app:`Pyramid` :term:`router` + object. #. A :term:`request` object is created based on the WSGI environment. @@ -45,7 +45,7 @@ request enters a :app:`Pyramid` application through to the point that #. If any route matches, the route mapper adds attributes to the request: ``matchdict`` and ``matched_route`` attributes are added to the request object. The former contains a dictionary representing the matched dynamic - elements of the request's ``PATH_INFO`` value, the latter contains the + 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: if the :term:`route configuration` which matched has an @@ -69,7 +69,7 @@ request enters a :app:`Pyramid` application through to the point that #. The request is decorated with various names returned from the traverser (such as ``context``, ``view_name``, and so forth), so they can be - accessed via e.g. ``request.context`` within :term:`view` code. + accessed via, for example, ``request.context`` within :term:`view` code. #. A :class:`~pyramid.events.ContextFound` :term:`event` is sent to any subscribers. @@ -93,7 +93,7 @@ request enters a :app:`Pyramid` application through to the point that exception. #. If any exception is raised within a :term:`root factory`, by - :term:`traversal`, by a :term:`view callable` or by :app:`Pyramid` itself + :term:`traversal`, by a :term:`view callable`, or by :app:`Pyramid` itself (such as when it raises :class:`~pyramid.httpexceptions.HTTPNotFound` or :class:`~pyramid.httpexceptions.HTTPForbidden`), the router catches the exception, and attaches it to the request as the ``exception`` attribute. @@ -113,8 +113,8 @@ request enters a :app:`Pyramid` application through to the point that generate a WSGI response. The response is sent back to the upstream WSGI server. -#. :app:`Pyramid` will attempt to execute any :term:`finished - callback` functions attached via +#. :app:`Pyramid` will attempt to execute any :term:`finished callback` + functions attached via :meth:`~pyramid.request.Request.add_finished_callback`. #. The :term:`thread local` stack is popped. @@ -123,7 +123,6 @@ request enters a :app:`Pyramid` application through to the point that :alt: Pyramid Router This is a very high-level overview that leaves out various details. For more -detail about subsystems invoked by the :app:`Pyramid` router such as +detail about subsystems invoked by the :app:`Pyramid` router, such as traversal, URL dispatch, views, and event processing, see :ref:`urldispatch_chapter`, :ref:`views_chapter`, and :ref:`events_chapter`. - -- cgit v1.2.3 From b7736b4552fb6ba2c1745503f47e947928b293b1 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Tue, 6 Oct 2015 19:53:17 -0600 Subject: Missing space was causing Sphinx to barf Sphinx was barfing about "Inline literal start-string without end-string.". It barfs no more. --- docs/narr/project.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/project.rst b/docs/narr/project.rst index d8312b4ea..c9e89aff4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1014,7 +1014,7 @@ its scaffolding. But we strongly recommend using ``pserve`` while developing your application because many other convenience introspection commands (such as ``pviews``, ``prequest``, ``proutes``, and others) are also implemented in terms of configuration availability of this ``.ini`` file format. It also -configures Pyramid logging and provides the ``--reload``switch for convenient +configures Pyramid logging and provides the ``--reload`` switch for convenient restarting of the server when code changes. .. _alternate_wsgi_server: -- cgit v1.2.3 From 519c49c645ff72d275be6e41b05d1e3140314259 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 6 Oct 2015 21:53:54 -0700 Subject: - grammar, rewrapping --- docs/narr/urldispatch.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index fa3e734fe..a9fc8c251 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -8,7 +8,7 @@ URL Dispatch :term:`URL dispatch` provides a simple way to map URLs to :term:`view` code using a simple pattern matching language. An ordered set of patterns is -checked one-by-one. If one of the patterns matches the path information +checked one by one. If one of the patterns matches the path information associated with a request, a particular :term:`view callable` is invoked. A view callable is a specific bit of code, defined in your application, that receives the :term:`request` and returns a :term:`response` object. @@ -21,8 +21,8 @@ If any route configuration is present in an application, the :app:`Pyramid` matching patterns present in a *route map*. If any route pattern matches the information in the :term:`request`, -:app:`Pyramid` will invoke the :term:`view lookup` process to find a -matching view. +:app:`Pyramid` will invoke the :term:`view lookup` process to find a matching +view. If no route pattern in the route map matches the information in the :term:`request` provided in your application, :app:`Pyramid` will fail over @@ -39,7 +39,7 @@ application. A route has a *name*, which acts as an identifier to be used for URL generation. The name also allows developers to associate a view configuration with the route. A route also has a *pattern*, meant to match against the ``PATH_INFO`` portion of a URL (the portion following the scheme -and port, e.g. ``/foo/bar`` in the URL ``_). It +and port, e.g., ``/foo/bar`` in the URL ``http://localhost:8080/foo/bar``). It also optionally has a ``factory`` and a set of :term:`route predicate` attributes. -- cgit v1.2.3 From 5b6fd0e0fc22e37053f8d612a9f0c5dbd485606c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Oct 2015 17:11:52 -0700 Subject: - grammar, rewrapping --- docs/narr/urldispatch.rst | 510 +++++++++++++++++++++++----------------------- 1 file changed, 250 insertions(+), 260 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index a9fc8c251..c13558008 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -25,8 +25,8 @@ If any route pattern matches the information in the :term:`request`, view. If no route pattern in the route map matches the information in the -:term:`request` provided in your application, :app:`Pyramid` will fail over -to using :term:`traversal` to perform resource location and view lookup. +:term:`request` provided in your application, :app:`Pyramid` will fail over to +using :term:`traversal` to perform resource location and view lookup. .. index:: single: route configuration @@ -35,8 +35,8 @@ Route Configuration ------------------- :term:`Route configuration` is the act of adding a new :term:`route` to an -application. A route has a *name*, which acts as an identifier to be used -for URL generation. The name also allows developers to associate a view +application. A route has a *name*, which acts as an identifier to be used for +URL generation. The name also allows developers to associate a view configuration with the route. A route also has a *pattern*, meant to match against the ``PATH_INFO`` portion of a URL (the portion following the scheme and port, e.g., ``/foo/bar`` in the URL ``http://localhost:8080/foo/bar``). It @@ -71,8 +71,8 @@ invoked when the associated route pattern matches during a request. More commonly, you will not use any ``add_view`` statements in your project's "setup" code. You will instead use ``add_route`` statements, and use a -:term:`scan` to associate view callables with routes. For example, if -this is a portion of your project's ``__init__.py``: +:term:`scan` to associate view callables with routes. For example, if this is +a portion of your project's ``__init__.py``: .. code-block:: python @@ -85,8 +85,8 @@ setup code. However, the above :term:`scan` execution decoration`, including any objects decorated with the :class:`pyramid.view.view_config` decorator in the ``mypackage`` Python package. For example, if you have a ``views.py`` in your package, a scan will -pick up any of its configuration decorators, so we can add one there -that references ``myroute`` as a ``route_name`` parameter: +pick up any of its configuration decorators, so we can add one there that +references ``myroute`` as a ``route_name`` parameter: .. code-block:: python @@ -97,8 +97,8 @@ that references ``myroute`` as a ``route_name`` parameter: def myview(request): return Response('OK') -The above combination of ``add_route`` and ``scan`` is completely equivalent -to using the previous combination of ``add_route`` and ``add_view``. +The above combination of ``add_route`` and ``scan`` is completely equivalent to +using the previous combination of ``add_route`` and ``add_view``. .. index:: single: route path pattern syntax @@ -109,13 +109,13 @@ to using the previous combination of ``add_route`` and ``add_view``. Route Pattern Syntax ~~~~~~~~~~~~~~~~~~~~ -The syntax of the pattern matching language used by :app:`Pyramid` URL -dispatch in the *pattern* argument is straightforward; it is close to that of -the :term:`Routes` system used by :term:`Pylons`. +The syntax of the pattern matching language used by :app:`Pyramid` URL dispatch +in the *pattern* argument is straightforward. It is close to that of the +:term:`Routes` system used by :term:`Pylons`. -The *pattern* used in route configuration may start with a slash character. -If the pattern does not start with a slash character, an implicit slash will -be prepended to it at matching time. For example, the following patterns are +The *pattern* used in route configuration may start with a slash character. If +the pattern does not start with a slash character, an implicit slash will be +prepended to it at matching time. For example, the following patterns are equivalent: .. code-block:: text @@ -128,28 +128,29 @@ and: /{foo}/bar/baz -If a pattern is a valid URL it won't be ever matched against an incoming -request. Instead it can be useful for generating external URLs. See -:ref:`External routes ` for details. +If a pattern is a valid URL it won't be matched against an incoming request. +Instead it can be useful for generating external URLs. See :ref:`External +routes ` for details. -A pattern segment (an individual item between ``/`` characters in the -pattern) may either be a literal string (e.g. ``foo``) *or* it may be a -replacement marker (e.g. ``{foo}``) or a certain combination of both. A -replacement marker does not need to be preceded by a ``/`` character. +A pattern segment (an individual item between ``/`` characters in the pattern) +may either be a literal string (e.g., ``foo``) *or* it may be a replacement +marker (e.g., ``{foo}``), or a certain combination of both. A replacement +marker does not need to be preceded by a ``/`` character. -A replacement marker is in the format ``{name}``, where this means "accept -any characters up to the next slash character and use this as the ``name`` +A replacement marker is in the format ``{name}``, where this means "accept any +characters up to the next slash character and use this as the ``name`` :term:`matchdict` value." A replacement marker in a pattern must begin with an uppercase or lowercase ASCII letter or an underscore, and can be composed only of uppercase or lowercase ASCII letters, underscores, and numbers. For example: ``a``, -``a_b``, ``_b``, and ``b9`` are all valid replacement marker names, but -``0a`` is not. +``a_b``, ``_b``, and ``b9`` are all valid replacement marker names, but ``0a`` +is not. -.. note:: A replacement marker could not start with an underscore until - Pyramid 1.2. Previous versions required that the replacement marker start - with an uppercase or lowercase letter. +.. versionchanged:: 1.2 + A replacement marker could not start with an underscore until Pyramid 1.2. + Previous versions required that the replacement marker start with an + uppercase or lowercase letter. A matchdict is the dictionary representing the dynamic parts extracted from a URL based on the routing pattern. It is available as ``request.matchdict``. @@ -174,18 +175,18 @@ It will not match the following patterns however: foo/1/2/ -> No match (trailing slash) bar/abc/def -> First segment literal mismatch -The match for a segment replacement marker in a segment will be done only up -to the first non-alphanumeric character in the segment in the pattern. So, -for instance, if this route pattern was used: +The match for a segment replacement marker in a segment will be done only up to +the first non-alphanumeric character in the segment in the pattern. So, for +instance, if this route pattern was used: .. code-block:: text foo/{name}.html -The literal path ``/foo/biz.html`` will match the above route pattern, and -the match result will be ``{'name':u'biz'}``. However, the literal path -``/foo/biz`` will not match, because it does not contain a literal ``.html`` -at the end of the segment represented by ``{name}.html`` (it only contains +The literal path ``/foo/biz.html`` will match the above route pattern, and the +match result will be ``{'name':u'biz'}``. However, the literal path +``/foo/biz`` will not match, because it does not contain a literal ``.html`` at +the end of the segment represented by ``{name}.html`` (it only contains ``biz``, not ``biz.html``). To capture both segments, two replacement markers can be used: @@ -194,28 +195,27 @@ To capture both segments, two replacement markers can be used: foo/{name}.{ext} -The literal path ``/foo/biz.html`` will match the above route pattern, and -the match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs -because there is a literal part of ``.`` (period) between the two replacement -markers ``{name}`` and ``{ext}``. +The literal path ``/foo/biz.html`` will match the above route pattern, and the +match result will be ``{'name': 'biz', 'ext': 'html'}``. This occurs because +there is a literal part of ``.`` (period) between the two replacement markers +``{name}`` and ``{ext}``. Replacement markers can optionally specify a regular expression which will be -used to decide whether a path segment should match the marker. To specify -that a replacement marker should match only a specific set of characters as -defined by a regular expression, you must use a slightly extended form of -replacement marker syntax. Within braces, the replacement marker name must -be followed by a colon, then directly thereafter, the regular expression. -The *default* regular expression associated with a replacement marker -``[^/]+`` matches one or more characters which are not a slash. For example, -under the hood, the replacement marker ``{foo}`` can more verbosely be -spelled as ``{foo:[^/]+}``. You can change this to be an arbitrary regular -expression to match an arbitrary sequence of characters, such as -``{foo:\d+}`` to match only digits. +used to decide whether a path segment should match the marker. To specify that +a replacement marker should match only a specific set of characters as defined +by a regular expression, you must use a slightly extended form of replacement +marker syntax. Within braces, the replacement marker name must be followed by +a colon, then directly thereafter, the regular expression. The *default* +regular expression associated with a replacement marker ``[^/]+`` matches one +or more characters which are not a slash. For example, under the hood, the +replacement marker ``{foo}`` can more verbosely be spelled as ``{foo:[^/]+}``. +You can change this to be an arbitrary regular expression to match an arbitrary +sequence of characters, such as ``{foo:\d+}`` to match only digits. It is possible to use two replacement markers without any literal characters between them, for instance ``/{foo}{bar}``. However, this would be a -nonsensical pattern without specifying a custom regular expression to -restrict what each marker captures. +nonsensical pattern without specifying a custom regular expression to restrict +what each marker captures. Segments must contain at least one character in order to match a segment replacement marker. For example, for the URL ``/abc/``: @@ -224,7 +224,7 @@ replacement marker. For example, for the URL ``/abc/``: - ``/{foo}/`` will match. -Note that values representing matched path segments will be url-unquoted and +Note that values representing matched path segments will be URL-unquoted and decoded from UTF-8 into Unicode within the matchdict. So for instance, the following pattern: @@ -244,9 +244,9 @@ The matchdict will look like so (the value is URL-decoded / UTF-8 decoded): {'bar':u'La Pe\xf1a'} -Literal strings in the path segment should represent the *decoded* value of -the ``PATH_INFO`` provided to Pyramid. You don't want to use a URL-encoded -value or a bytestring representing the literal's UTF-8 in the pattern. For +Literal strings in the path segment should represent the *decoded* value of the +``PATH_INFO`` provided to Pyramid. You don't want to use a URL-encoded value +or a bytestring representing the literal encoded as UTF-8 in the pattern. For example, rather than this: .. code-block:: text @@ -259,8 +259,8 @@ You'll want to use something like this: /Foo Bar/{baz} -For patterns that contain "high-order" characters in its literals, you'll -want to use a Unicode value as the pattern as opposed to any URL-encoded or +For patterns that contain "high-order" characters in its literals, you'll want +to use a Unicode value as the pattern as opposed to any URL-encoded or UTF-8-encoded value. For example, you might be tempted to use a bytestring pattern like this: @@ -268,12 +268,11 @@ pattern like this: /La Pe\xc3\xb1a/{x} -But this will either cause an error at startup time or it won't match -properly. You'll want to use a Unicode value as the pattern instead rather -than raw bytestring escapes. You can use a high-order Unicode value as the -pattern by using `Python source file encoding -`_ plus the "real" character in the -Unicode pattern in the source, like so: +But this will either cause an error at startup time or it won't match properly. +You'll want to use a Unicode value as the pattern instead rather than raw +bytestring escapes. You can use a high-order Unicode value as the pattern by +using `Python source file encoding `_ +plus the "real" character in the Unicode pattern in the source, like so: .. code-block:: text @@ -291,8 +290,8 @@ only to literals in the pattern. If the pattern has a ``*`` in it, the name which follows it is considered a "remainder match". A remainder match *must* come at the end of the pattern. -Unlike segment replacement markers, it does not need to be preceded by a -slash. For example: +Unlike segment replacement markers, it does not need to be preceded by a slash. +For example: .. code-block:: text @@ -310,7 +309,7 @@ The above pattern will match these URLs, generating the following matchdicts: Note that when a ``*stararg`` remainder match is matched, the value put into the matchdict is turned into a tuple of path segments representing the -remainder of the path. These path segments are url-unquoted and decoded from +remainder of the path. These path segments are URL-unquoted and decoded from UTF-8 into Unicode. For example, for the following pattern: .. code-block:: text @@ -357,15 +356,15 @@ Route Declaration Ordering Route configuration declarations are evaluated in a specific order when a request enters the system. As a result, the order of route configuration -declarations is very important. The order that routes declarations are +declarations is very important. The order in which route declarations are evaluated is the order in which they are added to the application at startup time. (This is unlike a different way of mapping URLs to code that :app:`Pyramid` provides, named :term:`traversal`, which does not depend on pattern ordering). For routes added via the :mod:`~pyramid.config.Configurator.add_route` method, -the order that routes are evaluated is the order in which they are added to -the configuration imperatively. +the order that routes are evaluated is the order in which they are added to the +configuration imperatively. For example, route configuration statements with the following patterns might be added in the following order: @@ -375,10 +374,9 @@ be added in the following order: members/{def} members/abc -In such a configuration, the ``members/abc`` pattern would *never* be -matched. This is because the match ordering will always match -``members/{def}`` first; the route configuration with ``members/abc`` will -never be evaluated. +In such a configuration, the ``members/abc`` pattern would *never* be matched. +This is because the match ordering will always match ``members/{def}`` first; +the route configuration with ``members/abc`` will never be evaluated. .. index:: single: route configuration arguments @@ -416,19 +414,18 @@ the system, for each route configuration declaration present in the system, declared. This checking happens in the order that the routes were declared via :meth:`pyramid.config.Configurator.add_route`. -When a route configuration is declared, it may contain :term:`route -predicate` arguments. All route predicates associated with a route -declaration must be ``True`` for the route configuration to be used for a -given request during a check. If any predicate in the set of :term:`route -predicate` arguments provided to a route configuration returns ``False`` -during a check, that route is skipped and route matching continues through -the ordered set of routes. +When a route configuration is declared, it may contain :term:`route predicate` +arguments. All route predicates associated with a route declaration must be +``True`` for the route configuration to be used for a given request during a +check. If any predicate in the set of :term:`route predicate` arguments +provided to a route configuration returns ``False`` during a check, that route +is skipped and route matching continues through the ordered set of routes. If any route matches, the route matching process stops and the :term:`view -lookup` subsystem takes over to find the most reasonable view callable for -the matched route. Most often, there's only one view that will match (a view -configured with a ``route_name`` argument matching the matched route). To -gain a better understanding of how routes and views are associated in a real +lookup` subsystem takes over to find the most reasonable view callable for the +matched route. Most often, there's only one view that will match (a view +configured with a ``route_name`` argument matching the matched route). To gain +a better understanding of how routes and views are associated in a real application, you can use the ``pviews`` command, as documented in :ref:`displaying_matching_views`. @@ -445,11 +442,10 @@ The Matchdict ~~~~~~~~~~~~~ When the URL pattern associated with a particular route configuration is -matched by a request, a dictionary named ``matchdict`` is added as an -attribute of the :term:`request` object. Thus, ``request.matchdict`` will -contain the values that match replacement patterns in the ``pattern`` -element. The keys in a matchdict will be strings. The values will be -Unicode objects. +matched by a request, a dictionary named ``matchdict`` is added as an attribute +of the :term:`request` object. Thus, ``request.matchdict`` will contain the +values that match replacement patterns in the ``pattern`` element. The keys in +a matchdict will be strings. The values will be Unicode objects. .. note:: @@ -466,10 +462,10 @@ The Matched Route When the URL pattern associated with a particular route configuration is matched by a request, an object named ``matched_route`` is added as an -attribute of the :term:`request` object. Thus, ``request.matched_route`` -will be an object implementing the :class:`~pyramid.interfaces.IRoute` -interface which matched the request. The most useful attribute of the route -object is ``name``, which is the name of the route that matched. +attribute of the :term:`request` object. Thus, ``request.matched_route`` will +be an object implementing the :class:`~pyramid.interfaces.IRoute` interface +which matched the request. The most useful attribute of the route object is +``name``, which is the name of the route that matched. .. note:: @@ -480,8 +476,8 @@ Routing Examples ---------------- Let's check out some examples of how route configuration statements might be -commonly declared, and what will happen if they are matched by the -information present in a request. +commonly declared, and what will happen if they are matched by the information +present in a request. .. _urldispatch_example1: @@ -505,18 +501,18 @@ configuration will be invoked. Recall that the ``@view_config`` is equivalent to calling ``config.add_view``, because the ``config.scan()`` call will import ``mypackage.views``, shown below, and execute ``config.add_view`` under the hood. Each view then maps the -route name to the matching view callable. In the case of the above -example, when the URL of a request matches ``/site/{id}``, the view callable at -the Python dotted path name ``mypackage.views.site_view`` will be called with -the request. In other words, we've associated a view callable directly with a +route name to the matching view callable. In the case of the above example, +when the URL of a request matches ``/site/{id}``, the view callable at the +Python dotted path name ``mypackage.views.site_view`` will be called with the +request. In other words, we've associated a view callable directly with a route pattern. When the ``/site/{id}`` route pattern matches during a request, the -``site_view`` view callable is invoked with that request as its sole -argument. When this route matches, a ``matchdict`` will be generated and -attached to the request as ``request.matchdict``. If the specific URL -matched is ``/site/1``, the ``matchdict`` will be a dictionary with a single -key, ``id``; the value will be the string ``'1'``, ex.: ``{'id':'1'}``. +``site_view`` view callable is invoked with that request as its sole argument. +When this route matches, a ``matchdict`` will be generated and attached to the +request as ``request.matchdict``. If the specific URL matched is ``/site/1``, +the ``matchdict`` will be a dictionary with a single key, ``id``; the value +will be the string ``'1'``, ex.: ``{'id':'1'}``. The ``mypackage.views`` module referred to above might look like so: @@ -539,8 +535,8 @@ information about views. Example 2 ~~~~~~~~~ -Below is an example of a more complicated set of route statements you might -add to your application: +Below is an example of a more complicated set of route statements you might add +to your application: .. code-block:: python :linenos: @@ -587,33 +583,32 @@ forms: and attached to the :term:`request` will consist of ``{'idea':'1'}``. - When a URL matches the pattern ``/users/{user}``, the view callable - available at the dotted Python pathname ``mypackage.views.user_view`` will - be called. For the specific URL ``/users/1``, the ``matchdict`` generated - and attached to the :term:`request` will consist of ``{'user':'1'}``. + available at the dotted Python pathname ``mypackage.views.user_view`` will be + called. For the specific URL ``/users/1``, the ``matchdict`` generated and + attached to the :term:`request` will consist of ``{'user':'1'}``. - When a URL matches the pattern ``/tags/{tag}``, the view callable available at the dotted Python pathname ``mypackage.views.tag_view`` will be called. - For the specific URL ``/tags/1``, the ``matchdict`` generated and attached - to the :term:`request` will consist of ``{'tag':'1'}``. + For the specific URL ``/tags/1``, the ``matchdict`` generated and attached to + the :term:`request` will consist of ``{'tag':'1'}``. In this example we've again associated each of our routes with a :term:`view -callable` directly. In all cases, the request, which will have a -``matchdict`` attribute detailing the information found in the URL by the -process will be passed to the view callable. +callable` directly. In all cases, the request, which will have a ``matchdict`` +attribute detailing the information found in the URL by the process will be +passed to the view callable. Example 3 ~~~~~~~~~ -The :term:`context` resource object passed in to a view found as the result -of URL dispatch will, by default, be an instance of the object returned by -the :term:`root factory` configured at startup time (the ``root_factory`` -argument to the :term:`Configurator` used to configure the application). +The :term:`context` resource object passed in to a view found as the result of +URL dispatch will, by default, be an instance of the object returned by the +:term:`root factory` configured at startup time (the ``root_factory`` argument +to the :term:`Configurator` used to configure the application). You can override this behavior by passing in a ``factory`` argument to the :meth:`~pyramid.config.Configurator.add_route` method for a particular route. -The ``factory`` should be a callable that accepts a :term:`request` and -returns an instance of a class that will be the context resource used by the -view. +The ``factory`` should be a callable that accepts a :term:`request` and returns +an instance of a class that will be the context resource used by the view. An example of using a route with a factory: @@ -685,9 +680,9 @@ Or provide the literal string ``/`` as the pattern: Generating Route URLs --------------------- -Use the :meth:`pyramid.request.Request.route_url` method to generate URLs -based on route patterns. For example, if you've configured a route with the -``name`` "foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. +Use the :meth:`pyramid.request.Request.route_url` method to generate URLs based +on route patterns. For example, if you've configured a route with the ``name`` +"foo" and the ``pattern`` "{a}/{b}/{c}", you might do this. .. code-block:: python :linenos: @@ -707,13 +702,12 @@ To generate only the *path* portion of a URL from a route, use the This will return the string ``/1/2/3`` rather than a full URL. -Replacement values passed to ``route_url`` or ``route_path`` must be Unicode -or bytestrings encoded in UTF-8. One exception to this rule exists: if -you're trying to replace a "remainder" match value (a ``*stararg`` -replacement value), the value may be a tuple containing Unicode strings or -UTF-8 strings. +Replacement values passed to ``route_url`` or ``route_path`` must be Unicode or +bytestrings encoded in UTF-8. One exception to this rule exists: if you're +trying to replace a "remainder" match value (a ``*stararg`` replacement value), +the value may be a tuple containing Unicode strings or UTF-8 strings. -Note that URLs and paths generated by ``route_path`` and ``route_url`` are +Note that URLs and paths generated by ``route_url`` and ``route_path`` are always URL-quoted string types (they contain no non-ASCII characters). Therefore, if you've added a route like so: @@ -727,7 +721,7 @@ And you later generate a URL using ``route_path`` or ``route_url`` like so: url = request.route_path('la', city=u'Québec') -You will wind up with the path encoded to UTF-8 and URL quoted like so: +You will wind up with the path encoded to UTF-8 and URL-quoted like so: .. code-block:: text @@ -759,7 +753,7 @@ You can get a similar result by passing a tuple composed of path elements: url = request.route_path('abc', foo=(u'Québec', u'biz')) -Each value in the tuple will be url-quoted and joined by slashes in this case: +Each value in the tuple will be URL-quoted and joined by slashes in this case: .. code-block:: text @@ -793,7 +787,7 @@ ignored when ``static`` is ``True``. :ref:`External routes ` are implicitly static. .. versionadded:: 1.1 - the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route` + the ``static`` argument to :meth:`~pyramid.config.Configurator.add_route`. .. _external_route_narr: @@ -836,13 +830,13 @@ argument to :meth:`pyramid.config.Configurator.add_notfound_view` or the equivalent ``append_slash`` argument to the :class:`pyramid.view.notfound_view_config` decorator. -Adding ``append_slash=True`` is a way to automatically redirect requests -where the URL lacks a trailing slash, but requires one to match the proper -route. When configured, along with at least one other route in your -application, this view will be invoked if the value of ``PATH_INFO`` does not -already end in a slash, and if the value of ``PATH_INFO`` *plus* a slash -matches any route's pattern. In this case it does an HTTP redirect to the -slash-appended ``PATH_INFO``. In addition you may pass anything that implements +Adding ``append_slash=True`` is a way to automatically redirect requests where +the URL lacks a trailing slash, but requires one to match the proper route. +When configured, along with at least one other route in your application, this +view will be invoked if the value of ``PATH_INFO`` does not already end in a +slash, and if the value of ``PATH_INFO`` *plus* a slash matches any route's +pattern. In this case it does an HTTP redirect to the slash-appended +``PATH_INFO``. In addition you may pass anything that implements :class:`pyramid.interfaces.IResponse` which will then be used in place of the default class (:class:`pyramid.httpexceptions.HTTPFound`). @@ -872,12 +866,11 @@ application: config.add_notfound_view(notfound, append_slash=True) If a request enters the application with the ``PATH_INFO`` value of -``/no_slash``, the first route will match and the browser will show "No -slash". However, if a request enters the application with the ``PATH_INFO`` -value of ``/no_slash/``, *no* route will match, and the slash-appending not -found view will not find a matching route with an appended slash. As a -result, the ``notfound`` view will be called and it will return a "Not found, -bro." body. +``/no_slash``, the first route will match and the browser will show "No slash". +However, if a request enters the application with the ``PATH_INFO`` value of +``/no_slash/``, *no* route will match, and the slash-appending not found view +will not find a matching route with an appended slash. As a result, the +``notfound`` view will be called and it will return a "Not found, bro." body. If a request enters the application with the ``PATH_INFO`` value of ``/has_slash/``, the second route will match. If a request enters the @@ -934,10 +927,10 @@ Debugging Route Matching It's useful to be able to take a peek under the hood when requests that enter your application aren't matching your routes as you expect them to. To debug -route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or the -``pyramid.debug_routematch`` configuration file setting (set either to ``true``). -Details of the route matching decision for a particular request to the -:app:`Pyramid` application will be printed to the ``stderr`` of the console +route matching, use the ``PYRAMID_DEBUG_ROUTEMATCH`` environment variable or +the ``pyramid.debug_routematch`` configuration file setting (set either to +``true``). Details of the route matching decision for a particular request to +the :app:`Pyramid` application will be printed to the ``stderr`` of the console which you started the application from. For example: .. code-block:: text @@ -954,11 +947,11 @@ which you started the application from. For example: http://localhost:6543/static/logo.png; \ route_name: 'static/', .... -See :ref:`environment_chapter` for more information about how, and where to -set these values. +See :ref:`environment_chapter` for more information about how and where to set +these values. -You can also use the ``proutes`` command to see a display of all the -routes configured in your application; for more information, see +You can also use the ``proutes`` command to see a display of all the routes +configured in your application. For more information, see :ref:`displaying_application_routes`. .. _route_prefix: @@ -979,11 +972,11 @@ named ``route_prefix`` which can be useful to authors of URL-dispatch-based applications. If ``route_prefix`` is supplied to the include method, it must be a string. This string represents a route prefix that will be prepended to all route patterns added by the *included* configuration. Any calls to -:meth:`pyramid.config.Configurator.add_route` within the included callable -will have their pattern prefixed with the value of ``route_prefix``. This can -be used to help mount a set of routes at a different location than the -included callable's author intended while still maintaining the same route -names. For example: +:meth:`pyramid.config.Configurator.add_route` within the included callable will +have their pattern prefixed with the value of ``route_prefix``. This can be +used to help mount a set of routes at a different location than the included +callable's author intended while still maintaining the same route names. For +example: .. code-block:: python :linenos: @@ -998,15 +991,15 @@ names. For example: config.include(users_include, route_prefix='/users') In the above configuration, the ``show_users`` route will have an effective -route pattern of ``/users/show``, instead of ``/show`` because the +route pattern of ``/users/show`` instead of ``/show`` because the ``route_prefix`` argument will be prepended to the pattern. The route will then only match if the URL path is ``/users/show``, and when the :meth:`pyramid.request.Request.route_url` function is called with the route name ``show_users``, it will generate a URL with that same path. Route prefixes are recursive, so if a callable executed via an include itself -turns around and includes another callable, the second-level route prefix -will be prepended with the first: +turns around and includes another callable, the second-level route prefix will +be prepended with the first: .. code-block:: python :linenos: @@ -1025,15 +1018,15 @@ will be prepended with the first: config.include(users_include, route_prefix='/users') In the above configuration, the ``show_users`` route will still have an -effective route pattern of ``/users/show``. The ``show_times`` route -however, will have an effective pattern of ``/users/timing/times``. +effective route pattern of ``/users/show``. The ``show_times`` route, however, +will have an effective pattern of ``/users/timing/times``. -Route prefixes have no impact on the requirement that the set of route -*names* in any given Pyramid configuration must be entirely unique. If you -compose your URL dispatch application out of many small subapplications using -:meth:`pyramid.config.Configurator.include`, it's wise to use a dotted name -for your route names, so they'll be unlikely to conflict with other packages -that may be added in the future. For example: +Route prefixes have no impact on the requirement that the set of route *names* +in any given Pyramid configuration must be entirely unique. If you compose +your URL dispatch application out of many small subapplications using +:meth:`pyramid.config.Configurator.include`, it's wise to use a dotted name for +your route names so they'll be unlikely to conflict with other packages that +may be added in the future. For example: .. code-block:: python :linenos: @@ -1060,15 +1053,16 @@ Custom Route Predicates ----------------------- Each of the predicate callables fed to the ``custom_predicates`` argument of -:meth:`~pyramid.config.Configurator.add_route` must be a callable accepting -two arguments. The first argument passed to a custom predicate is a -dictionary conventionally named ``info``. The second argument is the current +:meth:`~pyramid.config.Configurator.add_route` must be a callable accepting two +arguments. The first argument passed to a custom predicate is a dictionary +conventionally named ``info``. The second argument is the current :term:`request` object. -The ``info`` dictionary has a number of contained values: ``match`` is a -dictionary: it represents the arguments matched in the URL by the route. -``route`` is an object representing the route which was matched (see -:class:`pyramid.interfaces.IRoute` for the API of such a route object). +The ``info`` dictionary has a number of contained values, including ``match`` +and ``route``. ``match`` is a dictionary which represents the arguments matched +in the URL by the route. ``route`` is an object representing the route which +was matched (see :class:`pyramid.interfaces.IRoute` for the API of such a route +object). ``info['match']`` is useful when predicates need access to the route match. For example: @@ -1118,9 +1112,9 @@ instance, a predicate might do some type conversion of values: config.add_route('ymd', '/{year}/{month}/{day}', custom_predicates=(ymd_to_int,)) -Note that a conversion predicate is still a predicate so it must return -``True`` or ``False``; a predicate that does *only* conversion, such as the -one we demonstrate above should unconditionally return ``True``. +Note that a conversion predicate is still a predicate, so it must return +``True`` or ``False``. A predicate that does *only* conversion, such as the one +we demonstrate above, should unconditionally return ``True``. To avoid the try/except uncertainty, the route pattern can contain regular expressions specifying requirements for that marker. For instance: @@ -1141,31 +1135,31 @@ expressions specifying requirements for that marker. For instance: config.add_route('ymd', '/{year:\d+}/{month:\d+}/{day:\d+}', custom_predicates=(ymd_to_int,)) -Now the try/except is no longer needed because the route will not match at -all unless these markers match ``\d+`` which requires them to be valid digits -for an ``int`` type conversion. +Now the try/except is no longer needed because the route will not match at all +unless these markers match ``\d+`` which requires them to be valid digits for +an ``int`` type conversion. -The ``match`` dictionary passed within ``info`` to each predicate attached to -a route will be the same dictionary. Therefore, when registering a custom -predicate which modifies the ``match`` dict, the code registering the -predicate should usually arrange for the predicate to be the *last* custom -predicate in the custom predicate list. Otherwise, custom predicates which -fire subsequent to the predicate which performs the ``match`` modification -will receive the *modified* match dictionary. +The ``match`` dictionary passed within ``info`` to each predicate attached to a +route will be the same dictionary. Therefore, when registering a custom +predicate which modifies the ``match`` dict, the code registering the predicate +should usually arrange for the predicate to be the *last* custom predicate in +the custom predicate list. Otherwise, custom predicates which fire subsequent +to the predicate which performs the ``match`` modification will receive the +*modified* match dictionary. .. warning:: It is a poor idea to rely on ordering of custom predicates to build a conversion pipeline, where one predicate depends on the side effect of - another. For instance, it's a poor idea to register two custom - predicates, one which handles conversion of a value to an int, the next - which handles conversion of that integer to some custom object. Just do - all that in a single custom predicate. + another. For instance, it's a poor idea to register two custom predicates, + one which handles conversion of a value to an int, the next which handles + conversion of that integer to some custom object. Just do all that in a + single custom predicate. The ``route`` object in the ``info`` dict is an object that has two useful -attributes: ``name`` and ``pattern``. The ``name`` attribute is the route -name. The ``pattern`` attribute is the route pattern. An example of using -the route in a set of route predicates: +attributes: ``name`` and ``pattern``. The ``name`` attribute is the route name. +The ``pattern`` attribute is the route pattern. Here's an example of using the +route in a set of route predicates: .. code-block:: python :linenos: @@ -1180,14 +1174,14 @@ the route in a set of route predicates: custom_predicates=(twenty_ten,)) The above predicate, when added to a number of route configurations ensures -that the year match argument is '2010' if and only if the route name is -'ymd', 'ym', or 'y'. +that the year match argument is '2010' if and only if the route name is 'ymd', +'ym', or 'y'. -You can also caption the predicates by setting the ``__text__`` -attribute. This will help you with the ``pviews`` command (see +You can also caption the predicates by setting the ``__text__`` attribute. This +will help you with the ``pviews`` command (see :ref:`displaying_application_routes`) and the ``pyramid_debugtoolbar``. -If a predicate is a class just add __text__ property in a standard manner. +If a predicate is a class, just add ``__text__`` property in a standard manner. .. code-block:: python :linenos: @@ -1199,8 +1193,8 @@ If a predicate is a class just add __text__ property in a standard manner. class DummyCustomPredicate2(object): __text__ = 'my custom class predicate' -If a predicate is a method you'll need to assign it after method declaration -(see `PEP 232 `_) +If a predicate is a method, you'll need to assign it after method declaration +(see `PEP 232 `_). .. code-block:: python :linenos: @@ -1209,8 +1203,8 @@ If a predicate is a method you'll need to assign it after method declaration pass custom_predicate.__text__ = 'my custom method predicate' -If a predicate is a classmethod using @classmethod will not work, but you can -still easily do it by wrapping it in classmethod call. +If a predicate is a classmethod, using ``@classmethod`` will not work, but you +can still easily do it by wrapping it in a classmethod call. .. code-block:: python :linenos: @@ -1220,7 +1214,7 @@ still easily do it by wrapping it in classmethod call. classmethod_predicate.__text__ = 'my classmethod predicate' classmethod_predicate = classmethod(classmethod_predicate) -Same will work with staticmethod, just use ``staticmethod`` instead of +The same will work with ``staticmethod``, using ``staticmethod`` instead of ``classmethod``. .. seealso:: @@ -1236,10 +1230,10 @@ Same will work with staticmethod, just use ``staticmethod`` instead of Route Factories --------------- -Although it is not a particular common need in basic applications, a "route" -configuration declaration can mention a "factory". When that route matches a -request, and a factory is attached to a route, the :term:`root factory` -passed at startup time to the :term:`Configurator` is ignored; instead the +Although it is not a particularly common need in basic applications, a "route" +configuration declaration can mention a "factory". When a route matches a +request, and a factory is attached to the route, the :term:`root factory` +passed at startup time to the :term:`Configurator` is ignored. Instead the factory associated with the route is used to generate a :term:`root` object. This object will usually be used as the :term:`context` resource of the view callable ultimately found via :term:`view lookup`. @@ -1255,8 +1249,8 @@ The factory can either be a Python object or a :term:`dotted Python name` (a string) which points to such a Python object, as it is above. In this way, each route can use a different factory, making it possible to -supply a different :term:`context` resource object to the view related to -each particular route. +supply a different :term:`context` resource object to the view related to each +particular route. A factory must be a callable which accepts a request and returns an arbitrary Python object. For example, the below class can be used as a factory: @@ -1268,33 +1262,31 @@ Python object. For example, the below class can be used as a factory: def __init__(self, request): pass -A route factory is actually conceptually identical to the :term:`root -factory` described at :ref:`the_resource_tree`. +A route factory is actually conceptually identical to the :term:`root factory` +described at :ref:`the_resource_tree`. Supplying a different resource factory for each route is useful when you're trying to use a :app:`Pyramid` :term:`authorization policy` to provide -declarative, "context sensitive" security checks; each resource can maintain -a separate :term:`ACL`, as documented in -:ref:`using_security_with_urldispatch`. It is also useful when you wish to -combine URL dispatch with :term:`traversal` as documented within -:ref:`hybrid_chapter`. +declarative, "context sensitive" security checks. Each resource can maintain a +separate :term:`ACL`, as documented in :ref:`using_security_with_urldispatch`. +It is also useful when you wish to combine URL dispatch with :term:`traversal` +as documented within :ref:`hybrid_chapter`. .. index:: pair: URL dispatch; security .. _using_security_with_urldispatch: -Using :app:`Pyramid` Security With URL Dispatch --------------------------------------------------- +Using :app:`Pyramid` Security with URL Dispatch +----------------------------------------------- :app:`Pyramid` provides its own security framework which consults an -:term:`authorization policy` before allowing any application code to be -called. This framework operates in terms of an access control list, which is -stored as an ``__acl__`` attribute of a resource object. A common thing to -want to do is to attach an ``__acl__`` to the resource object dynamically for -declarative security purposes. You can use the ``factory`` argument that -points at a factory which attaches a custom ``__acl__`` to an object at its -creation time. +:term:`authorization policy` before allowing any application code to be called. +This framework operates in terms of an access control list, which is stored as +an ``__acl__`` attribute of a resource object. A common thing to want to do is +to attach an ``__acl__`` to the resource object dynamically for declarative +security purposes. You can use the ``factory`` argument that points at a +factory which attaches a custom ``__acl__`` to an object at its creation time. Such a ``factory`` might look like so: @@ -1310,15 +1302,15 @@ Such a ``factory`` might look like so: If the route ``archives/{article}`` is matched, and the article number is ``1``, :app:`Pyramid` will generate an ``Article`` :term:`context` resource -with an ACL on it that allows the ``editor`` principal the ``view`` -permission. Obviously you can do more generic things than inspect the routes -match dict to see if the ``article`` argument matches a particular string; -our sample ``Article`` factory class is not very ambitious. +with an ACL on it that allows the ``editor`` principal the ``view`` permission. +Obviously you can do more generic things than inspect the route's match dict to +see if the ``article`` argument matches a particular string. Our sample +``Article`` factory class is not very ambitious. .. note:: - See :ref:`security_chapter` for more information about - :app:`Pyramid` security and ACLs. + See :ref:`security_chapter` for more information about :app:`Pyramid` + security and ACLs. .. index:: pair: route; view callable lookup details @@ -1330,10 +1322,9 @@ When a request enters the system which matches the pattern of the route, the usual result is simple: the view callable associated with the route is invoked with the request that caused the invocation. -For most usage, you needn't understand more than this; how it works is an -implementation detail. In the interest of completeness, however, we'll -explain how it *does* work in this section. You can skip it if you're -uninterested. +For most usage, you needn't understand more than this. How it works is an +implementation detail. In the interest of completeness, however, we'll explain +how it *does* work in this section. You can skip it if you're uninterested. When a view is associated with a route configuration, :app:`Pyramid` ensures that a :term:`view configuration` is registered that will always be found @@ -1349,26 +1340,25 @@ when the route pattern is matched during a request. To do so: - At runtime, when a request causes any route to match, the :term:`request` object is decorated with the route-specific interface. -- The fact that the request is decorated with a route-specific interface - causes the :term:`view lookup` machinery to always use the view callable - registered using that interface by the route configuration to service - requests that match the route pattern. +- The fact that the request is decorated with a route-specific interface causes + the :term:`view lookup` machinery to always use the view callable registered + using that interface by the route configuration to service requests that + match the route pattern. As we can see from the above description, technically, URL dispatch doesn't -actually map a URL pattern directly to a view callable. Instead, URL -dispatch is a :term:`resource location` mechanism. A :app:`Pyramid` -:term:`resource location` subsystem (i.e., :term:`URL dispatch` or -:term:`traversal`) finds a :term:`resource` object that is the -:term:`context` of a :term:`request`. Once the :term:`context` is determined, -a separate subsystem named :term:`view lookup` is then responsible for -finding and invoking a :term:`view callable` based on information available -in the context and the request. When URL dispatch is used, the resource -location and view lookup subsystems provided by :app:`Pyramid` are still -being utilized, but in a way which does not require a developer to understand -either of them in detail. - -If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back -to :term:`traversal` to handle the :term:`request`. +actually map a URL pattern directly to a view callable. Instead URL dispatch +is a :term:`resource location` mechanism. A :app:`Pyramid` :term:`resource +location` subsystem (i.e., :term:`URL dispatch` or :term:`traversal`) finds a +:term:`resource` object that is the :term:`context` of a :term:`request`. Once +the :term:`context` is determined, a separate subsystem named :term:`view +lookup` is then responsible for finding and invoking a :term:`view callable` +based on information available in the context and the request. When URL +dispatch is used, the resource location and view lookup subsystems provided by +:app:`Pyramid` are still being utilized, but in a way which does not require a +developer to understand either of them in detail. + +If no route is matched using :term:`URL dispatch`, :app:`Pyramid` falls back to +:term:`traversal` to handle the :term:`request`. References ---------- -- cgit v1.2.3 From 6ce54f44141811c20869a6850a0d68997093b281 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 7 Oct 2015 23:51:52 -0700 Subject: Heading rst syntax, casing --- docs/narr/install.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 0f114a9c7..3cd7b5a14 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -1,7 +1,7 @@ .. _installing_chapter: Installing :app:`Pyramid` -============================ +========================= .. index:: single: install preparation @@ -52,7 +52,7 @@ 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) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If your system doesn't have a Python interpreter, and you're on UNIX, you can @@ -128,7 +128,7 @@ Once these steps are performed, the Python interpreter will be invokable via .. 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 @@ -153,7 +153,7 @@ also need to download and install the Python for Windows extensions. .. _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 @@ -285,8 +285,8 @@ it's an absolute path. acceptable (and desirable) to create a virtualenv as a normal user. -Installing :app:`Pyramid` Into the Virtual Python Environment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Installing :app:`Pyramid` into the Virtual Python Environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ After you've got your virtualenv installed, you may install :app:`Pyramid` itself using the following commands: @@ -311,7 +311,7 @@ complete, as it downloads and installs a number of dependencies. .. _installing_windows: Installing :app:`Pyramid` on a Windows System -------------------------------------------------- +--------------------------------------------- You can use Pyramid on Windows under Python 2 or 3. -- cgit v1.2.3 From 1cbf35a01d1a11d4519071766754c274e26bb533 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 00:09:36 -0700 Subject: rewrapping only --- docs/narr/install.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 3cd7b5a14..a81a559a7 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -32,9 +32,9 @@ dependency will fall back to using pure Python instead. 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. +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. You can install the latest verion of Python for Mac OS X from the binaries on `python.org `_. @@ -90,12 +90,12 @@ 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. +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. +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: @@ -204,7 +204,7 @@ it using the Python interpreter into which you want to install setuptools. $ python ez_setup.py -Once this command is invoked, setuptools should be installed on your system. +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: @@ -301,9 +301,9 @@ complete, as it downloads and installs a number of dependencies. .. note:: 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. + 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 @@ -382,4 +382,3 @@ 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 ca00fbd88aaa42af89d9243c4475ff1ccd08b187 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 01:03:31 -0700 Subject: rewrapping, rst heading underlines, minor grammar --- docs/narr/introduction.rst | 657 ++++++++++++++++++++++----------------------- 1 file changed, 322 insertions(+), 335 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 2d3cd23e9..7906dd85d 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -7,7 +7,7 @@ single: framework :app:`Pyramid` Introduction -============================== +=========================== :app:`Pyramid` is a general, open source, Python web application development *framework*. Its primary goal is to make it easier for a Python developer to @@ -15,40 +15,39 @@ create web applications. .. sidebar:: Frameworks vs. Libraries - A *framework* differs from a *library* in one very important way: - library code is always *called* by code that you write, while a - framework always *calls* code that you write. Using a set of - libraries to create an application is usually easier than using a - framework initially, because you can choose to cede control to - library code you have not authored very selectively. But when you - use a framework, you are required to cede a greater portion of - control to code you have not authored: code that resides in the - framework itself. You needn't use a framework at all to create a - web application using Python. A rich set of libraries already - exists for the platform. In practice, however, using a framework - to create an application is often more practical than rolling your - own via a set of libraries if the framework provides a set of - facilities that fits your application requirements. + A *framework* differs from a *library* in one very important way: library + code is always *called* by code that you write, while a framework always + *calls* code that you write. Using a set of libraries to create an + application is usually easier than using a framework initially, because you + can choose to cede control to library code you have not authored very + selectively. But when you use a framework, you are required to cede a + greater portion of control to code you have not authored: code that resides + in the framework itself. You needn't use a framework at all to create a web + application using Python. A rich set of libraries already exists for the + platform. In practice, however, using a framework to create an application + is often more practical than rolling your own via a set of libraries if the + framework provides a set of facilities that fits your application + requirements. Pyramid attempts to follow these design and engineering principles: Simplicity :app:`Pyramid` takes a *"pay only for what you eat"* approach. You can get - results even if you have only a partial understanding of :app:`Pyramid`. - It doesn’t force you to use any particular technology to produce an - application, and we try to keep the core set of concepts that you need to - understand to a minimum. + results even if you have only a partial understanding of :app:`Pyramid`. It + doesn't force you to use any particular technology to produce an application, + and we try to keep the core set of concepts that you need to understand to a + minimum. Minimalism - :app:`Pyramid` tries to solve only the fundamental problems of creating - a web application: the mapping of URLs to code, templating, security and - serving static assets. We consider these to be the core activities that are - common to nearly all web applications. + :app:`Pyramid` tries to solve only the fundamental problems of creating a web + application: the mapping of URLs to code, templating, security, and serving + static assets. We consider these to be the core activities that are common to + nearly all web applications. Documentation - Pyramid's minimalism means that it is easier for us to maintain complete - and up-to-date documentation. It is our goal that no aspect of Pyramid - is undocumented. + Pyramid's minimalism means that it is easier for us to maintain complete and + up-to-date documentation. It is our goal that no aspect of Pyramid is + undocumented. Speed :app:`Pyramid` is designed to provide noticeably fast execution for common @@ -56,12 +55,12 @@ Speed Reliability :app:`Pyramid` is developed conservatively and tested exhaustively. Where - Pyramid source code is concerned, our motto is: "If it ain’t tested, it’s + Pyramid source code is concerned, our motto is: "If it ain't tested, it's broke". Openness - As with Python, the Pyramid software is distributed under a `permissive - open source license `_. + As with Python, the Pyramid software is distributed under a `permissive open + source license `_. .. _what_makes_pyramid_unique: @@ -69,55 +68,53 @@ What makes Pyramid unique ------------------------- Understandably, people don't usually want to hear about squishy engineering -principles; they want to hear about concrete stuff that solves their -problems. With that in mind, what would make someone want to use Pyramid -instead of one of the many other web frameworks available today? What makes -Pyramid unique? - -This is a hard question to answer, because there are lots of excellent -choices, and it's actually quite hard to make a wrong choice, particularly in -the Python web framework market. But one reasonable answer is this: you can -write very small applications in Pyramid without needing to know a lot. -"What?", you say. "That can't possibly be a unique feature. Lots of other web -frameworks let you do that!" Well, you're right. But unlike many other -systems, you can also write very large applications in Pyramid if you learn a -little more about it. Pyramid will allow you to become productive quickly, -and will grow with you. It won't hold you back when your application is small, -and it won't get in your way when your application becomes large. "Well -that's fine," you say. "Lots of other frameworks let me write large apps, -too." Absolutely. But other Python web frameworks don't seamlessly let you -do both. They seem to fall into two non-overlapping categories: frameworks -for "small apps" and frameworks for "big apps". The "small app" frameworks -typically sacrifice "big app" features, and vice versa. +principles; they want to hear about concrete stuff that solves their problems. +With that in mind, what would make someone want to use Pyramid instead of one +of the many other web frameworks available today? What makes Pyramid unique? + +This is a hard question to answer because there are lots of excellent choices, +and it's actually quite hard to make a wrong choice, particularly in the Python +web framework market. But one reasonable answer is this: you can write very +small applications in Pyramid without needing to know a lot. "What?" you say. +"That can't possibly be a unique feature. Lots of other web frameworks let you +do that!" Well, you're right. But unlike many other systems, you can also +write very large applications in Pyramid if you learn a little more about it. +Pyramid will allow you to become productive quickly, and will grow with you. It +won't hold you back when your application is small, and it won't get in your +way when your application becomes large. "Well that's fine," you say. "Lots of +other frameworks let me write large apps, too." Absolutely. But other Python +web frameworks don't seamlessly let you do both. They seem to fall into two +non-overlapping categories: frameworks for "small apps" and frameworks for "big +apps". The "small app" frameworks typically sacrifice "big app" features, and +vice versa. We don't think it's a universally reasonable suggestion to write "small apps" in a "small framework" and "big apps" in a "big framework". You can't really -know to what size every application will eventually grow. We don't really -want to have to rewrite a previously small application in another framework -when it gets "too big". We believe the current binary distinction between -frameworks for small and large applications is just false. A well-designed -framework should be able to be good at both. Pyramid strives to be that kind -of framework. - -To this end, Pyramid provides a set of features that, combined, are unique +know to what size every application will eventually grow. We don't really want +to have to rewrite a previously small application in another framework when it +gets "too big". We believe the current binary distinction between frameworks +for small and large applications is just false. A well-designed framework +should be able to be good at both. Pyramid strives to be that kind of +framework. + +To this end, Pyramid provides a set of features that combined are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features. Pyramid of course actually stole many of them -from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful *à la carte* without +from those other frameworks. But Pyramid is the only one that has all of them +in one place, documented appropriately, and useful *à la carte* without necessarily paying for the entire banquet. These are detailed below. Single-file applications ~~~~~~~~~~~~~~~~~~~~~~~~ -You can write a Pyramid application that lives entirely in one Python file, -not unlike existing Python microframeworks. This is beneficial for one-off -prototyping, bug reproduction, and very small applications. These -applications are easy to understand because all the information about the -application lives in a single place, and you can deploy them without needing -to understand much about Python distributions and packaging. Pyramid isn't -really marketed as a microframework, but it allows you to do almost -everything that frameworks that are marketed as micro offer in very similar -ways. +You can write a Pyramid application that lives entirely in one Python file, not +unlike existing Python microframeworks. This is beneficial for one-off +prototyping, bug reproduction, and very small applications. These applications +are easy to understand because all the information about the application lives +in a single place, and you can deploy them without needing to understand much +about Python distributions and packaging. Pyramid isn't really marketed as a +microframework, but it allows you to do almost everything that frameworks that +are marketed as "micro" offer in very similar ways. .. literalinclude:: helloworld.py @@ -142,26 +139,25 @@ decorators to localize the configuration. For example: def fred_view(request): return Response('fred') -However, unlike some other systems, using decorators for Pyramid -configuration does not make your application difficult to extend, test, or -reuse. The :class:`~pyramid.view.view_config` decorator, for example, does -not actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation. You don't need to understand the -framework to test your own code. You just behave as if the decorator is not -there. You can also instruct Pyramid to ignore some decorators, or use -completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager. You detect and activate them -with a :term:`scan`. +However, unlike some other systems, using decorators for Pyramid configuration +does not make your application difficult to extend, test, or reuse. The +:class:`~pyramid.view.view_config` decorator, for example, does not actually +*change* the input or output of the function it decorates, so testing it is a +"WYSIWYG" operation. You don't need to understand the framework to test your +own code. You just behave as if the decorator is not there. You can also +instruct Pyramid to ignore some decorators, or use completely imperative +configuration instead of decorators to add views. Pyramid decorators are inert +instead of eager. You detect and activate them with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. URL generation ~~~~~~~~~~~~~~ -Pyramid is capable of generating URLs for resources, routes, and static -assets. Its URL generation APIs are easy to use and flexible. If you use -Pyramid's various APIs for generating URLs, you can change your configuration -around arbitrarily without fear of breaking a link on one of your web pages. +Pyramid is capable of generating URLs for resources, routes, and static assets. +Its URL generation APIs are easy to use and flexible. If you use Pyramid's +various APIs for generating URLs, you can change your configuration around +arbitrarily without fear of breaking a link on one of your web pages. Example: :ref:`generating_route_urls`. @@ -169,12 +165,12 @@ Static file serving ~~~~~~~~~~~~~~~~~~~ Pyramid is perfectly willing to serve static files itself. It won't make you -use some external web server to do that. You can even serve more than one -set of static files in a single Pyramid web application (e.g. ``/static`` and -``/static2``). You can optionally place your files on an external web -server and ask Pyramid to help you generate URLs to those files. This let's -you use Pyramid's internal file serving while doing development, and a faster -static file server in production, without changing any code. +use some external web server to do that. You can even serve more than one set +of static files in a single Pyramid web application (e.g., ``/static`` and +``/static2``). You can optionally place your files on an external web server +and ask Pyramid to help you generate URLs to those files. This let's you use +Pyramid's internal file serving while doing development, and a faster static +file server in production, without changing any code. Example: :ref:`static_assets_section`. @@ -189,10 +185,10 @@ code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and allows you access to framework data, such as the routes configured, the last -renderings performed, the current set of packages installed, SQLAlchemy -queries run, logging data, and various other facts. When an exception -occurs, you can use its interactive debugger to poke around right in your -browser to try to determine the cause of the exception. It's handy. +renderings performed, the current set of packages installed, SQLAlchemy queries +run, logging data, and various other facts. When an exception occurs, you can +use its interactive debugger to poke around right in your browser to try to +determine the cause of the exception. It's handy. Example: :ref:`debug_toolbar`. @@ -200,29 +196,29 @@ Debugging settings ~~~~~~~~~~~~~~~~~~ Pyramid has debugging settings that allow you to print Pyramid runtime -information to the console when things aren't behaving as you're expecting. -For example, you can turn on ``debug_notfound``, which prints an informative -message to the console every time a URL does not match any view. You can -turn on ``debug_authorization``, which lets you know why a view execution was +information to the console when things aren't behaving as you're expecting. For +example, you can turn on ``debug_notfound``, which prints an informative +message to the console every time a URL does not match any view. You can turn +on ``debug_authorization``, which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. There are also a number of commands that you can invoke within a Pyramid environment that allow you to introspect the configuration of your system. -``proutes`` shows all configured routes for an application in the order -they'll be evaluated for matching. ``pviews`` shows all configured views for -any given URL. These are also WTF-crushers in some circumstances. +``proutes`` shows all configured routes for an application in the order they'll +be evaluated for matching. ``pviews`` shows all configured views for any given +URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Add-ons -~~~~~~~~ +~~~~~~~ Pyramid has an extensive set of add-ons held to the same quality standards as -the Pyramid core itself. Add-ons are packages which provide functionality -that the Pyramid core doesn't. Add-on packages already exist which let you -easily send email, let you use the Jinja2 templating system, let you use -XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. +the Pyramid core itself. Add-ons are packages which provide functionality that +the Pyramid core doesn't. Add-on packages already exist which let you easily +send email, let you use the Jinja2 templating system, let you use XML-RPC or +JSON-RPC, let you integrate with jQuery Mobile, etc. Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation @@ -230,16 +226,16 @@ http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documen Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid has a structured, unified concept of a :term:`view callable`. -View callables can be functions, methods of classes, or even instances. When -you add a new view callable, you can choose to make it a function or a method -of a class. In either case Pyramid treats it largely the same way. You can -change your mind later and move code between methods of classes and -functions. A collection of similar view callables can be attached to a -single class as methods, if that floats your boat, and they can share -initialization code as necessary. All kinds of views are easy to understand -and use, and operate similarly. There is no phony distinction between them. -They can be used for the same purposes. +Pyramid has a structured, unified concept of a :term:`view callable`. View +callables can be functions, methods of classes, or even instances. When you +add a new view callable, you can choose to make it a function or a method of a +class. In either case Pyramid treats it largely the same way. You can change +your mind later and move code between methods of classes and functions. A +collection of similar view callables can be attached to a single class as +methods, if that floats your boat, and they can share initialization code as +necessary. All kinds of views are easy to understand and use, and operate +similarly. There is no phony distinction between them. They can be used for +the same purposes. Here's a view callable defined as a function: @@ -282,22 +278,22 @@ Here's a few views defined as methods of a class instead: Asset specifications ~~~~~~~~~~~~~~~~~~~~ -Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g., ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. An asset specification can refer -to a template, a translation directory, or any other package-bound static +Asset specifications are strings that contain both a Python package name and a +file or directory name, e.g., ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. An asset specification can refer to +a template, a translation directory, or any other package-bound static resource. This makes a system built on Pyramid extensible because you don't have to rely on globals ("*the* static directory") or lookup schemes ("*the* ordered set of template directories") to address your files. You can move files around as necessary, and include other packages that may not share your system's templates or static files without encountering conflicts. -Because asset specifications are used heavily in Pyramid, we've also provided -a way to allow users to override assets. Say you love a system that someone -else has created with Pyramid but you just need to change "that one template" -to make it all better. No need to fork the application. Just override the -asset specification for that template with your own inside a wrapper, and -you're good to go. +Because asset specifications are used heavily in Pyramid, we've also provided a +way to allow users to override assets. Say you love a system that someone else +has created with Pyramid but you just need to change "that one template" to +make it all better. No need to fork the application. Just override the asset +specification for that template with your own inside a wrapper, and you're good +to go. Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. @@ -309,12 +305,11 @@ Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated as renderers. Renderer bindings for all of these templating systems already exist for use in Pyramid. But if you'd rather use another, it's not a big deal. Just copy the code from an existing renderer package, and plug in your -favorite templating system. You'll then be able to use that templating -system from within Pyramid just as you'd use one of the "built-in" templating -systems. +favorite templating system. You'll then be able to use that templating system +from within Pyramid just as you'd use one of the "built-in" templating systems. -Pyramid does not make you use a single templating system exclusively. You -can use multiple templating systems, even in the same project. +Pyramid does not make you use a single templating system exclusively. You can +use multiple templating systems, even in the same project. Example: :ref:`templates_used_directly`. @@ -322,12 +317,12 @@ Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you use a :term:`renderer`, you don't have to return a special kind of -"webby" ``Response`` object from a view. Instead, you can return a -dictionary, and Pyramid will take care of converting that dictionary -to a Response using a template on your behalf. This makes the view easier to -test, because you don't have to parse HTML in your tests; instead just make an -assertion that the view returns "the right stuff" in the dictionary. You can -write "real" unit tests instead of functionally testing all of your views. +"webby" ``Response`` object from a view. Instead you can return a dictionary, +and Pyramid will take care of converting that dictionary to a Response using a +template on your behalf. This makes the view easier to test, because you don't +have to parse HTML in your tests. Instead just make an assertion that the view +returns "the right stuff" in the dictionary. You can write "real" unit tests +instead of functionally testing all of your views. .. index:: pair: renderer; explicitly calling @@ -363,7 +358,7 @@ be rendered to a response on your behalf. The string passed as ``renderer=`` above is an :term:`asset specification`. It is in the form ``packagename:directoryname/filename.ext``. In this case, it refers to the ``mytemplate.pt`` file in the ``templates`` directory within the ``myapp`` -Python package. Asset specifications are omnipresent in Pyramid: see +Python package. Asset specifications are omnipresent in Pyramid. See :ref:`intro_asset_specs` for more information. Example: :ref:`renderers_chapter`. @@ -372,9 +367,9 @@ Event system ~~~~~~~~~~~~ Pyramid emits *events* during its request processing lifecycle. You can -subscribe any number of listeners to these events. For example, to be -notified of a new request, you can subscribe to the ``NewRequest`` event. To -be notified that a template is about to be rendered, you can subscribe to the +subscribe any number of listeners to these events. For example, to be notified +of a new request, you can subscribe to the ``NewRequest`` event. To be +notified that a template is about to be rendered, you can subscribe to the ``BeforeRender`` event, and so forth. Using an event publishing system as a framework notification feature instead of hardcoded hook points tends to make systems based on that framework less brittle. @@ -382,9 +377,9 @@ systems based on that framework less brittle. You can also use Pyramid's event system to send your *own* events. For example, if you'd like to create a system that is itself a framework, and may want to notify subscribers that a document has just been indexed, you can -create your own event type (``DocumentIndexed`` perhaps) and send the event -via Pyramid. Users of this framework can then subscribe to your event like -they'd subscribe to the events that are normally sent by Pyramid itself. +create your own event type (``DocumentIndexed`` perhaps) and send the event via +Pyramid. Users of this framework can then subscribe to your event like they'd +subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. @@ -394,7 +389,7 @@ Built-in internationalization Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files and templates. Pyramid allows for a plurality of message catalogs via the use -of translation domains: you can create a system that has its own translations +of translation domains. You can create a system that has its own translations without conflict with other translations in other domains. Example: :ref:`i18n_chapter`. @@ -402,9 +397,9 @@ Example: :ref:`i18n_chapter`. HTTP caching ~~~~~~~~~~~~ -Pyramid provides an easy way to associate views with HTTP caching policies. -You can just tell Pyramid to configure your view with an ``http_cache`` -statement, and it will take care of the rest:: +Pyramid provides an easy way to associate views with HTTP caching policies. You +can just tell Pyramid to configure your view with an ``http_cache`` statement, +and it will take care of the rest:: @view_config(http_cache=3600) # 60 minutes def myview(request): .... @@ -412,8 +407,8 @@ statement, and it will take care of the rest:: Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to responses generated when this view is invoked. -See the :meth:`~pyramid.config.Configurator.add_view` method's -``http_cache`` documentation for more information. +See the :meth:`~pyramid.config.Configurator.add_view` method's ``http_cache`` +documentation for more information. Sessions ~~~~~~~~ @@ -422,9 +417,9 @@ Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But Pyramid also allows you to plug in your own sessioning system by creating some code that adheres to a documented interface. Currently there is a binding -package for the third-party Redis sessioning system that does exactly this. -But if you have a specialized need (perhaps you want to store your session data -in MongoDB), you can. You can even switch between implementations without +package for the third-party Redis sessioning system that does exactly this. But +if you have a specialized need (perhaps you want to store your session data in +MongoDB), you can. You can even switch between implementations without changing your application code. Example: :ref:`sessions_chapter`. @@ -432,17 +427,16 @@ Example: :ref:`sessions_chapter`. Speed ~~~~~ -The Pyramid core is, as far as we can tell, at least marginally faster than -any other existing Python web framework. It has been engineered from the -ground up for speed. It only does as much work as absolutely necessary when -you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are avoided. It is feasible to get, for -example, between 3500 and 4000 requests per second from a simple Pyramid view -on commodity dual-core laptop hardware and an appropriate WSGI server -(mod_wsgi or gunicorn). In any case, performance statistics are largely -useless without requirements and goals, but if you need speed, Pyramid will -almost certainly never be your application's bottleneck; at least no more -than Python will be a bottleneck. +The Pyramid core is, as far as we can tell, at least marginally faster than any +other existing Python web framework. It has been engineered from the ground up +for speed. It only does as much work as absolutely necessary when you ask it +to get a job done. Extraneous function calls and suboptimal algorithms in its +core codepaths are avoided. It is feasible to get, for example, between 3500 +and 4000 requests per second from a simple Pyramid view on commodity dual-core +laptop hardware and an appropriate WSGI server (mod_wsgi or gunicorn). In any +case, performance statistics are largely useless without requirements and +goals, but if you need speed, Pyramid will almost certainly never be your +application's bottleneck; at least no more than Python will be a bottleneck. Example: http://blog.curiasolutions.com/pages/the-great-web-framework-shootout.html @@ -456,9 +450,9 @@ views, but they're only invoked when an exception "bubbles up" to Pyramid itself. For example, you might register an exception view for the :exc:`Exception` exception, which will catch *all* exceptions, and present a pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when an action cannot be performed because the user doesn't have +exception view for only specific kinds of application-specific exceptions, such +as an exception that happens when a file is not found, or an exception that +happens when an action cannot be performed because the user doesn't have permission to do something. In the former case, you can show a pretty "Not Found" page; in the latter case you might show a login form. @@ -468,61 +462,59 @@ No singletons ~~~~~~~~~~~~~ Pyramid is written in such a way that it requires your application to have -exactly zero "singleton" data structures. Or put another way, Pyramid -doesn't require you to construct any "mutable globals". Or put even a -different way, an import of a Pyramid application needn't have any -"import-time side effects". This is esoteric-sounding, but if you've ever -tried to cope with parameterizing a Django ``settings.py`` file for multiple -installations of the same application, or if you've ever needed to -monkey-patch some framework fixture so that it behaves properly for your use -case, or if you've ever wanted to deploy your system using an asynchronous -server, you'll end up appreciating this feature. It just won't be a problem. -You can even run multiple copies of a similar but not identically configured -Pyramid application within the same Python process. This is good for shared -hosting environments, where RAM is at a premium. +exactly zero "singleton" data structures. Or put another way, Pyramid doesn't +require you to construct any "mutable globals". Or put even another different +way, an import of a Pyramid application needn't have any "import-time side +effects". This is esoteric-sounding, but if you've ever tried to cope with +parameterizing a Django ``settings.py`` file for multiple installations of the +same application, or if you've ever needed to monkey-patch some framework +fixture so that it behaves properly for your use case, or if you've ever wanted +to deploy your system using an asynchronous server, you'll end up appreciating +this feature. It just won't be a problem. You can even run multiple copies of +a similar but not identically configured Pyramid application within the same +Python process. This is good for shared hosting environments, where RAM is at +a premium. View predicates and many views per route ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike many other systems, Pyramid allows you to associate more than one view -per route. For example, you can create a route with the pattern ``/items`` -and when the route is matched, you can shuffle off the request to one view if -the request method is GET, another view if the request method is POST, etc. -A system known as "view predicates" allows for this. Request method matching -is the most basic thing you can do with a view predicate. You can also -associate views with other request parameters such as the elements in the -query string, the Accept header, whether the request is an XHR request or -not, and lots of other things. This feature allows you to keep your -individual views clean. They won't need much conditional logic, so they'll -be easier to test. +per route. For example, you can create a route with the pattern ``/items`` and +when the route is matched, you can shuffle off the request to one view if the +request method is GET, another view if the request method is POST, etc. A +system known as "view predicates" allows for this. Request method matching is +the most basic thing you can do with a view predicate. You can also associate +views with other request parameters, such as the elements in the query string, +the Accept header, whether the request is an XHR request or not, and lots of +other things. This feature allows you to keep your individual views clean. +They won't need much conditional logic, so they'll be easier to test. Example: :ref:`view_configuration_parameters`. Transaction management ~~~~~~~~~~~~~~~~~~~~~~ -Pyramid's :term:`scaffold` system renders projects that include a -*transaction management* system, stolen from Zope. When you use this -transaction management system, you cease being responsible for committing -your data anymore. Instead Pyramid takes care of committing: it commits at -the end of a request or aborts if there's an exception. Why is that a good -thing? Having a centralized place for transaction management is a great -thing. If instead of managing your transactions in a centralized place you -sprinkle ``session.commit`` calls in your application logic itself, you can -wind up in a bad place. Wherever you manually commit data to your database, -it's likely that some of your other code is going to run *after* your commit. -If that code goes on to do other important things after that commit, and an -error happens in the later code, you can easily wind up with inconsistent -data if you're not extremely careful. Some data will have been written to -the database that probably should not have. Having a centralized commit -point saves you from needing to think about this; it's great for lazy people -who also care about data integrity. Either the request completes -successfully, and all changes are committed, or it does not, and all changes -are aborted. - -Pyramid's transaction management system allows you to synchronize -commits between multiple databases. It also allows you to do things like -conditionally send email if a transaction commits, but otherwise keep quiet. +Pyramid's :term:`scaffold` system renders projects that include a *transaction +management* system, stolen from Zope. When you use this transaction management +system, you cease being responsible for committing your data anymore. Instead +Pyramid takes care of committing: it commits at the end of a request or aborts +if there's an exception. Why is that a good thing? Having a centralized place +for transaction management is a great thing. If, instead of managing your +transactions in a centralized place, you sprinkle ``session.commit`` calls in +your application logic itself, you can wind up in a bad place. Wherever you +manually commit data to your database, it's likely that some of your other code +is going to run *after* your commit. If that code goes on to do other important +things after that commit, and an error happens in the later code, you can +easily wind up with inconsistent data if you're not extremely careful. Some +data will have been written to the database that probably should not have. +Having a centralized commit point saves you from needing to think about this; +it's great for lazy people who also care about data integrity. Either the +request completes successfully, and all changes are committed, or it does not, +and all changes are aborted. + +Pyramid's transaction management system allows you to synchronize commits +between multiple databases. It also allows you to do things like conditionally +send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements anywhere in application code). @@ -530,18 +522,18 @@ anywhere in application code). Configuration conflict detection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a system is small, it's reasonably easy to keep it all in your head. -But when systems grow large, you may have hundreds or thousands of -configuration statements which add a view, add a route, and so forth. +When a system is small, it's reasonably easy to keep it all in your head. But +when systems grow large, you may have hundreds or thousands of configuration +statements which add a view, add a route, and so forth. -Pyramid's configuration system keeps track of your configuration statements. -If you accidentally add two that are identical, or Pyramid can't make -sense out of what it would mean to have both statements active at the same -time, it will complain loudly at startup time. It's not dumb though. It will -automatically resolve conflicting configuration statements on its own if you -use the configuration :meth:`~pyramid.config.Configurator.include` system. -"More local" statements are preferred over "less local" ones. This allows -you to intelligently factor large systems into smaller ones. +Pyramid's configuration system keeps track of your configuration statements. If +you accidentally add two that are identical, or Pyramid can't make sense out of +what it would mean to have both statements active at the same time, it will +complain loudly at startup time. It's not dumb though. It will automatically +resolve conflicting configuration statements on its own if you use the +configuration :meth:`~pyramid.config.Configurator.include` system. "More local" +statements are preferred over "less local" ones. This allows you to +intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. @@ -551,17 +543,17 @@ Configuration extensibility Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements -that can be performed in your "main" Pyramid application can also be -performed by included packages, including the addition of views, routes, -subscribers, and even authentication and authorization policies. You can even -extend or override an existing application by including another application's -configuration in your own, overriding or adding new views and routes to -it. This has the potential to allow you to create a big application out of -many other smaller ones. For example, if you want to reuse an existing -application that already has a bunch of routes, you can just use the -``include`` statement with a ``route_prefix``. The new application will live -within your application at an URL prefix. It's not a big deal, and requires -little up-front engineering effort. +that can be performed in your "main" Pyramid application can also be performed +by included packages, including the addition of views, routes, subscribers, and +even authentication and authorization policies. You can even extend or override +an existing application by including another application's configuration in +your own, overriding or adding new views and routes to it. This has the +potential to allow you to create a big application out of many other smaller +ones. For example, if you want to reuse an existing application that already +has a bunch of routes, you can just use the ``include`` statement with a +``route_prefix``. The new application will live within your application at an +URL prefix. It's not a big deal, and requires little up-front engineering +effort. For example: @@ -584,16 +576,15 @@ For example: Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid includes a flexible, pluggable authentication and authorization -system. No matter where your user data is stored, or what scheme you'd like -to use to permit your users to access your data, you can use a predefined -Pyramid plugpoint to plug in your custom authentication and authorization -code. If you want to change these schemes later, you can just change it in -one place rather than everywhere in your code. It also ships with prebuilt -well-tested authentication and authorization schemes out of the box. But -what if you don't want to use Pyramid's built-in system? You don't have to. -You can just write your own bespoke security code as you would in any other -system. +Pyramid includes a flexible, pluggable authentication and authorization system. +No matter where your user data is stored, or what scheme you'd like to use to +permit your users to access your data, you can use a predefined Pyramid +plugpoint to plug in your custom authentication and authorization code. If you +want to change these schemes later, you can just change it in one place rather +than everywhere in your code. It also ships with prebuilt well-tested +authentication and authorization schemes out of the box. But what if you don't +want to use Pyramid's built-in system? You don't have to. You can just write +your own bespoke security code as you would in any other system. Example: :ref:`enabling_authorization_policy`. @@ -601,19 +592,19 @@ Traversal ~~~~~~~~~ :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to -create a tree of resources, each of which can be addressed by one or more -URLs. Each of those resources can have one or more *views* associated with -it. If your data isn't naturally treelike, or you're unwilling to create a -treelike representation of your data, you aren't going to find traversal -very useful. However, traversal is absolutely fantastic for sites that need -to be arbitrarily extensible: it's a lot easier to add a node to a tree than -it is to shoehorn a route into an ordered list of other routes, or to create -another entire instance of an application to service a department and glue -code to allow disparate apps to share data. It's a great fit for sites that -naturally lend themselves to changing departmental hierarchies, such as -content management systems and document management systems. Traversal also -lends itself well to systems that require very granular security ("Bob can -edit *this* document" as opposed to "Bob can edit documents"). +create a tree of resources, each of which can be addressed by one or more URLs. +Each of those resources can have one or more *views* associated with it. If +your data isn't naturally treelike, or you're unwilling to create a treelike +representation of your data, you aren't going to find traversal very useful. +However, traversal is absolutely fantastic for sites that need to be +arbitrarily extensible. It's a lot easier to add a node to a tree than it is to +shoehorn a route into an ordered list of other routes, or to create another +entire instance of an application to service a department and glue code to +allow disparate apps to share data. It's a great fit for sites that naturally +lend themselves to changing departmental hierarchies, such as content +management systems and document management systems. Traversal also lends +itself well to systems that require very granular security ("Bob can edit +*this* document" as opposed to "Bob can edit documents"). Examples: :ref:`hello_traversal_chapter` and :ref:`much_ado_about_traversal_chapter`. @@ -662,12 +653,11 @@ The former is "prettier", right? Out of the box, if you define the former view callable (the one that simply returns a string) in Pyramid, when it is executed, Pyramid will raise an -exception. This is because "explicit is better than implicit", in most -cases, and by default, Pyramid wants you to return a :term:`Response` object -from a view callable. This is because there's usually a heck of a lot more -to a response object than just its body. But if you're the kind of person -who values such aesthetics, we have an easy way to allow for this sort of -thing: +exception. This is because "explicit is better than implicit", in most cases, +and by default Pyramid wants you to return a :term:`Response` object from a +view callable. This is because there's usually a heck of a lot more to a +response object than just its body. But if you're the kind of person who +values such aesthetics, we have an easy way to allow for this sort of thing: .. code-block:: python :linenos: @@ -733,9 +723,9 @@ Once this is done, both of these view callables will work: def anotherview(request): return (403, 'text/plain', "Forbidden") -Pyramid defaults to explicit behavior, because it's the most generally -useful, but provides hooks that allow you to adapt the framework to localized -aesthetic desires. +Pyramid defaults to explicit behavior, because it's the most generally useful, +but provides hooks that allow you to adapt the framework to localized aesthetic +desires. .. seealso:: @@ -744,9 +734,9 @@ aesthetic desires. "Global" response object ~~~~~~~~~~~~~~~~~~~~~~~~ -"Constructing these response objects in my view callables is such a chore! -And I'm way too lazy to register a response adapter, as per the prior -section," you say. Fine. Be that way: +"Constructing these response objects in my view callables is such a chore! And +I'm way too lazy to register a response adapter, as per the prior section," you +say. Fine. Be that way: .. code-block:: python :linenos: @@ -765,13 +755,13 @@ Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Does Pyramid's configurator allow you to do something, but you're a little -adventurous and just want it a little less verbose? Or you'd like to offer -up some handy configuration feature to other Pyramid users without requiring -that we change Pyramid? You can extend Pyramid's :term:`Configurator` with -your own directives. For example, let's say you find yourself calling +adventurous and just want it a little less verbose? Or you'd like to offer up +some handy configuration feature to other Pyramid users without requiring that +we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own +directives. For example, let's say you find yourself calling :meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can -take the boring away by using existing shortcuts, but let's say that this is -a case where there is no such shortcut: +take the boring away by using existing shortcuts, but let's say that this is a +case where there is no such shortcut: .. code-block:: python :linenos: @@ -817,7 +807,7 @@ the Configurator object: Your previously repetitive configuration lines have now morphed into one line. -You can share your configuration code with others this way too by packaging +You can share your configuration code with others this way, too, by packaging it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the :meth:`~pyramid.config.Configurator.include` method against your code. @@ -836,8 +826,7 @@ at the top of the screen based on an enumeration of views they registered. This is possible using Pyramid's :term:`introspector`. -Here's an example of using Pyramid's introspector from within a view -callable: +Here's an example of using Pyramid's introspector from within a view callable: .. code-block:: python :linenos: @@ -861,8 +850,8 @@ Python 3 compatibility Pyramid and most of its add-ons are Python 3 compatible. If you develop a Pyramid application today, you won't need to worry that five years from now -you'll be backwatered because there are language features you'd like to use -but your framework doesn't support newer Python versions. +you'll be backwatered because there are language features you'd like to use but +your framework doesn't support newer Python versions. Testing ~~~~~~~ @@ -886,8 +875,8 @@ It's our goal that no Pyramid question go unanswered. Whether you ask a question on IRC, on the Pylons-discuss mailing list, or on StackOverflow, you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow -users in our various official support channels. We try to keep it well-lit -and new-user-friendly. +users in our various official support channels. We try to keep it well-lit and +new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at @@ -896,13 +885,12 @@ http://groups.google.com/group/pylons-discuss/. Documentation ~~~~~~~~~~~~~ -It's a constant struggle, but we try to maintain a balance between -completeness and new-user-friendliness in the official narrative Pyramid -documentation (concrete suggestions for improvement are always appreciated, -by the way). We 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. +It's a constant struggle, but we try to maintain a balance between completeness +and new-user-friendliness in the official narrative Pyramid documentation +(concrete suggestions for improvement are always appreciated, by the way). We +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/. @@ -929,35 +917,34 @@ includes details about how :app:`Pyramid` relates to the Pylons Project. ------------------------------------------ The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made -in July of 2008. At the end of 2010, we changed the name of -:mod:`repoze.bfg` to :app:`Pyramid`. It was merged into the Pylons project -as :app:`Pyramid` in November of that year. +in July of 2008. At the end of 2010, we changed the name of :mod:`repoze.bfg` +to :app:`Pyramid`. It was merged into the Pylons project as :app:`Pyramid` in +November of that year. -:app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version -1.0), and :term:`Django`. As a result, :app:`Pyramid` borrows several -concepts and features from each, combining them into a unique web -framework. +:app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version 1.0), and +:term:`Django`. As a result, :app:`Pyramid` borrows several concepts and +features from each, combining them into a unique web framework. -Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. -Like Zope applications, :app:`Pyramid` applications can be easily extended. -If you obey certain constraints, the application you produce can be reused, -modified, re-integrated, or extended by third-party developers without -forking the original application. The concepts of :term:`traversal` and -declarative security in :app:`Pyramid` were pioneered first in Zope. +Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. Like +Zope applications, :app:`Pyramid` applications can be easily extended. If you +obey certain constraints, the application you produce can be reused, modified, +re-integrated, or extended by third-party developers without forking the +original application. The concepts of :term:`traversal` and declarative +security in :app:`Pyramid` were pioneered first in Zope. The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the :term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons version 1.0, :app:`Pyramid` is mostly policy-free. It makes no assertions about which database you should use. Pyramid no longer has built-in templating facilities as of version 1.5a2, but instead officially supports bindings for templating -languages, including Chameleon, Jinja2, and Mako. In essence, it only -supplies a mechanism to map URLs to :term:`view` code, along with a set of -conventions for calling those views. You are free to use third-party -components that fit your needs in your applications. +languages, including Chameleon, Jinja2, and Mako. In essence, it only supplies +a mechanism to map URLs to :term:`view` code, along with a set of conventions +for calling those views. You are free to use third-party components that fit +your needs in your applications. -The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be -by Django. :app:`Pyramid` has a documentation culture more like Django's -than like Zope's. +The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be by +Django. :app:`Pyramid` has a documentation culture more like Django's than +like Zope's. Like :term:`Pylons` version 1.0, but unlike :term:`Zope`, a :app:`Pyramid` application developer may use completely imperative code to perform common @@ -965,34 +952,34 @@ framework configuration tasks such as adding a view or a route. In Zope, :term:`ZCML` is typically required for similar purposes. In :term:`Grok`, a Zope-based web framework, :term:`decorator` objects and class-level declarations are used for this purpose. Out of the box, Pyramid supports -imperative and decorator-based configuration; :term:`ZCML` may be used via an +imperative and decorator-based configuration. :term:`ZCML` may be used via an add-on package named ``pyramid_zcml``. -Also unlike :term:`Zope` and other "full-stack" frameworks such -as :term:`Django`, :app:`Pyramid` makes no assumptions about which -persistence mechanisms you should use to build an application. Zope -applications are typically reliant on :term:`ZODB`; :app:`Pyramid` -allows you to build :term:`ZODB` applications, but it has no reliance -on the ZODB software. Likewise, :term:`Django` tends to assume that -you want to store your application's data in a relational database. -:app:`Pyramid` makes no such assumption, allowing you to use a -relational database, and neither encouraging nor discouraging the decision. - -Other Python web frameworks advertise themselves as members of a class -of web frameworks named `model-view-controller -`_ frameworks. -Insofar as this term has been claimed to represent a class of web -frameworks, :app:`Pyramid` also generally fits into this class. - -.. sidebar:: You Say :app:`Pyramid` is MVC, But Where's The Controller? - - The :app:`Pyramid` authors believe that the MVC pattern just doesn't - really fit the web very well. In a :app:`Pyramid` application, there is a - resource tree which represents the site structure, and views which tend - to present the data stored in the resource tree and a user-defined "domain - model". However, no facility provided *by the framework* actually - necessarily maps to the concept of a "controller" or "model". So if you - had to give it some acronym, I guess you'd say :app:`Pyramid` is actually - an "RV" framework rather than an "MVC" framework. "MVC", however, is - close enough as a general classification moniker for purposes of - comparison with other web frameworks. +Also unlike :term:`Zope` and other "full-stack" frameworks such as +:term:`Django`, :app:`Pyramid` makes no assumptions about which persistence +mechanisms you should use to build an application. Zope applications are +typically reliant on :term:`ZODB`. :app:`Pyramid` allows you to build +:term:`ZODB` applications, but it has no reliance on the ZODB software. +Likewise, :term:`Django` tends to assume that you want to store your +application's data in a relational database. :app:`Pyramid` makes no such +assumption, allowing you to use a relational database, and neither encouraging +nor discouraging the decision. + +Other Python web frameworks advertise themselves as members of a class of web +frameworks named `model-view-controller +`_ frameworks. Insofar as +this term has been claimed to represent a class of web frameworks, +:app:`Pyramid` also generally fits into this class. + +.. sidebar:: You Say :app:`Pyramid` is MVC, but Where's the Controller? + + The :app:`Pyramid` authors believe that the MVC pattern just doesn't really + fit the web very well. In a :app:`Pyramid` application, there is a resource + tree which represents the site structure, and views which tend to present + the data stored in the resource tree and a user-defined "domain model". + However, no facility provided *by the framework* actually necessarily maps + to the concept of a "controller" or "model". So if you had to give it some + acronym, I guess you'd say :app:`Pyramid` is actually an "RV" framework + rather than an "MVC" framework. "MVC", however, is close enough as a + general classification moniker for purposes of comparison with other web + frameworks. -- cgit v1.2.3 From e812341cfc68849395a77685e65272e39cf40ecc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 01:33:01 -0700 Subject: update tested versions in sidebar --- 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 a81a559a7..26d458727 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 and PyPy 2.2. :app:`Pyramid` does - not run under any version of Python before 2.6. + 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. :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 f9abe1811133966d99ae2321d9fc24e86fd22f7f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 23:27:15 -0700 Subject: wrap 79 cols --- docs/narr/firstapp.rst | 183 ++++++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 93 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index ee7511770..b85c1f3d1 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -37,17 +37,17 @@ On Windows: C:\> %VENV%\Scripts\python.exe helloworld.py -This command will not return and nothing will be printed to the console. -When port 8080 is visited by a browser on the URL ``/hello/world``, the -server will simply serve up the text "Hello world!". If your application is -running on your local system, using ``_ -in a browser will show this result. +This command will not return and nothing will be printed to the console. When +port 8080 is visited by a browser on the URL ``/hello/world``, the server will +simply serve up the text "Hello world!". If your application is running on +your local system, using ``_ in a browser +will show this result. Each time you visit a URL served by the application in a browser, a logging line will be emitted to the console displaying the hostname, the date, the -request method and path, and some additional information. This output is -done by the wsgiref server we've used to serve this application. It logs an -"access log" in Apache combined logging format to the console. +request method and path, and some additional information. This output is done +by the wsgiref server we've used to serve this application. It logs an "access +log" in Apache combined logging format to the console. Press ``Ctrl-C`` (or ``Ctrl-Break`` on Windows) to stop the application. @@ -57,8 +57,7 @@ let's examine it piece by piece. Imports ~~~~~~~ -The above ``helloworld.py`` script uses the following set of import -statements: +The above ``helloworld.py`` script uses the following set of import statements: .. literalinclude:: helloworld.py :linenos: @@ -71,32 +70,32 @@ The script imports the :class:`~pyramid.config.Configurator` class from the Like many other Python web frameworks, :app:`Pyramid` uses the :term:`WSGI` protocol to connect an application and a web server together. The -:mod:`wsgiref` server is used in this example as a WSGI server for -convenience, as it is shipped within the Python standard library. +:mod:`wsgiref` server is used in this example as a WSGI server for convenience, +as it is shipped within the Python standard library. -The script also imports the :class:`pyramid.response.Response` class for -later use. An instance of this class will be used to create a web response. +The script also imports the :class:`pyramid.response.Response` class for later +use. An instance of this class will be used to create a web response. View Callable Declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~ -The above script, beneath its set of imports, defines a function -named ``hello_world``. +The above script, beneath its set of imports, defines a function named +``hello_world``. .. literalinclude:: helloworld.py :linenos: :pyobject: hello_world -The function accepts a single argument (``request``) and it returns an -instance of the :class:`pyramid.response.Response` class. The single -argument to the class' constructor is a string computed from parameters -matched from the URL. This value becomes the body of the response. +The function accepts a single argument (``request``) and it returns an instance +of the :class:`pyramid.response.Response` class. The single argument to the +class' constructor is a string computed from parameters matched from the URL. +This value becomes the body of the response. -This function is known as a :term:`view callable`. A view callable -accepts a single argument, ``request``. It is expected to return a -:term:`response` object. A view callable doesn't need to be a function; it -can be represented via another type of object, like a class or an instance, -but for our purposes here, a function serves us well. +This function is known as a :term:`view callable`. A view callable accepts a +single argument, ``request``. It is expected to return a :term:`response` +object. A view callable doesn't need to be a function; it can be represented +via another type of object, like a class or an instance, but for our purposes +here, a function serves us well. A view callable is always called with a :term:`request` object. A request object is a representation of an HTTP request sent to :app:`Pyramid` via the @@ -105,10 +104,10 @@ active :term:`WSGI` server. A view callable is required to return a :term:`response` object because a response object has all the information necessary to formulate an actual HTTP response; this object is then converted to text by the :term:`WSGI` server -which called Pyramid and it is sent back to the requesting browser. To -return a response, each view callable creates an instance of the -:class:`~pyramid.response.Response` class. In the ``hello_world`` function, -a string is passed as the body to the response. +which called Pyramid and it is sent back to the requesting browser. To return +a response, each view callable creates an instance of the +:class:`~pyramid.response.Response` class. In the ``hello_world`` function, a +string is passed as the body to the response. .. index:: single: imperative configuration @@ -120,10 +119,10 @@ a string is passed as the body to the response. Application Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~ -In the above script, the following code represents the *configuration* of -this simple application. The application is configured using the previously -defined imports and function definitions, placed within the confines of an -``if`` statement: +In the above script, the following code represents the *configuration* of this +simple application. The application is configured using the previously defined +imports and function definitions, placed within the confines of an ``if`` +statement: .. literalinclude:: helloworld.py :linenos: @@ -140,26 +139,26 @@ Configurator Construction The ``if __name__ == '__main__':`` line in the code sample above represents a Python idiom: the code inside this if clause is not invoked unless the script -containing this code is run directly from the operating system command -line. For example, if the file named ``helloworld.py`` contains the entire -script body, the code within the ``if`` statement will only be invoked when -``python helloworld.py`` is executed from the command line. - -Using the ``if`` clause is necessary—or at least best practice—because -code in a Python ``.py`` file may be eventually imported via the Python -``import`` statement by another ``.py`` file. ``.py`` files that are -imported by other ``.py`` files are referred to as *modules*. By using the -``if __name__ == '__main__':`` idiom, the script above is indicating that it does -not want the code within the ``if`` statement to execute if this module is -imported from another; the code within the ``if`` block should only be run -during a direct script execution. +containing this code is run directly from the operating system command line. +For example, if the file named ``helloworld.py`` contains the entire script +body, the code within the ``if`` statement will only be invoked when ``python +helloworld.py`` is executed from the command line. + +Using the ``if`` clause is necessary—or at least best practice—because code in +a Python ``.py`` file may be eventually imported via the Python ``import`` +statement by another ``.py`` file. ``.py`` files that are imported by other +``.py`` files are referred to as *modules*. By using the ``if __name__ == +'__main__':`` idiom, the script above is indicating that it does not want the +code within the ``if`` statement to execute if this module is imported from +another; the code within the ``if`` block should only be run during a direct +script execution. The ``config = Configurator()`` line above creates an instance of the :class:`~pyramid.config.Configurator` class. The resulting ``config`` object represents an API which the script uses to configure this particular :app:`Pyramid` application. Methods called on the Configurator will cause -registrations to be made in an :term:`application registry` associated with -the application. +registrations to be made in an :term:`application registry` associated with the +application. .. _adding_configuration: @@ -171,12 +170,12 @@ Adding Configuration :lines: 11-12 The first line above calls the :meth:`pyramid.config.Configurator.add_route` -method, which registers a :term:`route` to match any URL path that begins -with ``/hello/`` followed by a string. +method, which registers a :term:`route` to match any URL path that begins with +``/hello/`` followed by a string. -The second line registers the ``hello_world`` function as a -:term:`view callable` and makes sure that it will be called when the -``hello`` route is matched. +The second line registers the ``hello_world`` function as a :term:`view +callable` and makes sure that it will be called when the ``hello`` route is +matched. .. index:: single: make_wsgi_app @@ -190,25 +189,24 @@ WSGI Application Creation :lines: 13 After configuring views and ending configuration, the script creates a WSGI -*application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` -method. A call to ``make_wsgi_app`` implies that all configuration is -finished (meaning all method calls to the configurator, which sets up views -and various other configuration settings, have been performed). The -``make_wsgi_app`` method returns a :term:`WSGI` application object that can -be used by any WSGI server to present an application to a requestor. -:term:`WSGI` is a protocol that allows servers to talk to Python -applications. We don't discuss :term:`WSGI` in any depth within this book, -but you can learn more about it by visiting `wsgi.org -`_. - -The :app:`Pyramid` application object, in particular, is an instance of a -class representing a :app:`Pyramid` :term:`router`. It has a reference to -the :term:`application registry` which resulted from method calls to the -configurator used to configure it. The :term:`router` consults the registry -to obey the policy choices made by a single application. These policy -choices were informed by method calls to the :term:`Configurator` made -earlier; in our case, the only policy choices made were implied by calls -to its ``add_view`` and ``add_route`` methods. +*application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` method. + A call to ``make_wsgi_app`` implies that all configuration is finished +(meaning all method calls to the configurator, which sets up views and various +other configuration settings, have been performed). The ``make_wsgi_app`` +method returns a :term:`WSGI` application object that can be used by any WSGI +server to present an application to a requestor. :term:`WSGI` is a protocol +that allows servers to talk to Python applications. We don't discuss +:term:`WSGI` in any depth within this book, but you can learn more about it by +visiting `wsgi.org `_. + +The :app:`Pyramid` application object, in particular, is an instance of a class +representing a :app:`Pyramid` :term:`router`. It has a reference to the +:term:`application registry` which resulted from method calls to the +configurator used to configure it. The :term:`router` consults the registry to +obey the policy choices made by a single application. These policy choices +were informed by method calls to the :term:`Configurator` made earlier; in our +case, the only policy choices made were implied by calls to its ``add_view`` +and ``add_route`` methods. WSGI Application Serving ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -217,37 +215,36 @@ WSGI Application Serving :linenos: :lines: 14-15 -Finally, we actually serve the application to requestors by starting up a -WSGI server. We happen to use the :mod:`wsgiref` ``make_server`` server -maker for this purpose. We pass in as the first argument ``'0.0.0.0'``, -which means "listen on all TCP interfaces". By default, the HTTP server -listens only on the ``127.0.0.1`` interface, which is problematic if you're -running the server on a remote system and you wish to access it with a web -browser from a local system. We also specify a TCP port number to listen on, -which is 8080, passing it as the second argument. The final argument is the -``app`` object (a :term:`router`), which is the application we wish to -serve. Finally, we call the server's ``serve_forever`` method, which starts -the main loop in which it will wait for requests from the outside world. - -When this line is invoked, it causes the server to start listening on TCP -port 8080. The server will serve requests forever, or at least until we stop -it by killing the process which runs it (usually by pressing ``Ctrl-C`` -or ``Ctrl-Break`` in the terminal we used to start it). +Finally, we actually serve the application to requestors by starting up a WSGI +server. We happen to use the :mod:`wsgiref` ``make_server`` server maker for +this purpose. We pass in as the first argument ``'0.0.0.0'``, which means +"listen on all TCP interfaces". By default, the HTTP server listens only on +the ``127.0.0.1`` interface, which is problematic if you're running the server +on a remote system and you wish to access it with a web browser from a local +system. We also specify a TCP port number to listen on, which is 8080, passing +it as the second argument. The final argument is the ``app`` object (a +:term:`router`), which is the application we wish to serve. Finally, we call +the server's ``serve_forever`` method, which starts the main loop in which it +will wait for requests from the outside world. + +When this line is invoked, it causes the server to start listening on TCP port +8080. The server will serve requests forever, or at least until we stop it by +killing the process which runs it (usually by pressing ``Ctrl-C`` or +``Ctrl-Break`` in the terminal we used to start it). Conclusion ~~~~~~~~~~ Our hello world application is one of the simplest possible :app:`Pyramid` applications, configured "imperatively". We can see that it's configured -imperatively because the full power of Python is available to us as we -perform configuration tasks. +imperatively because the full power of Python is available to us as we perform +configuration tasks. References ---------- -For more information about the API of a :term:`Configurator` object, -see :class:`~pyramid.config.Configurator` . +For more information about the API of a :term:`Configurator` object, see +:class:`~pyramid.config.Configurator` . For more information about :term:`view configuration`, see :ref:`view_config_chapter`. - -- cgit v1.2.3 From 553a948fe67e4c761ce0a9da85e898db7c2b6625 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 23:34:02 -0700 Subject: wrap 79 cols --- docs/narr/configuration.rst | 92 ++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 47 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index c1457fce5..cde166b21 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -3,27 +3,26 @@ .. _configuration_narr: -Application Configuration +Application Configuration ========================= Most people already understand "configuration" as settings that influence the -operation of an application. For instance, it's easy to think of the values -in a ``.ini`` file parsed at application startup time as "configuration". -However, if you're reasonably open-minded, it's easy to think of *code* as -configuration too. Since Pyramid, like most other web application platforms, -is a *framework*, it calls into code that you write (as opposed to a -*library*, which is code that exists purely for you to call). The act of -plugging application code that you've written into :app:`Pyramid` is also -referred to within this documentation as "configuration"; you are configuring +operation of an application. For instance, it's easy to think of the values in +a ``.ini`` file parsed at application startup time as "configuration". However, +if you're reasonably open-minded, it's easy to think of *code* as configuration +too. Since Pyramid, like most other web application platforms, is a +*framework*, it calls into code that you write (as opposed to a *library*, +which is code that exists purely for you to call). The act of plugging +application code that you've written into :app:`Pyramid` is also referred to +within this documentation as "configuration"; you are configuring :app:`Pyramid` to call the code that makes up your application. .. seealso:: For information on ``.ini`` files for Pyramid applications see the :ref:`startup_chapter` chapter. -There are two ways to configure a :app:`Pyramid` application: -:term:`imperative configuration` and :term:`declarative configuration`. Both -are described below. +There are two ways to configure a :app:`Pyramid` application: :term:`imperative +configuration` and :term:`declarative configuration`. Both are described below. .. index:: single: imperative configuration @@ -33,9 +32,9 @@ are described below. Imperative Configuration ------------------------ -"Imperative configuration" just means configuration done by Python -statements, one after the next. Here's one of the simplest :app:`Pyramid` -applications, configured imperatively: +"Imperative configuration" just means configuration done by Python statements, +one after the next. Here's one of the simplest :app:`Pyramid` applications, +configured imperatively: .. code-block:: python :linenos: @@ -57,9 +56,9 @@ applications, configured imperatively: We won't talk much about what this application does yet. Just note that the "configuration' statements take place underneath the ``if __name__ == '__main__':`` stanza in the form of method calls on a :term:`Configurator` -object (e.g., ``config.add_view(...)``). These statements take place one -after the other, and are executed in order, so the full power of Python, -including conditionals, can be employed in this mode of configuration. +object (e.g., ``config.add_view(...)``). These statements take place one after +the other, and are executed in order, so the full power of Python, including +conditionals, can be employed in this mode of configuration. .. index:: single: view_config @@ -72,13 +71,13 @@ Declarative Configuration ------------------------- It's sometimes painful to have all configuration done by imperative code, -because often the code for a single application may live in many files. If -the configuration is centralized in one place, you'll need to have at least -two files open at once to see the "big picture": the file that represents the -configuration, and the file that contains the implementation objects -referenced by the configuration. To avoid this, :app:`Pyramid` allows you to -insert :term:`configuration decoration` statements very close to code that is -referred to by the declaration itself. For example: +because often the code for a single application may live in many files. If the +configuration is centralized in one place, you'll need to have at least two +files open at once to see the "big picture": the file that represents the +configuration, and the file that contains the implementation objects referenced +by the configuration. To avoid this, :app:`Pyramid` allows you to insert +:term:`configuration decoration` statements very close to code that is referred +to by the declaration itself. For example: .. code-block:: python :linenos: @@ -90,20 +89,19 @@ referred to by the declaration itself. For example: def hello(request): return Response('Hello') -The mere existence of configuration decoration doesn't cause any -configuration registration to be performed. Before it has any effect on the -configuration of a :app:`Pyramid` application, a configuration decoration -within application code must be found through a process known as a -:term:`scan`. +The mere existence of configuration decoration doesn't cause any configuration +registration to be performed. Before it has any effect on the configuration of +a :app:`Pyramid` application, a configuration decoration within application +code must be found through a process known as a :term:`scan`. For example, the :class:`pyramid.view.view_config` decorator in the code -example above adds an attribute to the ``hello`` function, making it -available for a :term:`scan` to find it later. +example above adds an attribute to the ``hello`` function, making it available +for a :term:`scan` to find it later. -A :term:`scan` of a :term:`module` or a :term:`package` and its subpackages -for decorations happens when the :meth:`pyramid.config.Configurator.scan` -method is invoked: scanning implies searching for configuration declarations -in a package and its subpackages. For example: +A :term:`scan` of a :term:`module` or a :term:`package` and its subpackages for +decorations happens when the :meth:`pyramid.config.Configurator.scan` method is +invoked: scanning implies searching for configuration declarations in a package +and its subpackages. For example: .. code-block:: python :linenos: @@ -125,16 +123,16 @@ in a package and its subpackages. For example: server.serve_forever() The scanning machinery imports each module and subpackage in a package or -module recursively, looking for special attributes attached to objects -defined within a module. These special attributes are typically attached to -code via the use of a :term:`decorator`. For example, the +module recursively, looking for special attributes attached to objects defined +within a module. These special attributes are typically attached to code via +the use of a :term:`decorator`. For example, the :class:`~pyramid.view.view_config` decorator can be attached to a function or instance method. -Once scanning is invoked, and :term:`configuration decoration` is found by -the scanner, a set of calls are made to a :term:`Configurator` on your -behalf. These calls replace the need to add imperative configuration -statements that don't live near the code being configured. +Once scanning is invoked, and :term:`configuration decoration` is found by the +scanner, a set of calls are made to a :term:`Configurator` on your behalf. +These calls replace the need to add imperative configuration statements that +don't live near the code being configured. The combination of :term:`configuration decoration` and the invocation of a :term:`scan` is collectively known as :term:`declarative configuration`. @@ -150,7 +148,7 @@ In the example above, the scanner translates the arguments to Summary ------- -There are two ways to configure a :app:`Pyramid` application: declaratively -and imperatively. You can choose the mode with which you're most comfortable; -both are completely equivalent. Examples in this documentation will use both -modes interchangeably. +There are two ways to configure a :app:`Pyramid` application: declaratively and +imperatively. You can choose the mode with which you're most comfortable; both +are completely equivalent. Examples in this documentation will use both modes +interchangeably. -- cgit v1.2.3 From a54e4cf75402575ba7b12a03acc0738126c16e2d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 23:52:05 -0700 Subject: wrap 79 cols --- docs/narr/firstapp.rst | 2 +- docs/narr/project.rst | 598 ++++++++++++++++++++++++------------------------- 2 files changed, 291 insertions(+), 309 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/firstapp.rst b/docs/narr/firstapp.rst index b85c1f3d1..6a952dec9 100644 --- a/docs/narr/firstapp.rst +++ b/docs/narr/firstapp.rst @@ -190,7 +190,7 @@ WSGI Application Creation After configuring views and ending configuration, the script creates a WSGI *application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` method. - A call to ``make_wsgi_app`` implies that all configuration is finished +A call to ``make_wsgi_app`` implies that all configuration is finished (meaning all method calls to the configurator, which sets up views and various other configuration settings, have been performed). The ``make_wsgi_app`` method returns a :term:`WSGI` application object that can be used by any WSGI diff --git a/docs/narr/project.rst b/docs/narr/project.rst index c9e89aff4..25f3931e9 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -3,25 +3,24 @@ Creating a :app:`Pyramid` Project ================================= -As we saw in :ref:`firstapp_chapter`, it's possible to create a -:app:`Pyramid` application completely manually. However, it's usually more -convenient to use a :term:`scaffold` to generate a basic :app:`Pyramid` -:term:`project`. +As we saw in :ref:`firstapp_chapter`, it's possible to create a :app:`Pyramid` +application completely manually. However, it's usually more convenient to use +a :term:`scaffold` to generate a basic :app:`Pyramid` :term:`project`. A project is a directory that contains at least one Python :term:`package`. You'll use a scaffold to create a project, and you'll create your application -logic within a package that lives inside the project. Even if your -application is extremely simple, it is useful to place code that drives the -application within a package, because (1) a package is more easily extended -with new code, and (2) an application that lives inside a package can also be -distributed more easily than one which does not live within a package. +logic within a package that lives inside the project. Even if your application +is extremely simple, it is useful to place code that drives the application +within a package, because (1) a package is more easily extended with new code, +and (2) an application that lives inside a package can also be distributed more +easily than one which does not live within a package. -:app:`Pyramid` comes with a variety of scaffolds that you can use to generate -a project. Each scaffold makes different configuration assumptions about -what type of application you're trying to construct. +:app:`Pyramid` comes with a variety of scaffolds that you can use to generate a +project. Each scaffold makes different configuration assumptions about what +type of application you're trying to construct. -These scaffolds are rendered using the ``pcreate`` command that is installed -as part of Pyramid. +These scaffolds are rendered using the ``pcreate`` command that is installed as +part of Pyramid. .. index:: single: scaffolds @@ -34,11 +33,11 @@ as part of Pyramid. Scaffolds Included with :app:`Pyramid` -------------------------------------- -The convenience scaffolds included with :app:`Pyramid` differ from -each other on a number of axes: +The convenience scaffolds included with :app:`Pyramid` differ from each other +on a number of axes: -- the persistence mechanism they offer (no persistence mechanism, - :term:`ZODB`, or :term:`SQLAlchemy`) +- the persistence mechanism they offer (no persistence mechanism, :term:`ZODB`, + or :term:`SQLAlchemy`) - the mechanism they use to map URLs to code (:term:`traversal` or :term:`URL dispatch`) @@ -52,8 +51,7 @@ The included scaffolds are these: URL mapping via :term:`traversal` and persistence via :term:`ZODB` ``alchemy`` - URL mapping via :term:`URL dispatch` and persistence via - :term:`SQLAlchemy` + URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` .. index:: single: creating a project @@ -64,9 +62,9 @@ The included scaffolds are these: Creating the Project -------------------- -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 +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 ``starter`` scaffold for this purpose. When we invoke ``pcreate``, it will create a directory that represents our project. @@ -101,14 +99,14 @@ Here's sample output from a run of ``pcreate`` on UNIX for a project we name Running /Users/chrism/projects/pyramid/bin/python setup.py egg_info As a result of invoking the ``pcreate`` command, a directory named -``MyProject`` is created. That directory is a :term:`project` directory. -The ``setup.py`` file in that directory can be used to distribute your -application, or install your application for deployment or development. +``MyProject`` is created. That directory is a :term:`project` directory. The +``setup.py`` file in that directory can be used to distribute your application, +or install your application for deployment or development. A ``.ini`` file named ``development.ini`` will be created in the project -directory. You will use this ``.ini`` file to configure a server, to run -your application, and to debug your application. It contains configuration -that enables an interactive debugger and settings optimized for development. +directory. You will use this ``.ini`` file to configure a server, to run your +application, and to debug your application. It contains configuration that +enables an interactive debugger and settings optimized for development. Another ``.ini`` file named ``production.ini`` will also be created in the project directory. It contains configuration that disables any interactive @@ -117,28 +115,28 @@ number of debugging settings. You can use this file to put your application into production. The ``MyProject`` project directory contains an additional subdirectory named -``myproject`` (note the case difference) representing a Python -:term:`package` which holds very simple :app:`Pyramid` sample code. This is -where you'll edit your application's Python code and templates. - -We created this project within an ``env`` virtualenv directory. However, -note that this is not mandatory. The project directory can go more or less -anywhere on your filesystem. You don't need to put it in a special "web -server" directory, and you don't need to put it within a virtualenv -directory. The author uses Linux mainly, and tends to put project -directories which he creates within his ``~/projects`` directory. On -Windows, it's a good idea to put project directories within a directory that -contains no space characters, so it's wise to *avoid* a path that contains, -i.e., ``My Documents``. As a result, the author, when he uses Windows, just -puts his projects in ``C:\projects``. +``myproject`` (note the case difference) representing a Python :term:`package` +which holds very simple :app:`Pyramid` sample code. This is where you'll edit +your application's Python code and templates. + +We created this project within an ``env`` virtualenv directory. However, note +that this is not mandatory. The project directory can go more or less anywhere +on your filesystem. You don't need to put it in a special "web server" +directory, and you don't need to put it within a virtualenv directory. The +author uses Linux mainly, and tends to put project directories which he creates +within his ``~/projects`` directory. On Windows, it's a good idea to put +project directories within a directory that contains no space characters, so +it's wise to *avoid* a path that contains, i.e., ``My Documents``. As a +result, the author, when he uses Windows, just puts his projects in +``C:\projects``. .. warning:: You'll need to avoid using ``pcreate`` to create a project with the same name as a Python standard library component. In particular, this means you - should avoid using the names ``site`` or ``test``, both of which - conflict with Python standard library packages. You should also avoid - using the name ``pyramid``, which will conflict with Pyramid itself. + should avoid using the names ``site`` or ``test``, both of which conflict + with Python standard library packages. You should also avoid using the name + ``pyramid``, which will conflict with Pyramid itself. .. index:: single: setup.py develop @@ -153,10 +151,10 @@ newly created project directory and use the Python interpreter from the command ``python setup.py develop`` The file named ``setup.py`` will be in the root of the pcreate-generated -project directory. The ``python`` you're invoking should be the one that -lives in the ``bin`` (or ``Scripts`` on Windows) directory of your virtual -Python environment. Your terminal's current working directory *must* be the -newly created project directory. +project directory. The ``python`` you're invoking should be the one that lives +in the ``bin`` (or ``Scripts`` on Windows) directory of your virtual Python +environment. Your terminal's current working directory *must* be the newly +created project directory. On UNIX: @@ -181,10 +179,10 @@ Elided output from a run of this command on UNIX is shown below: ... Finished processing dependencies for MyProject==0.0 -This will install a :term:`distribution` representing your project -into the virtual environment interpreter's library set so it can be -found by ``import`` statements and by other console scripts such as -``pserve``, ``pshell``, ``proutes``, and ``pviews``. +This will install a :term:`distribution` representing your project into the +virtual environment interpreter's library set so it can be found by ``import`` +statements and by other console scripts such as ``pserve``, ``pshell``, +``proutes``, and ``pviews``. .. index:: single: running tests @@ -193,8 +191,8 @@ found by ``import`` statements and by other console scripts such as Running the Tests for Your Application -------------------------------------- -To run unit tests for your application, you should invoke them using the -Python interpreter from the :term:`virtualenv` you created during +To run unit tests for your application, you should invoke them using the Python +interpreter from the :term:`virtualenv` you created during :ref:`installing_chapter` (the ``python`` command that lives in the ``bin`` directory of your virtualenv). @@ -278,12 +276,12 @@ Here's sample output from a run of ``pserve`` on UNIX: 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 +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 @@ -305,28 +303,26 @@ example: 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]`` -section to ``port = 8080`` to run the server on port 8080 instead of -port 6543. +section to ``port = 8080`` to run the server on port 8080 instead of port 6543. You can shut down a server started this way by pressing ``Ctrl-C`` (or ``Ctrl-Break`` on Windows). The default server used to run your Pyramid application when a project is -created from a scaffold is named :term:`Waitress`. This server is what -prints the ``serving on...`` line when you run ``pserve``. It's a good idea -to use this server during development because it's very simple. It can also -be used for light production. Setting your application up under a different -server is not advised until you've done some development work under the -default server, particularly if you're not yet experienced with Python web -development. Python web server setup can be complex, and you should get some -confidence that your application works in a default environment before trying -to optimize it or make it "more like production". It's awfully easy to get -sidetracked trying to set up a non-default server for hours without actually -starting to do any development. One of the nice things about Python web -servers is that they're largely interchangeable, so if your application works -under the default server, it will almost certainly work under any other -server in production if you eventually choose to use a different one. Don't -worry about it right now. +created from a scaffold is named :term:`Waitress`. This server is what prints +the ``serving on...`` line when you run ``pserve``. It's a good idea to use +this server during development because it's very simple. It can also be used +for light production. Setting your application up under a different server is +not advised until you've done some development work under the default server, +particularly if you're not yet experienced with Python web development. Python +web server setup can be complex, and you should get some confidence that your +application works in a default environment before trying to optimize it or make +it "more like production". It's awfully easy to get sidetracked trying to set +up a non-default server for hours without actually starting to do any +development. One of the nice things about Python web servers is that they're +largely interchangeable, so if your application works under the default server, +it will almost certainly work under any other server in production if you +eventually choose to use a different one. Don't worry about it right now. For more detailed information about the startup process, see :ref:`startup_chapter`. For more information about environment variables and @@ -338,10 +334,10 @@ configuration file settings that influence startup and runtime behavior, see Reloading Code ~~~~~~~~~~~~~~ -During development, it's often useful to run ``pserve`` using its -``--reload`` option. When ``--reload`` is passed to ``pserve``, changes to -any Python module your project uses will cause the server to restart. This -typically makes development easier, as changes to Python code made within a +During development, it's often useful to run ``pserve`` using its ``--reload`` +option. When ``--reload`` is passed to ``pserve``, changes to any Python +module your project uses will cause the server to restart. This typically +makes development easier, as changes to Python code made within a :app:`Pyramid` application is not put into effect until the server restarts. For example, on UNIX: @@ -364,10 +360,10 @@ files, you'll see the server restart automatically: serving on http://0.0.0.0: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 long as the ``pyramid.reload_templates`` setting in the -``development.ini`` file is ``true``. Changes made to template files when -this setting is true will take effect immediately without a server restart. +server to restart. Changes to template files don't require a server restart as +long as the ``pyramid.reload_templates`` setting in the ``development.ini`` +file is ``true``. Changes made to template files when this setting is true +will take effect immediately without a server restart. .. index:: single: WSGI @@ -396,22 +392,21 @@ The Debug Toolbar If you click on the :app:`Pyramid` logo at the top right of the page, a new target window will open to present a debug toolbar that provides various -niceties while you're developing. This logo will float above every HTML -page served by :app:`Pyramid` while you develop an application, and allows -you to show the toolbar as necessary. +niceties while you're developing. This logo will float above every HTML page +served by :app:`Pyramid` while you develop an application, and allows you to +show the toolbar as necessary. .. image:: project-debug.png -If you don't see the Pyramid logo on the top right of the page, it means -you're browsing from a system that does not have debugging access. By -default, for security reasons, only a browser originating from ``localhost`` -(``127.0.0.1``) can see the debug toolbar. To allow your browser on a -remote system to access the server, add a line within the ``[app:main]`` -section of the ``development.ini`` file in the form ``debugtoolbar.hosts = X -.X.X.X``. For example, if your Pyramid application is running on a remote -system, and you're browsing from a host with the IP address ``192.168.1.1``, -you'd add something like this to enable the toolbar when your system -contacts Pyramid: +If you don't see the Pyramid logo on the top right of the page, it means you're +browsing from a system that does not have debugging access. By default, for +security reasons, only a browser originating from ``localhost`` (``127.0.0.1``) +can see the debug toolbar. To allow your browser on a remote system to access +the server, add a line within the ``[app:main]`` section of the +``development.ini`` file in the form ``debugtoolbar.hosts = X .X.X.X``. For +example, if your Pyramid application is running on a remote system, and you're +browsing from a host with the IP address ``192.168.1.1``, you'd add something +like this to enable the toolbar when your system contacts Pyramid: .. code-block:: ini @@ -423,9 +418,9 @@ For more information about what the debug toolbar allows you to do, see `the documentation for pyramid_debugtoolbar `_. -The debug toolbar will not be shown (and all debugging will be turned off) -when you use the ``production.ini`` file instead of the ``development.ini`` -ini file to run the application. +The debug toolbar will not be shown (and all debugging will be turned off) when +you use the ``production.ini`` file instead of the ``development.ini`` ini file +to run the application. You can also turn the debug toolbar off by editing ``development.ini`` and commenting out a line. For example, instead of: @@ -451,9 +446,9 @@ Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: Then restart the application to see that the toolbar has been turned off. Note that if you comment out the ``pyramid_debugtoolbar`` line, the ``#`` -*must* be in the first column. If you put it anywhere else, and then -attempt to restart the application, you'll receive an error that ends -something like this: +*must* be in the first column. If you put it anywhere else, and then attempt +to restart the application, you'll receive an error that ends something like +this: .. code-block:: text @@ -471,8 +466,7 @@ which contains a Python :term:`package`. The package is *also* named contains a package that shares its name except for case. All :app:`Pyramid` ``pcreate``-generated projects share a similar structure. -The ``MyProject`` project we've generated has the following directory -structure: +The ``MyProject`` project we've generated has the following directory structure: .. code-block:: text @@ -498,29 +492,29 @@ structure: The ``MyProject`` :term:`Project` --------------------------------- -The ``MyProject`` :term:`project` directory is the distribution and -deployment wrapper for your application. It contains both the ``myproject`` +The ``MyProject`` :term:`project` directory is the distribution and deployment +wrapper for your application. It contains both the ``myproject`` :term:`package` representing your application as well as files used to describe, run, and test your application. -#. ``CHANGES.txt`` describes the changes you've made to the application. It - is conventionally written in :term:`ReStructuredText` format. +#. ``CHANGES.txt`` describes the changes you've made to the application. It is + conventionally written in :term:`ReStructuredText` format. #. ``README.txt`` describes the application in general. It is conventionally written in :term:`ReStructuredText` format. -#. ``development.ini`` is a :term:`PasteDeploy` configuration file that can - be used to execute your application during development. +#. ``development.ini`` is a :term:`PasteDeploy` configuration file that can be + used to execute your application during development. -#. ``production.ini`` is a :term:`PasteDeploy` configuration file that can - be used to execute your application in a production configuration. +#. ``production.ini`` is a :term:`PasteDeploy` configuration file that can be + used to execute your application in a production configuration. #. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files should be included in a source distribution of the package when ``python setup.py sdist`` is run. -#. ``setup.py`` is the file you'll use to test and distribute your - application. It is a standard :term:`setuptools` ``setup.py`` file. +#. ``setup.py`` is the file you'll use to test and distribute your application. + It is a standard :term:`setuptools` ``setup.py`` file. .. index:: single: PasteDeploy @@ -531,9 +525,9 @@ describe, run, and test your application. ``development.ini`` ~~~~~~~~~~~~~~~~~~~ -The ``development.ini`` file is a :term:`PasteDeploy` configuration file. -Its purpose is to specify an application to run when you invoke ``pserve``, -as well as the deployment settings provided to that application. +The ``development.ini`` file is a :term:`PasteDeploy` configuration file. Its +purpose is to specify an application to run when you invoke ``pserve``, as well +as the deployment settings provided to that application. The generated ``development.ini`` file looks like so: @@ -542,33 +536,32 @@ The generated ``development.ini`` file looks like so: :linenos: This file contains several sections including ``[app:main]``, -``[server:main]``, and several other sections related to logging -configuration. +``[server:main]``, and several other sections related to logging configuration. The ``[app:main]`` section represents configuration for your :app:`Pyramid` -application. The ``use`` setting is the only setting required to be present -in the ``[app:main]`` section. Its default value, ``egg:MyProject``, -indicates that our MyProject project contains the application that should be -served. Other settings added to this section are passed as keyword arguments -to the function named ``main`` in our package's ``__init__.py`` module. You -can provide startup-time configuration parameters to your application by -adding more settings to this section. +application. The ``use`` setting is the only setting required to be present in +the ``[app:main]`` section. Its default value, ``egg:MyProject``, indicates +that our MyProject project contains the application that should be served. +Other settings added to this section are passed as keyword arguments to the +function named ``main`` in our package's ``__init__.py`` module. You can +provide startup-time configuration parameters to your application by adding +more settings to this section. .. seealso:: See :ref:`pastedeploy_entry_points` for more information about the meaning of the ``use = egg:MyProject`` value in this section. The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a :app:`Pyramid`-specific setting which is passed into the framework. If it -exists, and its value is ``true``, supported template changes will not -require an application restart to be detected. See -:ref:`reload_templates_section` for more information. +exists, and its value is ``true``, supported template changes will not require +an application restart to be detected. See :ref:`reload_templates_section` for +more information. .. warning:: The ``pyramid.reload_templates`` option should be turned off for production applications, as template rendering is slowed when it is turned on. -The ``pyramid.includes`` setting in the ``[app:main]`` section tells Pyramid -to "include" configuration from another package. In this case, the line +The ``pyramid.includes`` setting in the ``[app:main]`` section tells Pyramid to +"include" configuration from another package. In this case, the line ``pyramid.includes = pyramid_debugtoolbar`` tells Pyramid to include configuration from the ``pyramid_debugtoolbar`` package. This turns on a debugging panel in development mode which can be opened by clicking on the @@ -576,14 +569,14 @@ debugging panel in development mode which can be opened by clicking on the toolbar will also make it possible to interactively debug exceptions when an error occurs. -Various other settings may exist in this section having to do with debugging -or influencing runtime behavior of a :app:`Pyramid` application. See +Various other settings may exist in this section having to do with debugging or +influencing runtime behavior of a :app:`Pyramid` application. See :ref:`environment_chapter` for more information about these settings. The name ``main`` in ``[app:main]`` signifies that this is the default application run by ``pserve`` when it is invoked against this configuration -file. The name ``main`` is a convention used by PasteDeploy signifying that -it is the default application. +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 @@ -594,14 +587,12 @@ access to your system can see your Pyramid application. 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 -sends application logging output to the standard error output of your -terminal. For more information about logging configuration, see -:ref:`logging_chapter`. +: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 +sends application logging output to the standard error output of your terminal. +For more information about logging configuration, see :ref:`logging_chapter`. See the :term:`PasteDeploy` documentation for more information about other types of things you can put into this ``.ini`` file, such as other @@ -614,20 +605,20 @@ implementations. ``production.ini`` ~~~~~~~~~~~~~~~~~~ -The ``production.ini`` file is a :term:`PasteDeploy` configuration file with -a purpose much like that of ``development.ini``. However, it disables the -debug toolbar, and filters all log messages except those above the WARN -level. It also turns off template development options such that templates -are not automatically reloaded when changed, and turns off all debugging -options. This file is appropriate to use instead of ``development.ini`` when -you put your application into production. +The ``production.ini`` file is a :term:`PasteDeploy` configuration file with a +purpose much like that of ``development.ini``. However, it disables the debug +toolbar, and filters all log messages except those above the WARN level. It +also turns off template development options such that templates are not +automatically reloaded when changed, and turns off all debugging options. This +file is appropriate to use instead of ``development.ini`` when you put your +application into production. It's important to use ``production.ini`` (and *not* ``development.ini``) to benchmark your application and put it into production. ``development.ini`` configures your system with a debug toolbar that helps development, but the inclusion of this toolbar slows down page rendering times by over an order of -magnitude. The debug toolbar is also a potential security risk if you have -it configured incorrectly. +magnitude. The debug toolbar is also a potential security risk if you have it +configured incorrectly. .. index:: single: MANIFEST.in @@ -639,42 +630,40 @@ The ``MANIFEST.in`` file is a :term:`distutils` configuration file which specifies the non-Python files that should be included when a :term:`distribution` of your Pyramid project is created when you run ``python setup.py sdist``. Due to the information contained in the default -``MANIFEST.in``, an sdist of your Pyramid project will include ``.txt`` -files, ``.ini`` files, ``.rst`` files, graphics files, and template files, as -well as ``.py`` files. See +``MANIFEST.in``, an sdist of your Pyramid project will include ``.txt`` files, +``.ini`` files, ``.rst`` files, graphics files, and template files, as well as +``.py`` files. See http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template for more information about the syntax and usage of ``MANIFEST.in``. -Without the presence of a ``MANIFEST.in`` file or without checking your -source code into a version control repository, ``setup.py sdist`` places only -*Python source files* (files ending with a ``.py`` extension) into tarballs -generated by ``python setup.py sdist``. This means, for example, if your -project was not checked into a setuptools-compatible source control system, -and your project directory didn't contain a ``MANIFEST.in`` file that told -the ``sdist`` machinery to include ``*.pt`` files, the -``myproject/templates/mytemplate.pt`` file would not be included in the -generated tarball. - -Projects generated by Pyramid scaffolds include a default ``MANIFEST.in`` -file. The ``MANIFEST.in`` file contains declarations which tell it to -include files like ``*.pt``, ``*.css`` and ``*.js`` in the generated tarball. -If you include files with extensions other than the files named in the -project's ``MANIFEST.in`` and you don't make use of a setuptools-compatible -version control system, you'll need to edit the ``MANIFEST.in`` file and -include the statements necessary to include your new files. See -http://docs.python.org/distutils/sourcedist.html#principle for more -information about how to do this. - -You can also delete ``MANIFEST.in`` from your project and rely on a -setuptools feature which simply causes all files checked into a version -control system to be put into the generated tarball. To allow this to -happen, check all the files that you'd like to be distributed along with your -application's Python files into Subversion. After you do this, when you -rerun ``setup.py sdist``, all files checked into the version control system -will be included in the tarball. If you don't use Subversion, and instead -use a different version control system, you may need to install a setuptools -add-on such as ``setuptools-git`` or ``setuptools-hg`` for this behavior to -work properly. +Without the presence of a ``MANIFEST.in`` file or without checking your source +code into a version control repository, ``setup.py sdist`` places only *Python +source files* (files ending with a ``.py`` extension) into tarballs generated +by ``python setup.py sdist``. This means, for example, if your project was not +checked into a setuptools-compatible source control system, and your project +directory didn't contain a ``MANIFEST.in`` file that told the ``sdist`` +machinery to include ``*.pt`` files, the ``myproject/templates/mytemplate.pt`` +file would not be included in the generated tarball. + +Projects generated by Pyramid scaffolds include a default ``MANIFEST.in`` file. +The ``MANIFEST.in`` file contains declarations which tell it to include files +like ``*.pt``, ``*.css`` and ``*.js`` in the generated tarball. If you include +files with extensions other than the files named in the project's +``MANIFEST.in`` and you don't make use of a setuptools-compatible version +control system, you'll need to edit the ``MANIFEST.in`` file and include the +statements necessary to include your new files. See +http://docs.python.org/distutils/sourcedist.html#principle for more information +about how to do this. + +You can also delete ``MANIFEST.in`` from your project and rely on a setuptools +feature which simply causes all files checked into a version control system to +be put into the generated tarball. To allow this to happen, check all the +files that you'd like to be distributed along with your application's Python +files into Subversion. After you do this, when you rerun ``setup.py sdist``, +all files checked into the version control system will be included in the +tarball. If you don't use Subversion, and instead use a different version +control system, you may need to install a setuptools add-on such as +``setuptools-git`` or ``setuptools-hg`` for this behavior to work properly. .. index:: single: setup.py @@ -688,11 +677,11 @@ testing, packaging, and distributing your application. .. note:: - ``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 `_. + ``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 `_. Our generated ``setup.py`` looks like this: @@ -701,47 +690,47 @@ Our generated ``setup.py`` looks like this: :linenos: The ``setup.py`` file calls the setuptools ``setup`` function, which does -various things depending on the arguments passed to ``setup.py`` on the -command line. +various things depending on the arguments passed to ``setup.py`` on the command +line. -Within the arguments to this function call, information about your -application is kept. While it's beyond the scope of this documentation to -explain everything about setuptools setup files, we'll provide a whirlwind -tour of what exists in this file in this section. +Within the arguments to this function call, information about your application +is kept. While it's beyond the scope of this documentation to explain +everything about setuptools setup files, we'll provide a whirlwind tour of what +exists in this file in this section. Your application's name can be any string; it is specified in the ``name`` field. The version number is specified in the ``version`` value. A short -description is provided in the ``description`` field. The -``long_description`` is conventionally the content of the README and CHANGES -file appended together. The ``classifiers`` field is a list of `Trove +description is provided in the ``description`` field. The ``long_description`` +is conventionally the content of the README and CHANGES file appended together. +The ``classifiers`` field is a list of `Trove `_ classifiers describing your application. ``author`` and ``author_email`` are text fields which probably don't need any description. ``url`` is a field that should -point at your application project's URL (if any). -``packages=find_packages()`` causes all packages within the project to be -found when packaging the application. ``include_package_data`` will include -non-Python files when the application is packaged if those files are checked -into version control. ``zip_safe`` indicates that this package is not safe -to use as a zipped egg; instead it will always unpack as a directory, which -is more convenient. ``install_requires`` and ``tests_require`` indicate that -this package depends on the ``pyramid`` package. ``test_suite`` points at -the package for our application, which means all tests found in the package -will be run when ``setup.py test`` is invoked. We examined ``entry_points`` -in our discussion of the ``development.ini`` file; this file defines the -``main`` entry point that represents our project's application. - -Usually you only need to think about the contents of the ``setup.py`` file -when distributing your application to other people, when adding Python -package dependencies, or when versioning your application for your own use. -For fun, you can try this command now: +point at your application project's URL (if any). ``packages=find_packages()`` +causes all packages within the project to be found when packaging the +application. ``include_package_data`` will include non-Python files when the +application is packaged if those files are checked into version control. +``zip_safe`` indicates that this package is not safe to use as a zipped egg; +instead it will always unpack as a directory, which is more convenient. +``install_requires`` and ``tests_require`` indicate that this package depends +on the ``pyramid`` package. ``test_suite`` points at the package for our +application, which means all tests found in the package will be run when +``setup.py test`` is invoked. We examined ``entry_points`` in our discussion +of the ``development.ini`` file; this file defines the ``main`` entry point +that represents our project's application. + +Usually you only need to think about the contents of the ``setup.py`` file when +distributing your application to other people, when adding Python package +dependencies, or when versioning your application for your own use. For fun, +you can try this command now: .. code-block:: text $ $VENV/bin/python setup.py sdist -This will create a tarball of your application in a ``dist`` subdirectory -named ``MyProject-0.1.tar.gz``. You can send this tarball to other people -who want to install and use your application. +This will create a tarball of your application in a ``dist`` subdirectory named +``MyProject-0.1.tar.gz``. You can send this tarball to other people who want +to install and use your application. .. index:: single: package @@ -752,19 +741,17 @@ The ``myproject`` :term:`Package` The ``myproject`` :term:`package` lives inside the ``MyProject`` :term:`project`. It contains: -#. An ``__init__.py`` file signifies that this is a Python :term:`package`. - It also contains code that helps users run the application, including a +#. An ``__init__.py`` file signifies that this is a Python :term:`package`. It + also contains code that helps users run the application, including a ``main`` function which is used as a entry point for commands such as ``pserve``, ``pshell``, ``pviews``, and others. -#. A ``templates`` directory, which contains :term:`Chameleon` (or - other types of) templates. +#. A ``templates`` directory, which contains :term:`Chameleon` (or other types + of) templates. -#. A ``tests.py`` module, which contains unit test code for the - application. +#. A ``tests.py`` module, which contains unit test code for the application. -#. A ``views.py`` module, which contains view code for the - application. +#. A ``views.py`` module, which contains view code for the application. These are purely conventions established by the scaffold. :app:`Pyramid` doesn't insist that you name things in any particular way. However, it's @@ -803,11 +790,11 @@ also informs Python that the directory which contains it is a *package*. specify renderers with the ``.pt`` extension. Line 9 registers a static view, which will serve up the files from the - ``myproject:static`` :term:`asset specification` (the ``static`` - directory of the ``myproject`` package). + ``myproject:static`` :term:`asset specification` (the ``static`` directory + of the ``myproject`` package). - Line 10 adds a :term:`route` to the configuration. This route is later - used by a view in the ``views`` module. + Line 10 adds a :term:`route` to the configuration. This route is later used + by a view in the ``views`` module. Line 11 calls ``config.scan()``, which picks up view registrations declared elsewhere in the package (in this case, in the ``views.py`` module). @@ -823,38 +810,37 @@ also informs Python that the directory which contains it is a *package*. Much of the heavy lifting in a :app:`Pyramid` application is done by *view callables*. A :term:`view callable` is the main tool of a :app:`Pyramid` web -application developer; it is a bit of code which accepts a :term:`request` -and which returns a :term:`response`. +application developer; it is a bit of code which accepts a :term:`request` and +which returns a :term:`response`. .. literalinclude:: MyProject/myproject/views.py :language: python :linenos: Lines 4-6 define and register a :term:`view callable` named ``my_view``. The -function named ``my_view`` is decorated with a ``view_config`` decorator -(which is processed by the ``config.scan()`` line in our ``__init__.py``). -The view_config decorator asserts that this view be found when a -:term:`route` named ``home`` is matched. In our case, because our -``__init__.py`` maps the route named ``home`` to the URL pattern ``/``, this -route will match when a visitor visits the root URL. The view_config -decorator also names a ``renderer``, which in this case is a template that -will be used to render the result of the view callable. This particular view -declaration points at ``templates/mytemplate.pt``, which is an :term:`asset -specification` that specifies the ``mytemplate.pt`` file within the -``templates`` directory of the ``myproject`` package. The asset -specification could have also been specified as -``myproject:templates/mytemplate.pt``; the leading package name and colon is +function named ``my_view`` is decorated with a ``view_config`` decorator (which +is processed by the ``config.scan()`` line in our ``__init__.py``). The +view_config decorator asserts that this view be found when a :term:`route` +named ``home`` is matched. In our case, because our ``__init__.py`` maps the +route named ``home`` to the URL pattern ``/``, this route will match when a +visitor visits the root URL. The view_config decorator also names a +``renderer``, which in this case is a template that will be used to render the +result of the view callable. This particular view declaration points at +``templates/mytemplate.pt``, which is an :term:`asset specification` that +specifies the ``mytemplate.pt`` file within the ``templates`` directory of the +``myproject`` package. The asset specification could have also been specified +as ``myproject:templates/mytemplate.pt``; the leading package name and colon is optional. The template file pointed to is a :term:`Chameleon` ZPT template file (``templates/my_template.pt``). This view callable function is handed a single piece of information: the -:term:`request`. The *request* is an instance of the :term:`WebOb` -``Request`` class representing the browser's request to our server. +:term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` +class representing the browser's request to our server. This view is configured to invoke a :term:`renderer` on a template. The dictionary the view returns (on line 6) provides the value the renderer -substitutes into the template when generating HTML. The renderer then -returns the HTML in a :term:`response`. +substitutes into the template when generating HTML. The renderer then returns +the HTML in a :term:`response`. .. note:: Dictionaries provide values to :term:`template`\s. @@ -863,8 +849,8 @@ returns the HTML in a :term:`response`. ` to aid debugging. If an exception is raised, uncaught tracebacks are displayed after the startup messages on :ref:`the console running the server `. Also - ``print()`` statements may be inserted into the application for debugging - to send output to this console. + ``print()`` statements may be inserted into the application for debugging to + send output to this console. .. note:: ``development.ini`` has a setting that controls how templates are reloaded, ``pyramid.reload_templates``. @@ -873,14 +859,14 @@ returns the HTML in a :term:`response`. templates automatically reload without a server restart. This is convenient while developing, but slows template rendering speed. - - When set to ``False`` (the default value), changing templates requires - a server restart to reload them. Production applications should use + - When set to ``False`` (the default value), changing templates requires a + server restart to reload them. Production applications should use ``pyramid.reload_templates = False``. .. seealso:: - See also :ref:`views_which_use_a_renderer` for more information - about how views, renderers, and templates relate and cooperate. + See also :ref:`views_which_use_a_renderer` for more information about how + views, renderers, and templates relate and cooperate. .. seealso:: @@ -908,8 +894,8 @@ template. It includes CSS and images. This is the single :term:`Chameleon` template that exists in the project. Its contents are too long to show here, but it displays a default page when -rendered. It is referenced by the call to ``@view_config`` as the -``renderer`` of the ``my_view`` view callable in the ``views.py`` file. See +rendered. It is referenced by the call to ``@view_config`` as the ``renderer`` +of the ``my_view`` view callable in the ``views.py`` file. See :ref:`views_which_use_a_renderer` for more information about renderers. Templates are accessed and used by view configurations and sometimes by view @@ -930,10 +916,9 @@ The ``tests.py`` module includes unit tests for your application. :linenos: This sample ``tests.py`` file has a single unit test defined within it. This -test is executed when you run ``python setup.py test``. You may add more -tests here as you build your application. You are not required to write -tests to use :app:`Pyramid`. This file is simply provided for convenience and -example. +test is executed when you run ``python setup.py test``. You may add more tests +here as you build your application. You are not required to write tests to use +:app:`Pyramid`. This file is simply provided for convenience and example. See :ref:`testing_chapter` for more information about writing :app:`Pyramid` unit tests. @@ -947,28 +932,27 @@ Modifying Package Structure --------------------------- It is best practice for your application's code layout to not stray too much -from accepted Pyramid scaffold defaults. If you refrain from changing -things very much, other Pyramid coders will be able to more quickly -understand your application. However, the code layout choices made for you -by a scaffold are in no way magical or required. Despite the choices -made for you by any scaffold, you can decide to lay your code out any -way you see fit. +from accepted Pyramid scaffold defaults. If you refrain from changing things +very much, other Pyramid coders will be able to more quickly understand your +application. However, the code layout choices made for you by a scaffold are +in no way magical or required. Despite the choices made for you by any +scaffold, you can decide to lay your code out any way you see fit. For example, the configuration method named :meth:`~pyramid.config.Configurator.add_view` requires you to pass a :term:`dotted Python name` or a direct object reference as the class or -function to be used as a view. By default, the ``starter`` scaffold would -have you add view functions to the ``views.py`` module in your package. -However, you might be more comfortable creating a ``views`` *directory*, and -adding a single file for each view. +function to be used as a view. By default, the ``starter`` scaffold would have +you add view functions to the ``views.py`` module in your package. However, you +might be more comfortable creating a ``views`` *directory*, and adding a single +file for each view. If your project package name was ``myproject`` and you wanted to arrange all your views in a Python subpackage within the ``myproject`` :term:`package` named ``views`` instead of within a single ``views.py`` file, you might do the following. -- Create a ``views`` directory inside your ``myproject`` package directory - (the same directory which holds ``views.py``). +- Create a ``views`` directory inside your ``myproject`` package directory (the + same directory which holds ``views.py``). - Create a file within the new ``views`` directory named ``__init__.py``. (It can be empty. This just tells Python that the ``views`` directory is a @@ -980,20 +964,19 @@ following. specification` values in ``blog.py`` must now be fully qualified with the project's package name (``myproject:templates/blog.pt``). -You can then continue to add view callable functions to the ``blog.py`` -module, but you can also add other ``.py`` files which contain view callable -functions to the ``views`` directory. As long as you use the -``@view_config`` directive to register views in conjunction with -``config.scan()``, they will be picked up automatically when the application is -restarted. +You can then continue to add view callable functions to the ``blog.py`` module, +but you can also add other ``.py`` files which contain view callable functions +to the ``views`` directory. As long as you use the ``@view_config`` directive +to register views in conjunction with ``config.scan()``, they will be picked up +automatically when the application is restarted. Using the Interactive Shell --------------------------- It is possible to use the ``pshell`` command to load a Python interpreter -prompt with a similar configuration as would be loaded if you were running -your Pyramid application via ``pserve``. This can be a useful debugging tool. -See :ref:`interactive_shell` for more details. +prompt with a similar configuration as would be loaded if you were running your +Pyramid application via ``pserve``. This can be a useful debugging tool. See +:ref:`interactive_shell` for more details. .. _what_is_this_pserve_thing: @@ -1022,30 +1005,29 @@ restarting of the server when code changes. Using an Alternate WSGI Server ------------------------------ -Pyramid scaffolds generate projects which use the :term:`Waitress` WSGI -server. Waitress is a server that is suited for development and light -production usage. It's not the fastest nor the most featureful WSGI server. -Instead, its main feature is that it works on all platforms that Pyramid -needs to run on, making it a good choice as a default server from the -perspective of Pyramid's developers. +Pyramid scaffolds generate projects which use the :term:`Waitress` WSGI server. +Waitress is a server that is suited for development and light production +usage. It's not the fastest nor the most featureful WSGI server. Instead, its +main feature is that it works on all platforms that Pyramid needs to run on, +making it a good choice as a default server from the perspective of Pyramid's +developers. Any WSGI server is capable of running a :app:`Pyramid` application. But we -suggest you stick with the default server for development, and that you wait -to investigate other server options until you're ready to deploy your -application to production. Unless for some reason you need to develop on a -non-local system, investigating alternate server options is usually a -distraction until you're ready to deploy. But we recommend developing using -the default configuration on a local system that you have complete control -over; it will provide the best development experience. +suggest you stick with the default server for development, and that you wait to +investigate other server options until you're ready to deploy your application +to production. Unless for some reason you need to develop on a non-local +system, investigating alternate server options is usually a distraction until +you're ready to deploy. But we recommend developing using the default +configuration on a local system that you have complete control over; it will +provide the best development experience. One popular production alternative to the default Waitress server is -:term:`mod_wsgi`. You can use mod_wsgi to serve your :app:`Pyramid` -application using the Apache web server rather than any "pure-Python" server -like Waitress. It is fast and featureful. See :ref:`modwsgi_tutorial` for -details. +:term:`mod_wsgi`. You can use mod_wsgi to serve your :app:`Pyramid` application +using the Apache web server rather than any "pure-Python" server like Waitress. +It is fast and featureful. See :ref:`modwsgi_tutorial` for details. Another good production alternative is :term:`Green Unicorn` (aka -``gunicorn``). It's faster than Waitress and slightly easier to configure -than mod_wsgi, although it depends, in its default configuration, on having a -buffering HTTP proxy in front of it. It does not, as of this writing, work -on Windows. +``gunicorn``). It's faster than Waitress and slightly easier to configure than +mod_wsgi, although it depends, in its default configuration, on having a +buffering HTTP proxy in front of it. It does not, as of this writing, work on +Windows. -- cgit v1.2.3 From 911882cb691df23747595dda679fbc54a58d06c2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Oct 2015 00:11:12 -0700 Subject: wrap 79 cols --- docs/narr/startup.rst | 95 +++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 49 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst index b8d3bfac9..485f6b181 100644 --- a/docs/narr/startup.rst +++ b/docs/narr/startup.rst @@ -12,9 +12,9 @@ you'll see something much like this show up on the console: Starting server in PID 16601. serving on 0.0.0.0:6543 view at 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. +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. .. index:: single: startup process @@ -26,9 +26,8 @@ The Startup Process The easiest and best-documented way to start and serve a :app:`Pyramid` application is to use the ``pserve`` command against a :term:`PasteDeploy` ``.ini`` file. This uses the ``.ini`` file to infer settings and starts a -server listening on a port. For the purposes of this discussion, we'll -assume that you are using this command to run your :app:`Pyramid` -application. +server listening on a port. For the purposes of this discussion, we'll assume +that you are using this command to run your :app:`Pyramid` application. Here's a high-level time-ordered overview of what happens when you press ``return`` after running ``pserve development.ini``. @@ -40,30 +39,29 @@ Here's a high-level time-ordered overview of what happens when you press #. The framework finds a section named either ``[app:main]``, ``[pipeline:main]``, or ``[composite:main]`` in the ``.ini`` file. This - section represents the configuration of a :term:`WSGI` application that - will be served. If you're using a simple application (e.g., - ``[app:main]``), the application's ``paste.app_factory`` :term:`entry - point` will be named on the ``use=`` line within the section's - configuration. If instead of a simple application, you're using a WSGI - :term:`pipeline` (e.g., a ``[pipeline:main]`` section), the application - named on the "last" element will refer to your :app:`Pyramid` application. - If instead of a simple application or a pipeline, you're using a - "composite" (e.g., ``[composite:main]``), refer to the documentation for - that particular composite to understand how to make it refer to your - :app:`Pyramid` application. In most cases, a Pyramid application built - from a scaffold will have a single ``[app:main]`` section in it, and this - will be the application served. - -#. The framework finds all :mod:`logging` related configuration in the - ``.ini`` file and uses it to configure the Python standard library logging - system for this application. See :ref:`logging_config` for more - information. + section represents the configuration of a :term:`WSGI` application that will + be served. If you're using a simple application (e.g., ``[app:main]``), the + application's ``paste.app_factory`` :term:`entry point` will be named on the + ``use=`` line within the section's configuration. If instead of a simple + application, you're using a WSGI :term:`pipeline` (e.g., a + ``[pipeline:main]`` section), the application named on the "last" element + will refer to your :app:`Pyramid` application. If instead of a simple + application or a pipeline, you're using a "composite" (e.g., + ``[composite:main]``), refer to the documentation for that particular + composite to understand how to make it refer to your :app:`Pyramid` + application. In most cases, a Pyramid application built from a scaffold + will have a single ``[app:main]`` section in it, and this will be the + application served. + +#. The framework finds all :mod:`logging` related configuration in the ``.ini`` + file and uses it to configure the Python standard library logging system for + this application. See :ref:`logging_config` for more information. #. The application's *constructor* named by the entry point referenced on the - ``use=`` line of the section representing your :app:`Pyramid` application - is passed the key/value parameters mentioned within the section in which - it's defined. The constructor is meant to return a :term:`router` - instance, which is a :term:`WSGI` application. + ``use=`` line of the section representing your :app:`Pyramid` application is + passed the key/value parameters mentioned within the section in which it's + defined. The constructor is meant to return a :term:`router` instance, + which is a :term:`WSGI` application. For :app:`Pyramid` applications, the constructor will be a function named ``main`` in the ``__init__.py`` file within the :term:`package` in which @@ -79,11 +77,11 @@ Here's a high-level time-ordered overview of what happens when you press which is a dictionary of key/value pairs mentioned in the ``[DEFAULT]`` section of an ``.ini`` file (if :ref:`[DEFAULT] ` is present). It also accepts a - ``**settings`` argument, which collects another set of arbitrary - key/value pairs. The arbitrary key/value pairs received by this function in - ``**settings`` will be composed of all the key/value pairs that are - present in the ``[app:main]`` section (except for the ``use=`` setting) - when this function is called when you run ``pserve``. + ``**settings`` argument, which collects another set of arbitrary key/value + pairs. The arbitrary key/value pairs received by this function in + ``**settings`` will be composed of all the key/value pairs that are present + in the ``[app:main]`` section (except for the ``use=`` setting) when this + function is called when you run ``pserve``. Our generated ``development.ini`` file looks like so: @@ -93,8 +91,8 @@ 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', + 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 @@ -112,13 +110,13 @@ Here's a high-level time-ordered overview of what happens when you press #. The ``main`` function then calls various methods on the instance of the class :class:`~pyramid.config.Configurator` created in the previous step. - The intent of calling these methods is to populate an - :term:`application registry`, which represents the :app:`Pyramid` - configuration related to the application. + The intent of calling these methods is to populate an :term:`application + registry`, which represents the :app:`Pyramid` configuration related to the + application. -#. The :meth:`~pyramid.config.Configurator.make_wsgi_app` method is called. - The result is a :term:`router` instance. The router is associated with - the :term:`application registry` implied by the configurator previously +#. The :meth:`~pyramid.config.Configurator.make_wsgi_app` method is called. The + result is a :term:`router` instance. The router is associated with the + :term:`application registry` implied by the configurator previously populated by other methods run against the Configurator. The router is a WSGI application. @@ -140,9 +138,9 @@ Here's a high-level time-ordered overview of what happens when you press .. seealso:: Logging configuration is described in the :ref:`logging_chapter` chapter. - There, in :ref:`request_logging_with_pastes_translogger`, you will also - find an example of how to configure :term:`middleware` to add - pre-packaged functionality to your application. + There, in :ref:`request_logging_with_pastes_translogger`, you will also find + an example of how to configure :term:`middleware` to add pre-packaged + functionality to your application. .. index:: pair: settings; deployment @@ -155,8 +153,7 @@ Deployment Settings Note that an augmented version of the values passed as ``**settings`` to the :class:`~pyramid.config.Configurator` constructor will be available in -:app:`Pyramid` :term:`view callable` code as ``request.registry.settings``. -You can create objects you wish to access later from view code, and put them -into the dictionary you pass to the configurator as ``settings``. They will -then be present in the ``request.registry.settings`` dictionary at -application runtime. +:app:`Pyramid` :term:`view callable` code as ``request.registry.settings``. You +can create objects you wish to access later from view code, and put them into +the dictionary you pass to the configurator as ``settings``. They will then be +present in the ``request.registry.settings`` dictionary at application runtime. -- cgit v1.2.3 From abbe5040cf337c9224d356e6c0d637a6e995b6b7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Oct 2015 00:21:09 -0700 Subject: wrap 79 cols (cherry picked from commit 703b958) --- docs/narr/router.rst | 64 +++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/router.rst b/docs/narr/router.rst index 7037afcec..e02142e6e 100644 --- a/docs/narr/router.rst +++ b/docs/narr/router.rst @@ -35,41 +35,40 @@ request enters a :app:`Pyramid` application through to the point that #. A :class:`~pyramid.events.NewRequest` :term:`event` is sent to any subscribers. -#. If any :term:`route` has been defined within application configuration, - the :app:`Pyramid` :term:`router` calls a :term:`URL dispatch` "route - mapper." The job of the mapper is to examine the request to determine - whether any user-defined :term:`route` matches the current WSGI - environment. The :term:`router` passes the request as an argument to the - mapper. +#. If any :term:`route` has been defined within application configuration, the + :app:`Pyramid` :term:`router` calls a :term:`URL dispatch` "route mapper." + The job of the mapper is to examine the request to determine whether any + user-defined :term:`route` matches the current WSGI environment. The + :term:`router` passes the request as an argument to the mapper. #. If any route matches, the route mapper adds attributes to the request: ``matchdict`` and ``matched_route`` attributes are added to the request 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: 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 + matched. 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 :app:`Pyramid` router calls a "traverser" function with the root - object and the request. The traverser function attempts to traverse the - root object (using any existing ``__getitem__`` on the root object and +#. The :app:`Pyramid` router calls a "traverser" function with the root object + and the request. The traverser function attempts to traverse the root + object (using any existing ``__getitem__`` on the root object and subobjects) to find a :term:`context`. If the root object has no - ``__getitem__`` method, the root itself is assumed to be the context. The + ``__getitem__`` method, the root itself is assumed to be the context. The exact traversal algorithm is described in :ref:`traversal_chapter`. The traverser function returns a dictionary, which contains a :term:`context` and a :term:`view name` as well as other ancillary information. #. The request is decorated with various names returned from the traverser - (such as ``context``, ``view_name``, and so forth), so they can be - accessed via, for example, ``request.context`` within :term:`view` code. + (such as ``context``, ``view_name``, and so forth), so they can be accessed + via, for example, ``request.context`` within :term:`view` code. #. A :class:`~pyramid.events.ContextFound` :term:`event` is sent to any subscribers. @@ -87,8 +86,8 @@ request enters a :app:`Pyramid` application through to the point that protected by a :term:`permission`, :app:`Pyramid` determines whether the view callable being asked for can be executed by the requesting user based on credential information in the request and security information attached - to the context. If the view execution is allowed, :app:`Pyramid` calls - the view callable to obtain a response. If view execution is forbidden, + to the context. If the view execution is allowed, :app:`Pyramid` calls the + view callable to obtain a response. If view execution is forbidden, :app:`Pyramid` raises a :class:`~pyramid.httpexceptions.HTTPForbidden` exception. @@ -97,17 +96,16 @@ request enters a :app:`Pyramid` application through to the point that (such as when it raises :class:`~pyramid.httpexceptions.HTTPNotFound` or :class:`~pyramid.httpexceptions.HTTPForbidden`), the router catches the exception, and attaches it to the request as the ``exception`` attribute. - It then attempts to find a :term:`exception view` for the exception that - was caught. If it finds an exception view callable, that callable is - called, and is presumed to generate a response. If an :term:`exception - view` that matches the exception cannot be found, the exception is - reraised. - -#. The following steps occur only when a :term:`response` could be - successfully generated by a normal :term:`view callable` or an - :term:`exception view` callable. :app:`Pyramid` will attempt to execute - any :term:`response callback` functions attached via - :meth:`~pyramid.request.Request.add_response_callback`. A + It then attempts to find a :term:`exception view` for the exception that was + caught. If it finds an exception view callable, that callable is called, + and is presumed to generate a response. If an :term:`exception view` that + matches the exception cannot be found, the exception is reraised. + +#. The following steps occur only when a :term:`response` could be successfully + generated by a normal :term:`view callable` or an :term:`exception view` + callable. :app:`Pyramid` will attempt to execute any :term:`response + callback` functions attached via + :meth:`~pyramid.request.Request.add_response_callback`. A :class:`~pyramid.events.NewResponse` :term:`event` is then sent to any subscribers. The response object's ``__call__`` method is then used to generate a WSGI response. The response is sent back to the upstream WSGI -- cgit v1.2.3 From b8ceb465f08956b7ed594ef9d14940f8126eb37e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Oct 2015 23:40:59 -0700 Subject: minor grammar, wrap 79 cols --- docs/narr/views.rst | 296 +++++++++++++++++++++++++--------------------------- 1 file changed, 145 insertions(+), 151 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/views.rst b/docs/narr/views.rst index a746eb043..770d27919 100644 --- a/docs/narr/views.rst +++ b/docs/narr/views.rst @@ -4,23 +4,22 @@ Views ===== One of the primary jobs of :app:`Pyramid` is to find and invoke a :term:`view -callable` when a :term:`request` reaches your application. View callables -are bits of code which do something interesting in response to a request made -to your application. They are the "meat" of any interesting web application. +callable` when a :term:`request` reaches your application. View callables are +bits of code which do something interesting in response to a request made to +your application. They are the "meat" of any interesting web application. -.. note:: +.. note:: A :app:`Pyramid` :term:`view callable` is often referred to in - conversational shorthand as a :term:`view`. In this documentation, - however, we need to use less ambiguous terminology because there - are significant differences between view *configuration*, the code - that implements a view *callable*, and the process of view - *lookup*. + conversational shorthand as a :term:`view`. In this documentation, however, + we need to use less ambiguous terminology because there are significant + differences between view *configuration*, the code that implements a view + *callable*, and the process of view *lookup*. -This chapter describes how view callables should be defined. We'll have to -wait until a following chapter (entitled :ref:`view_config_chapter`) to find -out how we actually tell :app:`Pyramid` to wire up view callables to -particular URL patterns and other request circumstances. +This chapter describes how view callables should be defined. We'll have to wait +until a following chapter (entitled :ref:`view_config_chapter`) to find out how +we actually tell :app:`Pyramid` to wire up view callables to particular URL +patterns and other request circumstances. .. index:: single: view callables @@ -28,21 +27,21 @@ particular URL patterns and other request circumstances. View Callables -------------- -View callables are, at the risk of sounding obvious, callable Python -objects. Specifically, view callables can be functions, classes, or instances -that implement a ``__call__`` method (making the instance callable). +View callables are, at the risk of sounding obvious, callable Python objects. +Specifically, view callables can be functions, classes, or instances that +implement a ``__call__`` method (making the instance callable). -View callables must, at a minimum, accept a single argument named -``request``. This argument represents a :app:`Pyramid` :term:`Request` -object. A request object represents a :term:`WSGI` environment provided to -:app:`Pyramid` by the upstream WSGI server. As you might expect, the request -object contains everything your application needs to know about the specific -HTTP request being made. +View callables must, at a minimum, accept a single argument named ``request``. +This argument represents a :app:`Pyramid` :term:`Request` object. A request +object represents a :term:`WSGI` environment provided to :app:`Pyramid` by the +upstream WSGI server. As you might expect, the request object contains +everything your application needs to know about the specific HTTP request being +made. A view callable's ultimate responsibility is to create a :app:`Pyramid` -:term:`Response` object. This can be done by creating a :term:`Response` -object in the view callable code and returning it directly or by raising -special kinds of exceptions from within the body of a view callable. +:term:`Response` object. This can be done by creating a :term:`Response` object +in the view callable code and returning it directly or by raising special kinds +of exceptions from within the body of a view callable. .. index:: single: view calling convention @@ -76,17 +75,17 @@ Defining a View Callable as a Class ----------------------------------- A view callable may also be represented by a Python class instead of a -function. When a view callable is a class, the calling semantics are -slightly different than when it is a function or another non-class callable. -When a view callable is a class, the class' ``__init__`` method is called with a +function. When a view callable is a class, the calling semantics are slightly +different than when it is a function or another non-class callable. When a view +callable is a class, the class's ``__init__`` method is called with a ``request`` parameter. As a result, an instance of the class is created. Subsequently, that instance's ``__call__`` method is invoked with no -parameters. Views defined as classes must have the following traits: +parameters. Views defined as classes must have the following traits. -- an ``__init__`` method that accepts a ``request`` argument. +- an ``__init__`` method that accepts a ``request`` argument -- a ``__call__`` (or other) method that accepts no parameters and which - returns a response. +- a ``__call__`` (or other) method that accepts no parameters and which returns + a response For example: @@ -106,12 +105,12 @@ The request object passed to ``__init__`` is the same type of request object described in :ref:`function_as_view`. If you'd like to use a different attribute than ``__call__`` to represent the -method expected to return a response, you can use an ``attr`` value as part -of the configuration for the view. See :ref:`view_configuration_parameters`. -The same view callable class can be used in different view configuration -statements with different ``attr`` values, each pointing at a different -method of the class if you'd like the class to represent a collection of -related view callables. +method expected to return a response, you can use an ``attr`` value as part of +the configuration for the view. See :ref:`view_configuration_parameters`. The +same view callable class can be used in different view configuration statements +with different ``attr`` values, each pointing at a different method of the +class if you'd like the class to represent a collection of related view +callables. .. index:: single: view response @@ -135,11 +134,11 @@ implements the :term:`Response` interface is to return a def view(request): return Response('OK') -:app:`Pyramid` provides a range of different "exception" classes which -inherit from :class:`pyramid.response.Response`. For example, an instance of -the class :class:`pyramid.httpexceptions.HTTPFound` is also a valid response -object because it inherits from :class:`~pyramid.response.Response`. For -examples, see :ref:`http_exceptions` and :ref:`http_redirect`. +:app:`Pyramid` provides a range of different "exception" classes which inherit +from :class:`pyramid.response.Response`. For example, an instance of the class +:class:`pyramid.httpexceptions.HTTPFound` is also a valid response object +because it inherits from :class:`~pyramid.response.Response`. For examples, +see :ref:`http_exceptions` and :ref:`http_redirect`. .. note:: @@ -155,7 +154,7 @@ examples, see :ref:`http_exceptions` and :ref:`http_redirect`. .. _special_exceptions_in_callables: -Using Special Exceptions In View Callables +Using Special Exceptions in View Callables ------------------------------------------ Usually when a Python exception is raised within a view callable, @@ -176,14 +175,14 @@ exception` objects. HTTP Exceptions ~~~~~~~~~~~~~~~ -All :mod:`pyramid.httpexceptions` classes which are documented -as inheriting from the :class:`pyramid.httpexceptions.HTTPException` are -:term:`http exception` objects. Instances of an HTTP exception object may -either be *returned* or *raised* from within view code. In either case -(return or raise) the instance will be used as the view's response. +All :mod:`pyramid.httpexceptions` classes which are documented as inheriting +from the :class:`pyramid.httpexceptions.HTTPException` are :term:`http +exception` objects. Instances of an HTTP exception object may either be +*returned* or *raised* from within view code. In either case (return or raise) +the instance will be used as the view's response. -For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception -can be raised. This will cause a response to be generated with a ``401 +For example, the :class:`pyramid.httpexceptions.HTTPUnauthorized` exception can +be raised. This will cause a response to be generated with a ``401 Unauthorized`` status: .. code-block:: python @@ -194,8 +193,8 @@ Unauthorized`` status: def aview(request): raise HTTPUnauthorized() -An HTTP exception, instead of being raised, can alternately be *returned* -(HTTP exceptions are also valid response objects): +An HTTP exception, instead of being raised, can alternately be *returned* (HTTP +exceptions are also valid response objects): .. code-block:: python :linenos: @@ -207,11 +206,11 @@ An HTTP exception, instead of being raised, can alternately be *returned* A shortcut for creating an HTTP exception is the :func:`pyramid.httpexceptions.exception_response` function. This function -accepts an HTTP status code and returns the corresponding HTTP exception. -For example, instead of importing and constructing a -:class:`~pyramid.httpexceptions.HTTPUnauthorized` response object, you can -use the :func:`~pyramid.httpexceptions.exception_response` function to -construct and return the same object. +accepts an HTTP status code and returns the corresponding HTTP exception. For +example, instead of importing and constructing a +:class:`~pyramid.httpexceptions.HTTPUnauthorized` response object, you can use +the :func:`~pyramid.httpexceptions.exception_response` function to construct +and return the same object. .. code-block:: python :linenos: @@ -223,8 +222,8 @@ construct and return the same object. This is the case because ``401`` is the HTTP status code for "HTTP Unauthorized". Therefore, ``raise exception_response(401)`` is functionally -equivalent to ``raise HTTPUnauthorized()``. Documentation which maps each -HTTP response code to its purpose and its associated HTTP exception object is +equivalent to ``raise HTTPUnauthorized()``. Documentation which maps each HTTP +response code to its purpose and its associated HTTP exception object is provided within :mod:`pyramid.httpexceptions`. .. versionadded:: 1.1 @@ -233,22 +232,22 @@ provided within :mod:`pyramid.httpexceptions`. How Pyramid Uses HTTP Exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -HTTP exceptions are meant to be used directly by application -developers. However, Pyramid itself will raise two HTTP exceptions at -various points during normal operations: +HTTP exceptions are meant to be used directly by application developers. +However, Pyramid itself will raise two HTTP exceptions at various points during +normal operations. -* :exc:`~pyramid.httpexceptions.HTTPNotFound` - gets raised when a view to service a request is not found. -* :exc:`~pyramid.httpexceptions.HTTPForbidden` - gets raised when authorization was forbidden by a security policy. +* :exc:`~pyramid.httpexceptions.HTTPNotFound` gets raised when a view to + service a request is not found. +* :exc:`~pyramid.httpexceptions.HTTPForbidden` gets raised when authorization + was forbidden by a security policy. If :exc:`~pyramid.httpexceptions.HTTPNotFound` is raised by Pyramid itself or -within view code, the result of the :term:`Not Found View` will be returned -to the user agent which performed the request. +within view code, the result of the :term:`Not Found View` will be returned to +the user agent which performed the request. If :exc:`~pyramid.httpexceptions.HTTPForbidden` is raised by Pyramid itself -within view code, the result of the :term:`Forbidden View` will be returned -to the user agent which performed the request. +within view code, the result of the :term:`Forbidden View` will be returned to +the user agent which performed the request. .. index:: single: exception views @@ -266,7 +265,7 @@ responses. To register a view that should be called whenever a particular exception is raised from within :app:`Pyramid` view code, use the exception class (or one of its superclasses) as the :term:`context` of a view configuration which points -at a view callable you'd like to generate a response for. +at a view callable for which you'd like to generate a response. For example, given the following exception class in a module named ``helloworld.exceptions``: @@ -300,8 +299,8 @@ view callable will be invoked whenever a view code. The same exception raised by a custom root factory, a custom traverser, or a custom view or route predicate is also caught and hooked. -Other normal view predicates can also be used in combination with an -exception view registration: +Other normal view predicates can also be used in combination with an exception +view registration: .. code-block:: python :linenos: @@ -315,24 +314,24 @@ exception view registration: response.status_int = 500 return response -The above exception view names the ``route_name`` of ``home``, meaning that -it will only be called when the route matched has a name of ``home``. You -can therefore have more than one exception view for any given exception in -the system: the "most specific" one will be called when the set of request +The above exception view names the ``route_name`` of ``home``, meaning that it +will only be called when the route matched has a name of ``home``. You can +therefore have more than one exception view for any given exception in the +system: the "most specific" one will be called when the set of request circumstances match the view registration. -The only view predicate that cannot be used successfully when creating -an exception view configuration is ``name``. The name used to look up -an exception view is always the empty string. Views registered as -exception views which have a name will be ignored. +The only view predicate that cannot be used successfully when creating an +exception view configuration is ``name``. The name used to look up an +exception view is always the empty string. Views registered as exception views +which have a name will be ignored. .. note:: - Normal (i.e., non-exception) views registered against a context resource - type which inherits from :exc:`Exception` will work normally. When an - exception view configuration is processed, *two* views are registered. One - as a "normal" view, the other as an "exception" view. This means that you - can use an exception as ``context`` for a normal view. + Normal (i.e., non-exception) views registered against a context resource type + which inherits from :exc:`Exception` will work normally. When an exception + view configuration is processed, *two* views are registered. One as a + "normal" view, the other as an "exception" view. This means that you can use + an exception as ``context`` for a normal view. Exception views can be configured with any view registration mechanism: ``@view_config`` decorator or imperative ``add_view`` styles. @@ -340,9 +339,9 @@ Exception views can be configured with any view registration mechanism: .. note:: Pyramid's :term:`exception view` handling logic is implemented as a tween - factory function: :func:`pyramid.tweens.excview_tween_factory`. If - Pyramid exception view handling is desired, and tween factories are - specified via the ``pyramid.tweens`` configuration setting, the + factory function: :func:`pyramid.tweens.excview_tween_factory`. If Pyramid + exception view handling is desired, and tween factories are specified via + the ``pyramid.tweens`` configuration setting, the :func:`pyramid.tweens.excview_tween_factory` function must be added to the ``pyramid.tweens`` configuration setting list explicitly. If it is not present, Pyramid will not perform exception view handling. @@ -358,11 +357,9 @@ Using a View Callable to do an HTTP Redirect You can issue an HTTP redirect by using the :class:`pyramid.httpexceptions.HTTPFound` class. Raising or returning an -instance of this class will cause the client to receive a "302 Found" -response. +instance of this class will cause the client to receive a "302 Found" response. -To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` -instance. +To do so, you can *return* a :class:`pyramid.httpexceptions.HTTPFound` instance. .. code-block:: python :linenos: @@ -400,32 +397,31 @@ submission data using the :term:`WebOb` API, see :ref:`webob_chapter` and `"Query and POST variables" within the WebOb documentation `_. :app:`Pyramid` defers to WebOb for its request and response implementations, -and handling form submission data is a property of the request -implementation. Understanding WebOb's request API is the key to -understanding how to process form submission data. - -There are some defaults that you need to be aware of when trying to handle -form submission data in a :app:`Pyramid` view. Having high-order (i.e., -non-ASCII) characters in data contained within form submissions is -exceedingly common, and the UTF-8 encoding is the most common encoding used -on the web for character data. Since Unicode values are much saner than -working with and storing bytestrings, :app:`Pyramid` configures the -:term:`WebOb` request machinery to attempt to decode form submission values -into Unicode from UTF-8 implicitly. This implicit decoding happens when view -code obtains form field values via the ``request.params``, ``request.GET``, -or ``request.POST`` APIs (see :ref:`request_module` for details about these -APIs). +and handling form submission data is a property of the request implementation. +Understanding WebOb's request API is the key to understanding how to process +form submission data. + +There are some defaults that you need to be aware of when trying to handle form +submission data in a :app:`Pyramid` view. Having high-order (i.e., non-ASCII) +characters in data contained within form submissions is exceedingly common, and +the UTF-8 encoding is the most common encoding used on the web for character +data. Since Unicode values are much saner than working with and storing +bytestrings, :app:`Pyramid` configures the :term:`WebOb` request machinery to +attempt to decode form submission values into Unicode from UTF-8 implicitly. +This implicit decoding happens when view code obtains form field values via the +``request.params``, ``request.GET``, or ``request.POST`` APIs (see +:ref:`request_module` for details about these APIs). .. note:: - Many people find the difference between Unicode and UTF-8 confusing. - Unicode is a standard for representing text that supports most of the - world's writing systems. However, there are many ways that Unicode data - can be encoded into bytes for transit and storage. UTF-8 is a specific - encoding for Unicode, that is backwards-compatible with ASCII. This makes - UTF-8 very convenient for encoding data where a large subset of that data - is ASCII characters, which is largely true on the web. UTF-8 is also the - standard character encoding for URLs. + Many people find the difference between Unicode and UTF-8 confusing. Unicode + is a standard for representing text that supports most of the world's + writing systems. However, there are many ways that Unicode data can be + encoded into bytes for transit and storage. UTF-8 is a specific encoding for + Unicode that is backwards-compatible with ASCII. This makes UTF-8 very + convenient for encoding data where a large subset of that data is ASCII + characters, which is largely true on the web. UTF-8 is also the standard + character encoding for URLs. As an example, let's assume that the following form page is served up to a browser client, and its ``action`` points at some :app:`Pyramid` view code: @@ -450,8 +446,8 @@ browser client, and its ``action`` points at some :app:`Pyramid` view code: The ``myview`` view code in the :app:`Pyramid` application *must* expect that the values returned by ``request.params`` will be of type ``unicode``, as -opposed to type ``str``. The following will work to accept a form post from -the above form: +opposed to type ``str``. The following will work to accept a form post from the +above form: .. code-block:: python :linenos: @@ -479,31 +475,31 @@ encoding of UTF-8. This can be done via a response that has a with a ``meta http-equiv`` tag that implies that the charset is UTF-8 within the HTML ``head`` of the page containing the form. This must be done explicitly because all known browser clients assume that they should encode -form data in the same character set implied by ``Content-Type`` value of the -response containing the form when subsequently submitting that form. There is -no other generally accepted way to tell browser clients which charset to use -to encode form data. If you do not specify an encoding explicitly, the -browser client will choose to encode form data in its default character set -before submitting it, which may not be UTF-8 as the server expects. If a -request containing form data encoded in a non-UTF8 charset is handled by your -view code, eventually the request code accessed within your view will throw -an error when it can't decode some high-order character encoded in another -character set within form data, e.g., when ``request.params['somename']`` is -accessed. +form data in the same character set implied by the ``Content-Type`` value of +the response containing the form when subsequently submitting that form. There +is no other generally accepted way to tell browser clients which charset to use +to encode form data. If you do not specify an encoding explicitly, the browser +client will choose to encode form data in its default character set before +submitting it, which may not be UTF-8 as the server expects. If a request +containing form data encoded in a non-UTF-8 ``charset`` is handled by your view +code, eventually the request code accessed within your view will throw an error +when it can't decode some high-order character encoded in another character set +within form data, e.g., when ``request.params['somename']`` is accessed. If you are using the :class:`~pyramid.response.Response` class to generate a response, or if you use the ``render_template_*`` templating APIs, the UTF-8 -charset is set automatically as the default via the ``Content-Type`` header. -If you return a ``Content-Type`` header without an explicit charset, a -request will add a ``;charset=utf-8`` trailer to the ``Content-Type`` header -value for you, for response content types that are textual -(e.g. ``text/html``, ``application/xml``, etc) as it is rendered. If you are -using your own response object, you will need to ensure you do this yourself. +``charset`` is set automatically as the default via the ``Content-Type`` +header. If you return a ``Content-Type`` header without an explicit +``charset``, a request will add a ``;charset=utf-8`` trailer to the +``Content-Type`` header value for you for response content types that are +textual (e.g., ``text/html`` or ``application/xml``) as it is rendered. If you +are using your own response object, you will need to ensure you do this +yourself. -.. note:: Only the *values* of request params obtained via - ``request.params``, ``request.GET`` or ``request.POST`` are decoded - to Unicode objects implicitly in the :app:`Pyramid` default - configuration. The keys are still (byte) strings. +.. note:: Only the *values* of request params obtained via ``request.params``, + ``request.GET`` or ``request.POST`` are decoded to Unicode objects + implicitly in the :app:`Pyramid` default configuration. The keys are still + (byte) strings. .. index:: @@ -514,7 +510,7 @@ using your own response object, you will need to ensure you do this yourself. Alternate View Callable Argument/Calling Conventions ---------------------------------------------------- -Usually, view callables are defined to accept only a single argument: +Usually view callables are defined to accept only a single argument: ``request``. However, view callables may alternately be defined as classes, functions, or any callable that accept *two* positional arguments: a :term:`context` resource as the first argument and a :term:`request` as the @@ -532,8 +528,7 @@ request The following types work as view callables in this style: -#. Functions that accept two arguments: ``context``, and ``request``, - e.g.: +#. Functions that accept two arguments: ``context`` and ``request``, e.g.: .. code-block:: python :linenos: @@ -543,8 +538,8 @@ The following types work as view callables in this style: def view(context, request): return Response('OK') -#. Classes that have an ``__init__`` method that accepts ``context, - request`` and a ``__call__`` method which accepts no arguments, e.g.: +#. Classes that have an ``__init__`` method that accepts ``context, request``, + and a ``__call__`` method which accepts no arguments, e.g.: .. code-block:: python :linenos: @@ -559,8 +554,8 @@ The following types work as view callables in this style: def __call__(self): return Response('OK') -#. Arbitrary callables that have a ``__call__`` method that accepts - ``context, request``, e.g.: +#. Arbitrary callables that have a ``__call__`` method that accepts ``context, + request``, e.g.: .. code-block:: python :linenos: @@ -597,7 +592,6 @@ Pylons-1.0-Style "Controller" Dispatch -------------------------------------- A package named :term:`pyramid_handlers` (available from PyPI) provides an -analogue of :term:`Pylons` -style "controllers", which are a special kind of -view class which provides more automation when your application uses -:term:`URL dispatch` solely. - +analogue of :term:`Pylons`-style "controllers", which are a special kind of +view class which provides more automation when your application uses :term:`URL +dispatch` solely. -- cgit v1.2.3 From 3c966ca70dc1259a1a524ff524a4120011b2fcc1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 10 Oct 2015 00:52:07 -0700 Subject: minor grammar, wrap 79 cols --- docs/narr/renderers.rst | 321 +++++++++++++++++++++++------------------------- 1 file changed, 156 insertions(+), 165 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index 4f8c4bf77..cc5baf05e 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -5,8 +5,8 @@ Renderers A view callable needn't *always* return a :term:`Response` object. If a view happens to return something which does not implement the Pyramid Response -interface, :app:`Pyramid` will attempt to use a :term:`renderer` to construct -a response. For example: +interface, :app:`Pyramid` will attempt to use a :term:`renderer` to construct a +response. For example: .. code-block:: python :linenos: @@ -17,27 +17,26 @@ a response. For example: def hello_world(request): return {'content':'Hello!'} -The above example returns a *dictionary* from the view callable. A -dictionary does not implement the Pyramid response interface, so you might -believe that this example would fail. However, since a ``renderer`` is -associated with the view callable through its :term:`view configuration` (in -this case, using a ``renderer`` argument passed to -:func:`~pyramid.view.view_config`), if the view does *not* return a Response -object, the renderer will attempt to convert the result of the view to a -response on the developer's behalf. +The above example returns a *dictionary* from the view callable. A dictionary +does not implement the Pyramid response interface, so you might believe that +this example would fail. However, since a ``renderer`` is associated with the +view callable through its :term:`view configuration` (in this case, using a +``renderer`` argument passed to :func:`~pyramid.view.view_config`), if the view +does *not* return a Response object, the renderer will attempt to convert the +result of the view to a response on the developer's behalf. -Of course, if no renderer is associated with a view's configuration, -returning anything except an object which implements the Response interface -will result in an error. And, if a renderer *is* used, whatever is returned -by the view must be compatible with the particular kind of renderer used, or -an error may occur during view invocation. +Of course, if no renderer is associated with a view's configuration, returning +anything except an object which implements the Response interface will result +in an error. And, if a renderer *is* used, whatever is returned by the view +must be compatible with the particular kind of renderer used, or an error may +occur during view invocation. -One exception exists: it is *always* OK to return a Response object, even -when a ``renderer`` is configured. In such cases, the renderer is -bypassed entirely. +One exception exists: it is *always* OK to return a Response object, even when +a ``renderer`` is configured. In such cases, the renderer is bypassed +entirely. -Various types of renderers exist, including serialization renderers -and renderers which use templating systems. +Various types of renderers exist, including serialization renderers and +renderers which use templating systems. .. index:: single: renderer @@ -49,19 +48,19 @@ Writing View Callables Which Use a Renderer ------------------------------------------- As we've seen, a view callable needn't always return a Response object. -Instead, it may return an arbitrary Python object, with the expectation that -a :term:`renderer` will convert that object into a response instance on your -behalf. Some renderers use a templating system; other renderers use object -serialization techniques. In practice, renderers obtain application data -values from Python dictionaries so, in practice, view callables which use +Instead, it may return an arbitrary Python object, with the expectation that a +:term:`renderer` will convert that object into a response instance on your +behalf. Some renderers use a templating system, while other renderers use +object serialization techniques. In practice, renderers obtain application +data values from Python dictionaries so, in practice, view callables which use renderers return Python dictionaries. View callables can :ref:`explicitly call ` renderers, but typically don't. Instead view configuration declares the renderer used to render a view callable's results. This is done with the ``renderer`` attribute. For example, this call to -:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` -renderer with a view callable: +:meth:`~pyramid.config.Configurator.add_view` associates the ``json`` renderer +with a view callable: .. code-block:: python @@ -71,19 +70,19 @@ When this configuration is added to an application, the ``myproject.views.my_view`` view callable will now use a ``json`` renderer, which renders view return values to a :term:`JSON` response serialization. -Pyramid defines several :ref:`built_in_renderers`, and additional renderers -can be added by developers to the system as necessary. -See :ref:`adding_and_overriding_renderers`. +Pyramid defines several :ref:`built_in_renderers`, and additional renderers can +be added by developers to the system as necessary. See +:ref:`adding_and_overriding_renderers`. Views which use a renderer and return a non-Response value can vary non-body response attributes (such as headers and the HTTP status code) by attaching a -property to the ``request.response`` attribute. -See :ref:`request_response_attr`. +property to the ``request.response`` attribute. See +:ref:`request_response_attr`. As already mentioned, if the :term:`view callable` associated with a -:term:`view configuration` returns a Response object (or its instance), -any renderer associated with the view configuration is ignored, -and the response is passed back to :app:`Pyramid` unchanged. For example: +:term:`view configuration` returns a Response object (or its instance), any +renderer associated with the view configuration is ignored, and the response is +passed back to :app:`Pyramid` unchanged. For example: .. code-block:: python :linenos: @@ -126,7 +125,7 @@ avoid rendering: .. _built_in_renderers: -Built-In Renderers +Built-in Renderers ------------------ Several built-in renderers exist in :app:`Pyramid`. These renderers can be @@ -134,8 +133,8 @@ used in the ``renderer`` attribute of view configurations. .. note:: - Bindings for officially supported templating languages can be found - at :ref:`available_template_system_bindings`. + Bindings for officially supported templating languages can be found at + :ref:`available_template_system_bindings`. .. index:: pair: renderer; string @@ -143,17 +142,15 @@ used in the ``renderer`` attribute of view configurations. ``string``: String Renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``string`` renderer renders a view callable result to -a string. If a view callable returns a non-Response object, and the -``string`` renderer is associated in that view's configuration, the result -will be to run the object through the Python ``str`` function to generate a -string. Note that if a Unicode object is returned by the view callable, it -is not ``str()`` -ified. +The ``string`` renderer renders a view callable result to a string. If a view +callable returns a non-Response object, and the ``string`` renderer is +associated in that view's configuration, the result will be to run the object +through the Python ``str`` function to generate a string. Note that if a +Unicode object is returned by the view callable, it is not ``str()``-ified. Here's an example of a view that returns a dictionary. If the ``string`` -renderer is specified in the configuration for this view, the view will -render the returned dictionary to the ``str()`` representation of the -dictionary: +renderer is specified in the configuration for this view, the view will render +the returned dictionary to the ``str()`` representation of the dictionary: .. code-block:: python :linenos: @@ -164,8 +161,8 @@ dictionary: def hello_world(request): return {'content':'Hello!'} -The body of the response returned by such a view will be a string -representing the ``str()`` serialization of the return value: +The body of the response returned by such a view will be a string representing +the ``str()`` serialization of the return value: .. code-block:: python @@ -184,13 +181,13 @@ JSON Renderer ~~~~~~~~~~~~~ The ``json`` renderer renders view callable results to :term:`JSON`. By -default, it passes the return value through the ``json.dumps`` standard -library function, and wraps the result in a response object. It also sets -the response content-type to ``application/json``. +default, it passes the return value through the ``json.dumps`` standard library +function, and wraps the result in a response object. It also sets the response +content-type to ``application/json``. Here's an example of a view that returns a dictionary. Since the ``json`` -renderer is specified in the configuration for this view, the view will -render the returned dictionary to a JSON serialization: +renderer is specified in the configuration for this view, the view will render +the returned dictionary to a JSON serialization: .. code-block:: python :linenos: @@ -201,8 +198,8 @@ render the returned dictionary to a JSON serialization: def hello_world(request): return {'content':'Hello!'} -The body of the response returned by such a view will be a string -representing the JSON serialization of the return value: +The body of the response returned by such a view will be a string representing +the JSON serialization of the return value: .. code-block:: python @@ -211,8 +208,8 @@ representing the JSON serialization of the return value: The return value needn't be a dictionary, but the return value must contain values serializable by the configured serializer (by default ``json.dumps``). -You can configure a view to use the JSON renderer by naming``json`` as the -``renderer`` argument of a view configuration, e.g. by using +You can configure a view to use the JSON renderer by naming ``json`` as the +``renderer`` argument of a view configuration, e.g., by using :meth:`~pyramid.config.Configurator.add_view`: .. code-block:: python @@ -224,7 +221,7 @@ You can configure a view to use the JSON renderer by naming``json`` as the renderer='json') Views which use the JSON renderer can vary non-body response attributes by -using the api of the ``request.response`` attribute. See +using the API of the ``request.response`` attribute. See :ref:`request_response_attr`. .. _json_serializing_custom_objects: @@ -232,23 +229,23 @@ using the api of the ``request.response`` attribute. See Serializing Custom Objects ++++++++++++++++++++++++++ -Some objects are not, by default, JSON-serializable (such as datetimes and -other arbitrary Python objects). You can, however, register code that makes +Some objects are not, by default, JSON-serializable (such as datetimes and +other arbitrary Python objects). You can, however, register code that makes non-serializable objects serializable in two ways: -- By defining a ``__json__`` method on objects in your application. +- Define a ``__json__`` method on objects in your application. -- For objects you don't "own", you can register JSON renderer that knows about - an *adapter* for that kind of object. +- For objects you don't "own", you can register a JSON renderer that knows + about an *adapter* for that kind of object. Using a Custom ``__json__`` Method ********************************** Custom objects can be made easily JSON-serializable in Pyramid by defining a ``__json__`` method on the object's class. This method should return values -natively JSON-serializable (such as ints, lists, dictionaries, strings, and -so forth). It should accept a single additional argument, ``request``, which -will be the active request object at render time. +natively JSON-serializable (such as ints, lists, dictionaries, strings, and so +forth). It should accept a single additional argument, ``request``, which will +be the active request object at render time. .. code-block:: python :linenos: @@ -272,14 +269,14 @@ will be the active request object at render time. Using the ``add_adapter`` Method of a Custom JSON Renderer ********************************************************** -If you aren't the author of the objects being serialized, it won't be -possible (or at least not reasonable) to add a custom ``__json__`` method -to their classes in order to influence serialization. If the object passed -to the renderer is not a serializable type, and has no ``__json__`` method, -usually a :exc:`TypeError` will be raised during serialization. You can -change this behavior by creating a custom JSON renderer and adding adapters -to handle custom types. The renderer will attempt to adapt non-serializable -objects using the registered adapters. A short example follows: +If you aren't the author of the objects being serialized, it won't be possible +(or at least not reasonable) to add a custom ``__json__`` method to their +classes in order to influence serialization. If the object passed to the +renderer is not a serializable type and has no ``__json__`` method, usually a +:exc:`TypeError` will be raised during serialization. You can change this +behavior by creating a custom JSON renderer and adding adapters to handle +custom types. The renderer will attempt to adapt non-serializable objects using +the registered adapters. A short example follows: .. code-block:: python :linenos: @@ -294,16 +291,17 @@ objects using the registered adapters. A short example follows: json_renderer.add_adapter(datetime.datetime, datetime_adapter) config.add_renderer('json', json_renderer) -The ``add_adapter`` method should accept two arguments: the *class* of the object that you want this adapter to run for (in the example above, +The ``add_adapter`` method should accept two arguments: the *class* of the +object that you want this adapter to run for (in the example above, ``datetime.datetime``), and the adapter itself. -The adapter should be a callable. It should accept two arguments: the object -needing to be serialized and ``request``, which will be the current request -object at render time. The adapter should raise a :exc:`TypeError` -if it can't determine what to do with the object. +The adapter should be a callable. It should accept two arguments: the object +needing to be serialized and ``request``, which will be the current request +object at render time. The adapter should raise a :exc:`TypeError` if it can't +determine what to do with the object. -See :class:`pyramid.renderers.JSON` and -:ref:`adding_and_overriding_renderers` for more information. +See :class:`pyramid.renderers.JSON` and :ref:`adding_and_overriding_renderers` +for more information. .. versionadded:: 1.4 Serializing custom objects. @@ -319,12 +317,12 @@ JSONP Renderer .. versionadded:: 1.1 :class:`pyramid.renderers.JSONP` is a `JSONP -`_ renderer factory helper which -implements a hybrid json/jsonp renderer. JSONP is useful for making -cross-domain AJAX requests. +`_ renderer factory helper which implements +a hybrid JSON/JSONP renderer. JSONP is useful for making cross-domain AJAX +requests. -Unlike other renderers, a JSONP renderer needs to be configured at startup -time "by hand". Configure a JSONP renderer using the +Unlike other renderers, a JSONP renderer needs to be configured at startup time +"by hand". Configure a JSONP renderer using the :meth:`pyramid.config.Configurator.add_renderer` method: .. code-block:: python @@ -355,8 +353,8 @@ When a view is called that uses a JSONP renderer: renderer (by default, ``callback``), the renderer will return a JSONP response. -- If there is no callback parameter in the request's query string, the - renderer will return a 'plain' JSON response. +- If there is no callback parameter in the request's query string, the renderer + will return a "plain" JSON response. Javscript library AJAX functionality will help you make JSONP requests. For example, JQuery has a `getJSON function @@ -364,7 +362,7 @@ For example, JQuery has a `getJSON function complicated) functionality in its `ajax function `_. -For example (Javascript): +For example (JavaScript): .. code-block:: javascript @@ -375,10 +373,9 @@ For example (Javascript): '&callback=?'; jqhxr = $.getJSON(api_url); -The string ``callback=?`` above in the ``url`` param to the JQuery -``getJSON`` function indicates to jQuery that the query should be made as -a JSONP request; the ``callback`` parameter will be automatically filled -in for you and used. +The string ``callback=?`` above in the ``url`` param to the JQuery ``getJSON`` +function indicates to jQuery that the query should be made as a JSONP request; +the ``callback`` parameter will be automatically filled in for you and used. The same custom-object serialization scheme defined used for a "normal" JSON renderer in :ref:`json_serializing_custom_objects` can be used when passing @@ -397,10 +394,9 @@ Before a response constructed by a :term:`renderer` is returned to :app:`Pyramid`, several attributes of the request are examined which have the potential to influence response behavior. -View callables that don't directly return a response should use the API of -the :class:`pyramid.response.Response` attribute available as -``request.response`` during their execution, to influence associated response -behavior. +View callables that don't directly return a response should use the API of the +:class:`pyramid.response.Response` attribute, available as ``request.response`` +during their execution, to influence associated response behavior. For example, if you need to change the response status from within a view callable that uses a renderer, assign the ``status`` attribute to the @@ -419,7 +415,7 @@ callable that uses a renderer, assign the ``status`` attribute to the Note that mutations of ``request.response`` in views which return a Response object directly will have no effect unless the response object returned *is* ``request.response``. For example, the following example calls -``request.response.set_cookie``, but this call will have no effect, because a +``request.response.set_cookie``, but this call will have no effect because a different Response object is returned. .. code-block:: python @@ -441,8 +437,8 @@ effect, you must return ``request.response``: request.response.set_cookie('abc', '123') return request.response -For more information on attributes of the request, see the API documentation -in :ref:`request_module`. For more information on the API of +For more information on attributes of the request, see the API documentation in +:ref:`request_module`. For more information on the API of ``request.response``, see :attr:`pyramid.request.Request.response`. .. _adding_and_overriding_renderers: @@ -481,10 +477,9 @@ You may add a new renderer by creating and registering a :term:`renderer factory`. A renderer factory implementation should conform to the -:class:`pyramid.interfaces.IRendererFactory` interface. It should be capable -of creating an object that conforms to the -:class:`pyramid.interfaces.IRenderer` interface. A typical class that follows -this setup is as follows: +:class:`pyramid.interfaces.IRendererFactory` interface. It should be capable of +creating an object that conforms to the :class:`pyramid.interfaces.IRenderer` +interface. A typical class that follows this setup is as follows: .. code-block:: python :linenos: @@ -504,38 +499,36 @@ this setup is as follows: the result (a string or unicode object). The value is the return value of a view. The system value is a dictionary containing available system values - (e.g. view, context, and request). """ + (e.g., view, context, and request). """ The formal interface definition of the ``info`` object passed to a renderer factory constructor is available as :class:`pyramid.interfaces.IRendererInfo`. There are essentially two different kinds of renderer factories: -- A renderer factory which expects to accept an :term:`asset - specification`, or an absolute path, as the ``name`` attribute of the - ``info`` object fed to its constructor. These renderer factories are - registered with a ``name`` value that begins with a dot (``.``). These - types of renderer factories usually relate to a file on the filesystem, - such as a template. +- A renderer factory which expects to accept an :term:`asset specification`, or + an absolute path, as the ``name`` attribute of the ``info`` object fed to its + constructor. These renderer factories are registered with a ``name`` value + that begins with a dot (``.``). These types of renderer factories usually + relate to a file on the filesystem, such as a template. -- A renderer factory which expects to accept a token that does not represent - a filesystem path or an asset specification in the ``name`` - attribute of the ``info`` object fed to its constructor. These renderer - factories are registered with a ``name`` value that does not begin with a - dot. These renderer factories are typically object serializers. +- A renderer factory which expects to accept a token that does not represent a + filesystem path or an asset specification in the ``name`` attribute of the + ``info`` object fed to its constructor. These renderer factories are + registered with a ``name`` value that does not begin with a dot. These + renderer factories are typically object serializers. .. sidebar:: Asset Specifications - An asset specification is a colon-delimited identifier for an - :term:`asset`. The colon separates a Python :term:`package` - name from a package subpath. For example, the asset - specification ``my.package:static/baz.css`` identifies the file named - ``baz.css`` in the ``static`` subdirectory of the ``my.package`` Python - :term:`package`. + An asset specification is a colon-delimited identifier for an :term:`asset`. + The colon separates a Python :term:`package` name from a package subpath. + For example, the asset specification ``my.package:static/baz.css`` + identifies the file named ``baz.css`` in the ``static`` subdirectory of the + ``my.package`` Python :term:`package`. Here's an example of the registration of a simple renderer factory via -:meth:`~pyramid.config.Configurator.add_renderer`, where ``config`` -is an instance of :meth:`pyramid.config.Configurator`: +:meth:`~pyramid.config.Configurator.add_renderer`, where ``config`` is an +instance of :meth:`pyramid.config.Configurator`: .. code-block:: python @@ -556,16 +549,15 @@ renderer by specifying ``amf`` in the ``renderer`` attribute of a def myview(request): return {'Hello':'world'} -At startup time, when a :term:`view configuration` is encountered, which -has a ``name`` attribute that does not contain a dot, the full ``name`` -value is used to construct a renderer from the associated renderer -factory. In this case, the view configuration will create an instance -of an ``MyAMFRenderer`` for each view configuration which includes ``amf`` -as its renderer value. The ``name`` passed to the ``MyAMFRenderer`` -constructor will always be ``amf``. +At startup time, when a :term:`view configuration` is encountered which has a +``name`` attribute that does not contain a dot, the full ``name`` value is used +to construct a renderer from the associated renderer factory. In this case, +the view configuration will create an instance of an ``MyAMFRenderer`` for each +view configuration which includes ``amf`` as its renderer value. The ``name`` +passed to the ``MyAMFRenderer`` constructor will always be ``amf``. -Here's an example of the registration of a more complicated renderer -factory, which expects to be passed a filesystem path: +Here's an example of the registration of a more complicated renderer factory, +which expects to be passed a filesystem path: .. code-block:: python @@ -585,24 +577,23 @@ the ``renderer`` attribute of a :term:`view configuration`: def myview(request): return {'Hello':'world'} -When a :term:`view configuration` is encountered at startup time, which -has a ``name`` attribute that does contain a dot, the value of the name -attribute is split on its final dot. The second element of the split is -typically the filename extension. This extension is used to look up a -renderer factory for the configured view. Then the value of -``renderer`` is passed to the factory to create a renderer for the view. -In this case, the view configuration will create an instance of a -``MyJinja2Renderer`` for each view configuration which includes anything -ending with ``.jinja2`` in its ``renderer`` value. The ``name`` passed -to the ``MyJinja2Renderer`` constructor will be the full value that was -set as ``renderer=`` in the view configuration. +When a :term:`view configuration` is encountered at startup time which has a +``name`` attribute that does contain a dot, the value of the name attribute is +split on its final dot. The second element of the split is typically the +filename extension. This extension is used to look up a renderer factory for +the configured view. Then the value of ``renderer`` is passed to the factory +to create a renderer for the view. In this case, the view configuration will +create an instance of a ``MyJinja2Renderer`` for each view configuration which +includes anything ending with ``.jinja2`` in its ``renderer`` value. The +``name`` passed to the ``MyJinja2Renderer`` constructor will be the full value +that was set as ``renderer=`` in the view configuration. Adding a Default Renderer ~~~~~~~~~~~~~~~~~~~~~~~~~ -To associate a *default* renderer with *all* view configurations (even -ones which do not possess a ``renderer`` attribute), pass ``None`` as -the ``name`` attribute to the renderer tag: +To associate a *default* renderer with *all* view configurations (even ones +which do not possess a ``renderer`` attribute), pass ``None`` as the ``name`` +attribute to the renderer tag: .. code-block:: python @@ -616,40 +607,40 @@ Changing an Existing Renderer Pyramid supports overriding almost every aspect of its setup through its :ref:`Conflict Resolution ` mechanism. This -means that in most cases overriding a renderer is as simple as using the -:meth:`pyramid.config.Configurator.add_renderer` method to re-define the +means that, in most cases, overriding a renderer is as simple as using the +:meth:`pyramid.config.Configurator.add_renderer` method to redefine the template extension. For example, if you would like to override the ``.txt`` -extension to specify a new renderer you could do the following: +extension to specify a new renderer, you could do the following: .. code-block:: python json_renderer = pyramid.renderers.JSON() config.add_renderer('json', json_renderer) -After doing this, any views registered with the ``json`` renderer will use -the new renderer. +After doing this, any views registered with the ``json`` renderer will use the +new renderer. .. index:: pair: renderer; overriding at runtime -Overriding A Renderer At Runtime +Overriding a Renderer at Runtime -------------------------------- .. warning:: This is an advanced feature, not typically used by "civilians". In some circumstances, it is necessary to instruct the system to ignore the static renderer declaration provided by the developer in view configuration, -replacing the renderer with another *after a request starts*. For example, -an "omnipresent" XML-RPC implementation that detects that the request is from -an XML-RPC client might override a view configuration statement made by the -user instructing the view to use a template renderer with one that uses an -XML-RPC renderer. This renderer would produce an XML-RPC representation of -the data returned by an arbitrary view callable. +replacing the renderer with another *after a request starts*. For example, an +"omnipresent" XML-RPC implementation that detects that the request is from an +XML-RPC client might override a view configuration statement made by the user +instructing the view to use a template renderer with one that uses an XML-RPC +renderer. This renderer would produce an XML-RPC representation of the data +returned by an arbitrary view callable. To use this feature, create a :class:`~pyramid.events.NewRequest` :term:`subscriber` which sniffs at the request data and which conditionally -sets an ``override_renderer`` attribute on the request itself, which is the -*name* of a registered renderer. For example: +sets an ``override_renderer`` attribute on the request itself, which in turn is +the *name* of a registered renderer. For example: .. code-block:: python :linenos: @@ -670,6 +661,6 @@ sets an ``override_renderer`` attribute on the request itself, which is the request.override_renderer = 'xmlrpc' return True -The result of such a subscriber will be to replace any existing static -renderer configured by the developer with a (notional, nonexistent) XML-RPC -renderer if the request appears to come from an XML-RPC client. +The result of such a subscriber will be to replace any existing static renderer +configured by the developer with a (notional, nonexistent) XML-RPC renderer, if +the request appears to come from an XML-RPC client. -- cgit v1.2.3 From b932a45f834ae6bdb5850a2c58d1317844b32914 Mon Sep 17 00:00:00 2001 From: John Anderson Date: Sun, 11 Oct 2015 00:50:54 -0700 Subject: removed default fall through when passed a specific shell --- docs/narr/commandline.rst | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 89df13ce4..cb0c914d7 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -245,7 +245,7 @@ exposed, and the request is configured to generate urls from the host .. code-block:: text $ $VENV/bin/pshell starter/development.ini - Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -278,10 +278,10 @@ IPython or bpython If you have `IPython `_ and/or `bpython `_ in -the interpreter you use to invoke the ``pshell`` command, ``pshell`` will +the interpreter you use to invoke the ``pshell`` command, ``pshell`` will autodiscover and use the first one found, in this order: -IPython, bpython, standard Python interpreter. However you could -specifically invoke one of your choice with the ``-p choice`` or +IPython, bpython, standard Python interpreter. However you could +specifically invoke one of your choice with the ``-p choice`` or ``--python-shell choice`` option. .. code-block:: text @@ -308,20 +308,16 @@ and then your shell factory should return a function that accepts two arguments, .. code-block:: python def ptpython_shell_factory(): - try: - from ptpython.repl import embed - def PTPShell(banner, **kwargs): - print(banner) - return embed(**kwargs) - except ImportError: - return None + from ptpython.repl import embed + def PTPShell(banner, **kwargs): + print(banner) + return embed(**kwargs) def shell(env, help): PTPShell(banner=help, locals=env) return shell - .. index:: pair: routes; printing single: proutes -- cgit v1.2.3 From ac568b72d0f8214b169f28c5bbebb78c571c0a07 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 11 Oct 2015 01:24:08 -0700 Subject: minor grammar, wrap 79 cols --- docs/narr/templates.rst | 309 +++++++++++++++++++++++------------------------- 1 file changed, 147 insertions(+), 162 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 4c1364493..9e3a31845 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -3,15 +3,14 @@ Templates ========= -A :term:`template` is a file on disk which can be used to render -dynamic data provided by a :term:`view`. :app:`Pyramid` offers a -number of ways to perform templating tasks out of the box, and -provides add-on templating support through a set of bindings packages. +A :term:`template` is a file on disk which can be used to render dynamic data +provided by a :term:`view`. :app:`Pyramid` offers a number of ways to perform +templating tasks out of the box, and provides add-on templating support through +a set of bindings packages. -Before discussing how built-in templates are used in -detail, we'll discuss two ways to render templates within -:app:`Pyramid` in general: directly, and via renderer -configuration. +Before discussing how built-in templates are used in detail, we'll discuss two +ways to render templates within :app:`Pyramid` in general: directly and via +renderer configuration. .. index:: single: templates used directly @@ -21,16 +20,15 @@ configuration. Using Templates Directly ------------------------ -The most straightforward way to use a template within -:app:`Pyramid` is to cause it to be rendered directly within a -:term:`view callable`. You may use whatever API is supplied by a -given templating engine to do so. +The most straightforward way to use a template within :app:`Pyramid` is to +cause it to be rendered directly within a :term:`view callable`. You may use +whatever API is supplied by a given templating engine to do so. -:app:`Pyramid` provides various APIs that allow you to render templates -directly from within a view callable. For example, if there is a -:term:`Chameleon` ZPT template named ``foo.pt`` in a directory named -``templates`` in your application, you can render the template from -within the body of a view callable like so: +:app:`Pyramid` provides various APIs that allow you to render templates directly +from within a view callable. For example, if there is a :term:`Chameleon` ZPT +template named ``foo.pt`` in a directory named ``templates`` in your +application, you can render the template from within the body of a view +callable like so: .. code-block:: python :linenos: @@ -43,23 +41,21 @@ within the body of a view callable like so: request=request) The ``sample_view`` :term:`view callable` function above returns a -:term:`response` object which contains the body of the -``templates/foo.pt`` template. In this case, the ``templates`` -directory should live in the same directory as the module containing -the ``sample_view`` function. The template author will have the names -``foo`` and ``bar`` available as top-level names for replacement or -comparison purposes. +:term:`response` object which contains the body of the ``templates/foo.pt`` +template. In this case, the ``templates`` directory should live in the same +directory as the module containing the ``sample_view`` function. The template +author will have the names ``foo`` and ``bar`` available as top-level names for +replacement or comparison purposes. In the example above, the path ``templates/foo.pt`` is relative to the -directory containing the file which defines the view configuration. -In this case, this is the directory containing the file that -defines the ``sample_view`` function. Although a renderer path is -usually just a simple relative pathname, a path named as a renderer -can be absolute, starting with a slash on UNIX or a drive letter -prefix on Windows. The path can alternately be an -:term:`asset specification` in the form -``some.dotted.package_name:relative/path``. This makes it possible to -address template assets which live in another package. For example: +directory containing the file which defines the view configuration. In this +case, this is the directory containing the file that defines the +``sample_view`` function. Although a renderer path is usually just a simple +relative pathname, a path named as a renderer can be absolute, starting with a +slash on UNIX or a drive letter prefix on Windows. The path can alternatively +be an :term:`asset specification` in the form +``some.dotted.package_name:relative/path``. This makes it possible to address +template assets which live in another package. For example: .. code-block:: python :linenos: @@ -71,38 +67,36 @@ address template assets which live in another package. For example: {'foo':1, 'bar':2}, request=request) -An asset specification points at a file within a Python *package*. -In this case, it points at a file named ``foo.pt`` within the -``templates`` directory of the ``mypackage`` package. Using an -asset specification instead of a relative template name is usually -a good idea, because calls to :func:`~pyramid.renderers.render_to_response` -using asset specifications will continue to work properly if you move the -code containing them to another location. +An asset specification points at a file within a Python *package*. In this +case, it points at a file named ``foo.pt`` within the ``templates`` directory +of the ``mypackage`` package. Using an asset specification instead of a +relative template name is usually a good idea, because calls to +:func:`~pyramid.renderers.render_to_response` using asset specifications will +continue to work properly if you move the code containing them to another +location. In the examples above we pass in a keyword argument named ``request`` -representing the current :app:`Pyramid` request. Passing a request -keyword argument will cause the ``render_to_response`` function to -supply the renderer with more correct system values (see -:ref:`renderer_system_values`), because most of the information required -to compose proper system values is present in the request. If your -template relies on the name ``request`` or ``context``, or if you've -configured special :term:`renderer globals`, make sure to pass +representing the current :app:`Pyramid` request. Passing a request keyword +argument will cause the ``render_to_response`` function to supply the renderer +with more correct system values (see :ref:`renderer_system_values`), because +most of the information required to compose proper system values is present in +the request. If your template relies on the name ``request`` or ``context``, +or if you've configured special :term:`renderer globals`, make sure to pass ``request`` as a keyword argument in every call to a ``pyramid.renderers.render_*`` function. -Every view must return a :term:`response` object, except for views -which use a :term:`renderer` named via view configuration (which we'll -see shortly). The :func:`pyramid.renderers.render_to_response` -function is a shortcut function that actually returns a response -object. This allows the example view above to simply return the result -of its call to ``render_to_response()`` directly. +Every view must return a :term:`response` object, except for views which use a +:term:`renderer` named via view configuration (which we'll see shortly). The +:func:`pyramid.renderers.render_to_response` function is a shortcut function +that actually returns a response object. This allows the example view above to +simply return the result of its call to ``render_to_response()`` directly. Obviously not all APIs you might call to get response data will return a -response object. For example, you might render one or more templates to -a string that you want to use as response data. The -:func:`pyramid.renderers.render` API renders a template to a string. We -can manufacture a :term:`response` object directly, and use that string -as the body of the response: +response object. For example, you might render one or more templates to a +string that you want to use as response data. The +:func:`pyramid.renderers.render` API renders a template to a string. We can +manufacture a :term:`response` object directly, and use that string as the body +of the response: .. code-block:: python :linenos: @@ -119,10 +113,10 @@ as the body of the response: Because :term:`view callable` functions are typically the only code in :app:`Pyramid` that need to know anything about templates, and because view -functions are very simple Python, you can use whatever templating system you're -most comfortable with within :app:`Pyramid`. Install the templating system, -import its API functions into your views module, use those APIs to generate a -string, then return that string as the body of a :app:`Pyramid` +functions are very simple Python, you can use whatever templating system with +which you're most comfortable within :app:`Pyramid`. Install the templating +system, import its API functions into your views module, use those APIs to +generate a string, then return that string as the body of a :app:`Pyramid` :term:`Response` object. For example, here's an example of using "raw" Mako_ from within a @@ -141,34 +135,32 @@ For example, here's an example of using "raw" Mako_ from within a return response You probably wouldn't use this particular snippet in a project, because it's -easier to use the supported -:ref:`Mako bindings `. But if your -favorite templating system is not supported as a renderer extension for -:app:`Pyramid`, you can create your own simple combination as shown above. +easier to use the supported :ref:`Mako bindings +`. But if your favorite templating system +is not supported as a renderer extension for :app:`Pyramid`, you can create +your own simple combination as shown above. .. note:: If you use third-party templating languages without cooperating :app:`Pyramid` bindings directly within view callables, the - auto-template-reload strategy explained in - :ref:`reload_templates_section` will not be available, nor will the - template asset overriding capability explained in - :ref:`overriding_assets_section` be available, nor will it be - possible to use any template using that language as a - :term:`renderer`. However, it's reasonably easy to write custom - templating system binding packages for use under :app:`Pyramid` so - that templates written in the language can be used as renderers. - See :ref:`adding_and_overriding_renderers` for instructions on how - to create your own template renderer and - :ref:`available_template_system_bindings` for example packages. - -If you need more control over the status code and content-type, or -other response attributes from views that use direct templating, you -may set attributes on the response that influence these values. - -Here's an example of changing the content-type and status of the -response object returned by -:func:`~pyramid.renderers.render_to_response`: + auto-template-reload strategy explained in :ref:`reload_templates_section` + will not be available, nor will the template asset overriding capability + explained in :ref:`overriding_assets_section` be available, nor will it be + possible to use any template using that language as a :term:`renderer`. + However, it's reasonably easy to write custom templating system binding + packages for use under :app:`Pyramid` so that templates written in the + language can be used as renderers. See + :ref:`adding_and_overriding_renderers` for instructions on how to create + your own template renderer and :ref:`available_template_system_bindings` + for example packages. + +If you need more control over the status code and content-type, or other +response attributes from views that use direct templating, you may set +attributes on the response that influence these values. + +Here's an example of changing the content-type and status of the response +object returned by :func:`~pyramid.renderers.render_to_response`: .. code-block:: python :linenos: @@ -183,8 +175,8 @@ response object returned by response.status_int = 204 return response -Here's an example of manufacturing a response object using the result -of :func:`~pyramid.renderers.render` (a string): +Here's an example of manufacturing a response object using the result of +:func:`~pyramid.renderers.render` (a string): .. code-block:: python :linenos: @@ -214,9 +206,8 @@ of :func:`~pyramid.renderers.render` (a string): System Values Used During Rendering ----------------------------------- -When a template is rendered using -:func:`~pyramid.renderers.render_to_response` or -:func:`~pyramid.renderers.render`, or a ``renderer=`` argument to view +When a template is rendered using :func:`~pyramid.renderers.render_to_response` +or :func:`~pyramid.renderers.render`, or a ``renderer=`` argument to view configuration (see :ref:`templates_used_as_renderers`), the renderer representing the template will be provided with a number of *system* values. These values are provided to the template: @@ -232,31 +223,31 @@ These values are provided to the template: ``context`` The current :app:`Pyramid` :term:`context` if ``request`` was provided as a - keyword argument to ``render_to_response`` or ``render``, or ``None`` if - the ``request`` keyword argument was not provided. This value will always - be provided if the template is rendered as the result of a ``renderer=`` - argument to view configuration being used. + keyword argument to ``render_to_response`` or ``render``, or ``None`` if the + ``request`` keyword argument was not provided. This value will always be + provided if the template is rendered as the result of a ``renderer=`` + argument to the view configuration being used. ``renderer_name`` - The renderer name used to perform the rendering, - e.g. ``mypackage:templates/foo.pt``. + The renderer name used to perform the rendering, e.g., + ``mypackage:templates/foo.pt``. ``renderer_info`` An object implementing the :class:`pyramid.interfaces.IRendererInfo` interface. Basically, an object with the following attributes: ``name``, - ``package`` and ``type``. + ``package``, and ``type``. ``view`` - The view callable object that was used to render this template. If the - view callable is a method of a class-based view, this will be an instance - of the class that the method was defined on. If the view callable is a - function or instance, it will be that function or instance. Note that this - value will only be automatically present when a template is rendered as a - result of a ``renderer=`` argument; it will be ``None`` when the - ``render_to_response`` or ``render`` APIs are used. + The view callable object that was used to render this template. If the view + callable is a method of a class-based view, this will be an instance of the + class that the method was defined on. If the view callable is a function or + instance, it will be that function or instance. Note that this value will + only be automatically present when a template is rendered as a result of a + ``renderer=`` argument; it will be ``None`` when the ``render_to_response`` + or ``render`` APIs are used. -You can define more values which will be passed to every template executed as -a result of rendering by defining :term:`renderer globals`. +You can define more values which will be passed to every template executed as a +result of rendering by defining :term:`renderer globals`. What any particular renderer does with these system values is up to the renderer itself, but most template renderers make these names available as @@ -270,26 +261,23 @@ top-level template variables. Templates Used as Renderers via Configuration --------------------------------------------- -An alternative to using :func:`~pyramid.renderers.render_to_response` -to render templates manually in your view callable code, is -to specify the template as a :term:`renderer` in your -*view configuration*. This can be done with any of the +An alternative to using :func:`~pyramid.renderers.render_to_response` to render +templates manually in your view callable code is to specify the template as a +:term:`renderer` in your *view configuration*. This can be done with any of the templating languages supported by :app:`Pyramid`. -To use a renderer via view configuration, specify a template -:term:`asset specification` as the ``renderer`` argument, or -attribute to the :term:`view configuration` of a :term:`view -callable`. Then return a *dictionary* from that view callable. The -dictionary items returned by the view callable will be made available -to the renderer template as top-level names. +To use a renderer via view configuration, specify a template :term:`asset +specification` as the ``renderer`` argument, or attribute to the :term:`view +configuration` of a :term:`view callable`. Then return a *dictionary* from +that view callable. The dictionary items returned by the view callable will be +made available to the renderer template as top-level names. -The association of a template as a renderer for a :term:`view -configuration` makes it possible to replace code within a :term:`view -callable` that handles the rendering of a template. +The association of a template as a renderer for a :term:`view configuration` +makes it possible to replace code within a :term:`view callable` that handles +the rendering of a template. -Here's an example of using a :class:`~pyramid.view.view_config` -decorator to specify a :term:`view configuration` that names a -template renderer: +Here's an example of using a :class:`~pyramid.view.view_config` decorator to +specify a :term:`view configuration` that names a template renderer: .. code-block:: python :linenos: @@ -302,11 +290,10 @@ template renderer: .. note:: - You do not need to supply the ``request`` value as a key - in the dictionary result returned from a renderer-configured view - callable. :app:`Pyramid` automatically supplies this value for - you so that the "most correct" system values are provided to - the renderer. + You do not need to supply the ``request`` value as a key in the dictionary + result returned from a renderer-configured view callable. :app:`Pyramid` + automatically supplies this value for you, so that the "most correct" system + values are provided to the renderer. .. warning:: @@ -314,7 +301,7 @@ template renderer: shown above is the template *path*. In the example above, the path ``templates/foo.pt`` is *relative*. Relative to what, you ask? Because we're using a Chameleon renderer, it means "relative to the directory in - which the file which defines the view configuration lives". In this case, + which the file that defines the view configuration lives". In this case, this is the directory containing the file that defines the ``my_view`` function. @@ -327,7 +314,7 @@ Similar renderer configuration can be done imperatively. See Although a renderer path is usually just a simple relative pathname, a path named as a renderer can be absolute, starting with a slash on UNIX or a drive -letter prefix on Windows. The path can alternately be an :term:`asset +letter prefix on Windows. The path can alternatively be an :term:`asset specification` in the form ``some.dotted.package_name:relative/path``, making it possible to address template assets which live in another package. @@ -335,32 +322,31 @@ Not just any template from any arbitrary templating system may be used as a renderer. Bindings must exist specifically for :app:`Pyramid` to use a templating language template as a renderer. -.. sidebar:: Why Use A Renderer via View Configuration - - Using a renderer in view configuration is usually a better way to - render templates than using any rendering API directly from within a - :term:`view callable` because it makes the view callable more - unit-testable. Views which use templating or rendering APIs directly - must return a :term:`Response` object. Making testing assertions - about response objects is typically an indirect process, because it - means that your test code often needs to somehow parse information - out of the response body (often HTML). View callables configured - with renderers externally via view configuration typically return a - dictionary, as above. Making assertions about results returned in a - dictionary is almost always more direct and straightforward than - needing to parse HTML. +.. sidebar:: Why Use a Renderer via View Configuration + + Using a renderer in view configuration is usually a better way to render + templates than using any rendering API directly from within a :term:`view + callable` because it makes the view callable more unit-testable. Views + which use templating or rendering APIs directly must return a + :term:`Response` object. Making testing assertions about response objects + is typically an indirect process, because it means that your test code often + needs to somehow parse information out of the response body (often HTML). + View callables configured with renderers externally via view configuration + typically return a dictionary, as above. Making assertions about results + returned in a dictionary is almost always more direct and straightforward + than needing to parse HTML. By default, views rendered via a template renderer return a :term:`Response` object which has a *status code* of ``200 OK``, and a *content-type* of ``text/html``. To vary attributes of the response of a view that uses a -renderer, such as the content-type, headers, or status attributes, you must -use the API of the :class:`pyramid.response.Response` object exposed as +renderer, such as the content-type, headers, or status attributes, you must use +the API of the :class:`pyramid.response.Response` object exposed as ``request.response`` within the view before returning the dictionary. See :ref:`request_response_attr` for more information. -The same set of system values are provided to templates rendered via a -renderer view configuration as those provided to templates rendered -imperatively. See :ref:`renderer_system_values`. +The same set of system values are provided to templates rendered via a renderer +view configuration as those provided to templates rendered imperatively. See +:ref:`renderer_system_values`. .. index:: pair: debugging; templates @@ -401,32 +387,31 @@ displaying the arguments passed to the template itself. Automatically Reloading Templates --------------------------------- -It's often convenient to see changes you make to a template file -appear immediately without needing to restart the application process. -:app:`Pyramid` allows you to configure your application development -environment so that a change to a template will be automatically -detected, and the template will be reloaded on the next rendering. +It's often convenient to see changes you make to a template file appear +immediately without needing to restart the application process. :app:`Pyramid` +allows you to configure your application development environment so that a +change to a template will be automatically detected, and the template will be +reloaded on the next rendering. .. warning:: - Auto-template-reload behavior is not recommended for - production sites as it slows rendering slightly; it's - usually only desirable during development. + Auto-template-reload behavior is not recommended for production sites as it + slows rendering slightly; it's usually only desirable during development. In order to turn on automatic reloading of templates, you can use an -environment variable, or a configuration file setting. +environment variable or a configuration file setting. -To use an environment variable, start your application under a shell -using the ``PYRAMID_RELOAD_TEMPLATES`` operating system environment -variable set to ``1``, For example: +To use an environment variable, start your application under a shell using the +``PYRAMID_RELOAD_TEMPLATES`` operating system environment variable set to +``1``, For example: .. code-block:: text $ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini -To use a setting in the application ``.ini`` file for the same -purpose, set the ``pyramid.reload_templates`` key to ``true`` within the -application's configuration section, e.g.: +To use a setting in the application ``.ini`` file for the same purpose, set the +``pyramid.reload_templates`` key to ``true`` within the application's +configuration section, e.g.: .. code-block:: ini :linenos: -- cgit v1.2.3 From 8038177494a2bee1394fcb24357435662093fbe8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 12 Oct 2015 03:18:13 -0700 Subject: minor grammar, wrap 79 cols --- docs/narr/viewconfig.rst | 575 +++++++++++++++++++++++------------------------ 1 file changed, 283 insertions(+), 292 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 484350b31..cb3e78be3 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -10,8 +10,8 @@ View Configuration .. index:: single: view lookup -:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding -and invoking a :term:`view callable`. :term:`View configuration` controls how +:term:`View lookup` is the :app:`Pyramid` subsystem responsible for finding and +invoking a :term:`view callable`. :term:`View configuration` controls how :term:`view lookup` operates in your application. During any given request, view configuration information is compared against request data by the view lookup subsystem in order to find the "best" view callable for that request. @@ -30,8 +30,8 @@ Mapping a Resource or URL Pattern to a View Callable A developer makes a :term:`view callable` available for use within a :app:`Pyramid` application via :term:`view configuration`. A view configuration associates a view callable with a set of statements that -determine the set of circumstances which must be true for the view callable -to be invoked. +determine the set of circumstances which must be true for the view callable to +be invoked. A view configuration statement is made about information present in the :term:`context` resource and the :term:`request`. @@ -56,35 +56,34 @@ View Configuration Parameters All forms of view configuration accept the same general types of arguments. Many arguments supplied during view configuration are :term:`view predicate` -arguments. View predicate arguments used during view configuration are used -to narrow the set of circumstances in which :term:`view lookup` will find a +arguments. View predicate arguments used during view configuration are used to +narrow the set of circumstances in which :term:`view lookup` will find a particular view callable. :term:`View predicate` attributes are an important part of view configuration that enables the :term:`view lookup` subsystem to find and invoke the -appropriate view. The greater the number of predicate attributes possessed by a -view's configuration, the more specific the circumstances need to be before -the registered view callable will be invoked. The fewer the number of predicates -which are supplied to a particular view configuration, the more likely it is -that the associated view callable will be invoked. A view with five -predicates will always be found and evaluated before a view with two, for +appropriate view. The greater the number of predicate attributes possessed by +a view's configuration, the more specific the circumstances need to be before +the registered view callable will be invoked. The fewer the number of +predicates which are supplied to a particular view configuration, the more +likely it is that the associated view callable will be invoked. A view with +five predicates will always be found and evaluated before a view with two, for example. -This does not mean however, that :app:`Pyramid` "stops looking" when it -finds a view registration with predicates that don't match. If one set -of view predicates does not match, the "next most specific" view (if -any) is consulted for predicates, and so on, until a view is found, or -no view can be matched up with the request. The first view with a set -of predicates all of which match the request environment will be -invoked. +This does not mean however, that :app:`Pyramid` "stops looking" when it finds a +view registration with predicates that don't match. If one set of view +predicates does not match, the "next most specific" view (if any) is consulted +for predicates, and so on, until a view is found, or no view can be matched up +with the request. The first view with a set of predicates all of which match +the request environment will be invoked. If no view can be found with predicates which allow it to be matched up with the request, :app:`Pyramid` will return an error to the user's browser, representing a "not found" (404) page. See :ref:`changing_the_notfound_view` for more information about changing the default :term:`Not Found View`. -Other view configuration arguments are non-predicate arguments. These tend -to modify the response of the view callable or prevent the view callable from +Other view configuration arguments are non-predicate arguments. These tend to +modify the response of the view callable or prevent the view callable from being invoked due to an authorization policy. The presence of non-predicate arguments in a view configuration does not narrow the circumstances in which the view callable will be invoked. @@ -96,56 +95,55 @@ Non-Predicate Arguments ``permission`` The name of a :term:`permission` that the user must possess in order to - invoke the :term:`view callable`. See :ref:`view_security_section` for - more information about view security and permissions. + invoke the :term:`view callable`. See :ref:`view_security_section` for more + information about view security and permissions. - If ``permission`` is not supplied, no permission is registered for this - view (it's accessible by any caller). + If ``permission`` is not supplied, no permission is registered for this view + (it's accessible by any caller). ``attr`` The view machinery defaults to using the ``__call__`` method of the :term:`view callable` (or the function itself, if the view callable is a function) to obtain a response. The ``attr`` value allows you to vary the - method attribute used to obtain the response. For example, if your view - was a class, and the class has a method named ``index`` and you wanted to - use this method instead of the class's ``__call__`` method to return the - response, you'd say ``attr="index"`` in the view configuration for the - view. This is most useful when the view definition is a class. + method attribute used to obtain the response. For example, if your view was + a class, and the class has a method named ``index`` and you wanted to use + this method instead of the class's ``__call__`` method to return the + response, you'd say ``attr="index"`` in the view configuration for the view. + This is most useful when the view definition is a class. If ``attr`` is not supplied, ``None`` is used (implying the function itself - if the view is a function, or the ``__call__`` callable attribute if the - view is a class). + if the view is a function, or the ``__call__`` callable attribute if the view + is a class). ``renderer`` - Denotes the :term:`renderer` implementation which will be used to construct - a :term:`response` from the associated view callable's return value. + Denotes the :term:`renderer` implementation which will be used to construct a + :term:`response` from the associated view callable's return value. .. seealso:: See also :ref:`renderers_chapter`. - This is either a single string term (e.g. ``json``) or a string implying a - path or :term:`asset specification` (e.g. ``templates/views.pt``) naming a - :term:`renderer` implementation. If the ``renderer`` value does not - contain a dot (``.``), the specified string will be used to look up a - renderer implementation, and that renderer implementation will be used to - construct a response from the view return value. If the ``renderer`` value - contains a dot (``.``), the specified term will be treated as a path, and - the filename extension of the last element in the path will be used to look - up the renderer implementation, which will be passed the full path. - - When the renderer is a path, although a path is usually just a simple - relative pathname (e.g. ``templates/foo.pt``, implying that a template - named "foo.pt" is in the "templates" directory relative to the directory of - the current :term:`package`), a path can be absolute, starting with a slash - on UNIX or a drive letter prefix on Windows. The path can alternately be a - :term:`asset specification` in the form - ``some.dotted.package_name:relative/path``, making it possible to address - template assets which live in a separate package. + This is either a single string term (e.g., ``json``) or a string implying a + path or :term:`asset specification` (e.g., ``templates/views.pt``) naming a + :term:`renderer` implementation. If the ``renderer`` value does not contain + a dot (``.``), the specified string will be used to look up a renderer + implementation, and that renderer implementation will be used to construct a + response from the view return value. If the ``renderer`` value contains a + dot (``.``), the specified term will be treated as a path, and the filename + extension of the last element in the path will be used to look up the + renderer implementation, which will be passed the full path. + + When the renderer is a path—although a path is usually just a simple relative + pathname (e.g., ``templates/foo.pt``, implying that a template named "foo.pt" + is in the "templates" directory relative to the directory of the current + :term:`package`)—the path can be absolute, starting with a slash on UNIX or a + drive letter prefix on Windows. The path can alternatively be a :term:`asset + specification` in the form ``some.dotted.package_name:relative/path``, making + it possible to address template assets which live in a separate package. The ``renderer`` attribute is optional. If it is not defined, the "null" renderer is assumed (no rendering is performed and the value is passed back - to the upstream :app:`Pyramid` machinery unchanged). Note that if the - view callable itself returns a :term:`response` (see :ref:`the_response`), - the specified renderer implementation is never called. + to the upstream :app:`Pyramid` machinery unchanged). Note that if the view + callable itself returns a :term:`response` (see :ref:`the_response`), the + specified renderer implementation is never called. ``http_cache`` When you supply an ``http_cache`` value to a view configuration, the @@ -153,38 +151,36 @@ Non-Predicate Arguments associated view callable are modified. The value for ``http_cache`` may be one of the following: - - A nonzero integer. If it's a nonzero integer, it's treated as a number - of seconds. This number of seconds will be used to compute the - ``Expires`` header and the ``Cache-Control: max-age`` parameter of - responses to requests which call this view. For example: - ``http_cache=3600`` instructs the requesting browser to 'cache this - response for an hour, please'. + - A nonzero integer. If it's a nonzero integer, it's treated as a number of + seconds. This number of seconds will be used to compute the ``Expires`` + header and the ``Cache-Control: max-age`` parameter of responses to + requests which call this view. For example: ``http_cache=3600`` instructs + the requesting browser to 'cache this response for an hour, please'. - A ``datetime.timedelta`` instance. If it's a ``datetime.timedelta`` - instance, it will be converted into a number of seconds, and that number - of seconds will be used to compute the ``Expires`` header and the + instance, it will be converted into a number of seconds, and that number of + seconds will be used to compute the ``Expires`` header and the ``Cache-Control: max-age`` parameter of responses to requests which call this view. For example: ``http_cache=datetime.timedelta(days=1)`` instructs the requesting browser to 'cache this response for a day, please'. - - Zero (``0``). If the value is zero, the ``Cache-Control`` and - ``Expires`` headers present in all responses from this view will be - composed such that client browser cache (and any intermediate caches) are - instructed to never cache the response. - - - A two-tuple. If it's a two tuple (e.g. ``http_cache=(1, - {'public':True})``), the first value in the tuple may be a nonzero - integer or a ``datetime.timedelta`` instance; in either case this value - will be used as the number of seconds to cache the response. The second - value in the tuple must be a dictionary. The values present in the - dictionary will be used as input to the ``Cache-Control`` response - header. For example: ``http_cache=(3600, {'public':True})`` means 'cache - for an hour, and add ``public`` to the Cache-Control header of the - response'. All keys and values supported by the - ``webob.cachecontrol.CacheControl`` interface may be added to the - dictionary. Supplying ``{'public':True}`` is equivalent to calling - ``response.cache_control.public = True``. + - Zero (``0``). If the value is zero, the ``Cache-Control`` and ``Expires`` + headers present in all responses from this view will be composed such that + client browser cache (and any intermediate caches) are instructed to never + cache the response. + + - A two-tuple. If it's a two-tuple (e.g., ``http_cache=(1, + {'public':True})``), the first value in the tuple may be a nonzero integer + or a ``datetime.timedelta`` instance. In either case this value will be + used as the number of seconds to cache the response. The second value in + the tuple must be a dictionary. The values present in the dictionary will + be used as input to the ``Cache-Control`` response header. For example: + ``http_cache=(3600, {'public':True})`` means 'cache for an hour, and add + ``public`` to the Cache-Control header of the response'. All keys and + values supported by the ``webob.cachecontrol.CacheControl`` interface may + be added to the dictionary. Supplying ``{'public':True}`` is equivalent to + calling ``response.cache_control.public = True``. Providing a non-tuple value as ``http_cache`` is equivalent to calling ``response.cache_expires(value)`` within your view's body. @@ -192,35 +188,35 @@ Non-Predicate Arguments Providing a two-tuple value as ``http_cache`` is equivalent to calling ``response.cache_expires(value[0], **value[1])`` within your view's body. - If you wish to avoid influencing, the ``Expires`` header, and instead wish - to only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` - with the first element of ``None``, e.g.: ``(None, {'public':True})``. + If you wish to avoid influencing the ``Expires`` header, and instead wish to + only influence ``Cache-Control`` headers, pass a tuple as ``http_cache`` with + the first element of ``None``, i.e., ``(None, {'public':True})``. ``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`` - attribute of its own :term:`request`, and the :term:`response` returned by - this view as the ``request.wrapped_response`` attribute of its own request. - Using a wrapper makes it possible to "chain" views together to form a - composite response. The response of the outermost wrapper view will be - returned to the user. The wrapper view will be found as any view is found: - see :ref:`view_lookup`. The "best" wrapper view will be found based on the - lookup ordering: "under the hood" this wrapper view is looked up via - ``pyramid.view.render_view_to_response(context, request, - 'wrapper_viewname')``. The context and request of a wrapper view is the - same context and request of the inner view. - - If ``wrapper`` is not supplied, no wrapper view is used. + The :term:`view name` of a different :term:`view configuration` which will + receive the response body of this view as the ``request.wrapped_body`` + attribute of its own :term:`request`, and the :term:`response` returned by + this view as the ``request.wrapped_response`` attribute of its own request. + Using a wrapper makes it possible to "chain" views together to form a + composite response. The response of the outermost wrapper view will be + returned to the user. The wrapper view will be found as any view is found. + See :ref:`view_lookup`. The "best" wrapper view will be found based on the + lookup ordering. "Under the hood" this wrapper view is looked up via + ``pyramid.view.render_view_to_response(context, request, + 'wrapper_viewname')``. The context and request of a wrapper view is the same + context and request of the inner view. + + If ``wrapper`` is not supplied, no wrapper view is used. ``decorator`` A :term:`dotted Python name` to a function (or the function itself) which - will be used to decorate the registered :term:`view callable`. The - decorator function will be called with the view callable as a single - argument. The view callable it is passed will accept ``(context, - request)``. The decorator must return a replacement view callable which - also accepts ``(context, request)``. The ``decorator`` may also be an - iterable of decorators, in which case they will be applied one after the - other to the view, in reverse order. For example:: + will be used to decorate the registered :term:`view callable`. The decorator + function will be called with the view callable as a single argument. The + view callable it is passed will accept ``(context, request)``. The decorator + must return a replacement view callable which also accepts ``(context, + request)``. The ``decorator`` may also be an iterable of decorators, in which + case they will be applied one after the other to the view, in reverse order. + For example:: @view_config(..., decorator=(decorator2, decorator1)) def myview(request): @@ -253,33 +249,32 @@ Non-Predicate Arguments A Python object or :term:`dotted Python name` which refers to a :term:`view mapper`, or ``None``. By default it is ``None``, which indicates that the view should use the default view mapper. This plug-point is useful for - Pyramid extension developers, but it's not very useful for 'civilians' who + Pyramid extension developers, but it's not very useful for "civilians" who are just developing stock Pyramid applications. Pay no attention to the man behind the curtain. Predicate Arguments +++++++++++++++++++ -These arguments modify view lookup behavior. In general, the more predicate -arguments that are supplied, the more specific, and narrower the usage of the +These arguments modify view lookup behavior. In general the more predicate +arguments that are supplied, the more specific and narrower the usage of the configured view. ``name`` The :term:`view name` required to match this view callable. A ``name`` - argument is typically only used when your application uses - :term:`traversal`. Read :ref:`traversal_chapter` to understand the concept - of a view name. + argument is typically only used when your application uses :term:`traversal`. + Read :ref:`traversal_chapter` to understand the concept of a view name. If ``name`` is not supplied, the empty string is used (implying the default view). ``context`` - An object representing a Python class that the :term:`context` resource - must be an instance of *or* the :term:`interface` that the :term:`context` + An object representing a Python class of which the :term:`context` resource + must be an instance *or* the :term:`interface` that the :term:`context` resource must provide in order for this view to be found and called. This predicate is true when the :term:`context` resource is an instance of the - represented class or if the :term:`context` resource provides the - represented interface; it is otherwise false. + represented class or if the :term:`context` resource provides the represented + interface; it is otherwise false. If ``context`` is not supplied, the value ``None``, which matches any resource, is used. @@ -289,68 +284,68 @@ configured view. the named route has matched. This value must match the ``name`` of a :term:`route configuration` - declaration (see :ref:`urldispatch_chapter`) that must match before this - view will be called. Note that the ``route`` configuration referred to by + declaration (see :ref:`urldispatch_chapter`) that must match before this view + will be called. Note that the ``route`` configuration referred to by ``route_name`` will usually have a ``*traverse`` token in the value of its ``pattern``, representing a part of the path that will be used by :term:`traversal` against the result of the route's :term:`root factory`. If ``route_name`` is not supplied, the view callable will only have a chance of being invoked if no other route was matched. This is when the - request/context pair found via :term:`resource location` does not indicate - it matched any configured route. + request/context pair found via :term:`resource location` does not indicate it + matched any configured route. ``request_type`` This value should be an :term:`interface` that the :term:`request` must provide in order for this view to be found and called. - If ``request_type`` is not supplied, the value ``None`` is used, implying - any request type. + If ``request_type`` is not supplied, the value ``None`` is used, implying any + request type. *This is an advanced feature, not often used by "civilians"*. ``request_method`` This value can be either a string (such as ``"GET"``, ``"POST"``, - ``"PUT"``, ``"DELETE"``, ``"HEAD"`` or ``"OPTIONS"``) representing an - HTTP ``REQUEST_METHOD``, or a tuple containing one or more of these - strings. A view declaration with this argument ensures that the - view will only be called when the ``method`` attribute of the - request (aka the ``REQUEST_METHOD`` of the WSGI environment) matches - a supplied value. Note that use of ``"GET"`` also implies that the - view will respond to ``"HEAD"`` as of Pyramid 1.4. - - If ``request_method`` is not supplied, the view will be invoked regardless - of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. + ``"PUT"``, ``"DELETE"``, ``"HEAD"``, or ``"OPTIONS"``) representing an HTTP + ``REQUEST_METHOD`` or a tuple containing one or more of these strings. A + view declaration with this argument ensures that the view will only be called + when the ``method`` attribute of the request (i.e., the ``REQUEST_METHOD`` of + the WSGI environment) matches a supplied value. + + .. versionchanged:: 1.4 + The use of ``"GET"`` also implies that the view will respond to ``"HEAD"``. + + If ``request_method`` is not supplied, the view will be invoked regardless of + the ``REQUEST_METHOD`` of the :term:`WSGI` environment. ``request_param`` This value can be any string or a sequence of strings. A view declaration with this argument ensures that the view will only be called when the :term:`request` has a key in the ``request.params`` dictionary (an HTTP - ``GET`` or ``POST`` variable) that has a name which matches the - supplied value. + ``GET`` or ``POST`` variable) that has a name which matches the supplied + value. - If any value supplied has a ``=`` sign in it, - e.g. ``request_param="foo=123"``, then the key (``foo``) must both exist - in the ``request.params`` dictionary, *and* the value must match the right - hand side of the expression (``123``) for the view to "match" the current - request. + If any value supplied has an ``=`` sign in it, e.g., + ``request_param="foo=123"``, then the key (``foo``) must both exist in the + ``request.params`` dictionary, *and* the value must match the right hand side + of the expression (``123``) for the view to "match" the current request. If ``request_param`` is not supplied, the view will be invoked without consideration of keys and values in the ``request.params`` dictionary. ``match_param`` - This param may be either a single string of the format "key=value" or a - tuple containing one or more of these strings. + This param may be either a single string of the format "key=value" or a tuple + containing one or more of these strings. This argument ensures that the view will only be called when the - :term:`request` has key/value pairs in its :term:`matchdict` that equal - those supplied in the predicate. e.g. ``match_param="action=edit"`` would + :term:`request` has key/value pairs in its :term:`matchdict` that equal those + supplied in the predicate. For example, ``match_param="action=edit"`` would require the ``action`` parameter in the :term:`matchdict` match the right hand side of the expression (``edit``) for the view to "match" the current request. - If the ``match_param`` is a tuple, every key/value pair must match - for the predicate to pass. + If the ``match_param`` is a tuple, every key/value pair must match for the + predicate to pass. If ``match_param`` is not supplied, the view will be invoked without consideration of the keys and values in ``request.matchdict``. @@ -358,41 +353,40 @@ configured view. .. versionadded:: 1.2 ``containment`` - This value should be a reference to a Python class or :term:`interface` - that a parent object in the context resource's :term:`lineage` must provide - in order for this view to be found and called. The resources in your - resource tree must be "location-aware" to use this feature. + This value should be a reference to a Python class or :term:`interface` that + a parent object in the context resource's :term:`lineage` must provide in + order for this view to be found and called. The resources in your resource + tree must be "location-aware" to use this feature. - If ``containment`` is not supplied, the interfaces and classes in the - lineage are not considered when deciding whether or not to invoke the view - callable. + If ``containment`` is not supplied, the interfaces and classes in the lineage + are not considered when deciding whether or not to invoke the view callable. See :ref:`location_aware` for more information about location-awareness. ``xhr`` This value should be either ``True`` or ``False``. If this value is specified and is ``True``, the :term:`WSGI` environment must possess an - ``HTTP_X_REQUESTED_WITH`` (aka ``X-Requested-With``) header that has the + ``HTTP_X_REQUESTED_WITH`` header (i.e., ``X-Requested-With``) that has the value ``XMLHttpRequest`` for the associated view callable to be found and called. This is useful for detecting AJAX requests issued from jQuery, - Prototype and other Javascript libraries. + Prototype, and other Javascript libraries. - If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is - not taken into consideration when deciding whether or not to invoke the + If ``xhr`` is not specified, the ``HTTP_X_REQUESTED_WITH`` HTTP header is not + taken into consideration when deciding whether or not to invoke the associated view callable. ``accept`` - The value of this argument represents a match query for one or more - mimetypes in the ``Accept`` HTTP request header. If this value is - specified, it must be in one of the following forms: a mimetype match token - in the form ``text/plain``, a wildcard mimetype match token in the form - ``text/*`` or a match-all wildcard mimetype match token in the form - ``*/*``. If any of the forms matches the ``Accept`` header of the request, - this predicate will be true. - - If ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not - taken into consideration when deciding whether or not to invoke the - associated view callable. + The value of this argument represents a match query for one or more mimetypes + in the ``Accept`` HTTP request header. If this value is specified, it must + be in one of the following forms: a mimetype match token in the form + ``text/plain``, a wildcard mimetype match token in the form ``text/*``, or a + match-all wildcard mimetype match token in the form ``*/*``. If any of the + forms matches the ``Accept`` header of the request, this predicate will be + true. + + If ``accept`` is not specified, the ``HTTP_ACCEPT`` HTTP header is not taken + into consideration when deciding whether or not to invoke the associated view + callable. ``header`` This value represents an HTTP header name or a header name/value pair. @@ -400,94 +394,92 @@ configured view. If ``header`` is specified, it must be a header name or a ``headername:headervalue`` pair. - If ``header`` is specified without a value (a bare header name only, - e.g. ``If-Modified-Since``), the view will only be invoked if the HTTP - header exists with any value in the request. + If ``header`` is specified without a value (a bare header name only, e.g., + ``If-Modified-Since``), the view will only be invoked if the HTTP header + exists with any value in the request. - If ``header`` is specified, and possesses a name/value pair - (e.g. ``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP - header exists *and* the HTTP header matches the value requested. When the - ``headervalue`` contains a ``:`` (colon), it will be considered a - name/value pair (e.g. ``User-Agent:Mozilla/.*`` or ``Host:localhost``). - The value portion should be a regular expression. + If ``header`` is specified, and possesses a name/value pair (e.g., + ``User-Agent:Mozilla/.*``), the view will only be invoked if the HTTP header + exists *and* the HTTP header matches the value requested. When the + ``headervalue`` contains a ``:`` (colon), it will be considered a name/value + pair (e.g., ``User-Agent:Mozilla/.*`` or ``Host:localhost``). The value + portion should be a regular expression. Whether or not the value represents a header name or a header name/value pair, the case of the header name is not significant. - If ``header`` is not specified, the composition, presence or absence of - HTTP headers is not taken into consideration when deciding whether or not - to invoke the associated view callable. + If ``header`` is not specified, the composition, presence, or absence of HTTP + headers is not taken into consideration when deciding whether or not to + invoke the associated view callable. ``path_info`` This value represents a regular expression pattern that will be tested - against the ``PATH_INFO`` WSGI environment variable to decide whether or - not to call the associated view callable. If the regex matches, this - predicate will be ``True``. + against the ``PATH_INFO`` WSGI environment variable to decide whether or not + to call the associated view callable. If the regex matches, this predicate + will be ``True``. If ``path_info`` is not specified, the WSGI ``PATH_INFO`` is not taken into consideration when deciding whether or not to invoke the associated view callable. ``check_csrf`` - If specified, this value should be one of ``None``, ``True``, ``False``, or - a string representing the 'check name'. If the value is ``True`` or a - string, CSRF checking will be performed. If the value is ``False`` or - ``None``, CSRF checking will not be performed. + If specified, this value should be one of ``None``, ``True``, ``False``, or a + string representing the "check name". If the value is ``True`` or a string, + CSRF checking will be performed. If the value is ``False`` or ``None``, CSRF + checking will not be performed. - If the value provided is a string, that string will be used as the 'check - name'. If the value provided is ``True``, ``csrf_token`` will be used as - the check name. + If the value provided is a string, that string will be used as the "check + name". If the value provided is ``True``, ``csrf_token`` will be used as the + check name. If CSRF checking is performed, the checked value will be the value of ``request.params[check_name]``. This value will be compared against the value of ``request.session.get_csrf_token()``, and the check will pass if - these two values are the same. If the check passes, the associated view - will be permitted to execute. If the check fails, the associated view - will not be permitted to execute. + these two values are the same. If the check passes, the associated view will + be permitted to execute. If the check fails, the associated view will not be + permitted to execute. - Note that using this feature requires a :term:`session factory` to have - been configured. + Note that using this feature requires a :term:`session factory` to have been + configured. .. versionadded:: 1.4a2 ``physical_path`` If specified, this value should be a string or a tuple representing the :term:`physical path` of the context found via traversal for this predicate - to match as true. For example: ``physical_path='/'`` or - ``physical_path='/a/b/c'`` or ``physical_path=('', 'a', 'b', 'c')``. This is - not a path prefix match or a regex, it's a whole-path match. It's useful + to match as true. For example, ``physical_path='/'``, + ``physical_path='/a/b/c'``, or ``physical_path=('', 'a', 'b', 'c')``. This + is not a path prefix match or a regex, but a whole-path match. It's useful when you want to always potentially show a view when some object is traversed to, but you can't be sure about what kind of object it will be, so you can't - use the ``context`` predicate. The individual path elements inbetween slash + use the ``context`` predicate. The individual path elements between slash characters or in tuple elements should be the Unicode representation of the name of the resource and should not be encoded in any way. .. versionadded:: 1.4a3 ``effective_principals`` - If specified, this value should be a :term:`principal` identifier or a sequence of principal identifiers. If the - :meth:`pyramid.request.Request.effective_principals` method indicates that every - principal named in the argument list is present in the current request, this - predicate will return True; otherwise it will return False. For example: - ``effective_principals=pyramid.security.Authenticated`` or + :meth:`pyramid.request.Request.effective_principals` method indicates that + every principal named in the argument list is present in the current request, + this predicate will return True; otherwise it will return False. For + example: ``effective_principals=pyramid.security.Authenticated`` or ``effective_principals=('fred', 'group:admins')``. .. versionadded:: 1.4a4 ``custom_predicates`` - If ``custom_predicates`` is specified, it must be a sequence of references - to custom predicate callables. Use custom predicates when no set of - predefined predicates do what you need. Custom predicates can be combined - with predefined predicates as necessary. Each custom predicate callable - should accept two arguments: ``context`` and ``request`` and should return - either ``True`` or ``False`` after doing arbitrary evaluation of the - context resource and/or the request. If all callables return ``True``, the + If ``custom_predicates`` is specified, it must be a sequence of references to + custom predicate callables. Use custom predicates when no set of predefined + predicates do what you need. Custom predicates can be combined with + predefined predicates as necessary. Each custom predicate callable should + accept two arguments, ``context`` and ``request``, and should return either + ``True`` or ``False`` after doing arbitrary evaluation of the context + resource and/or the request. If all callables return ``True``, the associated view callable will be considered viable for a given request. - If ``custom_predicates`` is not specified, no custom predicates are - used. + If ``custom_predicates`` is not specified, no custom predicates are used. ``predicates`` Pass a key/value pair here to use a third-party predicate registered via @@ -515,8 +507,8 @@ You can invert the meaning of any predicate value by wrapping it in a call to request_method=not_('POST') ) -The above example will ensure that the view is called if the request method -is *not* ``POST``, at least if no other view is more specific. +The above example will ensure that the view is called if the request method is +*not* ``POST``, at least if no other view is more specific. This technique of wrapping a predicate value in ``not_`` can be used anywhere predicate values are accepted: @@ -538,11 +530,11 @@ Adding View Configuration Using the ``@view_config`` Decorator .. warning:: - Using this feature tends to slow down application startup slightly, as - more work is performed at application startup to scan for view - configuration declarations. For maximum startup performance, use the view - configuration method described in - :ref:`mapping_views_using_imperative_config_section` instead. + Using this feature tends to slow down application startup slightly, as more + work is performed at application startup to scan for view configuration + declarations. For maximum startup performance, use the view configuration + method described in :ref:`mapping_views_using_imperative_config_section` + instead. The :class:`~pyramid.view.view_config` decorator can be used to associate :term:`view configuration` information with a function, method, or class that @@ -592,9 +584,8 @@ request method, request type, request param, route name, or containment. The mere existence of a ``@view_config`` decorator doesn't suffice to perform view configuration. All that the decorator does is "annotate" the function with your configuration declarations, it doesn't process them. To make -:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, -you *must* use the ``scan`` method of a -:class:`pyramid.config.Configurator`: +:app:`Pyramid` process your :class:`pyramid.view.view_config` declarations, you +*must* use the ``scan`` method of a :class:`pyramid.config.Configurator`: .. code-block:: python :linenos: @@ -603,9 +594,9 @@ you *must* use the ``scan`` method of a # pyramid.config.Configurator class config.scan() -Please see :ref:`decorations_and_code_scanning` for detailed information -about what happens when code is scanned for configuration declarations -resulting from use of decorators like :class:`~pyramid.view.view_config`. +Please see :ref:`decorations_and_code_scanning` for detailed information about +what happens when code is scanned for configuration declarations resulting from +use of decorators like :class:`~pyramid.view.view_config`. See :ref:`configuration_module` for additional API arguments to the :meth:`~pyramid.config.Configurator.scan` method. For example, the method @@ -613,10 +604,10 @@ allows you to supply a ``package`` argument to better control exactly *which* code will be scanned. All arguments to the :class:`~pyramid.view.view_config` decorator mean -precisely the same thing as they would if they were passed as arguments to -the :meth:`pyramid.config.Configurator.add_view` method save for the ``view`` -argument. Usage of the :class:`~pyramid.view.view_config` decorator is a -form of :term:`declarative configuration`, while +precisely the same thing as they would if they were passed as arguments to the +:meth:`pyramid.config.Configurator.add_view` method save for the ``view`` +argument. Usage of the :class:`~pyramid.view.view_config` decorator is a form +of :term:`declarative configuration`, while :meth:`pyramid.config.Configurator.add_view` is a form of :term:`imperative configuration`. However, they both do the same thing. @@ -644,8 +635,8 @@ If your view callable is a function, it may be used as a function decorator: return Response('edited!') If your view callable is a class, the decorator can also be used as a class -decorator. All the arguments to the decorator are the same when applied -against a class as when they are applied against a function. For example: +decorator. All the arguments to the decorator are the same when applied against +a class as when they are applied against a function. For example: .. code-block:: python :linenos: @@ -696,15 +687,15 @@ The decorator can also be used against a method of a class: When the decorator is used against a method of a class, a view is registered for the *class*, so the class constructor must accept an argument list in one -of two forms: either it must accept a single argument ``request`` or it must -accept two arguments, ``context, request``. +of two forms: either a single argument, ``request``, or two arguments, +``context, request``. The method which is decorated must return a :term:`response`. Using the decorator against a particular method of a class is equivalent to -using the ``attr`` parameter in a decorator attached to the class itself. -For example, the above registration implied by the decorator being used -against the ``amethod`` method could be spelled equivalently as the below: +using the ``attr`` parameter in a decorator attached to the class itself. For +example, the above registration implied by the decorator being used against the +``amethod`` method could be written equivalently as follows: .. code-block:: python :linenos: @@ -730,9 +721,9 @@ Adding View Configuration Using :meth:`~pyramid.config.Configurator.add_view` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :meth:`pyramid.config.Configurator.add_view` method within -:ref:`configuration_module` is used to configure a view "imperatively" -(without a :class:`~pyramid.view.view_config` decorator). The arguments to -this method are very similar to the arguments that you provide to the +:ref:`configuration_module` is used to configure a view "imperatively" (without +a :class:`~pyramid.view.view_config` decorator). The arguments to this method +are very similar to the arguments that you provide to the :class:`~pyramid.view.view_config` decorator. For example: .. code-block:: python @@ -747,10 +738,10 @@ this method are very similar to the arguments that you provide to the # pyramid.config.Configurator class config.add_view(hello_world, route_name='hello') -The first argument, a :term:`view callable`, is the only required argument. -It must either be a Python object which is the view itself or a -:term:`dotted Python name` to such an object. -In the above example, the ``view callable`` is the ``hello_world`` function. +The first argument, a :term:`view callable`, is the only required argument. It +must either be a Python object which is the view itself or a :term:`dotted +Python name` to such an object. In the above example, the ``view callable`` is +the ``hello_world`` function. When you use only :meth:`~pyramid.config.Configurator.add_view` to add view configurations, you don't need to issue a :term:`scan` in order for the view @@ -772,7 +763,7 @@ defaults to the view configuration information used by every ``@view_config`` decorator that decorates a method of that class. For instance, if you've got a class that has methods that represent "REST -actions", all which are mapped to the same route, but different request +actions", all of which are mapped to the same route but different request methods, instead of this: .. code-block:: python @@ -824,17 +815,17 @@ You can do this: return Response('delete') In the above example, we were able to take the ``route_name='rest'`` argument -out of the call to each individual ``@view_config`` statement, because we -used a ``@view_defaults`` class decorator to provide the argument as a -default to each view method it possessed. +out of the call to each individual ``@view_config`` statement because we used a +``@view_defaults`` class decorator to provide the argument as a default to each +view method it possessed. Arguments passed to ``@view_config`` will override any default passed to ``@view_defaults``. The ``view_defaults`` class decorator can also provide defaults to the :meth:`pyramid.config.Configurator.add_view` directive when a decorated class -is passed to that directive as its ``view`` argument. For example, instead -of this: +is passed to that directive as its ``view`` argument. For example, instead of +this: .. code-block:: python :linenos: @@ -868,7 +859,7 @@ of this: To reduce the amount of repetition in the ``config.add_view`` statements, we can move the ``route_name='rest'`` argument to a ``@view_defaults`` class -decorator on the RESTView class: +decorator on the ``RESTView`` class: .. code-block:: python :linenos: @@ -904,8 +895,8 @@ decorator on the RESTView class: argument passed to ``view_defaults`` provides a default for the view configurations of methods of the class it's decorating. -Normal Python inheritance rules apply to defaults added via -``view_defaults``. For example: +Normal Python inheritance rules apply to defaults added via ``view_defaults``. +For example: .. code-block:: python :linenos: @@ -919,8 +910,8 @@ Normal Python inheritance rules apply to defaults added via The ``Bar`` class above will inherit its view defaults from the arguments passed to the ``view_defaults`` decorator of the ``Foo`` class. To prevent -this from happening, use a ``view_defaults`` decorator without any arguments -on the subclass: +this from happening, use a ``view_defaults`` decorator without any arguments on +the subclass: .. code-block:: python :linenos: @@ -946,11 +937,11 @@ Configuring View Security ~~~~~~~~~~~~~~~~~~~~~~~~~ If an :term:`authorization policy` is active, any :term:`permission` attached -to a :term:`view configuration` found during view lookup will be verified. -This will ensure that the currently authenticated user possesses that -permission against the :term:`context` resource before the view function is -actually called. Here's an example of specifying a permission in a view -configuration using :meth:`~pyramid.config.Configurator.add_view`: +to a :term:`view configuration` found during view lookup will be verified. This +will ensure that the currently authenticated user possesses that permission +against the :term:`context` resource before the view function is actually +called. Here's an example of specifying a permission in a view configuration +using :meth:`~pyramid.config.Configurator.add_view`: .. code-block:: python :linenos: @@ -964,8 +955,8 @@ configuration using :meth:`~pyramid.config.Configurator.add_view`: When an :term:`authorization policy` is enabled, this view will be protected with the ``add`` permission. The view will *not be called* if the user does not possess the ``add`` permission relative to the current :term:`context`. -Instead the :term:`forbidden view` result will be returned to the client as -per :ref:`protecting_views`. +Instead the :term:`forbidden view` result will be returned to the client as per +:ref:`protecting_views`. .. index:: single: debugging not found errors @@ -976,14 +967,14 @@ per :ref:`protecting_views`. :exc:`~pyramid.exceptions.NotFound` Errors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It's useful to be able to debug :exc:`~pyramid.exceptions.NotFound` -error responses when they -occur unexpectedly due to an application registry misconfiguration. To debug -these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the -``pyramid.debug_notfound`` configuration file setting. Details of why a view -was not found will be printed to ``stderr``, and the browser representation of -the error will include the same information. See :ref:`environment_chapter` -for more information about how, and where to set these values. +It's useful to be able to debug :exc:`~pyramid.exceptions.NotFound` error +responses when they occur unexpectedly due to an application registry +misconfiguration. To debug these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` +environment variable or the ``pyramid.debug_notfound`` configuration file +setting. Details of why a view was not found will be printed to ``stderr``, +and the browser representation of the error will include the same information. +See :ref:`environment_chapter` for more information about how, and where to set +these values. .. index:: single: HTTP caching @@ -995,23 +986,23 @@ Influencing HTTP Caching .. versionadded:: 1.1 -When a non-``None`` ``http_cache`` argument is passed to a view -configuration, Pyramid will set ``Expires`` and ``Cache-Control`` response -headers in the resulting response, causing browsers to cache the response -data for some time. See ``http_cache`` in :ref:`nonpredicate_view_args` for -the allowable values and what they mean. - -Sometimes it's undesirable to have these headers set as the result of -returning a response from a view, even though you'd like to decorate the view -with a view configuration decorator that has ``http_cache``. Perhaps there's -an alternate branch in your view code that returns a response that should -never be cacheable, while the "normal" branch returns something that should -always be cacheable. If this is the case, set the ``prevent_auto`` attribute -of the ``response.cache_control`` object to a non-``False`` value. For -example, the below view callable is configured with a ``@view_config`` -decorator that indicates any response from the view should be cached for 3600 -seconds. However, the view itself prevents caching from taking place unless -there's a ``should_cache`` GET or POST variable: +When a non-``None`` ``http_cache`` argument is passed to a view configuration, +Pyramid will set ``Expires`` and ``Cache-Control`` response headers in the +resulting response, causing browsers to cache the response data for some time. +See ``http_cache`` in :ref:`nonpredicate_view_args` for the allowable values +and what they mean. + +Sometimes it's undesirable to have these headers set as the result of returning +a response from a view, even though you'd like to decorate the view with a view +configuration decorator that has ``http_cache``. Perhaps there's an +alternative branch in your view code that returns a response that should never +be cacheable, while the "normal" branch returns something that should always be +cacheable. If this is the case, set the ``prevent_auto`` attribute of the +``response.cache_control`` object to a non-``False`` value. For example, the +below view callable is configured with a ``@view_config`` decorator that +indicates any response from the view should be cached for 3600 seconds. +However, the view itself prevents caching from taking place unless there's a +``should_cache`` GET or POST variable: .. code-block:: python @@ -1024,19 +1015,19 @@ there's a ``should_cache`` GET or POST variable: response.cache_control.prevent_auto = True return response -Note that the ``http_cache`` machinery will overwrite or add to caching -headers you set within the view itself unless you use ``prevent_auto``. +Note that the ``http_cache`` machinery will overwrite or add to caching headers +you set within the view itself, unless you use ``prevent_auto``. -You can also turn off the effect of ``http_cache`` entirely for the duration -of a Pyramid application lifetime. To do so, set the +You can also turn off the effect of ``http_cache`` entirely for the duration of +a Pyramid application lifetime. To do so, set the ``PYRAMID_PREVENT_HTTP_CACHE`` environment variable or the -``pyramid.prevent_http_cache`` configuration value setting to a true value. -For more information, see :ref:`preventing_http_caching`. +``pyramid.prevent_http_cache`` configuration value setting to a true value. For +more information, see :ref:`preventing_http_caching`. Note that setting ``pyramid.prevent_http_cache`` will have no effect on caching headers that your application code itself sets. It will only prevent caching -headers that would have been set by the Pyramid HTTP caching machinery -invoked as the result of the ``http_cache`` argument to view configuration. +headers that would have been set by the Pyramid HTTP caching machinery invoked +as the result of the ``http_cache`` argument to view configuration. .. index:: pair: view configuration; debugging -- cgit v1.2.3 From 2637158227f6e53acb1dbc40953377b797ac8e23 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 12 Oct 2015 03:20:14 -0700 Subject: rewrap 79 cols --- docs/narr/viewconfig.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index cb3e78be3..a7d0848ca 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -193,20 +193,20 @@ Non-Predicate Arguments the first element of ``None``, i.e., ``(None, {'public':True})``. ``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`` - attribute of its own :term:`request`, and the :term:`response` returned by - this view as the ``request.wrapped_response`` attribute of its own request. - Using a wrapper makes it possible to "chain" views together to form a - composite response. The response of the outermost wrapper view will be - returned to the user. The wrapper view will be found as any view is found. - See :ref:`view_lookup`. The "best" wrapper view will be found based on the - lookup ordering. "Under the hood" this wrapper view is looked up via - ``pyramid.view.render_view_to_response(context, request, - 'wrapper_viewname')``. The context and request of a wrapper view is the same - context and request of the inner view. - - If ``wrapper`` is not supplied, no wrapper view is used. + The :term:`view name` of a different :term:`view configuration` which will + receive the response body of this view as the ``request.wrapped_body`` + attribute of its own :term:`request`, and the :term:`response` returned by + this view as the ``request.wrapped_response`` attribute of its own request. + Using a wrapper makes it possible to "chain" views together to form a + composite response. The response of the outermost wrapper view will be + returned to the user. The wrapper view will be found as any view is found. + See :ref:`view_lookup`. The "best" wrapper view will be found based on the + lookup ordering. "Under the hood" this wrapper view is looked up via + ``pyramid.view.render_view_to_response(context, request, + 'wrapper_viewname')``. The context and request of a wrapper view is the same + context and request of the inner view. + + If ``wrapper`` is not supplied, no wrapper view is used. ``decorator`` A :term:`dotted Python name` to a function (or the function itself) which -- cgit v1.2.3 From 4a6aac80123afac25cb2c8a86269159e2735a11f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 13 Oct 2015 15:43:47 -0700 Subject: minor grammar, add rst directives for versionadded/changed, rewrap 79 cols --- docs/narr/assets.rst | 430 +++++++++++++++++++++++++-------------------------- 1 file changed, 213 insertions(+), 217 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 1beabe8de..4c0013298 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -7,8 +7,8 @@ Static Assets ============= -An :term:`asset` is any file contained within a Python :term:`package` which -is *not* a Python source code file. For example, each of the following is an +An :term:`asset` is any file contained within a Python :term:`package` which is +*not* a Python source code file. For example, each of the following is an asset: - a GIF image file contained within a Python package or contained within any @@ -20,20 +20,20 @@ asset: - a JavaScript source file contained within a Python package or contained within any subdirectory of a Python package. -- A directory within a package that does not have an ``__init__.py`` - in it (if it possessed an ``__init__.py`` it would *be* a package). +- A directory within a package that does not have an ``__init__.py`` in it (if + it possessed an ``__init__.py`` it would *be* a package). - a :term:`Chameleon` or :term:`Mako` template file contained within a Python package. The use of assets is quite common in most web development projects. For example, when you create a :app:`Pyramid` application using one of the -available scaffolds, as described in :ref:`creating_a_project`, the -directory representing the application contains a Python :term:`package`. -Within that Python package, there are directories full of files which are -static assets. For example, there's a ``static`` directory which contains -``.css``, ``.js``, and ``.gif`` files. These asset files are delivered when -a user visits an application URL. +available scaffolds, as described in :ref:`creating_a_project`, the directory +representing the application contains a Python :term:`package`. Within that +Python package, there are directories full of files which are static assets. +For example, there's a ``static`` directory which contains ``.css``, ``.js``, +and ``.gif`` files. These asset files are delivered when a user visits an +application URL. .. index:: single: asset specifications @@ -45,10 +45,10 @@ Understanding Asset Specifications Let's imagine you've created a :app:`Pyramid` application that uses a :term:`Chameleon` ZPT template via the -:func:`pyramid.renderers.render_to_response` API. For example, the -application might address the asset using the :term:`asset specification` -``myapp:templates/some_template.pt`` using that API within a ``views.py`` -file inside a ``myapp`` package: +:func:`pyramid.renderers.render_to_response` API. For example, the application +might address the asset using the :term:`asset specification` +``myapp:templates/some_template.pt`` using that API within a ``views.py`` file +inside a ``myapp`` package: .. code-block:: python :linenos: @@ -66,23 +66,23 @@ two parts: - The *asset name* (``templates/some_template.pt``), relative to the package directory. -The two parts are separated by the colon character. +The two parts are separated by a colon ``:`` character. -:app:`Pyramid` uses the Python :term:`pkg_resources` API to resolve the -package name and asset name to an absolute (operating-system-specific) file -name. It eventually passes this resolved absolute filesystem path to the -Chameleon templating engine, which then uses it to load, parse, and execute -the template file. +:app:`Pyramid` uses the Python :term:`pkg_resources` API to resolve the package +name and asset name to an absolute (operating system-specific) file name. It +eventually passes this resolved absolute filesystem path to the Chameleon +templating engine, which then uses it to load, parse, and execute the template +file. There is a second form of asset specification: a *relative* asset specification. Instead of using an "absolute" asset specification which includes the package name, in certain circumstances you can omit the package name from the specification. For example, you might be able to use ``templates/mytemplate.pt`` instead of ``myapp:templates/some_template.pt``. -Such asset specifications are usually relative to a "current package." The +Such asset specifications are usually relative to a "current package". The "current package" is usually the package which contains the code that *uses* the asset specification. :app:`Pyramid` APIs which accept relative asset -specifications typically describe what the asset is relative to in their +specifications typically describe to what the asset is relative in their individual documentation. .. index:: @@ -96,17 +96,17 @@ Serving Static Assets :app:`Pyramid` makes it possible to serve up static asset files from a directory on a filesystem to an application user's browser. Use the -:meth:`pyramid.config.Configurator.add_static_view` to instruct -:app:`Pyramid` to serve static assets such as JavaScript and CSS files. This -mechanism makes a directory of static files available at a name relative to -the application root URL, e.g. ``/static`` or as an external URL. +:meth:`pyramid.config.Configurator.add_static_view` to instruct :app:`Pyramid` +to serve static assets, such as JavaScript and CSS files. This mechanism makes +a directory of static files available at a name relative to the application +root URL, e.g., ``/static``, or as an external URL. .. note:: - :meth:`~pyramid.config.Configurator.add_static_view` cannot serve a - single file, nor can it serve a directory of static files directly - relative to the root URL of a :app:`Pyramid` application. For these - features, see :ref:`advanced_static`. + :meth:`~pyramid.config.Configurator.add_static_view` cannot serve a single + file, nor can it serve a directory of static files directly relative to the + root URL of a :app:`Pyramid` application. For these features, see + :ref:`advanced_static`. Here's an example of a use of :meth:`~pyramid.config.Configurator.add_static_view` that will serve files up @@ -121,11 +121,11 @@ from the ``/var/www/static`` directory of the computer which runs the The ``name`` represents a URL *prefix*. In order for files that live in the ``path`` directory to be served, a URL that requests one of them must begin -with that prefix. In the example above, ``name`` is ``static``, and ``path`` -is ``/var/www/static``. In English, this means that you wish to serve the -files that live in ``/var/www/static`` as sub-URLs of the ``/static`` URL -prefix. Therefore, the file ``/var/www/static/foo.css`` will be returned -when the user visits your application's URL ``/static/foo.css``. +with that prefix. In the example above, ``name`` is ``static`` and ``path`` is +``/var/www/static``. In English this means that you wish to serve the files +that live in ``/var/www/static`` as sub-URLs of the ``/static`` URL prefix. +Therefore, the file ``/var/www/static/foo.css`` will be returned when the user +visits your application's URL ``/static/foo.css``. A static directory named at ``path`` may contain subdirectories recursively, and any subdirectories may hold files; these will be resolved by the static @@ -134,16 +134,16 @@ view for each particular type of file is dependent upon its file extension. By default, all files made available via :meth:`~pyramid.config.Configurator.add_static_view` are accessible by -completely anonymous users. Simple authorization can be required, however. -To protect a set of static files using a permission, in addition to passing -the required ``name`` and ``path`` arguments, also pass the ``permission`` -keyword argument to :meth:`~pyramid.config.Configurator.add_static_view`. -The value of the ``permission`` argument represents the :term:`permission` -that the user must have relative to the current :term:`context` when the -static view is invoked. A user will be required to possess this permission -to view any of the files represented by ``path`` of the static view. If your -static assets must be protected by a more complex authorization scheme, -see :ref:`advanced_static`. +completely anonymous users. Simple authorization can be required, however. To +protect a set of static files using a permission, in addition to passing the +required ``name`` and ``path`` arguments, also pass the ``permission`` keyword +argument to :meth:`~pyramid.config.Configurator.add_static_view`. The value of +the ``permission`` argument represents the :term:`permission` that the user +must have relative to the current :term:`context` when the static view is +invoked. A user will be required to possess this permission to view any of the +files represented by ``path`` of the static view. If your static assets must +be protected by a more complex authorization scheme, see +:ref:`advanced_static`. Here's another example that uses an :term:`asset specification` instead of an absolute path as the ``path`` argument. To convince @@ -163,14 +163,14 @@ may be a fully qualified :term:`asset specification` or an *absolute path*. Instead of representing a URL prefix, the ``name`` argument of a call to :meth:`~pyramid.config.Configurator.add_static_view` can alternately be a -*URL*. Each of examples we've seen so far have shown usage of the ``name`` -argument as a URL prefix. However, when ``name`` is a *URL*, static assets -can be served from an external webserver. In this mode, the ``name`` is used -as the URL prefix when generating a URL using +*URL*. Each of the examples we've seen so far have shown usage of the ``name`` +argument as a URL prefix. However, when ``name`` is a *URL*, static assets can +be served from an external webserver. In this mode, the ``name`` is used as +the URL prefix when generating a URL using :meth:`pyramid.request.Request.static_url`. -For example, :meth:`~pyramid.config.Configurator.add_static_view` may -be fed a ``name`` argument which is ``http://example.com/images``: +For example, :meth:`~pyramid.config.Configurator.add_static_view` may be fed a +``name`` argument which is ``http://example.com/images``: .. code-block:: python :linenos: @@ -179,15 +179,15 @@ be fed a ``name`` argument which is ``http://example.com/images``: config.add_static_view(name='http://example.com/images', path='mypackage:images') -Because :meth:`~pyramid.config.Configurator.add_static_view` is provided with -a ``name`` argument that is the URL ``http://example.com/images``, subsequent -calls to :meth:`~pyramid.request.Request.static_url` with paths that start -with the ``path`` argument passed to +Because :meth:`~pyramid.config.Configurator.add_static_view` is provided with a +``name`` argument that is the URL ``http://example.com/images``, subsequent +calls to :meth:`~pyramid.request.Request.static_url` with paths that start with +the ``path`` argument passed to :meth:`~pyramid.config.Configurator.add_static_view` will generate a URL -something like ``http://example.com/images/logo.png``. The external -webserver listening on ``example.com`` must be itself configured to respond -properly to such a request. The :meth:`~pyramid.request.Request.static_url` -API is discussed in more detail later in this chapter. +something like ``http://example.com/images/logo.png``. The external webserver +listening on ``example.com`` must be itself configured to respond properly to +such a request. The :meth:`~pyramid.request.Request.static_url` API is +discussed in more detail later in this chapter. .. index:: single: generating static asset urls @@ -199,11 +199,11 @@ API is discussed in more detail later in this chapter. Generating Static Asset URLs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a :meth:`~pyramid.config.Configurator.add_static_view` method is used to +When an :meth:`~pyramid.config.Configurator.add_static_view` method is used to register a static asset directory, a special helper API named :meth:`pyramid.request.Request.static_url` can be used to generate the -appropriate URL for an asset that lives in one of the directories named by -the static registration ``path`` attribute. +appropriate URL for an asset that lives in one of the directories named by the +static registration ``path`` attribute. For example, let's assume you create a set of static declarations like so: @@ -213,12 +213,12 @@ For example, let's assume you create a set of static declarations like so: config.add_static_view(name='static1', path='mypackage:assets/1') config.add_static_view(name='static2', path='mypackage:assets/2') -These declarations create URL-accessible directories which have URLs that -begin with ``/static1`` and ``/static2``, respectively. The assets in the +These declarations create URL-accessible directories which have URLs that begin +with ``/static1`` and ``/static2``, respectively. The assets in the ``assets/1`` directory of the ``mypackage`` package are consulted when a user -visits a URL which begins with ``/static1``, and the assets in the -``assets/2`` directory of the ``mypackage`` package are consulted when a user -visits a URL which begins with ``/static2``. +visits a URL which begins with ``/static1``, and the assets in the ``assets/2`` +directory of the ``mypackage`` package are consulted when a user visits a URL +which begins with ``/static2``. You needn't generate the URLs to static assets "by hand" in such a configuration. Instead, use the :meth:`~pyramid.request.Request.static_url` @@ -238,8 +238,8 @@ API to generate them for you. For example: If the request "application URL" of the running system is ``http://example.com``, the ``css_url`` generated above would be: -``http://example.com/static1/foo.css``. The ``js_url`` generated -above would be ``http://example.com/static2/foo.js``. +``http://example.com/static1/foo.css``. The ``js_url`` generated above would +be ``http://example.com/static2/foo.js``. One benefit of using the :meth:`~pyramid.request.Request.static_url` function rather than constructing static URLs "by hand" is that if you need to change @@ -249,10 +249,9 @@ resolve properly after the rename. URLs may also be generated by :meth:`~pyramid.request.Request.static_url` to static assets that live *outside* the :app:`Pyramid` application. This will happen when the :meth:`~pyramid.config.Configurator.add_static_view` API -associated with the path fed to :meth:`~pyramid.request.Request.static_url` -is a *URL* instead of a view name. For example, the ``name`` argument may be -``http://example.com`` while the ``path`` given may be -``mypackage:images``: +associated with the path fed to :meth:`~pyramid.request.Request.static_url` is +a *URL* instead of a view name. For example, the ``name`` argument may be +``http://example.com`` while the ``path`` given may be ``mypackage:images``: .. code-block:: python :linenos: @@ -260,8 +259,8 @@ is a *URL* instead of a view name. For example, the ``name`` argument may be config.add_static_view(name='http://example.com/images', path='mypackage:images') -Under such a configuration, the URL generated by ``static_url`` for -assets which begin with ``mypackage:images`` will be prefixed with +Under such a configuration, the URL generated by ``static_url`` for assets +which begin with ``mypackage:images`` will be prefixed with ``http://example.com/images``: .. code-block:: python @@ -271,16 +270,16 @@ assets which begin with ``mypackage:images`` will be prefixed with # -> http://example.com/images/logo.png Using :meth:`~pyramid.request.Request.static_url` in conjunction with a -:meth:`~pyramid.config.Configurator.add_static_view` makes it possible -to put static media on a separate webserver during production (if the -``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is -a URL), while keeping static media package-internal and served by the -development webserver during development (if the ``name`` argument to +:meth:`~pyramid.config.Configurator.add_static_view` makes it possible to put +static media on a separate webserver during production (if the ``name`` +argument to :meth:`~pyramid.config.Configurator.add_static_view` is a URL), +while keeping static media package-internal and served by the development +webserver during development (if the ``name`` argument to :meth:`~pyramid.config.Configurator.add_static_view` is a URL prefix). For example, we may define a :ref:`custom setting ` -named ``media_location`` which we can set to an external URL in production -when our assets are hosted on a CDN. +named ``media_location`` which we can set to an external URL in production when +our assets are hosted on a CDN. .. code-block:: python :linenos: @@ -305,18 +304,19 @@ It is also possible to serve assets that live outside of the source by referring to an absolute path on the filesystem. There are two ways to accomplish this. -First, :meth:`~pyramid.config.Configurator.add_static_view` -supports taking an absolute path directly instead of an asset spec. This works -as expected, looking in the file or folder of files and serving them up at -some URL within your application or externally. Unfortunately, this technique -has a drawback that it is not possible to use the -:meth:`~pyramid.request.Request.static_url` method to generate URLs, since it -works based on an asset spec. +First, :meth:`~pyramid.config.Configurator.add_static_view` supports taking an +absolute path directly instead of an asset spec. This works as expected, +looking in the file or folder of files and serving them up at some URL within +your application or externally. Unfortunately, this technique has a drawback in +that it is not possible to use the :meth:`~pyramid.request.Request.static_url` +method to generate URLs, since it works based on an asset specification. -The second approach, available in Pyramid 1.6+, uses the asset overriding -APIs described in the :ref:`overriding_assets_section` section. It is then -possible to configure a "dummy" package which then serves its file or folder -from an absolute path. +.. versionadded:: 1.6 + +The second approach, available in Pyramid 1.6+, uses the asset overriding APIs +described in the :ref:`overriding_assets_section` section. It is then possible +to configure a "dummy" package which then serves its file or folder from an +absolute path. .. code-block:: python @@ -325,13 +325,13 @@ from an absolute path. override_with='/abs/path/to/images/') From this configuration it is now possible to use -:meth:`~pyramid.request.Request.static_url` to generate URLs to the data -in the folder by doing something like +:meth:`~pyramid.request.Request.static_url` to generate URLs to the data in the +folder by doing something like ``request.static_url('myapp:static_images/foo.png')``. While it is not necessary that the ``static_images`` file or folder actually exist in the -``myapp`` package, it is important that the ``myapp`` portion points to a -valid package. If the folder does exist then the overriden folder is given -priority if the file's name exists in both locations. +``myapp`` package, it is important that the ``myapp`` portion points to a valid +package. If the folder does exist, then the overriden folder is given priority, +if the file's name exists in both locations. .. index:: single: Cache Busting @@ -343,31 +343,30 @@ Cache Busting .. versionadded:: 1.6 -In order to maximize performance of a web application, you generally want to +In order to maximize performance of a web application, you generally want to limit the number of times a particular client requests the same static asset. -Ideally a client would cache a particular static asset "forever", requiring -it to be sent to the client a single time. The HTTP protocol allows you to -send headers with an HTTP response that can instruct a client to cache a -particular asset for an amount of time. As long as the client has a copy of -the asset in its cache and that cache hasn't expired, the client will use the -cached copy rather than request a new copy from the server. The drawback to -sending cache headers to the client for a static asset is that at some point -the static asset may change, and then you'll want the client to load a new copy -of the asset. Under normal circumstances you'd just need to wait for the -client's cached copy to expire before they get the new version of the static -resource. - -A commonly used workaround to this problem is a technique known as "cache -busting". Cache busting schemes generally involve generating a URL for a +Ideally a client would cache a particular static asset "forever", requiring it +to be sent to the client a single time. The HTTP protocol allows you to send +headers with an HTTP response that can instruct a client to cache a particular +asset for an amount of time. As long as the client has a copy of the asset in +its cache and that cache hasn't expired, the client will use the cached copy +rather than request a new copy from the server. The drawback to sending cache +headers to the client for a static asset is that at some point the static asset +may change, and then you'll want the client to load a new copy of the asset. +Under normal circumstances you'd just need to wait for the client's cached copy +to expire before they get the new version of the static resource. + +A commonly used workaround to this problem is a technique known as "cache +busting". Cache busting schemes generally involve generating a URL for a static asset that changes when the static asset changes. This way headers can be sent along with the static asset instructing the client to cache the asset for a very long time. When a static asset is changed, the URL used to refer to -it in a web page also changes, so the client sees it as a new resource and -requests a copy, regardless of any caching policy set for the resource's old +it in a web page also changes, so the client sees it as a new 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 +: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`: .. code-block:: python @@ -377,7 +376,7 @@ assets by passing the optional argument, ``cachebust`` to config.add_static_view(name='static', path='mypackage:folder/static', cachebust=True) -Setting the ``cachebust`` argument instructs :app:`Pyramid` to use a cache +Setting the ``cachebust`` argument instructs :app:`Pyramid` to use a cache busting scheme which adds the md5 checksum for a static asset as a path segment in the asset's URL: @@ -385,7 +384,7 @@ in the asset's URL: :linenos: js_url = request.static_url('mypackage:folder/static/js/myapp.js') - # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js` + # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js' When the asset changes, so will its md5 checksum, and therefore so will its URL. Supplying the ``cachebust`` argument also causes the static view to set @@ -394,17 +393,17 @@ headers instructing clients to cache the asset for ten years, unless the .. note:: - md5 checksums are cached in RAM so if you change a static resource without + md5 checksums are cached in RAM, so if you change a static resource without restarting your application, you may still generate URLs with a stale md5 - checksum. + checksum. Disabling the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~ -It can be useful in some situations (e.g. development) to globally disable all +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 -``PYRAMID_PREVENT_CACHEBUST`` environment variable or the +:meth:`~pyramid.config.Configurator.add_static_view`. To do this set the +``PYRAMID_PREVENT_CACHEBUST`` environment variable or the ``pyramid.prevent_cachebust`` configuration value to a true value. Customizing the Cache Buster @@ -420,8 +419,8 @@ Revisiting from the previous section: cachebust=True) Setting ``cachebust`` to ``True`` instructs :app:`Pyramid` to use a default -cache busting implementation that should work for many situations. The -``cachebust`` may be set to any object that implements the interface, +cache busting implementation that should work for many situations. The +``cachebust`` may be set to any object that implements the interface :class:`~pyramid.interfaces.ICacheBuster`. The above configuration is exactly equivalent to: @@ -440,7 +439,7 @@ checksum token in the path portion of the asset's URL, :class:`~pyramid.static.QueryStringMd5CacheBuster`, which adds an md5 checksum token to the query string of the asset's URL, and :class:`~pyramid.static.QueryStringConstantCacheBuster`, which adds an -arbitrary token you provide to the query string of the asset's URL. +arbitrary token you provide to the query string of the asset's URL. In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` @@ -461,9 +460,9 @@ the hash of the currently checked out code: class GitCacheBuster(PathSegmentCacheBuster): """ - Assuming your code is installed as a Git checkout, as opposed to as an - egg 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. + Assuming your code is installed as a Git checkout, as opposed to an egg + 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): here = os.path.dirname(os.path.abspath(__file__)) @@ -477,25 +476,25 @@ the hash of the currently checked out code: Choosing a Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~ -The default cache buster implementation, -:class:`~pyramid.static.PathSegmentMd5CacheBuster`, works very well assuming +The default cache buster implementation, +:class:`~pyramid.static.PathSegmentMd5CacheBuster`, works very well assuming that you're using :app:`Pyramid` to serve your static assets. The md5 checksum -is fine grained enough that browsers should only request new versions of -specific assets that have changed. Many caching HTTP proxies will fail to -cache a resource if the URL contains a query string. In general, therefore, -you should prefer a cache busting strategy which modifies the path segment to -a strategy which adds a query string. +is fine grained enough that browsers should only request new versions of +specific assets that have changed. Many caching HTTP proxies will fail to +cache a resource if the URL contains a query string. In general, therefore, +you should prefer a cache busting strategy which modifies the path segment to a +strategy which adds a query string. It is possible, however, that your static assets are being served by another web server or externally on a CDN. In these cases modifying the path segment for a static asset URL would cause the external service to fail to find the -asset, causing your customer to get a 404. In these cases you would need to -fall back to a cache buster which adds a query string. It is even possible +asset, causing your customer to get a 404. In these cases you would need to +fall back to a cache buster which adds a query string. It is even possible that there isn't a copy of your static assets available to the :app:`Pyramid` application, so a cache busting implementation that generates md5 checksums -would fail since it can't access the assets. In such a case, -:class:`~pyramid.static.QueryStringConstantCacheBuster` is a reasonable -fallback. The following code would set up a cachebuster that just uses the +would fail since it can't access the assets. In such a case, +:class:`~pyramid.static.QueryStringConstantCacheBuster` is a reasonable +fallback. The following code would set up a cachebuster that just uses the time at start up as a cachebust token: .. code-block:: python @@ -516,10 +515,10 @@ 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. +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. * Process the files by using a precompiler which rewrites URLs to their final cache busted form. @@ -536,8 +535,8 @@ packages. Relative cache busted URLs in CSS +++++++++++++++++++++++++++++++++ -Consider a CSS file ``/static/theme/css/site.css`` which contains the -following CSS code. +Consider a CSS file ``/static/theme/css/site.css`` which contains the following +CSS code. .. code-block:: css @@ -572,8 +571,8 @@ The browser would interpret this as having the CSS file hash in URL:: The downside of this approach is that if the background image changes, one needs to bump the CSS file. The CSS file hash change signals the caches that the relative URL to the image in the CSS has been changed. When updating CSS -and related image assets, updates usually happen hand in hand, so this does -not add extra effort to theming workflow. +and related image assets, updates usually happen hand in hand, so this does not +add extra effort to theming workflow. Passing cache busted URLs to JavaScript +++++++++++++++++++++++++++++++++++++++ @@ -593,7 +592,7 @@ relevant page. "{{ '/theme/img/background.jpg'|static_url() }}"; -Then in your main ``site.js`` file put the following code. +Then in your main ``site.js`` file, put the following code. .. code-block:: javascript @@ -606,13 +605,13 @@ Advanced: Serving Static Assets Using a View Callable For more flexibility, static assets can be served by a :term:`view callable` which you register manually. For example, if you're using :term:`URL -dispatch`, you may want static assets to only be available as a fallback if -no previous route matches. Alternately, you might like to serve a particular +dispatch`, you may want static assets to only be available as a fallback if no +previous route matches. Alternatively, you might like to serve a particular static asset manually, because its download requires authentication. -Note that you cannot use the :meth:`~pyramid.request.Request.static_url` API -to generate URLs against assets made accessible by registering a custom -static view. +Note that you cannot use the :meth:`~pyramid.request.Request.static_url` API to +generate URLs against assets made accessible by registering a custom static +view. Root-Relative Custom Static View (URL Dispatch Only) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -626,19 +625,19 @@ its behavior is almost exactly the same once it's configured. .. warning:: The following example *will not work* for applications that use - :term:`traversal`, it will only work if you use :term:`URL dispatch` + :term:`traversal`; it will only work if you use :term:`URL dispatch` exclusively. The root-relative route we'll be registering will always be matched before traversal takes place, subverting any views registered via ``add_view`` (at least those without a ``route_name``). A :class:`~pyramid.static.static_view` static view cannot be made - root-relative when you use traversal unless it's registered as a - :term:`Not Found View`. + root-relative when you use traversal unless it's registered as a :term:`Not + Found View`. To serve files within a directory located on your filesystem at ``/path/to/static/dir`` as the result of a "catchall" route hanging from the root that exists at the end of your routing table, create an instance of the -:class:`~pyramid.static.static_view` class inside a ``static.py`` file in -your application root as below. +:class:`~pyramid.static.static_view` class inside a ``static.py`` file in your +application root as below. .. code-block:: python :linenos: @@ -648,10 +647,10 @@ your application root as below. .. note:: - For better cross-system flexibility, use an :term:`asset - specification` as the argument to :class:`~pyramid.static.static_view` - instead of a physical absolute filesystem path, e.g. ``mypackage:static`` - instead of ``/path/to/mypackage/static``. + For better cross-system flexibility, use an :term:`asset specification` as + the argument to :class:`~pyramid.static.static_view` instead of a physical + absolute filesystem path, e.g., ``mypackage:static``, instead of + ``/path/to/mypackage/static``. Subsequently, you may wire the files that are served by this view up to be accessible as ``/`` using a configuration method in your @@ -670,11 +669,11 @@ The special name ``*subpath`` above is used by the :class:`~pyramid.static.static_view` view callable to signify the path of the file relative to the directory you're serving. -Registering A View Callable to Serve a "Static" Asset +Registering a View Callable to Serve a "Static" Asset ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can register a simple view callable to serve a single static asset. To -do so, do things "by hand". First define the view callable. +You can register a simple view callable to serve a single static asset. To do +so, do things "by hand". First define the view callable. .. code-block:: python :linenos: @@ -687,17 +686,16 @@ do so, do things "by hand". First define the view callable. icon = os.path.join(here, 'static', 'favicon.ico') return FileResponse(icon, request=request) -The above bit of code within ``favicon_view`` computes "here", which is a -path relative to the Python file in which the function is defined. It then -creates a :class:`pyramid.response.FileResponse` using the file path as the -response's ``path`` argument and the request as the response's ``request`` -argument. :class:`pyramid.response.FileResponse` will serve the file as -quickly as possible when it's used this way. It makes sure to set the right -content length and content_type too based on the file extension of the file -you pass. +The above bit of code within ``favicon_view`` computes "here", which is a path +relative to the Python file in which the function is defined. It then creates +a :class:`pyramid.response.FileResponse` using the file path as the response's +``path`` argument and the request as the response's ``request`` argument. +:class:`pyramid.response.FileResponse` will serve the file as quickly as +possible when it's used this way. It makes sure to set the right content +length and content_type, too, based on the file extension of the file you pass. -You might register such a view via configuration as a view callable that -should be called as the result of a traversal: +You might register such a view via configuration as a view callable that should +be called as the result of a traversal: .. code-block:: python :linenos: @@ -730,13 +728,12 @@ It can often be useful to override specific assets from "outside" a given :app:`Pyramid` application more or less unchanged. However, some specific template file owned by the application might have inappropriate HTML, or some static asset (such as a logo file or some CSS file) might not be appropriate. -You *could* just fork the application entirely, but it's often more -convenient to just override the assets that are inappropriate and reuse the -application "as is". This is particularly true when you reuse some "core" -application over and over again for some set of customers (such as a CMS -application, or some bug tracking application), and you want to make -arbitrary visual modifications to a particular application deployment without -forking the underlying code. +You *could* just fork the application entirely, but it's often more convenient +to just override the assets that are inappropriate and reuse the application +"as is". This is particularly true when you reuse some "core" application over +and over again for some set of customers (such as a CMS application, or some +bug tracking application), and you want to make arbitrary visual modifications +to a particular application deployment without forking the underlying code. To this end, :app:`Pyramid` contains a feature that makes it possible to "override" one asset with one or more other assets. In support of this @@ -754,8 +751,8 @@ feature, a :term:`Configurator` API exists named - A directory of static files served up by an instance of the ``pyramid.static.static_view`` helper class. -- Any other asset (or set of assets) addressed by code that uses the - setuptools :term:`pkg_resources` API. +- Any other asset (or set of assets) addressed by code that uses the setuptools + :term:`pkg_resources` API. .. index:: single: override_asset @@ -765,8 +762,8 @@ feature, a :term:`Configurator` API exists named The ``override_asset`` API ~~~~~~~~~~~~~~~~~~~~~~~~~~ -An individual call to :meth:`~pyramid.config.Configurator.override_asset` -can override a single asset. For example: +An individual call to :meth:`~pyramid.config.Configurator.override_asset` can +override a single asset. For example: .. code-block:: python :linenos: @@ -776,11 +773,11 @@ can override a single asset. For example: override_with='another.package:othertemplates/anothertemplate.pt') The string value passed to both ``to_override`` and ``override_with`` sent to -the ``override_asset`` API is called an :term:`asset specification`. The -colon separator in a specification separates the *package name* from the -*asset name*. The colon and the following asset name are optional. If they -are not specified, the override attempts to resolve every lookup into a -package from the directory of another package. For example: +the ``override_asset`` API is called an :term:`asset specification`. The colon +separator in a specification separates the *package name* from the *asset +name*. The colon and the following asset name are optional. If they are not +specified, the override attempts to resolve every lookup into a package from +the directory of another package. For example: .. code-block:: python :linenos: @@ -796,27 +793,25 @@ Individual subdirectories within a package can also be overridden: config.override_asset(to_override='some.package:templates/', override_with='another.package:othertemplates/') - -If you wish to override a directory with another directory, you *must* -make sure to attach the slash to the end of both the ``to_override`` -specification and the ``override_with`` specification. If you fail to -attach a slash to the end of a specification that points to a directory, -you will get unexpected results. +If you wish to override a directory with another directory, you *must* make +sure to attach the slash to the end of both the ``to_override`` specification +and the ``override_with`` specification. If you fail to attach a slash to the +end of a specification that points to a directory, you will get unexpected +results. You cannot override a directory specification with a file specification, and -vice versa: a startup error will occur if you try. You cannot override an -asset with itself: a startup error will occur if you try. +vice versa; a startup error will occur if you try. You cannot override an +asset with itself; a startup error will occur if you try. Only individual *package* assets may be overridden. Overrides will not -traverse through subpackages within an overridden package. This means that -if you want to override assets for both ``some.package:templates``, and +traverse through subpackages within an overridden package. This means that if +you want to override assets for both ``some.package:templates``, and ``some.package.views:templates``, you will need to register two overrides. -The package name in a specification may start with a dot, meaning that -the package is relative to the package in which the configuration -construction file resides (or the ``package`` argument to the -:class:`~pyramid.config.Configurator` class construction). -For example: +The package name in a specification may start with a dot, meaning that the +package is relative to the package in which the configuration construction file +resides (or the ``package`` argument to the +:class:`~pyramid.config.Configurator` class construction). For example: .. code-block:: python :linenos: @@ -824,18 +819,19 @@ For example: config.override_asset(to_override='.subpackage:templates/', override_with='another.package:templates/') -Multiple calls to ``override_asset`` which name a shared ``to_override`` but -a different ``override_with`` specification can be "stacked" to form a search -path. The first asset that exists in the search path will be used; if no -asset exists in the override path, the original asset is used. +Multiple calls to ``override_asset`` which name a shared ``to_override`` but a +different ``override_with`` specification can be "stacked" to form a search +path. The first asset that exists in the search path will be used; if no asset +exists in the override path, the original asset is used. Asset overrides can actually override assets other than templates and static files. Any software which uses the :func:`pkg_resources.get_resource_filename`, -:func:`pkg_resources.get_resource_stream` or +:func:`pkg_resources.get_resource_stream`, or :func:`pkg_resources.get_resource_string` APIs will obtain an overridden file 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. +.. versionadded:: 1.6 + 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. -- cgit v1.2.3 From e0d42dbd2e8570324439816fa204a6c907fbe894 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Oct 2015 22:59:53 -0700 Subject: minor grammar, rewrap 79 cols, update dead external links, .rst syntax, git mah intersphinx on yo! --- docs/narr/webob.rst | 423 +++++++++++++++++++++++++--------------------------- 1 file changed, 201 insertions(+), 222 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index f82cf6fbe..f18cf1dfb 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -13,26 +13,26 @@ Request and Response Objects :app:`Pyramid` uses the :term:`WebOb` package as a basis for its :term:`request` and :term:`response` object implementations. The :term:`request` object that is passed to a :app:`Pyramid` :term:`view` is an -instance of the :class:`pyramid.request.Request` class, which is a subclass -of :class:`webob.Request`. The :term:`response` returned from a -:app:`Pyramid` :term:`view` :term:`renderer` is an instance of the +instance of the :class:`pyramid.request.Request` class, which is a subclass of +:class:`webob.Request`. The :term:`response` returned from a :app:`Pyramid` +:term:`view` :term:`renderer` is an instance of the :mod:`pyramid.response.Response` class, which is a subclass of the :class:`webob.Response` class. Users can also return an instance of :class:`pyramid.response.Response` directly from a view as necessary. -WebOb is a project separate from :app:`Pyramid` with a separate set of -authors and a fully separate `set of documentation -`_. Pyramid adds some +WebOb is a project separate from :app:`Pyramid` with a separate set of authors +and a fully separate `set of documentation +`_. :app:`Pyramid` adds some functionality to the standard WebOb request, which is documented in the :ref:`request_module` API documentation. WebOb provides objects for HTTP requests and responses. Specifically it does -this by wrapping the `WSGI `_ request environment and -response status, header list, and app_iter (body) values. +this by wrapping the `WSGI `_ request environment and response +status, header list, and app_iter (body) values. WebOb request and response objects provide many conveniences for parsing WSGI requests and forming WSGI responses. WebOb is a nice way to represent "raw" -WSGI requests and responses; however, we won't cover that use case in this +WSGI requests and responses. However, we won't cover that use case in this document, as users of :app:`Pyramid` don't typically need to use the WSGI-related features of WebOb directly. The `reference documentation `_ shows many examples of @@ -47,64 +47,58 @@ Request The request object is a wrapper around the `WSGI environ dictionary `_. This -dictionary contains keys for each header, keys that describe the -request (including the path and query string), a file-like object for -the request body, and a variety of custom keys. You can always access -the environ with ``req.environ``. +dictionary contains keys for each header, keys that describe the request +(including the path and query string), a file-like object for the request body, +and a variety of custom keys. You can always access the environ with +``req.environ``. -Some of the most important/interesting attributes of a request -object: +Some of the most important and interesting attributes of a request object are +below. -``req.method``: - The request method, e.g., ``'GET'``, ``'POST'`` +``req.method`` + The request method, e.g., ``GET``, ``POST`` -``req.GET``: - A :term:`multidict` with all the variables in the query - string. +``req.GET`` + A :term:`multidict` with all the variables in the query string. -``req.POST``: - A :term:`multidict` with all the variables in the request - body. This only has variables if the request was a ``POST`` and - it is a form submission. +``req.POST`` + A :term:`multidict` with all the variables in the request body. This only + has variables if the request was a ``POST`` and it is a form submission. -``req.params``: - A :term:`multidict` with a combination of everything in - ``req.GET`` and ``req.POST``. +``req.params`` + A :term:`multidict` with a combination of everything in ``req.GET`` and + ``req.POST``. -``req.body``: - The contents of the body of the request. This contains the entire - request body as a string. This is useful when the request is a - ``POST`` that is *not* a form submission, or a request like a - ``PUT``. You can also get ``req.body_file`` for a file-like - object. +``req.body`` + The contents of the body of the request. This contains the entire request + body as a string. This is useful when the request is a ``POST`` that is + *not* a form submission, or a request like a ``PUT``. You can also get + ``req.body_file`` for a file-like object. ``req.json_body`` The JSON-decoded contents of the body of the request. See :ref:`request_json_body`. -``req.cookies``: +``req.cookies`` A simple dictionary of all the cookies. -``req.headers``: +``req.headers`` A dictionary of all the headers. This dictionary is case-insensitive. -``req.urlvars`` and ``req.urlargs``: - ``req.urlvars`` are the keyword parameters associated with the - request URL. ``req.urlargs`` are the positional parameters. - These are set by products like `Routes - `_ and `Selector - `_. +``req.urlvars`` and ``req.urlargs`` + ``req.urlvars`` are the keyword parameters associated with the request URL. + ``req.urlargs`` are the positional parameters. These are set by products + like `Routes `_ and `Selector + `_. -Also, for standard HTTP request headers there are usually attributes, -for instance: ``req.accept_language``, ``req.content_length``, -``req.user_agent``, as an example. These properties expose the -*parsed* form of each header, for whatever parsing makes sense. For -instance, ``req.if_modified_since`` returns a `datetime -`_ object -(or None if the header is was not provided). +Also for standard HTTP request headers, there are usually attributes such as +``req.accept_language``, ``req.content_length``, and ``req.user_agent``. These +properties expose the *parsed* form of each header, for whatever parsing makes +sense. For instance, ``req.if_modified_since`` returns a :mod:`datetime` +object (or None if the header is was not provided). -.. note:: Full API documentation for the :app:`Pyramid` request - object is available in :ref:`request_module`. +.. note:: Full API documentation for the :app:`Pyramid` request object is + available in :ref:`request_module`. .. index:: single: request attributes (special) @@ -112,14 +106,14 @@ instance, ``req.if_modified_since`` returns a `datetime .. _special_request_attributes: Special Attributes Added to the Request by :app:`Pyramid` -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ In addition to the standard :term:`WebOb` attributes, :app:`Pyramid` adds special attributes to every request: ``context``, ``registry``, ``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root``, -``virtual_root_path``, ``session``, ``matchdict``, and ``matched_route``. -These attributes are documented further within the -:class:`pyramid.request.Request` API documentation. +``virtual_root_path``, ``session``, ``matchdict``, and ``matched_route``. These +attributes are documented further within the :class:`pyramid.request.Request` +API documentation. .. index:: single: request URLs @@ -127,45 +121,43 @@ These attributes are documented further within the URLs ++++ -In addition to these attributes, there are several ways to get the URL -of the request. I'll show various values for an example URL +In addition to these attributes, there are several ways to get the URL of the +request and its parts. We'll show various values for an example URL ``http://localhost/app/blog?id=10``, where the application is mounted at ``http://localhost/app``. -``req.url``: - The full request URL, with query string, e.g., +``req.url`` + The full request URL with query string, e.g., ``http://localhost/app/blog?id=10`` -``req.host``: - The host information in the URL, e.g., - ``localhost`` +``req.host`` + The host information in the URL, e.g., ``localhost`` -``req.host_url``: +``req.host_url`` The URL with the host, e.g., ``http://localhost`` -``req.application_url``: - The URL of the application (just the SCRIPT_NAME portion of the - path, not PATH_INFO). E.g., ``http://localhost/app`` +``req.application_url`` + The URL of the application (just the ``SCRIPT_NAME`` portion of the path, + not ``PATH_INFO``), e.g., ``http://localhost/app`` -``req.path_url``: - The URL of the application including the PATH_INFO. e.g., +``req.path_url`` + The URL of the application including the ``PATH_INFO``, e.g., ``http://localhost/app/blog`` -``req.path``: - The URL including PATH_INFO without the host or scheme. e.g., +``req.path`` + The URL including ``PATH_INFO`` without the host or scheme, e.g., ``/app/blog`` -``req.path_qs``: - The URL including PATH_INFO and the query string. e.g, +``req.path_qs`` + The URL including ``PATH_INFO`` and the query string, e.g, ``/app/blog?id=10`` -``req.query_string``: - The query string in the URL, e.g., - ``id=10`` +``req.query_string`` + The query string in the URL, e.g., ``id=10`` -``req.relative_url(url, to_application=False)``: - Gives a URL, relative to the current URL. If ``to_application`` - is True, then resolves it relative to ``req.application_url``. +``req.relative_url(url, to_application=False)`` + Gives a URL relative to the current URL. If ``to_application`` is True, + then resolves it relative to ``req.application_url``. .. index:: single: request methods @@ -177,18 +169,17 @@ There are methods of request objects documented in :class:`pyramid.request.Request` but you'll find that you won't use very many of them. Here are a couple that might be useful: -``Request.blank(base_url)``: - Creates a new request with blank information, based at the given - URL. This can be useful for subrequests and artificial requests. - You can also use ``req.copy()`` to copy an existing request, or - for subrequests ``req.copy_get()`` which copies the request but - always turns it into a GET (which is safer to share for - subrequests). +``Request.blank(base_url)`` + Creates a new request with blank information, based at the given URL. This + can be useful for subrequests and artificial requests. You can also use + ``req.copy()`` to copy an existing request, or for subrequests + ``req.copy_get()`` which copies the request but always turns it into a GET + (which is safer to share for subrequests). -``req.get_response(wsgi_application)``: - This method calls the given WSGI application with this request, and - returns a :class:`pyramid.response.Response` object. You can also use - this for subrequests, or testing. +``req.get_response(wsgi_application)`` + This method calls the given WSGI application with this request, and returns + a :class:`pyramid.response.Response` object. You can also use this for + subrequests or testing. .. index:: single: request (and text/unicode) @@ -215,26 +206,25 @@ charset='utf8')``. Multidict +++++++++ -Several attributes of a WebOb request are "multidict"; structures (such as +Several attributes of a WebOb request are multidict structures (such as ``request.GET``, ``request.POST``, and ``request.params``). A multidict is a -dictionary where a key can have multiple values. The quintessential example -is a query string like ``?pref=red&pref=blue``; the ``pref`` variable has two +dictionary where a key can have multiple values. The quintessential example is +a query string like ``?pref=red&pref=blue``; the ``pref`` variable has two values: ``red`` and ``blue``. -In a multidict, when you do ``request.GET['pref']`` you'll get back -only ``'blue'`` (the last value of ``pref``). Sometimes returning a -string, and sometimes returning a list, is the cause of frequent -exceptions. If you want *all* the values back, use -``request.GET.getall('pref')``. If you want to be sure there is *one -and only one* value, use ``request.GET.getone('pref')``, which will -raise an exception if there is zero or more than one value for -``pref``. - -When you use operations like ``request.GET.items()`` you'll get back -something like ``[('pref', 'red'), ('pref', 'blue')]``. All the -key/value pairs will show up. Similarly ``request.GET.keys()`` -returns ``['pref', 'pref']``. Multidict is a view on a list of -tuples; all the keys are ordered, and all the values are ordered. +In a multidict, when you do ``request.GET['pref']``, you'll get back only +``"blue"`` (the last value of ``pref``). This returned result might not be +expected—sometimes returning a string, and sometimes returning a list—and may +be cause of frequent exceptions. If you want *all* the values back, use +``request.GET.getall('pref')``. If you want to be sure there is *one and only +one* value, use ``request.GET.getone('pref')``, which will raise an exception +if there is zero or more than one value for ``pref``. + +When you use operations like ``request.GET.items()``, you'll get back something +like ``[('pref', 'red'), ('pref', 'blue')]``. All the key/value pairs will +show up. Similarly ``request.GET.keys()`` returns ``['pref', 'pref']``. +Multidict is a view on a list of tuples; all the keys are ordered, and all the +values are ordered. API documentation for a multidict exists as :class:`pyramid.interfaces.IMultiDict`. @@ -244,19 +234,19 @@ API documentation for a multidict exists as .. _request_json_body: -Dealing With A JSON-Encoded Request Body +Dealing with a JSON-Encoded Request Body ++++++++++++++++++++++++++++++++++++++++ .. versionadded:: 1.1 :attr:`pyramid.request.Request.json_body` is a property that returns a -:term:`JSON` -decoded representation of the request body. If the request -does not have a body, or the body is not a properly JSON-encoded value, an -exception will be raised when this attribute is accessed. +:term:`JSON`-decoded representation of the request body. If the request does +not have a body, or the body is not a properly JSON-encoded value, an exception +will be raised when this attribute is accessed. -This attribute is useful when you invoke a Pyramid view callable via -e.g. jQuery's ``$.ajax`` function, which has the potential to send a request -with a JSON-encoded body. +This attribute is useful when you invoke a :app:`Pyramid` view callable via, +for example, jQuery's ``$.ajax`` function, which has the potential to send a +request with a JSON-encoded body. Using ``request.json_body`` is equivalent to: @@ -265,15 +255,15 @@ Using ``request.json_body`` is equivalent to: from json import loads loads(request.body, encoding=request.charset) -Here's how to construct an AJAX request in Javascript using :term:`jQuery` -that allows you to use the ``request.json_body`` attribute when the request -is sent to a Pyramid application: +Here's how to construct an AJAX request in JavaScript using :term:`jQuery` that +allows you to use the ``request.json_body`` attribute when the request is sent +to a :app:`Pyramid` application: .. code-block:: javascript - jQuery.ajax({type:'POST', + jQuery.ajax({type:'POST', url: 'http://localhost:6543/', // the pyramid server - data: JSON.stringify({'a':1}), + data: JSON.stringify({'a':1}), contentType: 'application/json; charset=utf-8'}); When such a request reaches a view in your application, the @@ -292,14 +282,14 @@ For the above view, printed to the console will be: {u'a': 1} -For bonus points, here's a bit of client-side code that will produce a -request that has a body suitable for reading via ``request.json_body`` using -Python's ``urllib2`` instead of a Javascript AJAX request: +For bonus points, here's a bit of client-side code that will produce a request +that has a body suitable for reading via ``request.json_body`` using Python's +``urllib2`` instead of a JavaScript AJAX request: .. code-block:: python import urllib2 - import json + import json json_payload = json.dumps({'a':1}) headers = {'Content-Type':'application/json; charset=utf-8'} @@ -308,22 +298,22 @@ Python's ``urllib2`` instead of a Javascript AJAX request: If you are doing Cross-origin resource sharing (CORS), then the standard requires the browser to do a pre-flight HTTP OPTIONS request. The easiest way -to handling this is adding an extra ``view_config`` for the same route, with -``request_method`` set to ``OPTIONS``, and setting the desired response header -before returning. You can find examples of response headers here_. - -.. _here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests +to handle this is to add an extra ``view_config`` for the same route, with +``request_method`` set to ``OPTIONS``, and set the desired response header +before returning. You can find examples of response headers `Access control +CORS, Preflighted requests +`_. .. index:: single: cleaning up after request .. _cleaning_up_after_a_request: -Cleaning Up After a Request +Cleaning up after a Request +++++++++++++++++++++++++++ -Sometimes it's required that some cleanup be performed at the end of a -request when a database connection is involved. +Sometimes it's required to perform some cleanup at the end of a request when a +database connection is involved. For example, let's say you have a ``mypackage`` :app:`Pyramid` application package that uses SQLAlchemy, and you'd like the current SQLAlchemy database @@ -348,29 +338,28 @@ session to be removed after each request. Put the following in the Registering the ``cleanup_callback`` finished callback at the start of a request (by causing the ``add_cleanup_callback`` to receive a :class:`pyramid.events.NewRequest` event at the start of each request) will -cause the DBSession to be removed whenever request processing has ended. -Note that in the example above, for the :class:`pyramid.events.subscriber` -decorator to "work", the :meth:`pyramid.config.Configurator.scan` method must -be called against your ``mypackage`` package during application -initialization. - -.. note:: This is only an example. In particular, it is not necessary to - cause ``DBSession.remove`` to be called in an application generated from - any :app:`Pyramid` scaffold, because these all use the ``pyramid_tm`` - package. The cleanup done by ``DBSession.remove`` is unnecessary when - ``pyramid_tm`` :term:`middleware` is configured into the application. +cause the DBSession to be removed whenever request processing has ended. Note +that in the example above, for the :class:`pyramid.events.subscriber` decorator +to work, the :meth:`pyramid.config.Configurator.scan` method must be called +against your ``mypackage`` package during application initialization. + +.. note:: + This is only an example. In particular, it is not necessary to cause + ``DBSession.remove`` to be called in an application generated from any + :app:`Pyramid` scaffold, because these all use the ``pyramid_tm`` package. + The cleanup done by ``DBSession.remove`` is unnecessary when ``pyramid_tm`` + :term:`middleware` is configured into the application. More Details ++++++++++++ -More detail about the request object API is available in: +More detail about the request object API is available as follows. -- The :class:`pyramid.request.Request` API documentation. +- :class:`pyramid.request.Request` API documentation -- The `WebOb documentation `_. - All methods and attributes of a ``webob.Request`` documented within the - WebOb documentation will work with request objects created by - :app:`Pyramid`. +- `WebOb documentation `_. All + methods and attributes of a ``webob.Request`` documented within the WebOb + documentation will work with request objects created by :app:`Pyramid`. .. index:: single: response object @@ -381,67 +370,62 @@ Response The :app:`Pyramid` response object can be imported as :class:`pyramid.response.Response`. This class is a subclass of the ``webob.Response`` class. The subclass does not add or change any -functionality, so the WebOb Response documentation will be completely -relevant for this class as well. +functionality, so the WebOb Response documentation will be completely relevant +for this class as well. A response object has three fundamental parts: -``response.status``: - The response code plus reason message, like ``'200 OK'``. To set - the code without a message, use ``status_int``, i.e.: - ``response.status_int = 200``. - -``response.headerlist``: - A list of all the headers, like ``[('Content-Type', - 'text/html')]``. There's a case-insensitive :term:`multidict` - in ``response.headers`` that also allows you to access - these same headers. - -``response.app_iter``: - An iterable (such as a list or generator) that will produce the - content of the response. This is also accessible as - ``response.body`` (a string), ``response.text`` (a - unicode object, informed by ``response.charset``), and - ``response.body_file`` (a file-like object; writing to it appends - to ``app_iter``). +``response.status`` + The response code plus reason message, like ``200 OK``. To set the code + without a message, use ``status_int``, i.e., ``response.status_int = 200``. + +``response.headerlist`` + A list of all the headers, like ``[('Content-Type', 'text/html')]``. + There's a case-insensitive :term:`multidict` in ``response.headers`` that + also allows you to access these same headers. + +``response.app_iter`` + An iterable (such as a list or generator) that will produce the content of + the response. This is also accessible as ``response.body`` (a string), + ``response.text`` (a unicode object, informed by ``response.charset``), and + ``response.body_file`` (a file-like object; writing to it appends to + ``app_iter``). Everything else in the object typically derives from this underlying state. Here are some highlights: ``response.content_type`` The content type *not* including the ``charset`` parameter. + Typical use: ``response.content_type = 'text/html'``. Default value: ``response.content_type = 'text/html'``. -``response.charset``: - The ``charset`` parameter of the content-type, it also informs - encoding in ``response.text``. - ``response.content_type_params`` is a dictionary of all the - parameters. - -``response.set_cookie(key, value, max_age=None, path='/', ...)``: - Set a cookie. The keyword arguments control the various cookie - parameters. The ``max_age`` argument is the length for the cookie - to live in seconds (you may also use a timedelta object). The - ``Expires`` key will also be set based on the value of - ``max_age``. - -``response.delete_cookie(key, path='/', domain=None)``: - Delete a cookie from the client. This sets ``max_age`` to 0 and - the cookie value to ``''``. - -``response.cache_expires(seconds=0)``: - This makes this response cacheable for the given number of seconds, - or if ``seconds`` is 0 then the response is uncacheable (this also - sets the ``Expires`` header). - -``response(environ, start_response)``: - The response object is a WSGI application. As an application, it - acts according to how you create it. It *can* do conditional - responses if you pass ``conditional_response=True`` when - instantiating (or set that attribute later). It can also do HEAD - and Range requests. +``response.charset`` + The ``charset`` parameter of the content-type, it also informs encoding in + ``response.text``. ``response.content_type_params`` is a dictionary of all + the parameters. + +``response.set_cookie(key, value, max_age=None, path='/', ...)`` + Set a cookie. The keyword arguments control the various cookie parameters. + The ``max_age`` argument is the length for the cookie to live in seconds + (you may also use a timedelta object). The ``Expires`` key will also be + set based on the value of ``max_age``. + +``response.delete_cookie(key, path='/', domain=None)`` + Delete a cookie from the client. This sets ``max_age`` to 0 and the cookie + value to ``''``. + +``response.cache_expires(seconds=0)`` + This makes the response cacheable for the given number of seconds, or if + ``seconds`` is ``0`` then the response is uncacheable (this also sets the + ``Expires`` header). + +``response(environ, start_response)`` + The response object is a WSGI application. As an application, it acts + according to how you create it. It *can* do conditional responses if you + pass ``conditional_response=True`` when instantiating (or set that + attribute later). It can also do HEAD and Range requests. .. index:: single: response headers @@ -449,12 +433,11 @@ Here are some highlights: Headers +++++++ -Like the request, most HTTP response headers are available as -properties. These are parsed, so you can do things like -``response.last_modified = os.path.getmtime(filename)``. +Like the request, most HTTP response headers are available as properties. These +are parsed, so you can do things like ``response.last_modified = +os.path.getmtime(filename)``. -The details are available in the `extracted Response documentation -`_. +The details are available in the :mod:`webob.response` API documentation. .. index:: single: response (creating) @@ -462,9 +445,9 @@ The details are available in the `extracted Response documentation Instantiating the Response ++++++++++++++++++++++++++ -Of course most of the time you just want to *make* a response. -Generally any attribute of the response can be passed in as a keyword -argument to the class; e.g.: +Of course most of the time you just want to *make* a response. Generally any +attribute of the response can be passed in as a keyword argument to the class, +e.g.: .. code-block:: python :linenos: @@ -474,9 +457,9 @@ argument to the class; e.g.: The status defaults to ``'200 OK'``. -The value of content_type defaults to -``webob.response.Response.default_content_type``; which is `text/html`. -You can subclass :class:`pyramid.response.Response` and set +The value of ``content_type`` defaults to +``webob.response.Response.default_content_type``, which is ``text/html``. You +can subclass :class:`pyramid.response.Response` and set ``default_content_type`` to override this behavior. .. index:: @@ -486,18 +469,16 @@ Exception Responses +++++++++++++++++++ To facilitate error responses like ``404 Not Found``, the module -:mod:`pyramid.httpexceptions` contains classes for each kind of error -response. These include boring, but appropriate error bodies. The -exceptions exposed by this module, when used under :app:`Pyramid`, should be -imported from the :mod:`pyramid.httpexceptions` module. This import location -contains subclasses and replacements that mirror those in the ``webob.exc`` -module. - -Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the -reason for the error. For instance, -:class:`pyramid.httpexceptions.HTTPNotFound` subclasses -:class:`pyramid.response.Response`, so you can manipulate the instances in the same -way. A typical example is: +:mod:`pyramid.httpexceptions` contains classes for each kind of error response. +These include boring but appropriate error bodies. The exceptions exposed by +this module, when used under :app:`Pyramid`, should be imported from the +:mod:`pyramid.httpexceptions` module. This import location contains subclasses +and replacements that mirror those in the ``webob.exc`` module. + +Each class is named ``pyramid.httpexceptions.HTTP*``, where ``*`` is the reason +for the error. For instance, :class:`pyramid.httpexceptions.HTTPNotFound` +subclasses :class:`pyramid.response.Response`, so you can manipulate the +instances in the same way. A typical example is: .. code-block:: python :linenos: @@ -513,8 +494,6 @@ More Details ++++++++++++ More details about the response object API are available in the -:mod:`pyramid.response` documentation. More details about exception -responses are in the :mod:`pyramid.httpexceptions` API documentation. The -`WebOb documentation `_ is also -useful. - +:mod:`pyramid.response` documentation. More details about exception responses +are in the :mod:`pyramid.httpexceptions` API documentation. The `WebOb +documentation `_ is also useful. -- cgit v1.2.3 From ba9c42c7594aec80a819b774fb2cf0635cf3aa5a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Oct 2015 00:08:13 -0700 Subject: strip trailing whitespace --- docs/narr/assets.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 4c0013298..020794062 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -30,7 +30,7 @@ The use of assets is quite common in most web development projects. For example, when you create a :app:`Pyramid` application using one of the available scaffolds, as described in :ref:`creating_a_project`, the directory representing the application contains a Python :term:`package`. Within that -Python package, there are directories full of files which are static assets. +Python package, there are directories full of files which are static assets. For example, there's a ``static`` directory which contains ``.css``, ``.js``, and ``.gif`` files. These asset files are delivered when a user visits an application URL. @@ -123,7 +123,7 @@ The ``name`` represents a URL *prefix*. In order for files that live in the ``path`` directory to be served, a URL that requests one of them must begin with that prefix. In the example above, ``name`` is ``static`` and ``path`` is ``/var/www/static``. In English this means that you wish to serve the files -that live in ``/var/www/static`` as sub-URLs of the ``/static`` URL prefix. +that live in ``/var/www/static`` as sub-URLs of the ``/static`` URL prefix. Therefore, the file ``/var/www/static/foo.css`` will be returned when the user visits your application's URL ``/static/foo.css``. @@ -176,7 +176,7 @@ For example, :meth:`~pyramid.config.Configurator.add_static_view` may be fed a :linenos: # config is an instance of pyramid.config.Configurator - config.add_static_view(name='http://example.com/images', + config.add_static_view(name='http://example.com/images', path='mypackage:images') Because :meth:`~pyramid.config.Configurator.add_static_view` is provided with a @@ -256,7 +256,7 @@ a *URL* instead of a view name. For example, the ``name`` argument may be .. code-block:: python :linenos: - config.add_static_view(name='http://example.com/images', + config.add_static_view(name='http://example.com/images', path='mypackage:images') Under such a configuration, the URL generated by ``static_url`` for assets @@ -391,7 +391,7 @@ 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. -.. note:: +.. note:: md5 checksums are cached in RAM, so if you change a static resource without restarting your application, you may still generate URLs with a stale md5 @@ -472,7 +472,7 @@ the hash of the currently checked out code: def tokenize(self, pathspec): return self.sha1 - + Choosing a Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~ @@ -504,7 +504,7 @@ time at start up as a cachebust token: from pyramid.static import QueryStringConstantCacheBuster config.add_static_view( - name='http://mycdn.example.com/', + name='http://mycdn.example.com/', path='mypackage:static', cachebust=QueryStringConstantCacheBuster(str(time.time()))) -- cgit v1.2.3 From 42049eb25d91a45d46f581a18d82a91b63470290 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Oct 2015 05:09:21 -0700 Subject: minor grammar, rewrap 79 cols (cherry picked from commit a18960a) --- docs/narr/sessions.rst | 239 +++++++++++++++++++++++-------------------------- 1 file changed, 113 insertions(+), 126 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 916c6c1f6..db554a93b 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -6,45 +6,44 @@ Sessions ======== -A :term:`session` is a namespace which is valid for some period of -continual activity that can be used to represent a user's interaction -with a web application. +A :term:`session` is a namespace which is valid for some period of continual +activity that can be used to represent a user's interaction with a web +application. -This chapter describes how to configure sessions, what session -implementations :app:`Pyramid` provides out of the box, how to store and -retrieve data from sessions, and two session-specific features: flash -messages, and cross-site request forgery attack prevention. +This chapter describes how to configure sessions, what session implementations +:app:`Pyramid` provides out of the box, how to store and retrieve data from +sessions, and two session-specific features: flash messages, and cross-site +request forgery attack prevention. .. index:: single: session factory (default) .. _using_the_default_session_factory: -Using The Default Session Factory +Using the Default Session Factory --------------------------------- -In order to use sessions, you must set up a :term:`session factory` -during your :app:`Pyramid` configuration. +In order to use sessions, you must set up a :term:`session factory` during your +:app:`Pyramid` configuration. -A very basic, insecure sample session factory implementation is -provided in the :app:`Pyramid` core. It uses a cookie to store -session information. This implementation has the following -limitations: +A very basic, insecure sample session factory implementation is provided in the +:app:`Pyramid` core. It uses a cookie to store session information. This +implementation has the following limitations: -- The session information in the cookies used by this implementation - is *not* encrypted, so it can be viewed by anyone with access to the - cookie storage of the user's browser or anyone with access to the - network along which the cookie travels. +- The session information in the cookies used by this implementation is *not* + encrypted, so it can be viewed by anyone with access to the cookie storage of + the user's browser or anyone with access to the network along which the + cookie travels. -- The maximum number of bytes that are storable in a serialized - representation of the session is fewer than 4000. This is - suitable only for very small data sets. +- The maximum number of bytes that are storable in a serialized representation + of the session is fewer than 4000. This is suitable only for very small data + sets. -It is digitally signed, however, and thus its data cannot easily be -tampered with. +It is digitally signed, however, and thus its data cannot easily be tampered +with. -You can configure this session factory in your :app:`Pyramid` application -by using the :meth:`pyramid.config.Configurator.set_session_factory` method. +You can configure this session factory in your :app:`Pyramid` application by +using the :meth:`pyramid.config.Configurator.set_session_factory` method. .. code-block:: python :linenos: @@ -59,17 +58,17 @@ by using the :meth:`pyramid.config.Configurator.set_session_factory` method. .. warning:: By default the :func:`~pyramid.session.SignedCookieSessionFactory` - implementation is *unencrypted*. You should not use it - when you keep sensitive information in the session object, as the - information can be easily read by both users of your application and third - parties who have access to your users' network traffic. And if you use this - sessioning implementation, and you inadvertently create a cross-site - scripting vulnerability in your application, because the session data is - stored unencrypted in a cookie, it will also be easier for evildoers to - obtain the current user's cross-site scripting token. In short, use a - different session factory implementation (preferably one which keeps session - data on the server) for anything but the most basic of applications where - "session security doesn't matter", and you are sure your application has no + implementation is *unencrypted*. You should not use it when you keep + sensitive information in the session object, as the information can be + easily read by both users of your application and third parties who have + access to your users' network traffic. And, if you use this sessioning + implementation, and you inadvertently create a cross-site scripting + vulnerability in your application, because the session data is stored + unencrypted in a cookie, it will also be easier for evildoers to obtain the + current user's cross-site scripting token. In short, use a different + session factory implementation (preferably one which keeps session data on + the server) for anything but the most basic of applications where "session + security doesn't matter", and you are sure your application has no cross-site scripting vulnerabilities. .. index:: @@ -78,10 +77,9 @@ by using the :meth:`pyramid.config.Configurator.set_session_factory` method. Using a Session Object ---------------------- -Once a session factory has been configured for your application, you -can access session objects provided by the session factory via -the ``session`` attribute of any :term:`request` object. For -example: +Once a session factory has been configured for your application, you can access +session objects provided by the session factory via the ``session`` attribute +of any :term:`request` object. For example: .. code-block:: python :linenos: @@ -98,13 +96,12 @@ example: else: return Response('Fred was not in the session') -The first time this view is invoked produces ``Fred was not in the -session``. Subsequent invocations produce ``Fred was in the -session``, assuming of course that the client side maintains the -session's identity across multiple requests. +The first time this view is invoked produces ``Fred was not in the session``. +Subsequent invocations produce ``Fred was in the session``, assuming of course +that the client side maintains the session's identity across multiple requests. You can use a session much like a Python dictionary. It supports all -dictionary methods, along with some extra attributes, and methods. +dictionary methods, along with some extra attributes and methods. Extra attributes: @@ -112,42 +109,39 @@ Extra attributes: An integer timestamp indicating the time that this session was created. ``new`` - A boolean. If ``new`` is True, this session is new. Otherwise, it has - been constituted from data that was already serialized. + A boolean. If ``new`` is True, this session is new. Otherwise, it has been + constituted from data that was already serialized. Extra methods: ``changed()`` - Call this when you mutate a mutable value in the session namespace. - See the gotchas below for details on when, and why you should - call this. + Call this when you mutate a mutable value in the session namespace. See the + gotchas below for details on when and why you should call this. ``invalidate()`` - Call this when you want to invalidate the session (dump all data, - and -- perhaps -- set a clearing cookie). + Call this when you want to invalidate the session (dump all data, and perhaps + set a clearing cookie). -The formal definition of the methods and attributes supported by the -session object are in the :class:`pyramid.interfaces.ISession` -documentation. +The formal definition of the methods and attributes supported by the session +object are in the :class:`pyramid.interfaces.ISession` documentation. Some gotchas: -- Keys and values of session data must be *pickleable*. This means, - typically, that they are instances of basic types of objects, - such as strings, lists, dictionaries, tuples, integers, etc. If you - place an object in a session data key or value that is not - pickleable, an error will be raised when the session is serialized. - -- If you place a mutable value (for example, a list or a dictionary) - in a session object, and you subsequently mutate that value, you must - call the ``changed()`` method of the session object. In this case, the - session has no way to know that is was modified. However, when you - modify a session object directly, such as setting a value (i.e., - ``__setitem__``), or removing a key (e.g., ``del`` or ``pop``), the - session will automatically know that it needs to re-serialize its - data, thus calling ``changed()`` is unnecessary. There is no harm in - calling ``changed()`` in either case, so when in doubt, call it after - you've changed sessioning data. +- Keys and values of session data must be *pickleable*. This means, typically, + that they are instances of basic types of objects, such as strings, lists, + dictionaries, tuples, integers, etc. If you place an object in a session + data key or value that is not pickleable, an error will be raised when the + session is serialized. + +- If you place a mutable value (for example, a list or a dictionary) in a + session object, and you subsequently mutate that value, you must call the + ``changed()`` method of the session object. In this case, the session has no + way to know that it was modified. However, when you modify a session object + directly, such as setting a value (i.e., ``__setitem__``), or removing a key + (e.g., ``del`` or ``pop``), the session will automatically know that it needs + to re-serialize its data, thus calling ``changed()`` is unnecessary. There is + no harm in calling ``changed()`` in either case, so when in doubt, call it + after you've changed sessioning data. .. index:: single: pyramid_redis_sessions @@ -183,14 +177,13 @@ pyramid_beaker_ Beaker_ Session factory for Pyramid Creating Your Own Session Factory --------------------------------- -If none of the default or otherwise available sessioning -implementations for :app:`Pyramid` suit you, you may create your own -session object by implementing a :term:`session factory`. Your -session factory should return a :term:`session`. The interfaces for -both types are available in +If none of the default or otherwise available sessioning implementations for +:app:`Pyramid` suit you, you may create your own session object by implementing +a :term:`session factory`. Your session factory should return a +:term:`session`. The interfaces for both types are available in :class:`pyramid.interfaces.ISessionFactory` and -:class:`pyramid.interfaces.ISession`. You might use the cookie -implementation in the :mod:`pyramid.session` module as inspiration. +:class:`pyramid.interfaces.ISession`. You might use the cookie implementation +in the :mod:`pyramid.session` module as inspiration. .. index:: single: flash messages @@ -205,9 +198,9 @@ Flash Messages factory` as described in :ref:`using_the_default_session_factory` or :ref:`using_alternate_session_factories`. -Flash messaging has two main uses: to display a status message only once to -the user after performing an internal redirect, and to allow generic code to -log messages for single-time display without having direct access to an HTML +Flash messaging has two main uses: to display a status message only once to the +user after performing an internal redirect, and to allow generic code to log +messages for single-time display without having direct access to an HTML template. The user interface consists of a number of methods of the :term:`session` object. @@ -235,22 +228,21 @@ The ``message`` argument is required. It represents a message you wish to later display to a user. It is usually a string but the ``message`` you provide is not modified in any way. -The ``queue`` argument allows you to choose a queue to which to append -the message you provide. This can be used to push different kinds of -messages into flash storage for later display in different places on a -page. You can pass any name for your queue, but it must be a string. -Each queue is independent, and can be popped by ``pop_flash()`` or -examined via ``peek_flash()`` separately. ``queue`` defaults to the -empty string. The empty string represents the default flash message -queue. +The ``queue`` argument allows you to choose a queue to which to append the +message you provide. This can be used to push different kinds of messages into +flash storage for later display in different places on a page. You can pass +any name for your queue, but it must be a string. Each queue is independent, +and can be popped by ``pop_flash()`` or examined via ``peek_flash()`` +separately. ``queue`` defaults to the empty string. The empty string +represents the default flash message queue. .. code-block:: python request.session.flash(msg, 'myappsqueue') -The ``allow_duplicate`` argument defaults to ``True``. If this is -``False``, and you attempt to add a message value which is already -present in the queue, it will not be added. +The ``allow_duplicate`` argument defaults to ``True``. If this is ``False``, +and you attempt to add a message value which is already present in the queue, +it will not be added. .. index:: single: session.pop_flash @@ -259,12 +251,12 @@ Using the ``session.pop_flash`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Once one or more messages have been added to a flash queue by the -``session.flash()`` API, the ``session.pop_flash()`` API can be used to -pop an entire queue and return it for use. +``session.flash()`` API, the ``session.pop_flash()`` API can be used to pop an +entire queue and return it for use. To pop a particular queue of messages from the flash object, use the session -object's ``pop_flash()`` method. This returns a list of the messages -that were added to the flash queue, and empties the queue. +object's ``pop_flash()`` method. This returns a list of the messages that were +added to the flash queue, and empties the queue. .. method:: pop_flash(queue='') @@ -288,10 +280,10 @@ been popped. Using the ``session.peek_flash`` Method ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once one or more messages has been added to a flash queue by the -``session.flash()`` API, the ``session.peek_flash()`` API can be used to -"peek" at that queue. Unlike ``session.pop_flash()``, the queue is not -popped from flash storage. +Once one or more messages have been added to a flash queue by the +``session.flash()`` API, the ``session.peek_flash()`` API can be used to "peek" +at that queue. Unlike ``session.pop_flash()``, the queue is not popped from +flash storage. .. method:: peek_flash(queue='') @@ -322,8 +314,8 @@ You can avoid most of these attacks by issuing a unique token to the browser and then requiring that it be present in all potentially unsafe requests. :app:`Pyramid` sessions provide facilities to create and check CSRF tokens. -To use CSRF tokens, you must first enable a :term:`session factory` -as described in :ref:`using_the_default_session_factory` or +To use CSRF tokens, you must first enable a :term:`session factory` as +described in :ref:`using_the_default_session_factory` or :ref:`using_alternate_session_factories`. .. index:: @@ -342,9 +334,9 @@ To get the current CSRF token from the session, use the The ``session.get_csrf_token()`` method accepts no arguments. It returns a CSRF *token* string. If ``session.get_csrf_token()`` or ``session.new_csrf_token()`` was invoked previously for this session, then the -existing token will be returned. If no CSRF token previously existed for -this session, then a new token will be will be set into the session and returned. -The newly created token will be opaque and randomized. +existing token will be returned. If no CSRF token previously existed for this +session, then a new token will be set into the session and returned. The newly +created token will be opaque and randomized. You can use the returned token as the value of a hidden field in a form that posts to a method that requires elevated privileges, or supply it as a request @@ -359,7 +351,7 @@ For example, include the CSRF token as a hidden field: -Or, include it as a header in a jQuery AJAX request: +Or include it as a header in a jQuery AJAX request: .. code-block:: javascript @@ -372,18 +364,17 @@ Or, include it as a header in a jQuery AJAX request: alert("Deleted"); }); - -The handler for the URL that receives the request -should then require that the correct CSRF token is supplied. +The handler for the URL that receives the request should then require that the +correct CSRF token is supplied. Checking CSRF Tokens Manually ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In request handling code, you can check the presence and validity of a CSRF -token with :func:`pyramid.session.check_csrf_token`. If the token is -valid, it will return ``True``, otherwise it will raise ``HTTPBadRequest``. -Optionally, you can specify ``raises=False`` to have the check return ``False`` -instead of raising an exception. +token with :func:`pyramid.session.check_csrf_token`. If the token is valid, it +will return ``True``, otherwise it will raise ``HTTPBadRequest``. Optionally, +you can specify ``raises=False`` to have the check return ``False`` instead of +raising an exception. By default, it checks for a GET or POST parameter named ``csrf_token`` or a header named ``X-CSRF-Token``. @@ -401,12 +392,12 @@ header named ``X-CSRF-Token``. .. index:: single: session.new_csrf_token -Checking CSRF Tokens With A View Predicate +Checking CSRF Tokens with a View Predicate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -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`. +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`. .. code-block:: python @@ -415,23 +406,19 @@ See :meth:`pyramid.config.Configurator.add_view`. ... .. note:: - A mismatch of CSRF token is treated like any other predicate miss, and the + A mismatch of a CSRF token is treated like any other predicate miss, and the 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`. - 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. +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() - - -- cgit v1.2.3 From b3f61c909736d5d6dc07d963decd2f3ce75230f5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 17 Oct 2015 02:57:09 -0700 Subject: minor grammar, rewrap 79 cols, .rst syntax fixes --- docs/narr/events.rst | 156 ++++++++++++++++++++++++--------------------------- 1 file changed, 73 insertions(+), 83 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 09caac898..c10d4cc47 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -9,18 +9,18 @@ .. _events_chapter: Using Events -============= +============ -An *event* is an object broadcast by the :app:`Pyramid` framework -at interesting points during the lifetime of an application. You -don't need to use events in order to create most :app:`Pyramid` -applications, but they can be useful when you want to perform slightly -advanced operations. For example, subscribing to an event can allow -you to run some code as the result of every new request. +An *event* is an object broadcast by the :app:`Pyramid` framework at +interesting points during the lifetime of an application. You don't need to +use events in order to create most :app:`Pyramid` applications, but they can be +useful when you want to perform slightly advanced operations. For example, +subscribing to an event can allow you to run some code as the result of every +new request. -Events in :app:`Pyramid` are always broadcast by the framework. -However, they only become useful when you register a *subscriber*. A -subscriber is a function that accepts a single argument named `event`: +Events in :app:`Pyramid` are always broadcast by the framework. However, they +only become useful when you register a *subscriber*. A subscriber is a +function that accepts a single argument named `event`: .. code-block:: python :linenos: @@ -28,23 +28,20 @@ subscriber is a function that accepts a single argument named `event`: def mysubscriber(event): print(event) -The above is a subscriber that simply prints the event to the console -when it's called. +The above is a subscriber that simply prints the event to the console when it's +called. The mere existence of a subscriber function, however, is not sufficient to arrange for it to be called. To arrange for the subscriber to be called, -you'll need to use the -:meth:`pyramid.config.Configurator.add_subscriber` method or you'll -need to use the :func:`pyramid.events.subscriber` decorator to decorate a -function found via a :term:`scan`. +you'll need to use the :meth:`pyramid.config.Configurator.add_subscriber` +method or you'll need to use the :func:`pyramid.events.subscriber` decorator to +decorate a function found via a :term:`scan`. Configuring an Event Listener Imperatively ------------------------------------------ -You can imperatively configure a subscriber function to be called -for some event type via the -:meth:`~pyramid.config.Configurator.add_subscriber` -method: +You can imperatively configure a subscriber function to be called for some +event type via the :meth:`~pyramid.config.Configurator.add_subscriber` method: .. code-block:: python :linenos: @@ -58,10 +55,9 @@ method: config.add_subscriber(mysubscriber, NewRequest) -The first argument to -:meth:`~pyramid.config.Configurator.add_subscriber` is the -subscriber function (or a :term:`dotted Python name` which refers -to a subscriber callable); the second argument is the event type. +The first argument to :meth:`~pyramid.config.Configurator.add_subscriber` is +the subscriber function (or a :term:`dotted Python name` which refers to a +subscriber callable); the second argument is the event type. .. seealso:: @@ -70,8 +66,8 @@ to a subscriber callable); the second argument is the event type. Configuring an Event Listener Using a Decorator ----------------------------------------------- -You can configure a subscriber function to be called for some event -type via the :func:`pyramid.events.subscriber` function. +You can configure a subscriber function to be called for some event type via +the :func:`pyramid.events.subscriber` function. .. code-block:: python :linenos: @@ -83,9 +79,9 @@ type via the :func:`pyramid.events.subscriber` function. def mysubscriber(event): event.request.foo = 1 -When the :func:`~pyramid.events.subscriber` decorator is used a -:term:`scan` must be performed against the package containing the -decorated function for the decorator to have any effect. +When the :func:`~pyramid.events.subscriber` decorator is used, a :term:`scan` +must be performed against the package containing the decorated function for the +decorator to have any effect. Either of the above registration examples implies that every time the :app:`Pyramid` framework emits an event object that supplies an @@ -96,13 +92,12 @@ As you can see, a subscription is made in terms of a *class* (such as :class:`pyramid.events.NewResponse`). The event object sent to a subscriber will always be an object that possesses an :term:`interface`. For :class:`pyramid.events.NewResponse`, that interface is -:class:`pyramid.interfaces.INewResponse`. The interface documentation -provides information about available attributes and methods of the event -objects. +:class:`pyramid.interfaces.INewResponse`. The interface documentation provides +information about available attributes and methods of the event objects. -The return value of a subscriber function is ignored. Subscribers to -the same event type are not guaranteed to be called in any particular -order relative to each other. +The return value of a subscriber function is ignored. Subscribers to the same +event type are not guaranteed to be called in any particular order relative to +each other. All the concrete :app:`Pyramid` event types are documented in the :ref:`events_module` API documentation. @@ -110,8 +105,8 @@ All the concrete :app:`Pyramid` event types are documented in the An Example ---------- -If you create event listener functions in a ``subscribers.py`` file in -your application like so: +If you create event listener functions in a ``subscribers.py`` file in your +application like so: .. code-block:: python :linenos: @@ -122,9 +117,8 @@ your application like so: def handle_new_response(event): print('response', event.response) -You may configure these functions to be called at the appropriate -times by adding the following code to your application's -configuration startup: +You may configure these functions to be called at the appropriate times by +adding the following code to your application's configuration startup: .. code-block:: python :linenos: @@ -136,22 +130,21 @@ configuration startup: config.add_subscriber('myproject.subscribers.handle_new_response', 'pyramid.events.NewResponse') -Either mechanism causes the functions in ``subscribers.py`` to be -registered as event subscribers. Under this configuration, when the -application is run, each time a new request or response is detected, a -message will be printed to the console. +Either mechanism causes the functions in ``subscribers.py`` to be registered as +event subscribers. Under this configuration, when the application is run, each +time a new request or response is detected, a message will be printed to the +console. -Each of our subscriber functions accepts an ``event`` object and -prints an attribute of the event object. This begs the question: how -can we know which attributes a particular event has? +Each of our subscriber functions accepts an ``event`` object and prints an +attribute of the event object. This begs the question: how can we know which +attributes a particular event has? We know that :class:`pyramid.events.NewRequest` event objects have a -``request`` attribute, which is a :term:`request` object, because the -interface defined at :class:`pyramid.interfaces.INewRequest` says it must. -Likewise, we know that :class:`pyramid.interfaces.NewResponse` events have a -``response`` attribute, which is a response object constructed by your -application, because the interface defined at -:class:`pyramid.interfaces.INewResponse` says it must +``request`` attribute, which is a :term:`request` object, because the interface +defined at :class:`pyramid.interfaces.INewRequest` says it must. Likewise, we +know that :class:`pyramid.interfaces.NewResponse` events have a ``response`` +attribute, which is a response object constructed by your application, because +the interface defined at :class:`pyramid.interfaces.INewResponse` says it must (:class:`pyramid.events.NewResponse` objects also have a ``request``). .. _custom_events: @@ -159,21 +152,20 @@ application, because the interface defined at Creating Your Own Events ------------------------ -In addition to using the events that the Pyramid framework creates, -you can create your own events for use in your application. This can -be useful to decouple parts of your application. +In addition to using the events that the Pyramid framework creates, you can +create your own events for use in your application. This can be useful to +decouple parts of your application. -For example, suppose your application has to do many things when a new -document is created. Rather than putting all this logic in the view -that creates the document, you can create the document in your view -and then fire a custom event. Subscribers to the custom event can take -other actions, such as indexing the document, sending email, or -sending a message to a remote system. +For example, suppose your application has to do many things when a new document +is created. Rather than putting all this logic in the view that creates the +document, you can create the document in your view and then fire a custom +event. Subscribers to the custom event can take other actions, such as indexing +the document, sending email, or sending a message to a remote system. -An event is simply an object. There are no required attributes or -method for your custom events. In general, your events should keep -track of the information that subscribers will need. Here are some -example custom event classes: +An event is simply an object. There are no required attributes or method for +your custom events. In general, your events should keep track of the +information that subscribers will need. Here are some example custom event +classes: .. code-block:: python :linenos: @@ -193,11 +185,10 @@ example custom event classes: Some Pyramid applications choose to define custom events classes in an ``events`` module. -You can subscribe to custom events in the same way that you subscribe -to Pyramid events -- either imperatively or with a decorator. You can -also use custom events with :ref:`subscriber predicates -`. Here's an example of subscribing to a custom -event with a decorator: +You can subscribe to custom events in the same way that you subscribe to +Pyramid events—either imperatively or with a decorator. You can also use custom +events with :ref:`subscriber predicates `. Here's an +example of subscribing to a custom event with a decorator: .. code-block:: python :linenos: @@ -211,12 +202,12 @@ event with a decorator: # index the document using our application's index_doc function index_doc(event.doc, event.request) -The above example assumes that the application defines a -``DocCreated`` event class and an ``index_doc`` function. +The above example assumes that the application defines a ``DocCreated`` event +class and an ``index_doc`` function. -To fire your custom events use the -:meth:`pyramid.registry.Registry.notify` method, which is most often -accessed as ``request.registry.notify``. For example: +To fire your custom events use the :meth:`pyramid.registry.Registry.notify` +method, which is most often accessed as ``request.registry.notify``. For +example: .. code-block:: python :linenos: @@ -229,11 +220,10 @@ accessed as ``request.registry.notify``. For example: request.registry.notify(event) return {'document': doc} -This example view will notify all subscribers to the custom -``DocCreated`` event. +This example view will notify all subscribers to the custom ``DocCreated`` +event. -Note that when you fire an event, all subscribers are run -synchronously so it's generally not a good idea -to create event handlers that may take a long time to run. Although -event handlers could be used as a central place to spawn tasks on your -own message queues. +Note that when you fire an event, all subscribers are run synchronously so it's +generally not a good idea to create event handlers that may take a long time to +run. Although event handlers could be used as a central place to spawn tasks on +your own message queues. -- cgit v1.2.3 From de6258689fd6a3e3d4726b6d1873fcca48e7ca02 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 17 Oct 2015 03:26:01 -0700 Subject: minor grammar, rewrap 79 cols, .rst syntax fixes --- docs/narr/environment.rst | 344 +++++++++++++++++++++------------------------- 1 file changed, 155 insertions(+), 189 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/environment.rst b/docs/narr/environment.rst index 0b06fb80b..743266d2c 100644 --- a/docs/narr/environment.rst +++ b/docs/narr/environment.rst @@ -21,39 +21,36 @@ Environment Variables and ``.ini`` File Settings ================================================ -:app:`Pyramid` behavior can be configured through a combination of -operating system environment variables and ``.ini`` configuration file -application section settings. The meaning of the environment -variables and the configuration file settings overlap. - -.. note:: Where a configuration file setting exists with the same - meaning as an environment variable, and both are present at - application startup time, the environment variable setting - takes precedence. - -The term "configuration file setting name" refers to a key in the -``.ini`` configuration for your application. The configuration file -setting names documented in this chapter are reserved for -:app:`Pyramid` use. You should not use them to indicate -application-specific configuration settings. +:app:`Pyramid` behavior can be configured through a combination of operating +system environment variables and ``.ini`` configuration file application +section settings. The meaning of the environment variables and the +configuration file settings overlap. + +.. note:: + Where a configuration file setting exists with the same meaning as an + environment variable, and both are present at application startup time, the + environment variable setting takes precedence. + +The term "configuration file setting name" refers to a key in the ``.ini`` +configuration for your application. The configuration file setting names +documented in this chapter are reserved for :app:`Pyramid` use. You should not +use them to indicate application-specific configuration settings. Reloading Templates ------------------- -When this value is true, templates are automatically reloaded whenever -they are modified without restarting the application, so you can see -changes to templates take effect immediately during development. This -flag is meaningful to Chameleon and Mako templates, as well as most -third-party template rendering extensions. - -+---------------------------------+--------------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+================================+ -| ``PYRAMID_RELOAD_TEMPLATES`` | ``pyramid.reload_templates`` | -| | or ``reload_templates`` | -| | | -| | | -+---------------------------------+--------------------------------+ +When this value is true, templates are automatically reloaded whenever they are +modified without restarting the application, so you can see changes to +templates take effect immediately during development. This flag is meaningful +to Chameleon and Mako templates, as well as most third-party template rendering +extensions. + ++-------------------------------+--------------------------------+ +| Environment Variable Name | Config File Setting Name | ++===============================+================================+ +| ``PYRAMID_RELOAD_TEMPLATES`` | ``pyramid.reload_templates`` | +| | or ``reload_templates`` | ++-------------------------------+--------------------------------+ Reloading Assets ---------------- @@ -64,24 +61,22 @@ Don't cache any asset file data when this value is true. See also :ref:`overriding_assets_section`. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_RELOAD_ASSETS`` | ``pyramid.reload_assets`` | -| | or ``reload_assets`` | -| | | -| | | -+---------------------------------+-----------------------------+ ++----------------------------+-----------------------------+ +| Environment Variable Name | Config File Setting Name | ++============================+=============================+ +| ``PYRAMID_RELOAD_ASSETS`` | ``pyramid.reload_assets`` | +| | or ``reload_assets`` | ++----------------------------+-----------------------------+ -.. note:: For backwards compatibility purposes, aliases can be - used for configurating asset reloading: ``PYRAMID_RELOAD_RESOURCES`` (envvar) - and ``pyramid.reload_resources`` (config file). +.. note:: For backwards compatibility purposes, aliases can be used for + configuring asset reloading: ``PYRAMID_RELOAD_RESOURCES`` (envvar) and + ``pyramid.reload_resources`` (config file). Debugging Authorization ----------------------- -Print view authorization failure and success information to stderr -when this value is true. +Print view authorization failure and success information to stderr when this +value is true. .. seealso:: @@ -92,28 +87,24 @@ when this value is true. +=================================+===================================+ | ``PYRAMID_DEBUG_AUTHORIZATION`` | ``pyramid.debug_authorization`` | | | or ``debug_authorization`` | -| | | -| | | +---------------------------------+-----------------------------------+ Debugging Not Found Errors -------------------------- -Print view-related ``NotFound`` debug messages to stderr -when this value is true. +Print view-related ``NotFound`` debug messages to stderr when this value is +true. .. seealso:: See also :ref:`debug_notfound_section`. -+---------------------------------+------------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+==============================+ -| ``PYRAMID_DEBUG_NOTFOUND`` | ``pyramid.debug_notfound`` | -| | or ``debug_notfound`` | -| | | -| | | -+---------------------------------+------------------------------+ ++----------------------------+------------------------------+ +| Environment Variable Name | Config File Setting Name | ++============================+==============================+ +| ``PYRAMID_DEBUG_NOTFOUND`` | ``pyramid.debug_notfound`` | +| | or ``debug_notfound`` | ++----------------------------+------------------------------+ Debugging Route Matching ------------------------ @@ -125,24 +116,22 @@ this value is true. See also :ref:`debug_routematch_section`. -+---------------------------------+--------------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+================================+ -| ``PYRAMID_DEBUG_ROUTEMATCH`` | ``pyramid.debug_routematch`` | -| | or ``debug_routematch`` | -| | | -| | | -+---------------------------------+--------------------------------+ ++------------------------------+--------------------------------+ +| Environment Variable Name | Config File Setting Name | ++==============================+================================+ +| ``PYRAMID_DEBUG_ROUTEMATCH`` | ``pyramid.debug_routematch`` | +| | or ``debug_routematch`` | ++------------------------------+--------------------------------+ .. _preventing_http_caching: Preventing HTTP Caching ------------------------- +----------------------- Prevent the ``http_cache`` view configuration argument from having any effect -globally in this process when this value is true. No http caching-related -response headers will be set by the Pyramid ``http_cache`` view configuration -feature when this is true. +globally in this process when this value is true. No HTTP caching-related +response headers will be set by the :app:`Pyramid` ``http_cache`` view +configuration feature when this is true. .. seealso:: @@ -153,8 +142,6 @@ feature when this is true. +=================================+==================================+ | ``PYRAMID_PREVENT_HTTP_CACHE`` | ``pyramid.prevent_http_cache`` | | | or ``prevent_http_cache`` | -| | | -| | | +---------------------------------+----------------------------------+ Preventing Cache Busting @@ -162,7 +149,7 @@ Preventing Cache Busting Prevent the ``cachebust`` static view configuration argument from having any effect globally in this process when this value is true. No cache buster will -be configured or used when this is true. +be configured or used when this is true. .. versionadded:: 1.6 @@ -175,8 +162,6 @@ be configured or used when this is true. +=================================+==================================+ | ``PYRAMID_PREVENT_CACHEBUST`` | ``pyramid.prevent_cachebust`` | | | or ``prevent_cachebust`` | -| | | -| | | +---------------------------------+----------------------------------+ Debugging All @@ -184,36 +169,32 @@ Debugging All Turns on all ``debug*`` settings. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_DEBUG_ALL`` | ``pyramid.debug_all`` | -| | or ``debug_all`` | -| | | -| | | -+---------------------------------+-----------------------------+ ++----------------------------+---------------------------+ +| Environment Variable Name | Config File Setting Name | ++============================+===========================+ +| ``PYRAMID_DEBUG_ALL`` | ``pyramid.debug_all`` | +| | or ``debug_all`` | ++----------------------------+---------------------------+ Reloading All ------------- Turns on all ``reload*`` settings. -+---------------------------------+-----------------------------+ -| Environment Variable Name | Config File Setting Name | -+=================================+=============================+ -| ``PYRAMID_RELOAD_ALL`` | ``pyramid.reload_all`` | -| | or ``reload_all`` | -| | | -| | | -+---------------------------------+-----------------------------+ ++---------------------------+----------------------------+ +| Environment Variable Name | Config File Setting Name | ++===========================+============================+ +| ``PYRAMID_RELOAD_ALL`` | ``pyramid.reload_all`` or | +| | ``reload_all`` | ++---------------------------+----------------------------+ .. _default_locale_name_setting: Default Locale Name --------------------- +------------------- -The value supplied here is used as the default locale name when a -:term:`locale negotiator` is not registered. +The value supplied here is used as the default locale name when a :term:`locale +negotiator` is not registered. .. seealso:: @@ -224,8 +205,6 @@ The value supplied here is used as the default locale name when a +=================================+===================================+ | ``PYRAMID_DEFAULT_LOCALE_NAME`` | ``pyramid.default_locale_name`` | | | or ``default_locale_name`` | -| | | -| | | +---------------------------------+-----------------------------------+ .. _including_packages: @@ -235,19 +214,16 @@ Including Packages ``pyramid.includes`` instructs your application to include other packages. Using the setting is equivalent to using the -:meth:`pyramid.config.Configurator.include` method. +:meth:`pyramid.config.Configurator.include` method. -+---------------------------------+ -| Config File Setting Name | -+=================================+ -| ``pyramid.includes`` | -| | -| | -| | -+---------------------------------+ ++--------------------------+ +| Config File Setting Name | ++==========================+ +| ``pyramid.includes`` | ++--------------------------+ -The value assigned to ``pyramid.includes`` should be a sequence. The -sequence can take several different forms. +The value assigned to ``pyramid.includes`` should be a sequence. The sequence +can take several different forms. 1) It can be a string. @@ -306,7 +282,7 @@ Plain Python ++++++++++++ Using the following ``pyramid.includes`` setting in your plain-Python Pyramid -application: +application: .. code-block:: python :linenos: @@ -341,33 +317,29 @@ This value allows you to perform explicit :term:`tween` ordering in your configuration. Tweens are bits of code used by add-on authors to extend Pyramid. They form a chain, and require ordering. -Ideally, you won't need to use the ``pyramid.tweens`` setting at all. Tweens +Ideally you won't need to use the ``pyramid.tweens`` setting at all. Tweens are generally ordered and included "implicitly" when an add-on package which registers a tween is "included". Packages are included when you name a ``pyramid.includes`` setting in your configuration or when you call :meth:`pyramid.config.Configurator.include`. Authors of included add-ons provide "implicit" tween configuration ordering -hints to Pyramid when their packages are included. However, the implicit -tween ordering is only best-effort. Pyramid will attempt to provide an -implicit order of tweens as best it can using hints provided by add-on -authors, but because it's only best-effort, if very precise tween ordering is -required, the only surefire way to get it is to use an explicit tween order. -You may be required to inspect your tween ordering (see -:ref:`displaying_tweens`) and add a ``pyramid.tweens`` configuration value at -the behest of an add-on author. - -+---------------------------------+ -| Config File Setting Name | -+=================================+ -| ``pyramid.tweens`` | -| | -| | -| | -+---------------------------------+ - -The value assigned to ``pyramid.tweens`` should be a sequence. The -sequence can take several different forms. +hints to Pyramid when their packages are included. However, the implicit tween +ordering is only best-effort. Pyramid will attempt to provide an implicit +order of tweens as best it can using hints provided by add-on authors, but +because it's only best-effort, if very precise tween ordering is required, the +only surefire way to get it is to use an explicit tween order. You may be +required to inspect your tween ordering (see :ref:`displaying_tweens`) and add +a ``pyramid.tweens`` configuration value at the behest of an add-on author. + ++---------------------------+ +| Config File Setting Name | ++===========================+ +| ``pyramid.tweens`` | ++---------------------------+ + +The value assigned to ``pyramid.tweens`` should be a sequence. The sequence +can take several different forms. 1) It can be a string. @@ -375,11 +347,11 @@ sequence can take several different forms. pkg.tween_factory1 pkg.tween_factory2 pkg.tween_factory3 - The tween names can also be separated by carriage returns:: + The tween names can also be separated by carriage returns:: - pkg.tween_factory1 - pkg.tween_factory2 - pkg.tween_factory3 + pkg.tween_factory1 + pkg.tween_factory2 + pkg.tween_factory3 2) It can be a Python list, where the values are strings:: @@ -390,8 +362,8 @@ Each value in the sequence should be a :term:`dotted Python name`. PasteDeploy Configuration vs. Plain-Python Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Using the following ``pyramid.tweens`` setting in the PasteDeploy ``.ini`` -file in your application: +Using the following ``pyramid.tweens`` setting in the PasteDeploy ``.ini`` file +in your application: .. code-block:: ini @@ -420,12 +392,11 @@ It is fine to use both or either form. Examples -------- -Let's presume your configuration file is named ``MyProject.ini``, and -there is a section representing your application named ``[app:main]`` -within the file that represents your :app:`Pyramid` application. -The configuration file settings documented in the above "Config File -Setting Name" column would go in the ``[app:main]`` section. Here's -an example of such a section: +Let's presume your configuration file is named ``MyProject.ini``, and there is +a section representing your application named ``[app:main]`` within the file +that represents your :app:`Pyramid` application. The configuration file +settings documented in the above "Config File Setting Name" column would go in +the ``[app:main]`` section. Here's an example of such a section: .. code-block:: ini :linenos: @@ -435,41 +406,39 @@ an example of such a section: pyramid.reload_templates = true pyramid.debug_authorization = true -You can also use environment variables to accomplish the same purpose -for settings documented as such. For example, you might start your -:app:`Pyramid` application using the following command line: +You can also use environment variables to accomplish the same purpose for +settings documented as such. For example, you might start your :app:`Pyramid` +application using the following command line: .. code-block:: text $ PYRAMID_DEBUG_AUTHORIZATION=1 PYRAMID_RELOAD_TEMPLATES=1 \ $VENV/bin/pserve MyProject.ini -If you started your application this way, your :app:`Pyramid` -application would behave in the same manner as if you had placed the -respective settings in the ``[app:main]`` section of your -application's ``.ini`` file. +If you started your application this way, your :app:`Pyramid` application would +behave in the same manner as if you had placed the respective settings in the +``[app:main]`` section of your application's ``.ini`` file. -If you want to turn all ``debug`` settings (every setting that starts -with ``pyramid.debug_``). on in one fell swoop, you can use -``PYRAMID_DEBUG_ALL=1`` as an environment variable setting or you may use -``pyramid.debug_all=true`` in the config file. Note that this does not affect -settings that do not start with ``pyramid.debug_*`` such as -``pyramid.reload_templates``. +If you want to turn all ``debug`` settings (every setting that starts with +``pyramid.debug_``) on in one fell swoop, you can use ``PYRAMID_DEBUG_ALL=1`` +as an environment variable setting or you may use ``pyramid.debug_all=true`` in +the config file. Note that this does not affect settings that do not start +with ``pyramid.debug_*`` such as ``pyramid.reload_templates``. If you want to turn all ``pyramid.reload`` settings (every setting that starts with ``pyramid.reload_``) on in one fell swoop, you can use ``PYRAMID_RELOAD_ALL=1`` as an environment variable setting or you may use -``pyramid.reload_all=true`` in the config file. Note that this does not -affect settings that do not start with ``pyramid.reload_*`` such as +``pyramid.reload_all=true`` in the config file. Note that this does not affect +settings that do not start with ``pyramid.reload_*`` such as ``pyramid.debug_notfound``. .. note:: Specifying configuration settings via environment variables is generally - most useful during development, where you may wish to augment or - override the more permanent settings in the configuration file. - This is useful because many of the reload and debug settings may - have performance or security (i.e., disclosure) implications - that make them undesirable in a production environment. + most useful during development, where you may wish to augment or override + the more permanent settings in the configuration file. This is useful + because many of the reload and debug settings may have performance or + security (i.e., disclosure) implications that make them undesirable in a + production environment. .. index:: single: reload_templates @@ -480,13 +449,13 @@ Understanding the Distinction Between ``reload_templates`` and ``reload_assets`` The difference between ``pyramid.reload_assets`` and ``pyramid.reload_templates`` is a bit subtle. Templates are themselves also -treated by :app:`Pyramid` as asset files (along with other static files), so the -distinction can be confusing. It's helpful to read +treated by :app:`Pyramid` as asset files (along with other static files), so +the distinction can be confusing. It's helpful to read :ref:`overriding_assets_section` for some context about assets in general. -When ``pyramid.reload_templates`` is true, :app:`Pyramid` takes advantage of the -underlying templating systems' ability to check for file modifications to an -individual template file. When ``pyramid.reload_templates`` is true but +When ``pyramid.reload_templates`` is true, :app:`Pyramid` takes advantage of +the underlying templating system's ability to check for file modifications to +an individual template file. When ``pyramid.reload_templates`` is true, but ``pyramid.reload_assets`` is *not* true, the template filename returned by the ``pkg_resources`` package (used under the hood by asset resolution) is cached by :app:`Pyramid` on the first request. Subsequent requests for the same @@ -499,21 +468,21 @@ because it has some effect). However, when ``pyramid.reload_assets`` is true, :app:`Pyramid` will not cache the template filename, meaning you can see the effect of changing the content of an overridden asset directory for templates without restarting the server -after every change. Subsequent requests for the same template file may -return different filenames based on the current state of overridden asset -directories. Setting ``pyramid.reload_assets`` to ``True`` affects performance -*dramatically*, slowing things down by an order of magnitude for each -template rendering. However, it's convenient to enable when moving files -around in overridden asset directories. ``pyramid.reload_assets`` makes the -system *very slow* when templates are in use. Never set -``pyramid.reload_assets`` to ``True`` on a production system. +after every change. Subsequent requests for the same template file may return +different filenames based on the current state of overridden asset directories. +Setting ``pyramid.reload_assets`` to ``True`` affects performance +*dramatically*, slowing things down by an order of magnitude for each template +rendering. However, it's convenient to enable when moving files around in +overridden asset directories. ``pyramid.reload_assets`` makes the system *very +slow* when templates are in use. Never set ``pyramid.reload_assets`` to +``True`` on a production system. .. index:: par: settings; adding custom .. _adding_a_custom_setting: -Adding A Custom Setting +Adding a Custom Setting ----------------------- From time to time, you may need to add a custom setting to your application. @@ -530,12 +499,12 @@ Here's how: debug_frobnosticator = True - In the ``main()`` function that represents the place that your Pyramid WSGI - application is created, anticipate that you'll be getting this key/value - pair as a setting and do any type conversion necessary. + application is created, anticipate that you'll be getting this key/value pair + as a setting and do any type conversion necessary. - If you've done any type conversion of your custom value, reset the - converted values into the ``settings`` dictionary *before* you pass the - dictionary as ``settings`` to the :term:`Configurator`. For example: + If you've done any type conversion of your custom value, reset the converted + values into the ``settings`` dictionary *before* you pass the dictionary as + ``settings`` to the :term:`Configurator`. For example: .. code-block:: python @@ -547,16 +516,17 @@ Here's how: settings['debug_frobnosticator'] = debug_frobnosticator config = Configurator(settings=settings) - .. note:: It's especially important that you mutate the ``settings`` - dictionary with the converted version of the variable *before* passing - it to the Configurator: the configurator makes a *copy* of ``settings``, - it doesn't use the one you pass directly. - -- When creating an ``includeme`` function that will be later added to your + .. note:: + It's especially important that you mutate the ``settings`` dictionary with + the converted version of the variable *before* passing it to the + Configurator: the configurator makes a *copy* of ``settings``, it doesn't + use the one you pass directly. + +- When creating an ``includeme`` function that will be later added to your application's configuration you may access the ``settings`` dictionary through the instance of the :term:`Configurator` that is passed into the function as its only argument. For Example: - + .. code-block:: python def includeme(config): @@ -573,8 +543,8 @@ Here's how: settings = request.registry.settings debug_frobnosticator = settings['debug_frobnosticator'] - If you wish to use the value in code that does not have access to the - request and you wish to use the value, you'll need to use the + If you wish to use the value in code that does not have access to the request + and you wish to use the value, you'll need to use the :func:`pyramid.threadlocal.get_current_registry` API to obtain the current registry, then ask for its ``settings`` attribute. For example: @@ -583,7 +553,3 @@ Here's how: registry = pyramid.threadlocal.get_current_registry() settings = registry.settings debug_frobnosticator = settings['debug_frobnosticator'] - - - - -- cgit v1.2.3 From 274412c9977bb0d31f8b92080ce5b8489a3e9fd3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 18 Oct 2015 02:32:22 -0700 Subject: minor grammar, rewrap 79 cols, .rst syntax fixes --- docs/narr/logging.rst | 310 +++++++++++++++++++++++++------------------------- 1 file changed, 152 insertions(+), 158 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/logging.rst b/docs/narr/logging.rst index 921883091..9c6e8a319 100644 --- a/docs/narr/logging.rst +++ b/docs/narr/logging.rst @@ -4,17 +4,17 @@ Logging ======= :app:`Pyramid` allows you to make use of the Python standard library -:mod:`logging` module. This chapter describes how to configure logging and -how to send log messages to loggers that you've configured. +:mod:`logging` module. This chapter describes how to configure logging and how +to send log messages to loggers that you've configured. .. warning:: - This chapter assumes you've used a :term:`scaffold` to create a - project which contains ``development.ini`` and ``production.ini`` files - which help configure logging. All of the scaffolds which ship along with - :app:`Pyramid` do this. If you're not using a scaffold, or if you've used - a third-party scaffold which does not create these files, the - configuration information in this chapter may not be applicable. + This chapter assumes you've used a :term:`scaffold` to create a project + which contains ``development.ini`` and ``production.ini`` files which help + configure logging. All of the scaffolds which ship with :app:`Pyramid` do + this. If you're not using a scaffold, or if you've used a third-party + scaffold which does not create these files, the configuration information in + this chapter may not be applicable. .. index: pair: settings; logging @@ -26,30 +26,29 @@ how to send log messages to loggers that you've configured. Logging Configuration --------------------- -A :app:`Pyramid` project created from a :term:`scaffold` is configured to -allow you to send messages to :mod:`Python standard library logging package -` loggers from within your -application. In particular, the :term:`PasteDeploy` ``development.ini`` and -``production.ini`` files created when you use a scaffold include a basic -configuration for the Python :mod:`logging` package. +A :app:`Pyramid` project created from a :term:`scaffold` is configured to allow +you to send messages to :mod:`Python standard library logging package +` loggers from within your application. In particular, the +:term:`PasteDeploy` ``development.ini`` and ``production.ini`` files created +when you use a scaffold include a basic configuration for the Python +:mod:`logging` package. PasteDeploy ``.ini`` files use the Python standard library :mod:`ConfigParser -format `; this is the same format used as the Python +format `. This is the same format used as the Python :ref:`logging module's Configuration file format `. The application-related and logging-related sections in the configuration file can coexist peacefully, and the logging-related sections in the file are used from when you run ``pserve``. -The ``pserve`` command calls the :func:`pyramid.paster.setup_logging` -function, a thin wrapper around the :func:`logging.config.fileConfig` -using the specified ``.ini`` file if it contains a ``[loggers]`` section -(all of the scaffold-generated ``.ini`` files do). ``setup_logging`` reads the -logging configuration from the ini file upon which ``pserve`` was -invoked. +The ``pserve`` command calls the :func:`pyramid.paster.setup_logging` function, +a thin wrapper around the :func:`logging.config.fileConfig` using the specified +``.ini`` file, if it contains a ``[loggers]`` section (all of the +scaffold-generated ``.ini`` files do). ``setup_logging`` reads the logging +configuration from the ini file upon which ``pserve`` was invoked. Default logging configuration is provided in both the default -``development.ini`` and the ``production.ini`` file. The logging -configuration in the ``development.ini`` file is as follows: +``development.ini`` and the ``production.ini`` file. The logging configuration +in the ``development.ini`` file is as follows: .. code-block:: ini :linenos: @@ -135,46 +134,44 @@ The logging configuration will literally be: In this logging configuration: -- a logger named ``root`` is created that logs messages at a level above - or equal to the ``INFO`` level to stderr, with the following format: +- a logger named ``root`` is created that logs messages at a level above or + equal to the ``INFO`` level to stderr, with the following format: - .. code-block:: text + .. code-block:: text - 2007-08-17 15:04:08,704 INFO [packagename] - Loading resource, id: 86 + 2007-08-17 15:04:08,704 INFO [packagename] Loading resource, id: 86 - a logger named ``myapp`` is configured that logs messages sent at a level - above or equal to ``DEBUG`` to stderr in the same format as the root - logger. + above or equal to ``DEBUG`` to stderr in the same format as the root logger. The ``root`` logger will be used by all applications in the Pyramid process -that ask for a logger (via ``logging.getLogger``) that has a name which -begins with anything except your project's package name (e.g. ``myapp``). -The logger with the same name as your package name is reserved for your own -usage in your Pyramid application. Its existence means that you can log to a -known logging location from any Pyramid application generated via a scaffold. - -Pyramid and many other libraries (such as Beaker, SQLAlchemy, Paste) log a -number of messages to the root logger for debugging purposes. Switching the +that ask for a logger (via ``logging.getLogger``) that has a name which begins +with anything except your project's package name (e.g., ``myapp``). The logger +with the same name as your package name is reserved for your own usage in your +:app:`Pyramid` application. Its existence means that you can log to a known +logging location from any :app:`Pyramid` application generated via a scaffold. + +:app:`Pyramid` and many other libraries (such as Beaker, SQLAlchemy, Paste) log +a number of messages to the root logger for debugging purposes. Switching the root logger level to ``DEBUG`` reveals them: -.. code-block:: ini +.. code-block:: ini - [logger_root] - #level = INFO - level = DEBUG - handlers = console + [logger_root] + #level = INFO + level = DEBUG + handlers = console -Some scaffolds configure additional loggers for additional subsystems they -use (such as SQLALchemy). Take a look at the ``production.ini`` and +Some scaffolds configure additional loggers for additional subsystems they use +(such as SQLALchemy). Take a look at the ``production.ini`` and ``development.ini`` files rendered when you create a project from a scaffold. Sending Logging Messages ------------------------ Python's special ``__name__`` variable refers to the current module's fully -qualified name. From any module in a package named ``myapp``, the -``__name__`` builtin variable will always be something like ``myapp``, or +qualified name. From any module in a package named ``myapp``, the ``__name__`` +builtin variable will always be something like ``myapp``, or ``myapp.subpackage`` or ``myapp.package.subpackage`` if your project is named ``myapp``. Sending a message to this logger will send it to the ``myapp`` logger. @@ -183,75 +180,75 @@ To log messages to the package-specific logger configured in your ``.ini`` file, simply create a logger object using the ``__name__`` builtin and call methods on it. -.. code-block:: python +.. code-block:: python :linenos: - import logging - log = logging.getLogger(__name__) + import logging + log = logging.getLogger(__name__) def myview(request): - content_type = 'text/plain' - content = 'Hello World!' - log.debug('Returning: %s (content-type: %s)', content, content_type) - request.response.content_type = content_type + content_type = 'text/plain' + content = 'Hello World!' + log.debug('Returning: %s (content-type: %s)', content, content_type) + request.response.content_type = content_type return request.response -This will result in the following printed to the console, on ``stderr``: +This will result in the following printed to the console, on ``stderr``: -.. code-block:: text +.. code-block:: text 16:20:20,440 DEBUG [myapp.views] Returning: Hello World! - (content-type: text/plain) + (content-type: text/plain) Filtering log messages ---------------------- -Often there's too much log output to sift through, such as when switching -the root logger's level to ``DEBUG``. +Often there's too much log output to sift through, such as when switching the +root logger's level to ``DEBUG``. -An example: you're diagnosing database connection issues in your application +For example, you're diagnosing database connection issues in your application and only want to see SQLAlchemy's ``DEBUG`` messages in relation to database connection pooling. You can leave the root logger's level at the less verbose ``INFO`` level and set that particular SQLAlchemy logger to ``DEBUG`` on its own, apart from the root logger: -.. code-block:: ini +.. code-block:: ini - [logger_sqlalchemy.pool] - level = DEBUG - handlers = - qualname = sqlalchemy.pool + [logger_sqlalchemy.pool] + level = DEBUG + handlers = + qualname = sqlalchemy.pool -then add it to the list of loggers: +then add it to the list of loggers: -.. code-block:: ini +.. code-block:: ini - [loggers] - keys = root, myapp, sqlalchemy.pool + [loggers] + keys = root, myapp, sqlalchemy.pool -No handlers need to be configured for this logger as by default non root -loggers will propagate their log records up to their parent logger's -handlers. The root logger is the top level parent of all loggers. +No handlers need to be configured for this logger as by default non-root +loggers will propagate their log records up to their parent logger's handlers. +The root logger is the top level parent of all loggers. This technique is used in the default ``development.ini``. The root logger's level is set to ``INFO``, whereas the application's log level is set to ``DEBUG``: -.. code-block:: ini +.. code-block:: ini - # Begin logging configuration + # Begin logging configuration - [loggers] + [loggers] keys = root, myapp - [logger_myapp] - level = DEBUG - handlers = - qualname = myapp + [logger_myapp] + level = DEBUG + handlers = + qualname = myapp All of the child loggers of the ``myapp`` logger will inherit the ``DEBUG`` level unless they're explicitly set differently. Meaning the ``myapp.views``, -``myapp.models`` (and all your app's modules') loggers by default have an +``myapp.models``, and all your app's modules' loggers by default have an effective level of ``DEBUG`` too. For more advanced filtering, the logging module provides a @@ -264,39 +261,38 @@ Advanced Configuration To capture log output to a separate file, use :class:`logging.FileHandler` (or :class:`logging.handlers.RotatingFileHandler`): -.. code-block:: ini +.. code-block:: ini - [handler_filelog] - class = FileHandler - args = ('%(here)s/myapp.log','a') - level = INFO - formatter = generic + [handler_filelog] + class = FileHandler + args = ('%(here)s/myapp.log','a') + level = INFO + formatter = generic -Before it's recognized, it needs to be added to the list of handlers: +Before it's recognized, it needs to be added to the list of handlers: -.. code-block:: ini +.. code-block:: ini - [handlers] + [handlers] keys = console, myapp, filelog -and finally utilized by a logger. +and finally utilized by a logger. -.. code-block:: ini +.. code-block:: ini - [logger_root] - level = INFO + [logger_root] + level = INFO handlers = console, filelog -These final 3 lines of configuration directs all of the root logger's output +These final three lines of configuration direct all of the root logger's output to the ``myapp.log`` as well as the console. Logging Exceptions ------------------ -To log (or email) exceptions generated by your :app:`Pyramid` application, -use the :term:`pyramid_exclog` package. Details about its configuration are -in its `documentation -`_. +To log or email exceptions generated by your :app:`Pyramid` application, use +the :term:`pyramid_exclog` package. Details about its configuration are in its +`documentation `_. .. index:: single: TransLogger @@ -307,40 +303,40 @@ in its `documentation .. _request_logging_with_pastes_translogger: -Request Logging with Paste's TransLogger +Request Logging with Paste's TransLogger ---------------------------------------- -The term:`WSGI` design is modular. Waitress logs error conditions, debugging -output, etc., but not web traffic. For web traffic logging Paste provides the +The :term:`WSGI` design is modular. Waitress logs error conditions, debugging +output, etc., but not web traffic. For web traffic logging, Paste provides the `TransLogger `_ :term:`middleware`. TransLogger produces logs in the `Apache Combined Log Format `_. But -TransLogger does not write to files, the Python logging system must be -configured to do this. The Python :class:`logging.FileHandler` logging -handler can be used alongside TransLogger to create an ``access.log`` file -similar to Apache's. +TransLogger does not write to files; the Python logging system must be +configured to do this. The Python :class:`logging.FileHandler` logging handler +can be used alongside TransLogger to create an ``access.log`` file similar to +Apache's. Like any standard :term:`middleware` with a Paste entry point, TransLogger can -be configured to wrap your application using ``.ini`` file syntax. First, +be configured to wrap your application using ``.ini`` file syntax. First rename your Pyramid ``.ini`` file's ``[app:main]`` section to -``[app:mypyramidapp]``, then add a ``[filter:translogger]`` section, then use -a ``[pipeline:main]`` section file to form a WSGI pipeline with both the +``[app:mypyramidapp]``, then add a ``[filter:translogger]`` section, then use a +``[pipeline:main]`` section file to form a WSGI pipeline with both the translogger and your application in it. For instance, change from this: -.. code-block:: ini +.. code-block:: ini [app:main] use = egg:MyProject To this: -.. code-block:: ini +.. code-block:: ini [app:mypyramidapp] use = egg:MyProject - [filter:translogger] - use = egg:Paste#translogger + [filter:translogger] + use = egg:Paste#translogger setup_console_handler = False [pipeline:main] @@ -351,41 +347,40 @@ Using PasteDeploy this way to form and serve a pipeline is equivalent to wrapping your app in a TransLogger instance via the bottom of the ``main`` function of your project's ``__init__`` file: -.. code-block:: python +.. code-block:: python ... app = config.make_wsgi_app() - from paste.translogger import TransLogger - app = TransLogger(app, setup_console_handler=False) - return app - + from paste.translogger import TransLogger + app = TransLogger(app, setup_console_handler=False) + return app .. note:: TransLogger will automatically setup a logging handler to the console when - called with no arguments, so it 'just works' in environments that don't - configure logging. Since our logging handlers are configured we disable + called with no arguments, so it "just works" in environments that don't + configure logging. Since our logging handlers are configured, we disable the automation via ``setup_console_handler = False``. With the filter in place, TransLogger's logger (named the ``wsgi`` logger) will -propagate its log messages to the parent logger (the root logger), sending -its output to the console when we request a page: +propagate its log messages to the parent logger (the root logger), sending its +output to the console when we request a page: -.. code-block:: text +.. code-block:: text 00:50:53,694 INFO [myapp.views] Returning: Hello World! - (content-type: text/plain) + (content-type: text/plain) 00:50:53,695 INFO [wsgi] 192.168.1.111 - - [11/Aug/2011:20:09:33 -0700] "GET /hello - HTTP/1.1" 404 - "-" + HTTP/1.1" 404 - "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.6) Gecko/20070725 - Firefox/2.0.0.6" + Firefox/2.0.0.6" To direct TransLogger to an ``access.log`` FileHandler, we need the following to add a FileHandler (named ``accesslog``) to the list of handlers, and ensure that the ``wsgi`` logger is configured and uses this handler accordingly: -.. code-block:: ini +.. code-block:: ini - # Begin logging configuration + # Begin logging configuration [loggers] keys = root, myapp, wsgi @@ -393,44 +388,43 @@ that the ``wsgi`` logger is configured and uses this handler accordingly: [handlers] keys = console, accesslog - [logger_wsgi] - level = INFO + [logger_wsgi] + level = INFO handlers = accesslog - qualname = wsgi - propagate = 0 - - [handler_accesslog] - class = FileHandler - args = ('%(here)s/access.log','a') - level = INFO - formatter = generic - -As mentioned above, non-root loggers by default propagate their log records -to the root logger's handlers (currently the console handler). Setting -``propagate`` to ``0`` (``False``) here disables this; so the ``wsgi`` logger + qualname = wsgi + propagate = 0 + + [handler_accesslog] + class = FileHandler + args = ('%(here)s/access.log','a') + level = INFO + formatter = generic + +As mentioned above, non-root loggers by default propagate their log records to +the root logger's handlers (currently the console handler). Setting +``propagate`` to ``0`` (``False``) here disables this; so the ``wsgi`` logger directs its records only to the ``accesslog`` handler. Finally, there's no need to use the ``generic`` formatter with TransLogger as -TransLogger itself provides all the information we need. We'll use a -formatter that passes-through the log messages as is. Add a new formatter -called ``accesslog`` by including the following in your configuration file: - -.. code-block:: ini +TransLogger itself provides all the information we need. We'll use a formatter +that passes through the log messages as is. Add a new formatter called +``accesslog`` by including the following in your configuration file: - [formatters] - keys = generic, accesslog +.. code-block:: ini - [formatter_accesslog] - format = %(message)s + [formatters] + keys = generic, accesslog + [formatter_accesslog] + format = %(message)s -Finally alter the existing configuration to wire this new -``accesslog`` formatter into the FileHandler: +Finally alter the existing configuration to wire this new ``accesslog`` +formatter into the FileHandler: -.. code-block:: ini +.. code-block:: ini - [handler_accesslog] - class = FileHandler - args = ('%(here)s/access.log','a') - level = INFO - formatter = accesslog + [handler_accesslog] + class = FileHandler + args = ('%(here)s/access.log','a') + level = INFO + formatter = accesslog -- cgit v1.2.3 From fc3f6b05e086ed4e111013fcd5b09454982d58f3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 18 Oct 2015 02:48:55 -0700 Subject: minor grammar, rewrap 79 cols, .rst syntax fixes --- docs/narr/paste.rst | 96 ++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 49 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/paste.rst b/docs/narr/paste.rst index f1fb70869..0a217e6e3 100644 --- a/docs/narr/paste.rst +++ b/docs/narr/paste.rst @@ -7,54 +7,54 @@ Packages generated via a :term:`scaffold` make use of a system created by Ian Bicking named :term:`PasteDeploy`. PasteDeploy defines a way to declare :term:`WSGI` application configuration in an ``.ini`` file. -Pyramid uses this configuration file format in input to its :term:`WSGI` -server runner ``pserve``, as well as other commands such as ``pviews``, -``pshell``, ``proutes``, and ``ptweens``. +Pyramid uses this configuration file format as input to its :term:`WSGI` server +runner ``pserve``, as well as other commands such as ``pviews``, ``pshell``, +``proutes``, and ``ptweens``. PasteDeploy is not a particularly integral part of Pyramid. It's possible to -create a Pyramid application which does not use PasteDeploy at all. We show -a Pyramid application that doesn't use PasteDeploy in -:ref:`firstapp_chapter`. However, all Pyramid scaffolds render PasteDeploy -configuration files, to provide new developers with a standardized way of -setting deployment values, and to provide new users with a standardized way -of starting, stopping, and debugging an application. - -This chapter is not a replacement for documentation about PasteDeploy; it -only contextualizes the use of PasteDeploy within Pyramid. For detailed +create a Pyramid application which does not use PasteDeploy at all. We show a +Pyramid application that doesn't use PasteDeploy in :ref:`firstapp_chapter`. +However, all Pyramid scaffolds render PasteDeploy configuration files, to +provide new developers with a standardized way of setting deployment values, +and to provide new users with a standardized way of starting, stopping, and +debugging an application. + +This chapter is not a replacement for documentation about PasteDeploy; it only +contextualizes the use of PasteDeploy within Pyramid. For detailed documentation, see http://pythonpaste.org/deploy/. PasteDeploy ----------- -:term:`PasteDeploy` is the system that Pyramid uses to allow -:term:`deployment settings` to be spelled using an ``.ini`` configuration -file format. It also allows the ``pserve`` command to work. Its -configuration format provides a convenient place to define application -:term:`deployment settings` and WSGI server settings, and its server runner -allows you to stop and start a Pyramid application easily. +:term:`PasteDeploy` is the system that Pyramid uses to allow :term:`deployment +settings` to be specified using an ``.ini`` configuration file format. It also +allows the ``pserve`` command to work. Its configuration format provides a +convenient place to define application :term:`deployment settings` and WSGI +server settings, and its server runner allows you to stop and start a Pyramid +application easily. .. _pastedeploy_entry_points: Entry Points and PasteDeploy ``.ini`` Files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the :ref:`project_narr` chapter, we breezed over the meaning of a configuration line in the ``deployment.ini`` file. This was the ``use = -egg:MyProject`` line in the ``[app:main]`` section. We breezed over it -because it's pretty confusing and "too much information" for an introduction -to the system. We'll try to give it a bit of attention here. Let's see the -config file again: +egg:MyProject`` line in the ``[app:main]`` section. We breezed over it because +it's pretty confusing and "too much information" for an introduction to the +system. We'll try to give it a bit of attention here. Let's see the config +file again: .. literalinclude:: MyProject/development.ini :language: ini :linenos: -The line in ``[app:main]`` above that says ``use = egg:MyProject`` is -actually shorthand for a longer spelling: ``use = egg:MyProject#main``. The -``#main`` part is omitted for brevity, as ``#main`` is a default defined by -PasteDeploy. ``egg:MyProject#main`` is a string which has meaning to -PasteDeploy. It points at a :term:`setuptools` :term:`entry point` named -``main`` defined in the ``MyProject`` project. +The line in ``[app:main]`` above that says ``use = egg:MyProject`` is actually +shorthand for a longer spelling: ``use = egg:MyProject#main``. The ``#main`` +part is omitted for brevity, as ``#main`` is a default defined by PasteDeploy. +``egg:MyProject#main`` is a string which has meaning to PasteDeploy. It points +at a :term:`setuptools` :term:`entry point` named ``main`` defined in the +``MyProject`` project. Take a look at the generated ``setup.py`` file for this project. @@ -62,19 +62,19 @@ Take a look at the generated ``setup.py`` file for this project. :language: python :linenos: -Note that ``entry_points`` is assigned a string which -looks a lot like an ``.ini`` file. This string representation of an ``.ini`` -file has a section named ``[paste.app_factory]``. Within this section, there -is a key named ``main`` (the entry point name) which has a value -``myproject:main``. The *key* ``main`` is what our ``egg:MyProject#main`` -value of the ``use`` section in our config file is pointing at, although it -is actually shortened to ``egg:MyProject`` there. The value represents a -:term:`dotted Python name` path, which refers to a callable in our -``myproject`` package's ``__init__.py`` module. +Note that ``entry_points`` is assigned a string which looks a lot like an +``.ini`` file. This string representation of an ``.ini`` file has a section +named ``[paste.app_factory]``. Within this section, there is a key named +``main`` (the entry point name) which has a value ``myproject:main``. The +*key* ``main`` is what our ``egg:MyProject#main`` value of the ``use`` section +in our config file is pointing at, although it is actually shortened to +``egg:MyProject`` there. The value represents a :term:`dotted Python name` +path, which refers to a callable in our ``myproject`` package's ``__init__.py`` +module. -The ``egg:`` prefix in ``egg:MyProject`` indicates that this is an entry -point *URI* specifier, where the "scheme" is "egg". An "egg" is created when -you run ``setup.py install`` or ``setup.py develop`` within your project. +The ``egg:`` prefix in ``egg:MyProject`` indicates that this is an entry point +*URI* specifier, where the "scheme" is "egg". An "egg" is created when you run +``setup.py install`` or ``setup.py develop`` within your project. In English, this entry point can thus be referred to as a "PasteDeploy application factory in the ``MyProject`` project which has the entry point @@ -88,13 +88,11 @@ configuration object and *returns* an instance of our application. .. _defaults_section_of_pastedeploy_file: ``[DEFAULT]`` Section of a PasteDeploy ``.ini`` File -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can add a ``[DEFAULT]`` section to your PasteDeploy ``.ini`` file. Such -a section should consists of global parameters that are shared by all the -applications, servers and :term:`middleware` defined within the configuration +You can add a ``[DEFAULT]`` section to your PasteDeploy ``.ini`` file. Such a +section should consist of global parameters that are shared by all the +applications, servers, and :term:`middleware` defined within the configuration file. The values in a ``[DEFAULT]`` section will be passed to your -application's ``main`` function as ``global_config`` (see the reference to -the ``main`` function in :ref:`init_py`). - - +application's ``main`` function as ``global_config`` (see the reference to the +``main`` function in :ref:`init_py`). -- cgit v1.2.3 From 65f9452d1a1be412ab118e6fc081dac555849cd2 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 18 Oct 2015 13:50:43 -0500 Subject: Fix entrypoints syntax in pshell as part of #1891. --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index cb0c914d7..641fe43cf 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -298,7 +298,7 @@ a new shell by registering an entrypoint in your setup.py: setup( entry_points = """\ [pyramid.pshell] - myshell=my_app.ptpython_shell_factory + myshell=my_app:ptpython_shell_factory """ ) -- cgit v1.2.3 From 760691509b4d85e66934e00b9ddc0c295bc2b632 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 19 Oct 2015 02:58:45 -0700 Subject: add Method sentence and heading for proutes, minor grammar, rewrap 79 cols, .rst syntax fixes --- docs/narr/commandline.rst | 479 +++++++++++++++++++++++----------------------- 1 file changed, 237 insertions(+), 242 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index cb0c914d7..dcffdb3eb 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -3,9 +3,8 @@ 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. +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 @@ -17,15 +16,15 @@ Displaying Matching Views for a Given URL ----------------------------------------- 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 matching routes and views for a given URL in your -application. The ``pviews`` command accepts two arguments. The first -argument to ``pviews`` is the path to your application's ``.ini`` file and -section name inside the ``.ini`` file which points to your application. This -should be of the format ``config_file#section_name``. The second argument is -the URL to test for matching views. The ``section_name`` may be omitted; if -it is, it's considered to be ``main``. +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 +matching routes and views for a given URL in your application. The ``pviews`` +command accepts two arguments. The first argument to ``pviews`` is the path to +your application's ``.ini`` file and section name inside the ``.ini`` file +which points to your application. This should be of the format +``config_file#section_name``. The second argument is the URL to test for +matching views. The ``section_name`` may be omitted; if it is, it's considered +to be ``main``. Here is an example for a simple view configuration using :term:`traversal`: @@ -44,12 +43,11 @@ Here is an example for a simple view configuration using :term:`traversal`: tutorial.views.view_page required permission = view -The output always has the requested URL at the top and below that all the -views that matched with their view configuration details. In this example -only one view matches, so there is just a single *View* section. For each -matching view, the full code path to the associated view callable is shown, -along with any permissions and predicates that are part of that view -configuration. +The output always has the requested URL at the top and below that all the views +that matched with their view configuration details. In this example only one +view matches, so there is just a single *View* section. For each matching view, +the full code path to the associated view callable is shown, along with any +permissions and predicates that are part of that view configuration. A more complex configuration might generate something like this: @@ -99,12 +97,12 @@ A more complex configuration might generate something like this: In this case, we are dealing with a :term:`URL dispatch` application. This specific URL has two matching routes. The matching route information is -displayed first, followed by any views that are associated with that route. -As you can see from the second matching route output, a route can be -associated with more than one view. +displayed first, followed by any views that are associated with that route. As +you can see from the second matching route output, a route can be associated +with more than one view. -For a URL that doesn't match any views, ``pviews`` will simply print out a -*Not found* message. +For a URL that doesn't match any views, ``pviews`` will simply print out a *Not +found* message. .. index:: @@ -118,17 +116,16 @@ For a URL that doesn't match any views, ``pviews`` will simply print out a The Interactive Shell --------------------- -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 "for real". To do so, use the ``pshell`` command line -utility. +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 +"for real". To do so, use the ``pshell`` command line utility. The argument to ``pshell`` follows the format ``config_file#section_name`` where ``config_file`` is the path to your application's ``.ini`` file and ``section_name`` is the ``app`` section name inside the ``.ini`` file which -points to your application. For example, if your application ``.ini`` file -might have a ``[app:main]`` section that looks like so: +points to your application. For example, your application ``.ini`` file might +have an ``[app:main]`` section that looks like so: .. code-block:: ini :linenos: @@ -141,13 +138,13 @@ might have a ``[app:main]`` section that looks like so: pyramid.debug_templates = true pyramid.default_locale_name = en -If so, you can use the following command to invoke a debug shell using the -name ``main`` as a section name: +If so, you can use the following command to invoke a debug shell using the name +``main`` as a section name: .. code-block:: text $ $VENV/bin/pshell starter/development.ini#main - Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -172,9 +169,8 @@ name ``main`` as a section name: The WSGI application that is loaded will be available in the shell as the ``app`` global. Also, if the application that is loaded is the :app:`Pyramid` -app with no surrounding :term:`middleware`, the ``root`` object returned by -the default :term:`root factory`, ``registry``, and ``request`` will be -available. +app with no surrounding :term:`middleware`, the ``root`` object returned by the +default :term:`root factory`, ``registry``, and ``request`` will be available. You can also simply rely on the ``main`` default section name by omitting any hash after the filename: @@ -193,22 +189,22 @@ Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). Extending the Shell ~~~~~~~~~~~~~~~~~~~ -It is convenient when using the interactive shell often to have some -variables significant to your application already loaded as globals when -you start the ``pshell``. To facilitate this, ``pshell`` will look for a -special ``[pshell]`` section in your INI file and expose the subsequent -key/value pairs to the shell. Each key is a variable name that will be -global within the pshell session; each value is a :term:`dotted Python name`. -If specified, the special key ``setup`` should be a :term:`dotted Python name` -pointing to a callable that accepts the dictionary of globals that will -be loaded into the shell. This allows for some custom initializing code -to be executed each time the ``pshell`` is run. The ``setup`` callable -can also be specified from the commandline using the ``--setup`` option -which will override the key in the INI file. - -For example, you want to expose your model to the shell, along with the -database session so that you can mutate the model on an actual database. -Here, we'll assume your model is stored in the ``myapp.models`` package. +It is convenient when using the interactive shell often to have some variables +significant to your application already loaded as globals when you start the +``pshell``. To facilitate this, ``pshell`` will look for a special ``[pshell]`` +section in your INI file and expose the subsequent key/value pairs to the +shell. Each key is a variable name that will be global within the pshell +session; each value is a :term:`dotted Python name`. If specified, the special +key ``setup`` should be a :term:`dotted Python name` pointing to a callable +that accepts the dictionary of globals that will be loaded into the shell. This +allows for some custom initializing code to be executed each time the +``pshell`` is run. The ``setup`` callable can also be specified from the +commandline using the ``--setup`` option which will override the key in the INI +file. + +For example, you want to expose your model to the shell along with the database +session so that you can mutate the model on an actual database. Here, we'll +assume your model is stored in the ``myapp.models`` package. .. code-block:: ini :linenos: @@ -236,10 +232,10 @@ of the application to which we can easily submit requests. env['request'].scheme = 'https' env['testapp'] = TestApp(env['app']) -When this INI file is loaded, the extra variables ``m``, ``session`` and -``t`` will be available for use immediately. Since a ``setup`` callable -was also specified, it is executed and a new variable ``testapp`` is -exposed, and the request is configured to generate urls from the host +When this INI file is loaded, the extra variables ``m``, ``session`` and ``t`` +will be available for use immediately. Since a ``setup`` callable was also +specified, it is executed and a new variable ``testapp`` is exposed, and the +request is configured to generate urls from the host ``http://www.example.com``. For example: .. code-block:: text @@ -276,13 +272,12 @@ exposed, and the request is configured to generate urls from the host IPython or bpython ~~~~~~~~~~~~~~~~~~ -If you have `IPython `_ and/or -`bpython `_ in -the interpreter you use to invoke the ``pshell`` command, ``pshell`` will -autodiscover and use the first one found, in this order: -IPython, bpython, standard Python interpreter. However you could -specifically invoke one of your choice with the ``-p choice`` or -``--python-shell choice`` option. +If you have `IPython `_ and/or `bpython +`_ in the interpreter you use to invoke the +``pshell`` command, ``pshell`` will autodiscover and use the first one found, +in this order: IPython, bpython, standard Python interpreter. However you could +specifically invoke your choice with the ``-p choice`` or ``--python-shell +choice`` option. .. code-block:: text @@ -290,8 +285,8 @@ specifically invoke one of your choice with the ``-p choice`` or Alternative Shells ~~~~~~~~~~~~~~~~~~ -If you want to use a shell that isn't supported out of the box you can introduce -a new shell by registering an entrypoint in your setup.py: +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: .. code-block:: python @@ -302,8 +297,8 @@ a new shell by registering an entrypoint in your setup.py: """ ) -and then your shell factory should return a function that accepts two arguments, -``env`` and ``help``, this would look like this: +And then your shell factory should return a function that accepts two +arguments, ``env`` and ``help``, which would look like this: .. code-block:: python @@ -318,6 +313,8 @@ and then your shell factory should return a function that accepts two arguments, return shell +.. versionadded:: 1.6 + .. index:: pair: routes; printing single: proutes @@ -327,14 +324,13 @@ and then your shell factory should return a function that accepts two arguments, Displaying All Application Routes --------------------------------- -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 the format ``config_file#section_name``. The -``config_file`` is the path to your application's ``.ini`` file, and -``section_name`` is the ``app`` section name inside the ``.ini`` file which -points to your application. By default, the ``section_name`` is ``main`` and -can be omitted. +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 +the format ``config_file#section_name``. The ``config_file`` is the path to +your application's ``.ini`` file, and ``section_name`` is the ``app`` section +name inside the ``.ini`` file which points to your application. By default, +the ``section_name`` is ``main`` and can be omitted. For example: @@ -342,8 +338,8 @@ For example: :linenos: $ $VENV/bin/proutes development.ini - Name Pattern View - ---- ------- ---- + Name Pattern View Method + ---- ------- ---- ------ debugtoolbar /_debug_toolbar/*subpath * __static/ /static/*subpath dummy_starter:static/ * __static2/ /static2/*subpath /var/www/static/ * @@ -355,22 +351,25 @@ For example: multiview /multiview app1.standard_views.multiview GET,PATCH not_post /not_post app1.standard_views.multview !POST,* -``proutes`` generates a table with four columns: *Name*, *Pattern*, *Method*, -and *View*. The items listed in the -Name column are route names, the items listed in the Pattern column are route -patterns, and the items listed in the View column are representations of the -view callable that will be invoked when a request matches the associated -route pattern. The view column may show ```` if no associated view -callable could be found. If no routes are configured within your -application, nothing will be printed to the console when ``proutes`` -is executed. - -It is convenient when using the ``proutes`` often to configure which columns -and the order you would like to view them. To facilitate this, ``proutes`` will -look for a special ``[proutes]`` section in your INI file and use those as -defaults. - -For example you may remove request method and place the view first: +``proutes`` generates a table with four columns: *Name*, *Pattern*, *View*, and +*Method*. The items listed in the Name column are route names, the items +listed in the Pattern column are route patterns, the items listed in the View +column are representations of the view callable that will be invoked when a +request matches the associated route pattern, and the items listed in the +Method column are the request methods that are associated with the route name. +The View column may show ```` if no associated view callable could be +found. The Method column, for the route name, may show either ```` if the view callable does not accept any of the route's request +methods, or ``*`` if the view callable will accept any of the route's request +methods. If no routes are configured within your application, nothing will be +printed to the console when ``proutes`` is executed. + +It is convenient when using the ``proutes`` command often to configure which +columns and the order you would like to view them. To facilitate this, +``proutes`` will look for a special ``[proutes]`` section in your ``.ini`` file +and use those as defaults. + +For example you may remove the request method and place the view first: .. code-block:: text :linenos: @@ -391,9 +390,10 @@ You can also separate the formats with commas or spaces: [proutes] format = view, name, pattern -If you want to temporarily configure the columns and order there is the -``--format`` which is a comma separated list of columns you want to include. The -current available formats are ``name``, ``pattern``, ``view``, and ``method``. +If you want to temporarily configure the columns and order, there is the +argument ``--format``, which is a comma separated list of columns you want to +include. The current available formats are ``name``, ``pattern``, ``view``, and +``method``. .. index:: @@ -405,17 +405,16 @@ current available formats are ``name``, ``pattern``, ``view``, and ``method``. Displaying "Tweens" ------------------- -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 calls to :meth:`pyramid.config.Configurator.add_tween`) and the -explicit tween ordering (specified by the ``pyramid.tweens`` configuration -setting) orderings using the ``ptweens`` command. Tween factories -will show up represented by their standard Python dotted name in the -``ptweens`` output. +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 +calls to :meth:`pyramid.config.Configurator.add_tween`) and the explicit tween +ordering (specified by the ``pyramid.tweens`` configuration setting) using the +``ptweens`` command. Tween factories will show up represented by their +standard Python dotted name in the ``ptweens`` output. -For example, here's the ``ptweens`` command run against a system -configured without any explicit tweens: +For example, here's the ``ptweens`` command run against a system configured +without any explicit tweens: .. code-block:: text :linenos: @@ -425,15 +424,15 @@ configured without any explicit tweens: Implicit Tween Chain - Position Name Alias + Position Name Alias -------- ---- ----- - - INGRESS 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory pdbt 1 pyramid.tweens.excview_tween_factory excview - - MAIN -Here's the ``ptweens`` command run against a system configured *with* -explicit tweens defined in its ``development.ini`` file: +Here's the ``ptweens`` command run against a system configured *with* explicit +tweens defined in its ``development.ini`` file: .. code-block:: text :linenos: @@ -443,13 +442,13 @@ explicit tweens defined in its ``development.ini`` file: Explicit Tween Chain (used) - Position Name - -------- ---- - - INGRESS - 0 starter.tween_factory2 - 1 starter.tween_factory1 - 2 pyramid.tweens.excview_tween_factory - - MAIN + Position Name + -------- ---- + - INGRESS + 0 starter.tween_factory2 + 1 starter.tween_factory1 + 2 pyramid.tweens.excview_tween_factory + - MAIN Implicit Tween Chain (not used) @@ -460,9 +459,9 @@ explicit tweens defined in its ``development.ini`` file: 1 pyramid.tweens.excview_tween_factory - MAIN -Here's the application configuration section of the ``development.ini`` used -by the above ``ptweens`` command which reports that the explicit tween chain -is used: +Here's the application configuration section of the ``development.ini`` used by +the above ``ptweens`` command which reports that the explicit tween chain is +used: .. code-block:: ini :linenos: @@ -496,13 +495,13 @@ application and see the response body without starting a server. There are two required arguments to ``prequest``: -- The config file/section: follows the format ``config_file#section_name`` +- The config file/section: follows the format ``config_file#section_name``, where ``config_file`` is the path to your application's ``.ini`` file and ``section_name`` is the ``app`` section name inside the ``.ini`` file. The - ``section_name`` is optional, it defaults to ``main``. For example: + ``section_name`` is optional; it defaults to ``main``. For example: ``development.ini``. -- The path: this should be the non-url-quoted path element of the URL to the +- The path: this should be the non-URL-quoted path element of the URL to the resource you'd like to be rendered on the server. For example, ``/``. For example:: @@ -512,31 +511,31 @@ For example:: This will print the body of the response to the console on which it was invoked. -Several options are supported by ``prequest``. These should precede any -config file name or URL. +Several options are supported by ``prequest``. These should precede any config +file name or URL. -``prequest`` has a ``-d`` (aka ``--display-headers``) option which prints the +``prequest`` has a ``-d`` (i.e., ``--display-headers``) option which prints the status and headers returned by the server before the output:: $ $VENV/bin/prequest -d development.ini / -This will print the status, then the headers, then the body of the response -to the console. +This will print the status, headers, and the body of the response to the +console. You can add request header values by using the ``--header`` option:: $ $VENV/bin/prequest --header=Host:example.com development.ini / -Headers are added to the WSGI environment by converting them to their -CGI/WSGI equivalents (e.g. ``Host=example.com`` will insert the ``HTTP_HOST`` -header variable as the value ``example.com``). Multiple ``--header`` options -can be supplied. The special header value ``content-type`` sets the -``CONTENT_TYPE`` in the WSGI environment. +Headers are added to the WSGI environment by converting them to their CGI/WSGI +equivalents (e.g., ``Host=example.com`` will insert the ``HTTP_HOST`` header +variable as the value ``example.com``). Multiple ``--header`` options can be +supplied. The special header value ``content-type`` sets the ``CONTENT_TYPE`` +in the WSGI environment. -By default, ``prequest`` sends a ``GET`` request. You can change this by -using the ``-m`` (aka ``--method``) option. ``GET``, ``HEAD``, ``POST`` and -``DELETE`` are currently supported. When you use ``POST``, the standard -input of the ``prequest`` process is used as the ``POST`` body:: +By default, ``prequest`` sends a ``GET`` request. You can change this by using +the ``-m`` (aka ``--method``) option. ``GET``, ``HEAD``, ``POST``, and +``DELETE`` are currently supported. When you use ``POST``, the standard input +of the ``prequest`` process is used as the ``POST`` body:: $ $VENV/bin/prequest -mPOST development.ini / < somefile @@ -545,28 +544,28 @@ Using Custom Arguments to Python when Running ``p*`` Scripts .. versionadded:: 1.5 -Each of Pyramid's console scripts (``pserve``, ``pviews``, etc) can be run +Each of Pyramid's console scripts (``pserve``, ``pviews``, etc.) can be run directly using ``python -m``, allowing custom arguments to be sent to the -python interpreter at runtime. For example:: +Python interpreter at runtime. For example:: python -3 -m pyramid.scripts.pserve development.ini -Showing All Installed Distributions and their Versions +Showing All Installed Distributions and Their Versions ------------------------------------------------------ .. versionadded:: 1.5 -You can use the ``pdistreport`` command to show the Pyramid version in use, the -Python version in use, and all installed versions of Python distributions in -your Python environment:: +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:: $ $VENV/bin/pdistreport - Pyramid version: 1.5dev - Platform Linux-3.2.0-51-generic-x86_64-with-debian-wheezy-sid - Packages: - authapp 0.0 - /home/chrism/projects/foo/src/authapp - beautifulsoup4 4.1.3 + Pyramid version: 1.5dev + Platform Linux-3.2.0-51-generic-x86_64-with-debian-wheezy-sid + Packages: + authapp 0.0 + /home/chrism/projects/foo/src/authapp + beautifulsoup4 4.1.3 /home/chrism/projects/foo/lib/python2.7/site-packages/beautifulsoup4-4.1.3-py2.7.egg ... more output ... @@ -581,35 +580,33 @@ Writing a Script ---------------- All web applications are, at their hearts, systems which accept a request and -return a response. When a request is accepted by a :app:`Pyramid` -application, the system receives state from the request which is later relied -on by your application code. For example, one :term:`view callable` may assume -it's working against a request that has a ``request.matchdict`` of a -particular composition, while another assumes a different composition of the -matchdict. +return a response. When a request is accepted by a :app:`Pyramid` application, +the system receives state from the request which is later relied on by your +application code. For example, one :term:`view callable` may assume it's +working against a request that has a ``request.matchdict`` of a particular +composition, while another assumes a different composition of the matchdict. In the meantime, it's convenient to be able to write a Python script that can -work "in a Pyramid environment", for instance to update database tables used -by your :app:`Pyramid` application. But a "real" Pyramid environment doesn't -have a completely static state independent of a request; your application -(and Pyramid itself) is almost always reliant on being able to obtain -information from a request. When you run a Python script that simply imports -code from your application and tries to run it, there just is no request -data, because there isn't any real web request. Therefore some parts of your -application and some Pyramid APIs will not work. +work "in a Pyramid environment", for instance to update database tables used by +your :app:`Pyramid` application. But a "real" Pyramid environment doesn't have +a completely static state independent of a request; your application (and +Pyramid itself) is almost always reliant on being able to obtain information +from a request. When you run a Python script that simply imports code from +your application and tries to run it, there just is no request data, because +there isn't any real web request. Therefore some parts of your application and +some Pyramid APIs will not work. For this reason, :app:`Pyramid` makes it possible to run a script in an environment much like the environment produced when a particular :term:`request` reaches your :app:`Pyramid` application. This is achieved by -using the :func:`pyramid.paster.bootstrap` command in the body of your -script. +using the :func:`pyramid.paster.bootstrap` command in the body of your script. .. versionadded:: 1.1 :func:`pyramid.paster.bootstrap` In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a single argument, which accepts the :term:`PasteDeploy` ``.ini`` file -representing Pyramid your application configuration as a single argument: +representing your Pyramid application's configuration as a single argument: .. code-block:: python @@ -645,14 +642,13 @@ registry closer - A parameterless callable that can be used to pop an internal - :app:`Pyramid` threadlocal stack (used by - :func:`pyramid.threadlocal.get_current_registry` and - :func:`pyramid.threadlocal.get_current_request`) when your scripting job - is finished. + A parameterless callable that can be used to pop an internal :app:`Pyramid` + threadlocal stack (used by :func:`pyramid.threadlocal.get_current_registry` + and :func:`pyramid.threadlocal.get_current_request`) when your scripting + job is finished. -Let's assume that the ``/path/to/my/development.ini`` file used in the -example above looks like so: +Let's assume that the ``/path/to/my/development.ini`` file used in the example +above looks like so: .. code-block:: ini @@ -669,15 +665,15 @@ example above looks like so: use = egg:MyProject The configuration loaded by the above bootstrap example will use the -configuration implied by the ``[pipeline:main]`` section of your -configuration file by default. Specifying ``/path/to/my/development.ini`` is -logically equivalent to specifying ``/path/to/my/development.ini#main``. In -this case, we'll be using a configuration that includes an ``app`` object -which is wrapped in the Paste "translogger" :term:`middleware` (which logs -requests to the console). +configuration implied by the ``[pipeline:main]`` section of your configuration +file by default. Specifying ``/path/to/my/development.ini`` is logically +equivalent to specifying ``/path/to/my/development.ini#main``. In this case, +we'll be using a configuration that includes an ``app`` object which is wrapped +in the Paste "translogger" :term:`middleware` (which logs requests to the +console). -You can also specify a particular *section* of the PasteDeploy ``.ini`` file -to load instead of ``main``: +You can also specify a particular *section* of the PasteDeploy ``.ini`` file to +load instead of ``main``: .. code-block:: python @@ -694,9 +690,9 @@ Changing the Request ~~~~~~~~~~~~~~~~~~~~ By default, Pyramid will generate a request object in the ``env`` dictionary -for the URL ``http://localhost:80/``. This means that any URLs generated -by Pyramid during the execution of your script will be anchored here. This -is generally not what you want. +for the URL ``http://localhost:80/``. This means that any URLs generated by +Pyramid during the execution of your script will be anchored here. This is +generally not what you want. So how do we make Pyramid generate the correct URLs? @@ -708,10 +704,10 @@ Assuming that you have a route configured in your application like so: You need to inform the Pyramid environment that the WSGI application is handling requests from a certain base. For example, we want to simulate -mounting our application at `https://example.com/prefix`, to ensure that -the generated URLs are correct for our deployment. This can be done by -either mutating the resulting request object, or more simply by constructing -the desired request and passing it into :func:`~pyramid.paster.bootstrap`: +mounting our application at `https://example.com/prefix`, to ensure that the +generated URLs are correct for our deployment. This can be done by either +mutating the resulting request object, or more simply by constructing the +desired request and passing it into :func:`~pyramid.paster.bootstrap`: .. code-block:: python @@ -770,43 +766,43 @@ Making Your Script into a Console Script ---------------------------------------- A "console script" is :term:`setuptools` terminology for a script that gets -installed into the ``bin`` directory of a Python :term:`virtualenv` (or -"base" Python environment) when a :term:`distribution` which houses that -script is installed. Because it's installed into the ``bin`` directory of a -virtualenv when the distribution is installed, it's a convenient way to -package and distribute functionality that you can call from the command-line. -It's often more convenient to create a console script than it is to create a -``.py`` script and instruct people to call it with the "right" Python -interpreter. A console script generates a file that lives in ``bin``, and when it's -invoked it will always use the "right" Python environment, which means it -will always be invoked in an environment where all the libraries it needs -(such as Pyramid) are available. +installed into the ``bin`` directory of a Python :term:`virtualenv` (or "base" +Python environment) when a :term:`distribution` which houses that script is +installed. Because it's installed into the ``bin`` directory of a virtualenv +when the distribution is installed, it's a convenient way to package and +distribute functionality that you can call from the command-line. It's often +more convenient to create a console script than it is to create a ``.py`` +script and instruct people to call it with the "right" Python interpreter. A +console script generates a file that lives in ``bin``, and when it's invoked it +will always use the "right" Python environment, which means it will always be +invoked in an environment where all the libraries it needs (such as Pyramid) +are available. In general, you can make your script into a console script by doing the following: - Use an existing distribution (such as one you've already created via - ``pcreate``) or create a new distribution that possesses at least one - package or module. It should, within any module within the distribution, - house a callable (usually a function) that takes no arguments and which - runs any of the code you wish to run. + ``pcreate``) or create a new distribution that possesses at least one package + or module. It should, within any module within the distribution, house a + callable (usually a function) that takes no arguments and which runs any of + the code you wish to run. - Add a ``[console_scripts]`` section to the ``entry_points`` argument of the - distribution which creates a mapping between a script name and a dotted - name representing the callable you added to your distribution. + 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. + 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 pretend you have a distribution with a package in it named -``myproject``. Within this package, we'll pretend you've added a -``scripts.py`` module which contains the following code: +that prints the deployment settings of a Pyramid application. To do so, we'll +pretend you have a distribution with a package in it named ``myproject``. +Within this package, we'll pretend you've added a ``scripts.py`` module which +contains the following code: .. code-block:: python :linenos: @@ -865,7 +861,7 @@ defined in that config file. After adding this script to the package, you'll need to tell your distribution's ``setup.py`` about its existence. Within your distribution's -top-level directory your ``setup.py`` file will look something like this: +top-level directory, your ``setup.py`` file will look something like this: .. code-block:: python :linenos: @@ -908,9 +904,9 @@ top-level directory your ``setup.py`` file will look something like this: """, ) -We're going to change the setup.py file to add an ``[console_scripts]`` -section with in 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:: [console_scripts] show_settings = myproject.scripts:settings_show @@ -918,9 +914,9 @@ specify a ``scriptname = dotted.path.to:yourfunction`` line. For example:: The ``show_settings`` name will be the name of the script that is installed into ``bin``. The colon (``:``) between ``myproject.scripts`` and ``settings_show`` above indicates that ``myproject.scripts`` is a Python -module, and ``settings_show`` is the function in that module which contains -the code you'd like to run as the result of someone invoking the -``show_settings`` script from their command line. +module, and ``settings_show`` is the function in that module which contains the +code you'd like to run as the result of someone invoking the ``show_settings`` +script from their command line. The result will be something like: @@ -967,29 +963,28 @@ 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/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``:: $ $VENV/bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar - debug_routematch False - debug_templates True - reload_templates True - mako.directories [] - debug_notfound False - default_locale_name en - reload_resources False - debug_authorization False - reload_assets False - prevent_http_cache False - -Pyramid's ``pserve``, ``pcreate``, ``pshell``, ``prequest``, ``ptweens`` and + debug_routematch False + debug_templates True + reload_templates True + mako.directories [] + debug_notfound False + default_locale_name en + reload_resources False + debug_authorization False + reload_assets False + prevent_http_cache False + +Pyramid's ``pserve``, ``pcreate``, ``pshell``, ``prequest``, ``ptweens``, and other ``p*`` scripts are implemented as console scripts. When you invoke one of those, you are using a console script. -- cgit v1.2.3 From f016cdfdb7a6b8ac20784bdab8f9fcff13a634e1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 19 Oct 2015 04:00:30 -0700 Subject: resolve whitespace diff between master and 1.6-branch --- docs/narr/viewconfig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index a7d0848ca..0bd52b6e2 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -311,7 +311,7 @@ configured view. view declaration with this argument ensures that the view will only be called when the ``method`` attribute of the request (i.e., the ``REQUEST_METHOD`` of the WSGI environment) matches a supplied value. - + .. versionchanged:: 1.4 The use of ``"GET"`` also implies that the view will respond to ``"HEAD"``. @@ -972,7 +972,7 @@ responses when they occur unexpectedly due to an application registry misconfiguration. To debug these errors, use the ``PYRAMID_DEBUG_NOTFOUND`` environment variable or the ``pyramid.debug_notfound`` configuration file setting. Details of why a view was not found will be printed to ``stderr``, -and the browser representation of the error will include the same information. +and the browser representation of the error will include the same information. See :ref:`environment_chapter` for more information about how, and where to set these values. -- cgit v1.2.3 From 208e7b5e363b07476797d9f754962982c686e907 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Oct 2015 23:44:17 -0500 Subject: add pshell --list and default_shell ini options --- docs/narr/commandline.rst | 59 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 9db92b669..c3791adf2 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -269,32 +269,39 @@ request is configured to generate urls from the host .. _ipython_or_bpython: -IPython or bpython +Alternative Shells ~~~~~~~~~~~~~~~~~~ - If you have `IPython `_ and/or `bpython `_ in the interpreter you use to invoke the -``pshell`` command, ``pshell`` will autodiscover and use the first one found, -in this order: IPython, bpython, standard Python interpreter. However you could -specifically invoke your choice with the ``-p choice`` or ``--python-shell -choice`` option. +``pshell`` command, ``pshell`` will autodiscover and use the first one found. +However you could specifically invoke your choice with the ``-p choice`` or +``--python-shell choice`` option. .. code-block:: text - $ $VENV/bin/pshell -p ipython | bpython | python development.ini#MyProject + $ $VENV/bin/pshell -p ipython development.ini#MyProject + +You may use the ``--list-shells`` option to see the available shells. + +.. code-block:: text + + $ $VENV/bin/pshell --list-shells + Available shells: + bpython [not available] + ipython + python -Alternative Shells -~~~~~~~~~~~~~~~~~~ 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: .. code-block:: python setup( - entry_points = """\ - [pyramid.pshell] - myshell=my_app:ptpython_shell_factory - """ + entry_points={ + 'pyramid.pshell': [ + 'myshell=my_app:ptpython_shell_factory', + ], + }, ) And then your shell factory should return a function that accepts two @@ -303,7 +310,12 @@ arguments, ``env`` and ``help``, which would look like this: .. code-block:: python def ptpython_shell_factory(): - from ptpython.repl import embed + try: + from ptpython.repl import embed + except ImportError: + # ptpython is not installed + return None + def PTPShell(banner, **kwargs): print(banner) return embed(**kwargs) @@ -313,6 +325,25 @@ arguments, ``env`` and ``help``, which would look like this: return shell +If the factory returns ``None`` then it is assumed that the shell is not +supported. + +.. versionchanged:: 1.6 + User-defined shells may be registered using entry points. Prior to this + the only supported shells were ``ipython``, ``bpython`` and ``python``. + +Setting a Default Shell +~~~~~~~~~~~~~~~~~~~~~~~ + +You may use the ``default_shell`` option in your ``[pshell]`` ini section to +specify a list of preferred shells. + +.. code-block:: ini + :linenos: + + [pshell] + default_shell = ptpython ipython bpython + .. versionadded:: 1.6 .. index:: -- cgit v1.2.3 From d2b365b3cf9185fd979dbb2c2692499ede706513 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 20 Oct 2015 00:01:16 -0700 Subject: minor grammar, rewrap 79 columns --- docs/narr/i18n.rst | 632 +++++++++++++++++++++++++---------------------------- 1 file changed, 297 insertions(+), 335 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/i18n.rst b/docs/narr/i18n.rst index 7b6903d01..bb0bbe511 100644 --- a/docs/narr/i18n.rst +++ b/docs/narr/i18n.rst @@ -9,16 +9,16 @@ Internationalization and Localization ===================================== -:term:`Internationalization` (i18n) is the act of creating software -with a user interface that can potentially be displayed in more than -one language or cultural context. :term:`Localization` (l10n) is the -process of displaying the user interface of an internationalized -application in a *particular* language or cultural context. +:term:`Internationalization` (i18n) is the act of creating software with a user +interface that can potentially be displayed in more than one language or +cultural context. :term:`Localization` (l10n) is the process of displaying the +user interface of an internationalized application in a *particular* language +or cultural context. -:app:`Pyramid` offers internationalization and localization -subsystems that can be used to translate the text of buttons, error -messages and other software- and template-defined values into the -native language of a user of your application. +:app:`Pyramid` offers internationalization and localization subsystems that can +be used to translate the text of buttons, error messages, and other software- +and template-defined values into the native language of a user of your +application. .. index:: single: translation string @@ -29,15 +29,15 @@ native language of a user of your application. Creating a Translation String ----------------------------- -While you write your software, you can insert specialized markup into -your Python code that makes it possible for the system to translate -text values into the languages used by your application's users. This -markup creates a :term:`translation string`. A translation string is -an object that behaves mostly like a normal Unicode object, except that -it also carries around extra information related to its job as part of -the :app:`Pyramid` translation machinery. +While you write your software, you can insert specialized markup into your +Python code that makes it possible for the system to translate text values into +the languages used by your application's users. This markup creates a +:term:`translation string`. A translation string is an object that behaves +mostly like a normal Unicode object, except that it also carries around extra +information related to its job as part of the :app:`Pyramid` translation +machinery. -Using The ``TranslationString`` Class +Using the ``TranslationString`` Class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The most primitive way to create a translation string is to use the @@ -53,17 +53,17 @@ This creates a Unicode-like object that is a TranslationString. .. note:: - For people more familiar with :term:`Zope` i18n, a TranslationString - is a lot like a ``zope.i18nmessageid.Message`` object. It is not a - subclass, however. For people more familiar with :term:`Pylons` or - :term:`Django` i18n, using a TranslationString is a lot like using - "lazy" versions of related gettext APIs. + For people more familiar with :term:`Zope` i18n, a TranslationString is a + lot like a ``zope.i18nmessageid.Message`` object. It is not a subclass, + however. For people more familiar with :term:`Pylons` or :term:`Django` + i18n, using a TranslationString is a lot like using "lazy" versions of + related gettext APIs. -The first argument to :class:`~pyramid.i18n.TranslationString` is -the ``msgid``; it is required. It represents the key into the -translation mappings provided by a particular localization. The -``msgid`` argument must be a Unicode object or an ASCII string. The -msgid may optionally contain *replacement markers*. For instance: +The first argument to :class:`~pyramid.i18n.TranslationString` is the +``msgid``; it is required. It represents the key into the translation mappings +provided by a particular localization. The ``msgid`` argument must be a Unicode +object or an ASCII string. The msgid may optionally contain *replacement +markers*. For instance: .. code-block:: python :linenos: @@ -71,10 +71,9 @@ msgid may optionally contain *replacement markers*. For instance: from pyramid.i18n import TranslationString ts = TranslationString('Add ${number}') -Within the string above, ``${number}`` is a replacement marker. It -will be replaced by whatever is in the *mapping* for a translation -string. The mapping may be supplied at the same time as the -replacement marker itself: +Within the string above, ``${number}`` is a replacement marker. It will be +replaced by whatever is in the *mapping* for a translation string. The mapping +may be supplied at the same time as the replacement marker itself: .. code-block:: python :linenos: @@ -82,14 +81,14 @@ replacement marker itself: from pyramid.i18n import TranslationString ts = TranslationString('Add ${number}', mapping={'number':1}) -Any number of replacement markers can be present in the msgid value, -any number of times. Only markers which can be replaced by the values -in the *mapping* will be replaced at translation time. The others -will not be interpolated and will be output literally. +Any number of replacement markers can be present in the msgid value, any number +of times. Only markers which can be replaced by the values in the *mapping* +will be replaced at translation time. The others will not be interpolated and +will be output literally. A translation string should also usually carry a *domain*. The domain -represents a translation category to disambiguate it from other -translations of the same msgid, in case they conflict. +represents a translation category to disambiguate it from other translations of +the same msgid, in case they conflict. .. code-block:: python :linenos: @@ -98,13 +97,12 @@ translations of the same msgid, in case they conflict. ts = TranslationString('Add ${number}', mapping={'number':1}, domain='form') -The above translation string named a domain of ``form``. A -:term:`translator` function will often use the domain to locate the -right translator file on the filesystem which contains translations -for a given domain. In this case, if it were trying to translate -our msgid to German, it might try to find a translation from a -:term:`gettext` file within a :term:`translation directory` like this -one: +The above translation string named a domain of ``form``. A :term:`translator` +function will often use the domain to locate the right translator file on the +filesystem which contains translations for a given domain. In this case, if it +were trying to translate our msgid to German, it might try to find a +translation from a :term:`gettext` file within a :term:`translation directory` +like this one: .. code-block:: text @@ -113,14 +111,13 @@ one: In other words, it would want to take translations from the ``form.mo`` translation file in the German language. -Finally, the TranslationString constructor accepts a ``default`` -argument. If a ``default`` argument is supplied, it replaces usages -of the ``msgid`` as the *default value* for the translation string. -When ``default`` is ``None``, the ``msgid`` value passed to a -TranslationString is used as an implicit message identifier. Message -identifiers are matched with translations in translation files, so it -is often useful to create translation strings with "opaque" message -identifiers unrelated to their default text: +Finally, the TranslationString constructor accepts a ``default`` argument. If +a ``default`` argument is supplied, it replaces usages of the ``msgid`` as the +*default value* for the translation string. When ``default`` is ``None``, the +``msgid`` value passed to a TranslationString is used as an implicit message +identifier. Message identifiers are matched with translations in translation +files, so it is often useful to create translation strings with "opaque" +message identifiers unrelated to their default text: .. code-block:: python :linenos: @@ -129,8 +126,7 @@ identifiers unrelated to their default text: ts = TranslationString('add-number', default='Add ${number}', domain='form', mapping={'number':1}) -When default text is used, Default text objects may contain -replacement values. +When default text is used, Default text objects may contain replacement values. .. index:: single: translation string factory @@ -139,10 +135,10 @@ Using the ``TranslationStringFactory`` Class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another way to generate a translation string is to use the -:attr:`~pyramid.i18n.TranslationStringFactory` object. This object -is a *translation string factory*. Basically a translation string -factory presets the ``domain`` value of any :term:`translation string` -generated by using it. For example: +:attr:`~pyramid.i18n.TranslationStringFactory` object. This object is a +*translation string factory*. Basically a translation string factory presets +the ``domain`` value of any :term:`translation string` generated by using it. +For example: .. code-block:: python :linenos: @@ -151,20 +147,18 @@ generated by using it. For example: _ = TranslationStringFactory('pyramid') ts = _('add-number', default='Add ${number}', mapping={'number':1}) -.. note:: We assigned the translation string factory to the name - ``_``. This is a convention which will be supported by translation - file generation tools. +.. note:: We assigned the translation string factory to the name ``_``. This + is a convention which will be supported by translation file generation + tools. After assigning ``_`` to the result of a -:func:`~pyramid.i18n.TranslationStringFactory`, the subsequent result -of calling ``_`` will be a :class:`~pyramid.i18n.TranslationString` -instance. Even though a ``domain`` value was not passed to ``_`` (as -would have been necessary if the -:class:`~pyramid.i18n.TranslationString` constructor were used instead -of a translation string factory), the ``domain`` attribute of the -resulting translation string will be ``pyramid``. As a result, the -previous code example is completely equivalent (except for spelling) -to: +:func:`~pyramid.i18n.TranslationStringFactory`, the subsequent result of +calling ``_`` will be a :class:`~pyramid.i18n.TranslationString` instance. +Even though a ``domain`` value was not passed to ``_`` (as would have been +necessary if the :class:`~pyramid.i18n.TranslationString` constructor were used +instead of a translation string factory), the ``domain`` attribute of the +resulting translation string will be ``pyramid``. As a result, the previous +code example is completely equivalent (except for spelling) to: .. code-block:: python :linenos: @@ -173,12 +167,11 @@ to: ts = _('add-number', default='Add ${number}', mapping={'number':1}, domain='pyramid') -You can set up your own translation string factory much like the one -provided above by using the -:class:`~pyramid.i18n.TranslationStringFactory` class. For example, -if you'd like to create a translation string factory which presets the -``domain`` value of generated translation strings to ``form``, you'd -do something like this: +You can set up your own translation string factory much like the one provided +above by using the :class:`~pyramid.i18n.TranslationStringFactory` class. For +example, if you'd like to create a translation string factory which presets the +``domain`` value of generated translation strings to ``form``, you'd do +something like this: .. code-block:: python :linenos: @@ -187,71 +180,68 @@ do something like this: _ = TranslationStringFactory('form') ts = _('add-number', default='Add ${number}', mapping={'number':1}) -Creating a unique domain for your application via a translation string -factory is best practice. Using your own unique translation domain -allows another person to reuse your application without needing to -merge your translation files with his own. Instead, he can just -include your package's :term:`translation directory` via the -:meth:`pyramid.config.Configurator.add_translation_dirs` -method. +Creating a unique domain for your application via a translation string factory +is best practice. Using your own unique translation domain allows another +person to reuse your application without needing to merge your translation +files with their own. Instead they can just include your package's +:term:`translation directory` via the +:meth:`pyramid.config.Configurator.add_translation_dirs` method. .. note:: For people familiar with Zope internationalization, a TranslationStringFactory is a lot like a - ``zope.i18nmessageid.MessageFactory`` object. It is not a - subclass, however. + ``zope.i18nmessageid.MessageFactory`` object. It is not a subclass, + however. .. index:: single: gettext single: translation directories -Working With ``gettext`` Translation Files +Working with ``gettext`` Translation Files ------------------------------------------ -The basis of :app:`Pyramid` translation services is -GNU :term:`gettext`. Once your application source code files and templates -are marked up with translation markers, you can work on translations -by creating various kinds of gettext files. +The basis of :app:`Pyramid` translation services is GNU :term:`gettext`. Once +your application source code files and templates are marked up with translation +markers, you can work on translations by creating various kinds of gettext +files. .. note:: - The steps a developer must take to work with :term:`gettext` - :term:`message catalog` files within a :app:`Pyramid` - application are very similar to the steps a :term:`Pylons` - developer must take to do the same. See the :ref:`Pylons - Internationalization and Localization documentation + The steps a developer must take to work with :term:`gettext` :term:`message + catalog` files within a :app:`Pyramid` application are very similar to the + steps a :term:`Pylons` developer must take to do the same. See the + :ref:`Pylons Internationalization and Localization documentation ` for more information. -GNU gettext uses three types of files in the translation framework, -``.pot`` files, ``.po`` files and ``.mo`` files. +GNU gettext uses three types of files in the translation framework, ``.pot`` +files, ``.po`` files, and ``.mo`` files. ``.pot`` (Portable Object Template) files - A ``.pot`` file is created by a program which searches through your - project's source code and which picks out every :term:`message - identifier` passed to one of the ``_()`` functions - (eg. :term:`translation string` constructions). The list of all - message identifiers is placed into a ``.pot`` file, which serves as - a template for creating ``.po`` files. + A ``.pot`` file is created by a program which searches through your project's + source code and which picks out every :term:`message identifier` passed to + one of the ``_()`` functions (e.g., :term:`translation string` + constructions). The list of all message identifiers is placed into a ``.pot`` + file, which serves as a template for creating ``.po`` files. ``.po`` (Portable Object) files - The list of messages in a ``.pot`` file are translated by a human to - a particular language; the result is saved as a ``.po`` file. + The list of messages in a ``.pot`` file are translated by a human to a + particular language; the result is saved as a ``.po`` file. ``.mo`` (Machine Object) files - A ``.po`` file is turned into a machine-readable binary file, which - is the ``.mo`` file. Compiling the translations to machine code - makes the localized program start faster. + A ``.po`` file is turned into a machine-readable binary file, which is the + ``.mo`` file. Compiling the translations to machine code makes the + localized program start faster. The tools for working with :term:`gettext` translation files related to a -:app:`Pyramid` application are :term:`Lingua` and :term:`Gettext`. Lingua -can scrape i18n references out of Python and Chameleon files and create -the ``.pot`` file. Gettext includes ``msgmerge`` tool to update a ``.po`` file -from an updated ``.pot`` file and ``msgfmt`` to compile ``.po`` files to -``.mo`` files. +:app:`Pyramid` application are :term:`Lingua` and :term:`Gettext`. Lingua can +scrape i18n references out of Python and Chameleon files and create the +``.pot`` file. Gettext includes ``msgmerge`` tool to update a ``.po`` file from +an updated ``.pot`` file and ``msgfmt`` to compile ``.po`` files to ``.mo`` +files. .. index:: single: Gettext @@ -262,19 +252,18 @@ from an updated ``.pot`` file and ``msgfmt`` to compile ``.po`` files to Installing Lingua and Gettext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In order for the commands related to working with ``gettext`` translation -files to work properly, you will need to have :term:`Lingua` and -:term:`Gettext` installed into the same environment in which :app:`Pyramid` is -installed. +In order for the commands related to working with ``gettext`` translation files +to work properly, you will need to have :term:`Lingua` and :term:`Gettext` +installed into the same environment in which :app:`Pyramid` is installed. Installation on UNIX ++++++++++++++++++++ Gettext is often already installed on UNIX systems. You can check if it is installed by testing if the ``msgfmt`` command is available. If it is not -available you can install it through the packaging system from your OS; -the package name is almost always ``gettext``. For example on a Debian or -Ubuntu system run this command: +available you can install it through the packaging system from your OS; the +package name is almost always ``gettext``. For example on a Debian or Ubuntu +system run this command: .. code-block:: text @@ -282,8 +271,7 @@ Ubuntu system run this command: Installing Lingua is done with the Python packaging tools. If the :term:`virtualenv` into which you've installed your :app:`Pyramid` application -lives in ``/my/virtualenv``, you can install Lingua -like so: +lives in ``/my/virtualenv``, you can install Lingua like so: .. code-block:: text @@ -295,11 +283,10 @@ Installation on Windows There are several ways to install Gettext on Windows: it is included in the `Cygwin `_ collection, or you can use the `installer -from the GnuWin32 `_ -or compile it yourself. Make sure the installation path is added to your +from the GnuWin32 `_, or +compile it yourself. Make sure the installation path is added to your ``$PATH``. - Installing Lingua is done with the Python packaging tools. If the :term:`virtualenv` into which you've installed your :app:`Pyramid` application lives in ``C:\my\virtualenv``, you can install Lingua like so: @@ -317,7 +304,7 @@ lives in ``C:\my\virtualenv``, you can install Lingua like so: Extracting Messages from Code and Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once Lingua is installed you may extract a message catalog template from the +Once Lingua is installed, you may extract a message catalog template from the code and :term:`Chameleon` templates which reside in your :app:`Pyramid` application. You run a ``pot-create`` command to extract the messages: @@ -327,8 +314,7 @@ application. You run a ``pot-create`` command to extract the messages: $ mkdir -p myapplication/locale $ $VENV/bin/pot-create -o myapplication/locale/myapplication.pot src -The message catalog ``.pot`` template will end up in: - +The message catalog ``.pot`` template will end up in ``myapplication/locale/myapplication.pot``. @@ -339,12 +325,11 @@ Initializing a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Once you've extracted messages into a ``.pot`` file (see -:ref:`extracting_messages`), to begin localizing the messages present -in the ``.pot`` file, you need to generate at least one ``.po`` file. -A ``.po`` file represents translations of a particular set of messages -to a particular locale. Initialize a ``.po`` file for a specific -locale from a pre-generated ``.pot`` template by using the ``msginit`` -command from Gettext: +:ref:`extracting_messages`), to begin localizing the messages present in the +``.pot`` file, you need to generate at least one ``.po`` file. A ``.po`` file +represents translations of a particular set of messages to a particular locale. +Initialize a ``.po`` file for a specific locale from a pre-generated ``.pot`` +template by using the ``msginit`` command from Gettext: .. code-block:: text @@ -353,18 +338,15 @@ command from Gettext: $ mkdir -p es/LC_MESSAGES $ msginit -l es -o es/LC_MESSAGES/myapplication.po -This will create a new message catalog ``.po`` file in: - +This will create a new message catalog ``.po`` file in ``myapplication/locale/es/LC_MESSAGES/myapplication.po``. -Once the file is there, it can be worked on by a human translator. -One tool which may help with this is `Poedit -`_. +Once the file is there, it can be worked on by a human translator. One tool +which may help with this is `Poedit `_. -Note that :app:`Pyramid` itself ignores the existence of all -``.po`` files. For a running application to have translations -available, a ``.mo`` file must exist. See -:ref:`compiling_message_catalog`. +Note that :app:`Pyramid` itself ignores the existence of all ``.po`` files. +For a running application to have translations available, a ``.mo`` file must +exist. See :ref:`compiling_message_catalog`. .. index:: pair: updating; message catalog @@ -372,13 +354,13 @@ available, a ``.mo`` file must exist. See Updating a Catalog File ~~~~~~~~~~~~~~~~~~~~~~~ -If more translation strings are added to your application, or -translation strings change, you will need to update existing ``.po`` -files based on changes to the ``.pot`` file, so that the new and -changed messages can also be translated or re-translated. +If more translation strings are added to your application, or translation +strings change, you will need to update existing ``.po`` files based on changes +to the ``.pot`` file, so that the new and changed messages can also be +translated or re-translated. -First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. -Then use the ``msgmerge`` command from Gettext. +First, regenerate the ``.pot`` file as per :ref:`extracting_messages`. Then use +the ``msgmerge`` command from Gettext. .. code-block:: text @@ -394,20 +376,21 @@ Then use the ``msgmerge`` command from Gettext. Compiling a Message Catalog File ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Finally, to prepare an application for performing actual runtime -translations, compile ``.po`` files to ``.mo`` files use the ``msgfmt`` -command from Gettext: +Finally, to prepare an application for performing actual runtime translations, +compile ``.po`` files to ``.mo`` files using the ``msgfmt`` command from +Gettext: .. code-block:: text $ cd /place/where/myapplication/setup.py/lives - $ msgfmt -o myapplication/locale/es/LC_MESSAGES/myapplication.mo myapplication/locale/es/LC_MESSAGES/myapplication.po + $ msgfmt -o myapplication/locale/es/LC_MESSAGES/myapplication.mo \ + myapplication/locale/es/LC_MESSAGES/myapplication.po This will create a ``.mo`` file for each ``.po`` file in your application. As long as the :term:`translation directory` in which the ``.mo`` file ends up in is configured into your application (see -:ref:`adding_a_translation_directory`), these translations will be available -to :app:`Pyramid`. +:ref:`adding_a_translation_directory`), these translations will be available to +:app:`Pyramid`. .. index:: single: localizer @@ -418,10 +401,10 @@ Using a Localizer ----------------- A :term:`localizer` is an object that allows you to perform translation or -pluralization "by hand" in an application. You may use the -:attr:`pyramid.request.Request.localizer` attribute to obtain a -:term:`localizer`. The localizer object will be configured to produce -translations implied by the active :term:`locale negotiator` or a default +pluralization "by hand" in an application. You may use the +:attr:`pyramid.request.Request.localizer` attribute to obtain a +:term:`localizer`. The localizer object will be configured to produce +translations implied by the active :term:`locale negotiator`, or a default localizer object if no explicit locale negotiator is registered. .. code-block:: python @@ -432,7 +415,7 @@ localizer object if no explicit locale negotiator is registered. .. note:: - If you need to create a localizer for a locale use the + If you need to create a localizer for a locale, use the :func:`pyramid.i18n.make_localizer` function. .. index:: @@ -444,9 +427,9 @@ Performing a Translation ~~~~~~~~~~~~~~~~~~~~~~~~ A :term:`localizer` has a ``translate`` method which accepts either a -:term:`translation string` or a Unicode string and which returns a -Unicode object representing the translation. So, generating a -translation in a view component of an application might look like so: +:term:`translation string` or a Unicode string and which returns a Unicode +object representing the translation. Generating a translation in a view +component of an application might look like so: .. code-block:: python :linenos: @@ -469,9 +452,8 @@ locale of the localizer. .. note:: - If you're using :term:`Chameleon` templates, you don't need - to pre-translate translation strings this way. See - :ref:`chameleon_translation_strings`. + If you're using :term:`Chameleon` templates, you don't need to pre-translate + translation strings this way. See :ref:`chameleon_translation_strings`. .. index:: single: pluralizing (i18n) @@ -481,8 +463,7 @@ locale of the localizer. Performing a Pluralization ~~~~~~~~~~~~~~~~~~~~~~~~~~ -A :term:`localizer` has a ``pluralize`` method with the following -signature: +A :term:`localizer` has a ``pluralize`` method with the following signature: .. code-block:: python :linenos: @@ -491,7 +472,7 @@ signature: ... The simplest case is the ``singular`` and ``plural`` arguments being passed as -unicode literals. This returns the appropriate literal according to the locale +Unicode literals. This returns the appropriate literal according to the locale pluralization rules for the number ``n``, and interpolates ``mapping``. .. code-block:: python @@ -502,15 +483,14 @@ pluralization rules for the number ``n``, and interpolates ``mapping``. translated = localizer.pluralize('Item', 'Items', 1, 'mydomain') # ... use translated ... -However, for support of other languages, the ``singular`` argument should -be a Unicode value representing a :term:`message identifier`. In this -case the ``plural`` value is ignored. -``domain`` should be a :term:`translation domain`, and -``mapping`` should be a dictionary that is used for *replacement -value* interpolation of the translated string. +However, for support of other languages, the ``singular`` argument should be a +Unicode value representing a :term:`message identifier`. In this case the +``plural`` value is ignored. ``domain`` should be a :term:`translation domain`, +and ``mapping`` should be a dictionary that is used for *replacement value* +interpolation of the translated string. The value of ``n`` will be used to find the appropriate plural form for the -current language and ``pluralize`` will return a Unicode translation for the +current language, and ``pluralize`` will return a Unicode translation for the message id ``singular``. The message file must have defined ``singular`` as a translation with plural forms. @@ -561,18 +541,17 @@ You can obtain the locale name related to a request by using the def aview(request): locale_name = request.locale_name -The locale name of a request is dynamically computed; it will be the locale -name negotiated by the currently active :term:`locale negotiator` or -the :term:`default locale name` if the locale negotiator returns ``None``. -You can change the default locale name by changing the -``pyramid.default_locale_name`` setting; see :ref:`default_locale_name_setting`. +The locale name of a request is dynamically computed; it will be the locale +name negotiated by the currently active :term:`locale negotiator`, or the +:term:`default locale name` if the locale negotiator returns ``None``. You can +change the default locale name by changing the ``pyramid.default_locale_name`` +setting. See :ref:`default_locale_name_setting`. -Once :func:`~pyramid.request.Request.locale_name` is first run, the locale -name is stored on the request object. Subsequent calls to -:func:`~pyramid.request.Request.locale_name` will return the stored locale -name without invoking the :term:`locale negotiator`. To avoid this -caching, you can use the :func:`pyramid.i18n.negotiate_locale_name` -function: +Once :func:`~pyramid.request.Request.locale_name` is first run, the locale name +is stored on the request object. Subsequent calls to +:func:`~pyramid.request.Request.locale_name` will return the stored locale name +without invoking the :term:`locale negotiator`. To avoid this caching, you can +use the :func:`pyramid.i18n.negotiate_locale_name` function: .. code-block:: python :linenos: @@ -592,8 +571,8 @@ You can also obtain the locale name related to a request using the localizer = request.localizer locale_name = localizer.locale_name -Obtaining the locale name as an attribute of a localizer is equivalent -to obtaining a locale name by asking for the +Obtaining the locale name as an attribute of a localizer is equivalent to +obtaining a locale name by asking for the :func:`~pyramid.request.Request.locale_name` attribute. .. index:: @@ -603,20 +582,18 @@ to obtaining a locale name by asking for the 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 +: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 locale name for a request to pass to the -:class:`babel.core.Locale` constructor; see -:ref:`obtaining_the_locale_name`. For example: +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 +locale name for a request to pass to the :class:`babel.core.Locale` +constructor. See :ref:`obtaining_the_locale_name`. For example: .. code-block:: python :linenos: @@ -635,15 +612,14 @@ obtain the locale name for a request to pass to the Chameleon Template Support for Translation Strings -------------------------------------------------- -When a :term:`translation string` is used as the subject of textual -rendering by a :term:`Chameleon` template renderer, it will -automatically be translated to the requesting user's language if a -suitable translation exists. This is true of both the ZPT and text -variants of the Chameleon template renderers. +When a :term:`translation string` is used as the subject of textual rendering +by a :term:`Chameleon` template renderer, it will automatically be translated +to the requesting user's language if a suitable translation exists. This is +true of both the ZPT and text variants of the Chameleon template renderers. -For example, in a Chameleon ZPT template, the translation string -represented by "some_translation_string" in each example below will go -through translation before being rendered: +For example, in a Chameleon ZPT template, the translation string represented by +"some_translation_string" in each example below will go through translation +before being rendered: .. code-block:: xml :linenos: @@ -668,32 +644,31 @@ through translation before being rendered: .. XXX the last example above appears to not yet work as of Chameleon .. 1.2.3 -The features represented by attributes of the ``i18n`` namespace of -Chameleon will also consult the :app:`Pyramid` translations. -See http://chameleon.readthedocs.org/en/latest/reference.html#id50. +The features represented by attributes of the ``i18n`` namespace of Chameleon +will also consult the :app:`Pyramid` translations. See +http://chameleon.readthedocs.org/en/latest/reference.html#id50. .. note:: - Unlike when Chameleon is used outside of :app:`Pyramid`, when it - is used *within* :app:`Pyramid`, it does not support use of the - ``zope.i18n`` translation framework. Applications which use - :app:`Pyramid` should use the features documented in this - chapter rather than ``zope.i18n``. + Unlike when Chameleon is used outside of :app:`Pyramid`, when it is used + *within* :app:`Pyramid`, it does not support use of the ``zope.i18n`` + translation framework. Applications which use :app:`Pyramid` should use the + features documented in this chapter rather than ``zope.i18n``. -Third party :app:`Pyramid` template renderers might not provide -this support out of the box and may need special code to do an -equivalent. For those, you can always use the more manual translation -facility described in :ref:`performing_a_translation`. +Third party :app:`Pyramid` template renderers might not provide this support +out of the box and may need special code to do an equivalent. For those, you +can always use the more manual translation facility described in +:ref:`performing_a_translation`. .. index:: single: Mako i18n -Mako Pyramid I18N Support +Mako Pyramid i18n Support ------------------------- -There exists a recipe within the :term:`Pyramid Cookbook` named "Mako -Internationalization" which explains how to add idiomatic I18N support to -:term:`Mako` templates. +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. .. index:: single: localization deployment settings @@ -705,10 +680,9 @@ Localization-Related Deployment Settings ---------------------------------------- A :app:`Pyramid` application will have a ``pyramid.default_locale_name`` -setting. This value represents the :term:`default locale name` used -when the :term:`locale negotiator` returns ``None``. Pass it to the -:mod:`~pyramid.config.Configurator` constructor at startup -time: +setting. This value represents the :term:`default locale name` used when the +:term:`locale negotiator` returns ``None``. Pass it to the +:mod:`~pyramid.config.Configurator` constructor at startup time: .. code-block:: python :linenos: @@ -729,11 +703,11 @@ application's ``.ini`` file: pyramid.debug_notfound = false pyramid.default_locale_name = de -If this value is not supplied via the Configurator constructor or via a -config file, it will default to ``en``. +If this value is not supplied via the Configurator constructor or via a config +file, it will default to ``en``. -If this setting is supplied within the :app:`Pyramid` application -``.ini`` file, it will be available as a settings key: +If this setting is supplied within the :app:`Pyramid` application ``.ini`` +file, it will be available as a settings key: .. code-block:: python :linenos: @@ -748,34 +722,32 @@ If this setting is supplied within the :app:`Pyramid` application "Detecting" Available Languages ------------------------------- -Other systems provide an API that returns the set of "available -languages" as indicated by the union of all languages in all -translation directories on disk at the time of the call to the API. +Other systems provide an API that returns the set of "available languages" as +indicated by the union of all languages in all translation directories on disk +at the time of the call to the API. -It is by design that :app:`Pyramid` doesn't supply such an API. -Instead, the application itself is responsible for knowing the "available -languages". The rationale is this: any particular application -deployment must always know which languages it should be translatable -to anyway, regardless of which translation files are on disk. +It is by design that :app:`Pyramid` doesn't supply such an API. Instead the +application itself is responsible for knowing the "available languages". The +rationale is this: any particular application deployment must always know which +languages it should be translatable to anyway, regardless of which translation +files are on disk. -Here's why: it's not a given that because translations exist in a -particular language within the registered set of translation -directories that this particular deployment wants to allow translation -to that language. For example, some translations may exist but they -may be incomplete or incorrect. Or there may be translations to a -language but not for all translation domains. +Here's why: it's not a given that because translations exist in a particular +language within the registered set of translation directories that this +particular deployment wants to allow translation to that language. For +example, some translations may exist but they may be incomplete or incorrect. +Or there may be translations to a language but not for all translation domains. Any nontrivial application deployment will always need to be able to -selectively choose to allow only some languages even if that set of -languages is smaller than all those detected within registered -translation directories. The easiest way to allow for this is to make -the application entirely responsible for knowing which languages are -allowed to be translated to instead of relying on the framework to -divine this information from translation directory file info. +selectively choose to allow only some languages even if that set of languages +is smaller than all those detected within registered translation directories. +The easiest way to allow for this is to make the application entirely +responsible for knowing which languages are allowed to be translated to instead +of relying on the framework to divine this information from translation +directory file info. -You can set up a system to allow a deployer to select available -languages based on convention by using the :mod:`pyramid.settings` -mechanism: +You can set up a system to allow a deployer to select available languages based +on convention by using the :mod:`pyramid.settings` mechanism. Allow a deployer to modify your application's ``.ini`` file: @@ -798,8 +770,8 @@ Then as a part of the code of a custom :term:`locale negotiator`: languages = aslist(request.registry.settings['available_languages']) # ... -This is only a suggestion. You can create your own "available -languages" configuration scheme as necessary. +This is only a suggestion. You can create your own "available languages" +configuration scheme as necessary. .. index:: pair: translation; activating @@ -814,8 +786,8 @@ languages" configuration scheme as necessary. Activating Translation ---------------------- -By default, a :app:`Pyramid` application performs no translation. -To turn translation on, you must: +By default, a :app:`Pyramid` application performs no translation. To turn +translation on you must: - add at least one :term:`translation directory` to your application. @@ -829,24 +801,23 @@ To turn translation on, you must: Adding a Translation Directory ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -:term:`gettext` is the underlying machinery behind the -:app:`Pyramid` translation machinery. A translation directory is a -directory organized to be useful to :term:`gettext`. A translation -directory usually includes a listing of language directories, each of -which itself includes an ``LC_MESSAGES`` directory. Each -``LC_MESSAGES`` directory should contain one or more ``.mo`` files. -Each ``.mo`` file represents a :term:`message catalog`, which is used -to provide translations to your application. +:term:`gettext` is the underlying machinery behind the :app:`Pyramid` +translation machinery. A translation directory is a directory organized to be +useful to :term:`gettext`. A translation directory usually includes a listing +of language directories, each of which itself includes an ``LC_MESSAGES`` +directory. Each ``LC_MESSAGES`` directory should contain one or more ``.mo`` +files. Each ``.mo`` file represents a :term:`message catalog`, which is used to +provide translations to your application. Adding a :term:`translation directory` registers all of its constituent -:term:`message catalog` files within your :app:`Pyramid` application to -be available to use for translation services. This includes all of the -``.mo`` files found within all ``LC_MESSAGES`` directories within each -locale directory in the translation directory. +:term:`message catalog` files within your :app:`Pyramid` application to be +available to use for translation services. This includes all of the ``.mo`` +files found within all ``LC_MESSAGES`` directories within each locale directory +in the translation directory. You can add a translation directory imperatively by using the -:meth:`pyramid.config.Configurator.add_translation_dirs` during -application startup. For example: +:meth:`pyramid.config.Configurator.add_translation_dirs` during application +startup. For example: .. code-block:: python :linenos: @@ -856,10 +827,10 @@ application startup. For example: 'another.application:locale/') A message catalog in a translation directory added via -:meth:`~pyramid.config.Configurator.add_translation_dirs` -will be merged into translations from a message catalog added earlier -if both translation directories contain translations for the same -locale and :term:`translation domain`. +:meth:`~pyramid.config.Configurator.add_translation_dirs` will be merged into +translations from a message catalog added earlier if both translation +directories contain translations for the same locale and :term:`translation +domain`. .. index:: pair: setting; locale @@ -867,32 +838,29 @@ locale and :term:`translation domain`. Setting the Locale ~~~~~~~~~~~~~~~~~~ -When the *default locale negotiator* (see -:ref:`default_locale_negotiator`) is in use, you can inform -:app:`Pyramid` of the current locale name by doing any of these -things before any translations need to be performed: +When the *default locale negotiator* (see :ref:`default_locale_negotiator`) is +in use, you can inform :app:`Pyramid` of the current locale name by doing any +of these things before any translations need to be performed: -- Set the ``_LOCALE_`` attribute of the request to a valid locale name - (usually directly within view code). E.g. ``request._LOCALE_ = - 'de'``. +- Set the ``_LOCALE_`` attribute of the request to a valid locale name (usually + directly within view code), e.g., ``request._LOCALE_ = 'de'``. -- Ensure that a valid locale name value is in the ``request.params`` - dictionary under the key named ``_LOCALE_``. This is usually the - result of passing a ``_LOCALE_`` value in the query string or in the - body of a form post associated with a request. For example, - visiting ``http://my.application?_LOCALE_=de``. +- Ensure that a valid locale name value is in the ``request.params`` dictionary + under the key named ``_LOCALE_``. This is usually the result of passing a + ``_LOCALE_`` value in the query string or in the body of a form post + associated with a request. For example, visiting + ``http://my.application?_LOCALE_=de``. - Ensure that a valid locale name value is in the ``request.cookies`` - dictionary under the key named ``_LOCALE_``. This is usually the - result of setting a ``_LOCALE_`` cookie in a prior response, - e.g. ``response.set_cookie('_LOCALE_', 'de')``. + dictionary under the key named ``_LOCALE_``. This is usually the result of + setting a ``_LOCALE_`` cookie in a prior response, e.g., + ``response.set_cookie('_LOCALE_', 'de')``. .. note:: If this locale negotiation scheme is inappropriate for a particular - application, you can configure a custom :term:`locale negotiator` - function into that application as required. See - :ref:`custom_locale_negotiator`. + application, you can configure a custom :term:`locale negotiator` function + into that application as required. See :ref:`custom_locale_negotiator`. .. index:: single: locale negotiator @@ -902,57 +870,55 @@ things before any translations need to be performed: Locale Negotiators ------------------ -A :term:`locale negotiator` informs the operation of a -:term:`localizer` by telling it what :term:`locale name` is related to -a particular request. A locale negotiator is a bit of code which -accepts a request and which returns a :term:`locale name`. It is -consulted when :meth:`pyramid.i18n.Localizer.translate` or -:meth:`pyramid.i18n.Localizer.pluralize` is invoked. It is also -consulted when :func:`~pyramid.request.Request.locale_name` is accessed or -when :func:`~pyramid.i18n.negotiate_locale_name` is invoked. +A :term:`locale negotiator` informs the operation of a :term:`localizer` by +telling it what :term:`locale name` is related to a particular request. A +locale negotiator is a bit of code which accepts a request and which returns a +:term:`locale name`. It is consulted when +:meth:`pyramid.i18n.Localizer.translate` or +:meth:`pyramid.i18n.Localizer.pluralize` is invoked. It is also consulted when +:func:`~pyramid.request.Request.locale_name` is accessed or when +:func:`~pyramid.i18n.negotiate_locale_name` is invoked. .. _default_locale_negotiator: The Default Locale Negotiator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Most applications can make use of the default locale negotiator, which -requires no additional coding or configuration. +Most applications can make use of the default locale negotiator, which requires +no additional coding or configuration. The default locale negotiator implementation named -:class:`~pyramid.i18n.default_locale_negotiator` uses the following -set of steps to determine the locale name. +:class:`~pyramid.i18n.default_locale_negotiator` uses the following set of +steps to determine the locale name. -- First, the negotiator looks for the ``_LOCALE_`` attribute of the - request object (possibly set directly by view code or by a listener - for an :term:`event`). +- First the negotiator looks for the ``_LOCALE_`` attribute of the request + object (possibly set directly by view code or by a listener for an + :term:`event`). - Then it looks for the ``request.params['_LOCALE_']`` value. - Then it looks for the ``request.cookies['_LOCALE_']`` value. -- If no locale can be found via the request, it falls back to using - the :term:`default locale name` (see - :ref:`localization_deployment_settings`). +- If no locale can be found via the request, it falls back to using the + :term:`default locale name` (see :ref:`localization_deployment_settings`). -- Finally, if the default locale name is not explicitly set, it uses - the locale name ``en``. +- Finally if the default locale name is not explicitly set, it uses the locale + name ``en``. .. _custom_locale_negotiator: Using a Custom Locale Negotiator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Locale negotiation is sometimes policy-laden and complex. If the -(simple) default locale negotiation scheme described in -:ref:`activating_translation` is inappropriate for your application, -you may create and a special :term:`locale negotiator`. Subsequently -you may override the default locale negotiator by adding your newly -created locale negotiator to your application's configuration. +Locale negotiation is sometimes policy-laden and complex. If the (simple) +default locale negotiation scheme described in :ref:`activating_translation` is +inappropriate for your application, you may create a special :term:`locale +negotiator`. Subsequently you may override the default locale negotiator by +adding your newly created locale negotiator to your application's +configuration. -A locale negotiator is simply a callable which -accepts a request and returns a single :term:`locale name` or ``None`` -if no locale can be determined. +A locale negotiator is simply a callable which accepts a request and returns a +single :term:`locale name` or ``None`` if no locale can be determined. Here's an implementation of a simple locale negotiator: @@ -963,16 +929,14 @@ Here's an implementation of a simple locale negotiator: locale_name = request.params.get('my_locale') return locale_name -If a locale negotiator returns ``None``, it signifies to -:app:`Pyramid` that the default application locale name should be -used. +If a locale negotiator returns ``None``, it signifies to :app:`Pyramid` that +the default application locale name should be used. You may add your newly created locale negotiator to your application's configuration by passing an object which can act as the negotiator (or a :term:`dotted Python name` referring to the object) as the -``locale_negotiator`` argument of the -:class:`~pyramid.config.Configurator` instance during application -startup. For example: +``locale_negotiator`` argument of the :class:`~pyramid.config.Configurator` +instance during application startup. For example: .. code-block:: python :linenos: @@ -980,9 +944,8 @@ startup. For example: from pyramid.config import Configurator config = Configurator(locale_negotiator=my_locale_negotiator) -Alternately, use the -:meth:`pyramid.config.Configurator.set_locale_negotiator` -method. +Alternatively, use the +:meth:`pyramid.config.Configurator.set_locale_negotiator` method. For example: @@ -992,4 +955,3 @@ For example: from pyramid.config import Configurator config = Configurator() config.set_locale_negotiator(my_locale_negotiator) - -- cgit v1.2.3 From df04cbcc7e4e3f9d73eb1bb213f786554d000740 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 20 Oct 2015 02:05:02 -0700 Subject: minor grammar, rewrap 79 columns --- docs/narr/vhosting.rst | 117 +++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 62 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/vhosting.rst b/docs/narr/vhosting.rst index 53f6888b3..0edf03353 100644 --- a/docs/narr/vhosting.rst +++ b/docs/narr/vhosting.rst @@ -6,13 +6,13 @@ Virtual Hosting =============== -"Virtual hosting" is, loosely, the act of serving a :app:`Pyramid` -application or a portion of a :app:`Pyramid` application under a -URL space that it does not "naturally" inhabit. +"Virtual hosting" is, loosely, the act of serving a :app:`Pyramid` application +or a portion of a :app:`Pyramid` application under a URL space that it does not +"naturally" inhabit. -:app:`Pyramid` provides facilities for serving an application under -a URL "prefix", as well as serving a *portion* of a :term:`traversal` -based application under a root URL. +:app:`Pyramid` provides facilities for serving an application under a URL +"prefix", as well as serving a *portion* of a :term:`traversal` based +application under a root URL. .. index:: single: hosting an app under a prefix @@ -20,27 +20,26 @@ based application under a root URL. Hosting an Application Under a URL Prefix ----------------------------------------- -:app:`Pyramid` supports a common form of virtual hosting whereby you -can host a :app:`Pyramid` application as a "subset" of some other site -(e.g. under ``http://example.com/mypyramidapplication/`` as opposed to -under ``http://example.com/``). +:app:`Pyramid` supports a common form of virtual hosting whereby you can host a +:app:`Pyramid` application as a "subset" of some other site (e.g., under +``http://example.com/mypyramidapplication/`` as opposed to under +``http://example.com/``). If you use a "pure Python" environment, this functionality can be provided by -Paste's `urlmap `_ "composite" -WSGI application. Alternately, you can use :term:`mod_wsgi` to serve your -application, which handles this virtual hosting translation for you "under -the hood". - -If you use the ``urlmap`` composite application "in front" of a -:app:`Pyramid` application or if you use :term:`mod_wsgi` to serve -up a :app:`Pyramid` application, nothing special needs to be done -within the application for URLs to be generated that contain a -prefix. :mod:`paste.urlmap` and :term:`mod_wsgi` manipulate the -:term:`WSGI` environment in such a way that the ``PATH_INFO`` and -``SCRIPT_NAME`` variables are correct for some given prefix. - -Here's an example of a PasteDeploy configuration snippet that includes -a ``urlmap`` composite. +Paste's `urlmap `_ "composite" WSGI +application. Alternatively, you can use :term:`mod_wsgi` to serve your +application, which handles this virtual hosting translation for you "under the +hood". + +If you use the ``urlmap`` composite application "in front" of a :app:`Pyramid` +application or if you use :term:`mod_wsgi` to serve up a :app:`Pyramid` +application, nothing special needs to be done within the application for URLs +to be generated that contain a prefix. :mod:`paste.urlmap` and :term:`mod_wsgi` +manipulate the :term:`WSGI` environment in such a way that the ``PATH_INFO`` +and ``SCRIPT_NAME`` variables are correct for some given prefix. + +Here's an example of a PasteDeploy configuration snippet that includes a +``urlmap`` composite. .. code-block:: ini :linenos: @@ -52,23 +51,21 @@ a ``urlmap`` composite. use = egg:Paste#urlmap /pyramidapp = mypyramidapp -This "roots" the :app:`Pyramid` application at the prefix -``/pyramidapp`` and serves up the composite as the "main" application -in the file. +This "roots" the :app:`Pyramid` application at the prefix ``/pyramidapp`` and +serves up the composite as the "main" application in the file. -.. note:: If you're using an Apache server to proxy to a Paste - ``urlmap`` composite, you may have to use the `ProxyPreserveHost +.. note:: If you're using an Apache server to proxy to a Paste ``urlmap`` + composite, you may have to use the `ProxyPreserveHost `_ directive to pass the original ``HTTP_HOST`` header along to the - application, so URLs get generated properly. As of this writing - the ``urlmap`` composite does not seem to respect the - ``HTTP_X_FORWARDED_HOST`` parameter, which will contain the - original host header even if ``HTTP_HOST`` is incorrect. + application, so URLs get generated properly. As of this writing the + ``urlmap`` composite does not seem to respect the ``HTTP_X_FORWARDED_HOST`` + parameter, which will contain the original host header even if ``HTTP_HOST`` + is incorrect. -If you use :term:`mod_wsgi`, you do not need to use a ``composite`` -application in your ``.ini`` file. The ``WSGIScriptAlias`` -configuration setting in a :term:`mod_wsgi` configuration does the -work for you: +If you use :term:`mod_wsgi`, you do not need to use a ``composite`` application +in your ``.ini`` file. The ``WSGIScriptAlias`` configuration setting in a +:term:`mod_wsgi` configuration does the work for you: .. code-block:: apache :linenos: @@ -87,8 +84,7 @@ Virtual Root Support -------------------- :app:`Pyramid` also supports "virtual roots", which can be used in -:term:`traversal` -based (but not :term:`URL dispatch` -based) -applications. +:term:`traversal`-based (but not :term:`URL dispatch`-based) applications. Virtual root support is useful when you'd like to host some resource in a :app:`Pyramid` resource tree as an application under a URL pathname that does @@ -98,15 +94,14 @@ object at the traversal path ``/cms`` as an application reachable via To specify a virtual root, cause an environment variable to be inserted into the WSGI environ named ``HTTP_X_VHM_ROOT`` with a value that is the absolute -pathname to the resource object in the resource tree that should behave as -the "root" resource. As a result, the traversal machinery will respect this -value during traversal (prepending it to the PATH_INFO before traversal -starts), and the :meth:`pyramid.request.Request.resource_url` API will -generate the "correct" virtually-rooted URLs. +pathname to the resource object in the resource tree that should behave as the +"root" resource. As a result, the traversal machinery will respect this value +during traversal (prepending it to the PATH_INFO before traversal starts), and +the :meth:`pyramid.request.Request.resource_url` API will generate the +"correct" virtually-rooted URLs. -An example of an Apache ``mod_proxy`` configuration that will host the -``/cms`` subobject as ``http://www.example.com/`` using this facility -is below: +An example of an Apache ``mod_proxy`` configuration that will host the ``/cms`` +subobject as ``http://www.example.com/`` using this facility is below: .. code-block:: apache :linenos: @@ -121,13 +116,12 @@ is below: RequestHeader add X-Vhm-Root /cms -.. note:: Use of the ``RequestHeader`` directive requires that the - Apache `mod_headers - `_ module be - available in the Apache environment you're using. +.. note:: Use of the ``RequestHeader`` directive requires that the Apache + `mod_headers `_ + module be available in the Apache environment you're using. -For a :app:`Pyramid` application running under :term:`mod_wsgi`, -the same can be achieved using ``SetEnv``: +For a :app:`Pyramid` application running under :term:`mod_wsgi`, the same can +be achieved using ``SetEnv``: .. code-block:: apache :linenos: @@ -136,17 +130,16 @@ the same can be achieved using ``SetEnv``: SetEnv HTTP_X_VHM_ROOT /cms -Setting a virtual root has no effect when using an application based -on :term:`URL dispatch`. +Setting a virtual root has no effect when using an application based on +:term:`URL dispatch`. Further Documentation and Examples ---------------------------------- The API documentation in :ref:`traversal_module` documents a -:func:`pyramid.traversal.virtual_root` API. When called, it -returns the virtual root object (or the physical root object if no -virtual root has been specified). - -:ref:`modwsgi_tutorial` has detailed information about using -:term:`mod_wsgi` to serve :app:`Pyramid` applications. +:func:`pyramid.traversal.virtual_root` API. When called, it returns the +virtual root object (or the physical root object if no virtual root has been +specified). +:ref:`modwsgi_tutorial` has detailed information about using :term:`mod_wsgi` +to serve :app:`Pyramid` applications. -- cgit v1.2.3 From b7350ee78ad4101ea4112741ab26ce583b620ea7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 21 Oct 2015 01:32:48 -0500 Subject: remove ipython and bpython from core --- docs/narr/commandline.rst | 43 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 30 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index c3791adf2..d466bed44 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -107,9 +107,7 @@ found* message. .. index:: single: interactive shell - single: IPython single: pshell - single: bpython .. _interactive_shell: @@ -263,18 +261,13 @@ request is configured to generate urls from the host >>> request.route_url('home') 'https://www.example.com/' -.. index:: - single: IPython - single: bpython - -.. _ipython_or_bpython: - Alternative Shells ~~~~~~~~~~~~~~~~~~ -If you have `IPython `_ and/or `bpython -`_ in the interpreter you use to invoke the -``pshell`` command, ``pshell`` will autodiscover and use the first one found. -However you could specifically invoke your choice with the ``-p choice`` or + +The ``pshell`` command can be easily extended with alternate REPLs if the +default python REPL is not satisfactory. Assuming you have a binding +installed such as ``pyramid_ipython`` it will normally be auto-selected and +used. You may also specifically invoke your choice with the ``-p choice`` or ``--python-shell choice`` option. .. code-block:: text @@ -287,7 +280,7 @@ You may use the ``--list-shells`` option to see the available shells. $ $VENV/bin/pshell --list-shells Available shells: - bpython [not available] + bpython ipython python @@ -309,29 +302,19 @@ arguments, ``env`` and ``help``, which would look like this: .. code-block:: python - def ptpython_shell_factory(): - try: - from ptpython.repl import embed - except ImportError: - # ptpython is not installed - return None + from ptpython.repl import embed - def PTPShell(banner, **kwargs): - print(banner) - return embed(**kwargs) - - def shell(env, help): - PTPShell(banner=help, locals=env) - - return shell - -If the factory returns ``None`` then it is assumed that the shell is not -supported. + def ptpython_shell_runner(env, help): + print(help) + return embed(locals=env) .. versionchanged:: 1.6 User-defined shells may be registered using entry points. Prior to this the only supported shells were ``ipython``, ``bpython`` and ``python``. + ``ipython`` and ``bpython`` have been moved into their respective + packages ``pyramid_ipython`` and ``pyramid_bpython``. + Setting a Default Shell ~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 02011f1f5d3fae6eac0209b5faccc06079dd1b41 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 20 Oct 2015 00:32:14 -0500 Subject: first cut at removing default cache busters --- docs/narr/assets.rst | 80 +++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 45 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 020794062..397e0258d 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -372,30 +372,38 @@ assets by passing the optional argument, ``cachebust`` to .. code-block:: python :linenos: + import time + from pyramid.static import QueryStringConstantCacheBuster + # config is an instance of pyramid.config.Configurator - config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=True) + config.add_static_view( + name='static', path='mypackage:folder/static', + cachebust=QueryStringConstantCacheBuster(str(int(time.time()))), + ) Setting the ``cachebust`` argument instructs :app:`Pyramid` to use a cache -busting scheme which adds the md5 checksum for a static asset as a path segment -in the asset's URL: +busting scheme which adds the curent time for a static asset to the query +string in the asset's URL: .. code-block:: python :linenos: js_url = request.static_url('mypackage:folder/static/js/myapp.js') - # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js' + # Returns: 'http://www.example.com/static/js/myapp.js?x=1445318121' -When the asset changes, so will its md5 checksum, 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. +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. -.. note:: +.. warning:: - md5 checksums are cached in RAM, so if you change a static resource without - restarting your application, you may still generate URLs with a stale md5 - checksum. + Cache busting is an inherently complex topic as it integrates the asset + pipeline and the web application. It is expected and desired that + application authors will write their own cache buster implementations + conforming to the properties of their own asset pipelines. See + :ref:`custom_cache_busters` for information on writing your own. Disabling the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -406,40 +414,21 @@ configured cache busters without changing calls to ``PYRAMID_PREVENT_CACHEBUST`` environment variable or the ``pyramid.prevent_cachebust`` configuration value to a true value. +.. _custom_cache_busters: + Customizing the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Revisiting from the previous section: - -.. code-block:: python - :linenos: +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`. - # config is an instance of pyramid.config.Configurator - config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=True) - -Setting ``cachebust`` to ``True`` instructs :app:`Pyramid` to use a default -cache busting implementation that should work for many situations. The -``cachebust`` may be set to any object that implements the interface -:class:`~pyramid.interfaces.ICacheBuster`. The above configuration is exactly -equivalent to: - -.. code-block:: python - :linenos: - - from pyramid.static import PathSegmentMd5CacheBuster - - # config is an instance of pyramid.config.Configurator - config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=PathSegmentMd5CacheBuster()) - -:app:`Pyramid` includes a handful of ready to use cache buster implementations: -:class:`~pyramid.static.PathSegmentMd5CacheBuster`, which inserts an md5 -checksum token in the path portion of the asset's URL, -:class:`~pyramid.static.QueryStringMd5CacheBuster`, which adds an md5 checksum -token to the query string of the asset's URL, and +:app:`Pyramid` ships with a very simplistic :class:`~pyramid.static.QueryStringConstantCacheBuster`, which adds an -arbitrary token you provide to the query string of the asset's URL. +arbitrary token you provide to the query string of the asset's URL. This +is almost never what you want in production as it does not allow fine-grained +busting of individual assets. + In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` @@ -456,15 +445,16 @@ the hash of the currently checked out code: import os import subprocess - from pyramid.static import PathSegmentCacheBuster + from pyramid.static import QueryStringCacheBuster - class GitCacheBuster(PathSegmentCacheBuster): + class GitCacheBuster(QueryStringCacheBuster): """ Assuming your code is installed as a Git checkout, as opposed to an egg 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): + def __init__(self, param='x'): + super(GitCacheBuster, self).__init__(param=param) here = os.path.dirname(os.path.abspath(__file__)) self.sha1 = subprocess.check_output( ['git', 'rev-parse', 'HEAD'], -- cgit v1.2.3 From 4ade6de3bef51483a442fc404c350b3ce9c10988 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 22 Oct 2015 09:32:42 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/testing.rst | 195 ++++++++++++++++++++++++-------------------------- 1 file changed, 95 insertions(+), 100 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/testing.rst b/docs/narr/testing.rst index ecda57489..c05ee41ad 100644 --- a/docs/narr/testing.rst +++ b/docs/narr/testing.rst @@ -13,34 +13,32 @@ application. In this context, a "unit" is often a function or a method of a class instance. The unit is also referred to as a "unit under test". The goal of a single unit test is to test **only** some permutation of the -"unit under test". If you write a unit test that aims to verify the result -of a particular codepath through a Python function, you need only be -concerned about testing the code that *lives in the function body itself*. -If the function accepts a parameter that represents a complex application -"domain object" (such as a resource, a database connection, or an SMTP -server), the argument provided to this function during a unit test *need not -be* and likely *should not be* a "real" implementation object. For example, -although a particular function implementation may accept an argument that -represents an SMTP server object, and the function may call a method of this -object when the system is operating normally that would result in an email -being sent, a unit test of this codepath of the function does *not* need to -test that an email is actually sent. It just needs to make sure that the -function calls the method of the object provided as an argument that *would* -send an email if the argument happened to be the "real" implementation of an -SMTP server object. +"unit under test". If you write a unit test that aims to verify the result of +a particular codepath through a Python function, you need only be concerned +about testing the code that *lives in the function body itself*. If the +function accepts a parameter that represents a complex application "domain +object" (such as a resource, a database connection, or an SMTP server), the +argument provided to this function during a unit test *need not be* and likely +*should not be* a "real" implementation object. For example, although a +particular function implementation may accept an argument that represents an +SMTP server object, and the function may call a method of this object when the +system is operating normally that would result in an email being sent, a unit +test of this codepath of the function does *not* need to test that an email is +actually sent. It just needs to make sure that the function calls the method +of the object provided as an argument that *would* send an email if the +argument happened to be the "real" implementation of an SMTP server object. An *integration test*, on the other hand, is a different form of testing in which the interaction between two or more "units" is explicitly tested. -Integration tests verify that the components of your application work -together. You *might* make sure that an email was actually sent in an -integration test. +Integration tests verify that the components of your application work together. +You *might* make sure that an email was actually sent in an integration test. A *functional test* is a form of integration test in which the application is -run "literally". You would *have to* make sure that an email was actually -sent in a functional test, because it tests your code end to end. +run "literally". You would *have to* make sure that an email was actually sent +in a functional test, because it tests your code end to end. -It is often considered best practice to write each type of tests for any -given codebase. Unit testing often provides the opportunity to obtain better +It is often considered best practice to write each type of tests for any given +codebase. Unit testing often provides the opportunity to obtain better "coverage": it's usually possible to supply a unit under test with arguments and/or an environment which causes *all* of its potential codepaths to be executed. This is usually not as easy to do with a set of integration or @@ -55,9 +53,9 @@ integration tests. A good :mod:`unittest` tutorial is available within `Dive Into Python `_ by Mark Pilgrim. -:app:`Pyramid` provides a number of facilities that make unit, integration, -and functional tests easier to write. The facilities become particularly -useful when your code calls into :app:`Pyramid` -related framework functions. +:app:`Pyramid` provides a number of facilities that make unit, integration, and +functional tests easier to write. The facilities become particularly useful +when your code calls into :app:`Pyramid`-related framework functions. .. index:: single: test setup @@ -67,42 +65,41 @@ useful when your code calls into :app:`Pyramid` -related framework functions. .. _test_setup_and_teardown: Test Set Up and Tear Down --------------------------- +------------------------- :app:`Pyramid` uses a "global" (actually :term:`thread local`) data structure to hold two items: the current :term:`request` and the current :term:`application registry`. These data structures are available via the :func:`pyramid.threadlocal.get_current_request` and -:func:`pyramid.threadlocal.get_current_registry` functions, respectively. -See :ref:`threadlocals_chapter` for information about these functions and the -data structures they return. +:func:`pyramid.threadlocal.get_current_registry` functions, respectively. See +:ref:`threadlocals_chapter` for information about these functions and the data +structures they return. If your code uses these ``get_current_*`` functions or calls :app:`Pyramid` code which uses ``get_current_*`` functions, you will need to call :func:`pyramid.testing.setUp` in your test setup and you will need to call :func:`pyramid.testing.tearDown` in your test teardown. -:func:`~pyramid.testing.setUp` pushes a registry onto the :term:`thread -local` stack, which makes the ``get_current_*`` functions work. It returns a +:func:`~pyramid.testing.setUp` pushes a registry onto the :term:`thread local` +stack, which makes the ``get_current_*`` functions work. It returns a :term:`Configurator` object which can be used to perform extra configuration required by the code under test. :func:`~pyramid.testing.tearDown` pops the thread local stack. -Normally when a Configurator is used directly with the ``main`` block of -a Pyramid application, it defers performing any "real work" until its -``.commit`` method is called (often implicitly by the -:meth:`pyramid.config.Configurator.make_wsgi_app` method). The -Configurator returned by :func:`~pyramid.testing.setUp` is an -*autocommitting* Configurator, however, which performs all actions -implied by methods called on it immediately. This is more convenient -for unit-testing purposes than needing to call -:meth:`pyramid.config.Configurator.commit` in each test after adding -extra configuration statements. +Normally when a Configurator is used directly with the ``main`` block of a +Pyramid application, it defers performing any "real work" until its ``.commit`` +method is called (often implicitly by the +:meth:`pyramid.config.Configurator.make_wsgi_app` method). The Configurator +returned by :func:`~pyramid.testing.setUp` is an *autocommitting* Configurator, +however, which performs all actions implied by methods called on it +immediately. This is more convenient for unit testing purposes than needing to +call :meth:`pyramid.config.Configurator.commit` in each test after adding extra +configuration statements. The use of the :func:`~pyramid.testing.setUp` and -:func:`~pyramid.testing.tearDown` functions allows you to supply each unit -test method in a test case with an environment that has an isolated registry -and an isolated request for the duration of a single test. Here's an example -of using this feature: +:func:`~pyramid.testing.tearDown` functions allows you to supply each unit test +method in a test case with an environment that has an isolated registry and an +isolated request for the duration of a single test. Here's an example of using +this feature: .. code-block:: python :linenos: @@ -117,22 +114,21 @@ of using this feature: def tearDown(self): testing.tearDown() -The above will make sure that -:func:`~pyramid.threadlocal.get_current_registry` called within a test -case method of ``MyTest`` will return the :term:`application registry` -associated with the ``config`` Configurator instance. Each test case -method attached to ``MyTest`` will use an isolated registry. +The above will make sure that :func:`~pyramid.threadlocal.get_current_registry` +called within a test case method of ``MyTest`` will return the +:term:`application registry` associated with the ``config`` Configurator +instance. Each test case method attached to ``MyTest`` will use an isolated +registry. The :func:`~pyramid.testing.setUp` and :func:`~pyramid.testing.tearDown` -functions accepts various arguments that influence the environment of the -test. See the :ref:`testing_module` API for information about the extra -arguments supported by these functions. +functions accept various arguments that influence the environment of the test. +See the :ref:`testing_module` API for information about the extra arguments +supported by these functions. If you also want to make :func:`~pyramid.threadlocal.get_current_request` return something other than ``None`` during the course of a single test, you -can pass a -:term:`request` object into the :func:`pyramid.testing.setUp` within the -``setUp`` method of your test: +can pass a :term:`request` object into the :func:`pyramid.testing.setUp` within +the ``setUp`` method of your test: .. code-block:: python :linenos: @@ -148,24 +144,23 @@ can pass a def tearDown(self): testing.tearDown() -If you pass a :term:`request` object into :func:`pyramid.testing.setUp` -within your test case's ``setUp``, any test method attached to the -``MyTest`` test case that directly or indirectly calls +If you pass a :term:`request` object into :func:`pyramid.testing.setUp` within +your test case's ``setUp``, any test method attached to the ``MyTest`` test +case that directly or indirectly calls :func:`~pyramid.threadlocal.get_current_request` will receive the request object. Otherwise, during testing, -:func:`~pyramid.threadlocal.get_current_request` will return ``None``. -We use a "dummy" request implementation supplied by -:class:`pyramid.testing.DummyRequest` because it's easier to construct -than a "real" :app:`Pyramid` request object. +:func:`~pyramid.threadlocal.get_current_request` will return ``None``. We use a +"dummy" request implementation supplied by +:class:`pyramid.testing.DummyRequest` because it's easier to construct than a +"real" :app:`Pyramid` request object. Test setup using a context manager ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -An alternative style of setting up a test configuration is to use the -`with` statement and :func:`pyramid.testing.testConfig` to create a -context manager. The context manager will call -:func:`pyramid.testing.setUp` before the code under test and -:func:`pyramid.testing.tearDown` afterwards. +An alternative style of setting up a test configuration is to use the ``with`` +statement and :func:`pyramid.testing.testConfig` to create a context manager. +The context manager will call :func:`pyramid.testing.setUp` before the code +under test and :func:`pyramid.testing.tearDown` afterwards. This style is useful for small self-contained tests. For example: @@ -193,8 +188,8 @@ they're used by frameworks. Sorry. So here's a rule of thumb: if you don't about any of this, but you still want to write test code, just always call :func:`pyramid.testing.setUp` in your test's ``setUp`` method and :func:`pyramid.testing.tearDown` in your tests' ``tearDown`` method. This -won't really hurt anything if the application you're testing does not call -any ``get_current*`` function. +won't really hurt anything if the application you're testing does not call any +``get_current*`` function. .. index:: single: pyramid.testing @@ -225,15 +220,15 @@ function. .. note:: This code implies that you have defined a renderer imperatively in a - relevant :class:`pyramid.config.Configurator` instance, - otherwise it would fail when run normally. + relevant :class:`pyramid.config.Configurator` instance, otherwise it would + fail when run normally. Without doing anything special during a unit test, the call to :meth:`~pyramid.request.Request.has_permission` in this view function will always return a ``True`` value. When a :app:`Pyramid` application starts -normally, it will populate a :term:`application registry` using +normally, it will populate an :term:`application registry` using :term:`configuration declaration` calls made against a :term:`Configurator`. -But if this application registry is not created and populated (e.g. by +But if this application registry is not created and populated (e.g., by initializing the configurator with an authorization policy), like when you invoke application code via a unit test, :app:`Pyramid` API functions will tend to either fail or return default results. So how do you test the branch of the @@ -283,10 +278,10 @@ In the above example, we create a ``MyTest`` test case that inherits from be found when ``setup.py test`` is run. It has two test methods. The first test method, ``test_view_fn_forbidden`` tests the ``view_fn`` when -the authentication policy forbids the current user the ``edit`` permission. -Its third line registers a "dummy" "non-permissive" authorization policy -using the :meth:`~pyramid.config.Configurator.testing_securitypolicy` method, -which is a special helper method for unit testing. +the authentication policy forbids the current user the ``edit`` permission. Its +third line registers a "dummy" "non-permissive" authorization policy using the +:meth:`~pyramid.config.Configurator.testing_securitypolicy` method, which is a +special helper method for unit testing. We then create a :class:`pyramid.testing.DummyRequest` object which simulates a WebOb request object API. A :class:`pyramid.testing.DummyRequest` is a request @@ -300,25 +295,25 @@ access. We check that the view function raises a The second test method, named ``test_view_fn_allowed``, tests the alternate case, where the authentication policy allows access. Notice that we pass -different values to -:meth:`~pyramid.config.Configurator.testing_securitypolicy` to obtain this -result. We assert at the end of this that the view function returns a value. +different values to :meth:`~pyramid.config.Configurator.testing_securitypolicy` +to obtain this result. We assert at the end of this that the view function +returns a value. Note that the test calls the :func:`pyramid.testing.setUp` function in its ``setUp`` method and the :func:`pyramid.testing.tearDown` function in its -``tearDown`` method. We assign the result of :func:`pyramid.testing.setUp` -as ``config`` on the unittest class. This is a :term:`Configurator` object -and all methods of the configurator can be called as necessary within -tests. If you use any of the :class:`~pyramid.config.Configurator` APIs during -testing, be sure to use this pattern in your test case's ``setUp`` and -``tearDown``; these methods make sure you're using a "fresh" -:term:`application registry` per test run. - -See the :ref:`testing_module` chapter for the entire :app:`Pyramid` -specific +``tearDown`` method. We assign the result of :func:`pyramid.testing.setUp` as +``config`` on the unittest class. This is a :term:`Configurator` object and +all methods of the configurator can be called as necessary within tests. If you +use any of the :class:`~pyramid.config.Configurator` APIs during testing, be +sure to use this pattern in your test case's ``setUp`` and ``tearDown``; these +methods make sure you're using a "fresh" :term:`application registry` per test +run. + +See the :ref:`testing_module` chapter for the entire :app:`Pyramid`-specific testing API. This chapter describes APIs for registering a security policy, -registering resources at paths, registering event listeners, registering -views and view permissions, and classes representing "dummy" implementations -of a request and a resource. +registering resources at paths, registering event listeners, registering views +and view permissions, and classes representing "dummy" implementations of a +request and a resource. .. seealso:: @@ -392,7 +387,7 @@ In Pyramid, functional tests are typically written using the :term:`WebTest` 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 to your application's +``tests_require`` dependency on that package to your application's ``setup.py`` file: .. literalinclude:: MyProject/setup.py @@ -400,7 +395,7 @@ Regardless of which testing :term:`package` you use, ensure to add a :emphasize-lines: 26-28,48 :language: python -Assuming your :term:`package` is named ``myproject``, which contains a +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: @@ -408,8 +403,8 @@ that returns a HTML body when the root URL is invoked: :linenos: :language: python -Then the following example functional test (shown below) demonstrates invoking -the :term:`view` shown above: +Then the following example functional test demonstrates invoking the above +:term:`view`: .. literalinclude:: MyProject/myproject/tests.py :linenos: @@ -419,9 +414,9 @@ the :term:`view` shown 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``. -See the :term:`WebTest` documentation for further information about the -methods available to a :class:`webtest.app.TestApp` instance. +See the :term:`WebTest` documentation for further information about the methods +available to a :class:`webtest.app.TestApp` instance. -- cgit v1.2.3 From aac38eab09547d5dfb11ff00128c3aab91e947ac Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 22 Oct 2015 21:58:47 -0500 Subject: fix entry point example --- docs/narr/commandline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index d466bed44..430641a50 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -291,7 +291,7 @@ introduce a new shell by registering an entry point in your setup.py: setup( entry_points={ - 'pyramid.pshell': [ + 'pyramid.pshell_runner': [ 'myshell=my_app:ptpython_shell_factory', ], }, -- cgit v1.2.3 From 2a6d72c661dba7f874f4c6f4bec753ee8fe9db18 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 24 Oct 2015 01:23:01 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/resources.rst | 390 ++++++++++++++++++++++++------------------------ 1 file changed, 191 insertions(+), 199 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/resources.rst b/docs/narr/resources.rst index 6139154ff..92139c0ff 100644 --- a/docs/narr/resources.rst +++ b/docs/narr/resources.rst @@ -3,50 +3,47 @@ Resources ========= -A :term:`resource` is an object that represents a "place" in a tree -related to your application. Every :app:`Pyramid` application has at -least one resource object: the :term:`root` resource. Even if you don't -define a root resource manually, a default one is created for you. The -root resource is the root of a :term:`resource tree`. A resource tree -is a set of nested dictionary-like objects which you can use to -represent your website's structure. +A :term:`resource` is an object that represents a "place" in a tree related to +your application. Every :app:`Pyramid` application has at least one resource +object: the :term:`root` resource. Even if you don't define a root resource +manually, a default one is created for you. The root resource is the root of a +:term:`resource tree`. A resource tree is a set of nested dictionary-like +objects which you can use to represent your website's structure. In an application which uses :term:`traversal` to map URLs to code, the resource tree structure is used heavily to map each URL to a :term:`view -callable`. When :term:`traversal` is used, :app:`Pyramid` will walk -through the resource tree by traversing through its nested dictionary -structure in order to find a :term:`context` resource. Once a context -resource is found, the context resource and data in the request will be -used to find a :term:`view callable`. +callable`. When :term:`traversal` is used, :app:`Pyramid` will walk through +the resource tree by traversing through its nested dictionary structure in +order to find a :term:`context` resource. Once a context resource is found, +the context resource and data in the request will be used to find a :term:`view +callable`. In an application which uses :term:`URL dispatch`, the resource tree is only used indirectly, and is often "invisible" to the developer. In URL dispatch applications, the resource "tree" is often composed of only the root resource -by itself. This root resource sometimes has security declarations attached -to it, but is not required to have any. In general, the resource tree is -much less important in applications that use URL dispatch than applications -that use traversal. +by itself. This root resource sometimes has security declarations attached to +it, but is not required to have any. In general, the resource tree is much +less important in applications that use URL dispatch than applications that use +traversal. In "Zope-like" :app:`Pyramid` applications, resource objects also often store data persistently, and offer methods related to mutating that persistent data. -In these kinds of applications, resources not only represent the site -structure of your website, but they become the :term:`domain model` of the -application. +In these kinds of applications, resources not only represent the site structure +of your website, but they become the :term:`domain model` of the application. Also: - The ``context`` and ``containment`` predicate arguments to :meth:`~pyramid.config.Configurator.add_view` (or a - :func:`~pyramid.view.view_config` decorator) reference a resource class - or resource :term:`interface`. + :func:`~pyramid.view.view_config` decorator) reference a resource class or + resource :term:`interface`. - A :term:`root factory` returns a resource. -- A resource is exposed to :term:`view` code as the :term:`context` of a - view. +- A resource is exposed to :term:`view` code as the :term:`context` of a view. - Various helpful :app:`Pyramid` API methods expect a resource as an argument - (e.g. :meth:`~pyramid.request.Request.resource_url` and others). + (e.g., :meth:`~pyramid.request.Request.resource_url` and others). .. index:: single: resource tree @@ -58,27 +55,26 @@ Also: Defining a Resource Tree ------------------------ -When :term:`traversal` is used (as opposed to a purely :term:`url dispatch` +When :term:`traversal` is used (as opposed to a purely :term:`URL dispatch` based application), :app:`Pyramid` expects to be able to traverse a tree -composed of resources (the :term:`resource tree`). Traversal begins at a -root resource, and descends into the tree recursively, trying each resource's +composed of resources (the :term:`resource tree`). Traversal begins at a root +resource, and descends into the tree recursively, trying each resource's ``__getitem__`` method to resolve a path segment to another resource object. -:app:`Pyramid` imposes the following policy on resource instances in the -tree: +:app:`Pyramid` imposes the following policy on resource instances in the tree: -- A container resource (a resource which contains other resources) must - supply a ``__getitem__`` method which is willing to resolve a unicode name - to a sub-resource. If a sub-resource by a particular name does not exist - in a container resource, ``__getitem__`` method of the container resource - must raise a :exc:`KeyError`. If a sub-resource by that name *does* exist, - the container's ``__getitem__`` should return the sub-resource. +- A container resource (a resource which contains other resources) must supply + a ``__getitem__`` method which is willing to resolve a Unicode name to a + sub-resource. If a sub-resource by a particular name does not exist in a + container resource, the ``__getitem__`` method of the container resource must + raise a :exc:`KeyError`. If a sub-resource by that name *does* exist, the + container's ``__getitem__`` should return the sub-resource. - Leaf resources, which do not contain other resources, must not implement a ``__getitem__``, or if they do, their ``__getitem__`` method must always raise a :exc:`KeyError`. -See :ref:`traversal_chapter` for more information about how traversal -works against resource instances. +See :ref:`traversal_chapter` for more information about how traversal works +against resource instances. Here's a sample resource tree, represented by a variable named ``root``: @@ -90,8 +86,8 @@ Here's a sample resource tree, represented by a variable named ``root``: root = Resource({'a':Resource({'b':Resource({'c':Resource()})})}) -The resource tree we've created above is represented by a dictionary-like -root object which has a single child named ``'a'``. ``'a'`` has a single child +The resource tree we've created above is represented by a dictionary-like root +object which has a single child named ``'a'``. ``'a'`` has a single child named ``'b'``, and ``'b'`` has a single child named ``'c'``, which has no children. It is therefore possible to access the ``'c'`` leaf resource like so: @@ -100,20 +96,20 @@ children. It is therefore possible to access the ``'c'`` leaf resource like so: root['a']['b']['c'] -If you returned the above ``root`` object from a :term:`root factory`, the -path ``/a/b/c`` would find the ``'c'`` object in the resource tree as the -result of :term:`traversal`. +If you returned the above ``root`` object from a :term:`root factory`, the path +``/a/b/c`` would find the ``'c'`` object in the resource tree as the result of +:term:`traversal`. -In this example, each of the resources in the tree is of the same class. -This is not a requirement. Resource elements in the tree can be of any type. -We used a single class to represent all resources in the tree for the sake of +In this example, each of the resources in the tree is of the same class. This +is not a requirement. Resource elements in the tree can be of any type. We +used a single class to represent all resources in the tree for the sake of simplicity, but in a "real" app, the resources in the tree can be arbitrary. -Although the example tree above can service a traversal, the resource -instances in the above example are not aware of :term:`location`, so their -utility in a "real" application is limited. To make best use of built-in -:app:`Pyramid` API facilities, your resources should be "location-aware". -The next section details how to make resources location-aware. +Although the example tree above can service a traversal, the resource instances +in the above example are not aware of :term:`location`, so their utility in a +"real" application is limited. To make best use of built-in :app:`Pyramid` API +facilities, your resources should be "location-aware". The next section details +how to make resources location-aware. .. index:: pair: location-aware; resource @@ -125,16 +121,16 @@ Location-Aware Resources In order for certain :app:`Pyramid` location, security, URL-generation, and traversal APIs to work properly against the resources in a resource tree, all -resources in the tree must be :term:`location` -aware. This means they must +resources in the tree must be :term:`location`-aware. This means they must have two attributes: ``__parent__`` and ``__name__``. -The ``__parent__`` attribute of a location-aware resource should be a -reference to the resource's parent resource instance in the tree. The -``__name__`` attribute should be the name with which a resource's parent -refers to the resource via ``__getitem__``. +The ``__parent__`` attribute of a location-aware resource should be a reference +to the resource's parent resource instance in the tree. The ``__name__`` +attribute should be the name with which a resource's parent refers to the +resource via ``__getitem__``. -The ``__parent__`` of the root resource should be ``None`` and its -``__name__`` should be the empty string. For instance: +The ``__parent__`` of the root resource should be ``None`` and its ``__name__`` +should be the empty string. For instance: .. code-block:: python :linenos: @@ -143,18 +139,18 @@ The ``__parent__`` of the root resource should be ``None`` and its __name__ = '' __parent__ = None -A resource returned from the root resource's ``__getitem__`` method should -have a ``__parent__`` attribute that is a reference to the root resource, and -its ``__name__`` attribute should match the name by which it is reachable via -the root resource's ``__getitem__``. A container resource within the root -resource should have a ``__getitem__`` that returns resources with a -``__parent__`` attribute that points at the container, and these subobjects -should have a ``__name__`` attribute that matches the name by which they are -retrieved from the container via ``__getitem__``. This pattern continues -recursively "up" the tree from the root. +A resource returned from the root resource's ``__getitem__`` method should have +a ``__parent__`` attribute that is a reference to the root resource, and its +``__name__`` attribute should match the name by which it is reachable via the +root resource's ``__getitem__``. A container resource within the root resource +should have a ``__getitem__`` that returns resources with a ``__parent__`` +attribute that points at the container, and these sub-objects should have a +``__name__`` attribute that matches the name by which they are retrieved from +the container via ``__getitem__``. This pattern continues recursively "up" the +tree from the root. The ``__parent__`` attributes of each resource form a linked list that points -"downwards" toward the root. This is analogous to the `..` entry in +"downwards" toward the root. This is analogous to the ``..`` entry in filesystem directories. If you follow the ``__parent__`` values from any resource in the resource tree, you will eventually come to the root resource, just like if you keep executing the ``cd ..`` filesystem command, eventually @@ -162,44 +158,41 @@ you will reach the filesystem root directory. .. warning:: - If your root resource has a ``__name__`` argument that is not - ``None`` or the empty string, URLs returned by the - :func:`~pyramid.request.Request.resource_url` function and paths generated + If your root resource has a ``__name__`` argument that is not ``None`` or + the empty string, URLs returned by the + :func:`~pyramid.request.Request.resource_url` function, and paths generated by the :func:`~pyramid.traversal.resource_path` and - :func:`~pyramid.traversal.resource_path_tuple` APIs will be generated + :func:`~pyramid.traversal.resource_path_tuple` APIs, will be generated improperly. The value of ``__name__`` will be prepended to every path and - URL generated (as opposed to a single leading slash or empty tuple - element). + URL generated (as opposed to a single leading slash or empty tuple element). .. sidebar:: For your convenience - If you'd rather not manage the ``__name__`` and ``__parent__`` attributes - of your resources "by hand", an add-on package named + If you'd rather not manage the ``__name__`` and ``__parent__`` attributes of + your resources "by hand", an add-on package named :mod:`pyramid_traversalwrapper` can help. In order to use this helper feature, you must first install the :mod:`pyramid_traversalwrapper` package (available via PyPI), then register - its ``ModelGraphTraverser`` as the traversal policy, rather than the - default :app:`Pyramid` traverser. The package contains instructions for - doing so. - - Once :app:`Pyramid` is configured with this feature, you will no longer - need to manage the ``__parent__`` and ``__name__`` attributes on resource - objects "by hand". Instead, as necessary, during traversal :app:`Pyramid` - will wrap each resource (even the root resource) in a ``LocationProxy`` - which will dynamically assign a ``__name__`` and a ``__parent__`` to the - traversed resource (based on the last traversed resource and the name - supplied to ``__getitem__``). The root resource will have a ``__name__`` - attribute of ``None`` and a ``__parent__`` attribute of ``None``. - -Applications which use tree-walking :app:`Pyramid` APIs require -location-aware resources. These APIs include (but are not limited to) + its ``ModelGraphTraverser`` as the traversal policy, rather than the default + :app:`Pyramid` traverser. The package contains instructions for doing so. + + Once :app:`Pyramid` is configured with this feature, you will no longer need + to manage the ``__parent__`` and ``__name__`` attributes on resource objects + "by hand". Instead, as necessary during traversal, :app:`Pyramid` will wrap + each resource (even the root resource) in a ``LocationProxy``, which will + dynamically assign a ``__name__`` and a ``__parent__`` to the traversed + resource, based on the last traversed resource and the name supplied to + ``__getitem__``. The root resource will have a ``__name__`` attribute of + ``None`` and a ``__parent__`` attribute of ``None``. + +Applications which use tree-walking :app:`Pyramid` APIs require location-aware +resources. These APIs include (but are not limited to) :meth:`~pyramid.request.Request.resource_url`, -:func:`~pyramid.traversal.find_resource`, -:func:`~pyramid.traversal.find_root`, +:func:`~pyramid.traversal.find_resource`, :func:`~pyramid.traversal.find_root`, :func:`~pyramid.traversal.find_interface`, :func:`~pyramid.traversal.resource_path`, -:func:`~pyramid.traversal.resource_path_tuple`, or +:func:`~pyramid.traversal.resource_path_tuple`, :func:`~pyramid.traversal.traverse`, :func:`~pyramid.traversal.virtual_root`, and (usually) :meth:`~pyramid.request.Request.has_permission` and :func:`~pyramid.security.principals_allowed_by_permission`. @@ -214,15 +207,15 @@ location-aware. .. _generating_the_url_of_a_resource: -Generating The URL Of A Resource +Generating the URL of a Resource -------------------------------- -If your resources are :term:`location` aware, you can use the +If your resources are :term:`location`-aware, you can use the :meth:`pyramid.request.Request.resource_url` API to generate a URL for the resource. This URL will use the resource's position in the parent tree to create a resource path, and it will prefix the path with the current -application URL to form a fully-qualified URL with the scheme, host, port, -and path. You can also pass extra arguments to +application URL to form a fully-qualified URL with the scheme, host, port, and +path. You can also pass extra arguments to :meth:`~pyramid.request.Request.resource_url` to influence the generated URL. The simplest call to :meth:`~pyramid.request.Request.resource_url` looks like @@ -237,17 +230,17 @@ The ``request`` in the above example is an instance of a :app:`Pyramid` :term:`request` object. If the resource referred to as ``resource`` in the above example was the root -resource, and the host that was used to contact the server was -``example.com``, the URL generated would be ``http://example.com/``. -However, if the resource was a child of the root resource named ``a``, the -generated URL would be ``http://example.com/a/``. +resource, and the host that was used to contact the server was ``example.com``, +the URL generated would be ``http://example.com/``. However, if the resource +was a child of the root resource named ``a``, the generated URL would be +``http://example.com/a/``. A slash is appended to all resource URLs when -:meth:`~pyramid.request.Request.resource_url` is used to generate them in -this simple manner, because resources are "places" in the hierarchy, and URLs -are meant to be clicked on to be visited. Relative URLs that you include on -HTML pages rendered as the result of the default view of a resource are more -apt to be relative to these resources than relative to their parent. +:meth:`~pyramid.request.Request.resource_url` is used to generate them in this +simple manner, because resources are "places" in the hierarchy, and URLs are +meant to be clicked on to be visited. Relative URLs that you include on HTML +pages rendered as the result of the default view of a resource are more apt to +be relative to these resources than relative to their parent. You can also pass extra elements to :meth:`~pyramid.request.Request.resource_url`: @@ -258,12 +251,12 @@ You can also pass extra elements to url = request.resource_url(resource, 'foo', 'bar') If the resource referred to as ``resource`` in the above example was the root -resource, and the host that was used to contact the server was -``example.com``, the URL generated would be ``http://example.com/foo/bar``. -Any number of extra elements can be passed to -:meth:`~pyramid.request.Request.resource_url` as extra positional arguments. -When extra elements are passed, they are appended to the resource's URL. A -slash is not appended to the final segment when elements are passed. +resource, and the host that was used to contact the server was ``example.com``, +the URL generated would be ``http://example.com/foo/bar``. Any number of extra +elements can be passed to :meth:`~pyramid.request.Request.resource_url` as +extra positional arguments. When extra elements are passed, they are appended +to the resource's URL. A slash is not appended to the final segment when +elements are passed. You can also pass a query string: @@ -273,16 +266,16 @@ You can also pass a query string: url = request.resource_url(resource, query={'a':'1'}) If the resource referred to as ``resource`` in the above example was the root -resource, and the host that was used to contact the server was -``example.com``, the URL generated would be ``http://example.com/?a=1``. +resource, and the host that was used to contact the server was ``example.com``, +the URL generated would be ``http://example.com/?a=1``. When a :term:`virtual root` is active, the URL generated by :meth:`~pyramid.request.Request.resource_url` for a resource may be "shorter" than its physical tree path. See :ref:`virtual_root_support` for more information about virtually rooting a resource. -For more information about generating resource URLs, see the documentation -for :meth:`pyramid.request.Request.resource_url`. +For more information about generating resource URLs, see the documentation for +:meth:`pyramid.request.Request.resource_url`. .. index:: pair: resource URL generation; overriding @@ -292,10 +285,10 @@ for :meth:`pyramid.request.Request.resource_url`. Overriding Resource URL Generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If a resource object implements a ``__resource_url__`` method, this method -will be called when :meth:`~pyramid.request.Request.resource_url` is called -to generate a URL for the resource, overriding the default URL returned for -the resource by :meth:`~pyramid.request.Request.resource_url`. +If a resource object implements a ``__resource_url__`` method, this method will +be called when :meth:`~pyramid.request.Request.resource_url` is called to +generate a URL for the resource, overriding the default URL returned for the +resource by :meth:`~pyramid.request.Request.resource_url`. The ``__resource_url__`` hook is passed two arguments: ``request`` and ``info``. ``request`` is the :term:`request` object passed to @@ -304,21 +297,21 @@ the following keys: ``physical_path`` A string representing the "physical path" computed for the resource, as - defined by ``pyramid.traversal.resource_path(resource)``. It will begin - and end with a slash. + defined by ``pyramid.traversal.resource_path(resource)``. It will begin and + end with a slash. ``virtual_path`` A string representing the "virtual path" computed for the resource, as defined by :ref:`virtual_root_support`. This will be identical to the - physical path if virtual rooting is not enabled. It will begin and end - with a slash. + physical path if virtual rooting is not enabled. It will begin and end with + a slash. ``app_url`` A string representing the application URL generated during ``request.resource_url``. It will not end with a slash. It represents a - potentially customized URL prefix, containing potentially custom scheme, - host and port information passed by the user to ``request.resource_url``. - It should be preferred over use of ``request.application_url``. + potentially customized URL prefix, containing potentially custom scheme, host + and port information passed by the user to ``request.resource_url``. It + should be preferred over use of ``request.application_url``. The ``__resource_url__`` method of a resource should return a string representing a URL. If it cannot override the default, it should return @@ -335,12 +328,12 @@ Here's an example ``__resource_url__`` method. The above example actually just generates and returns the default URL, which would have been what was generated by the default ``resource_url`` machinery, -but your code can perform arbitrary logic as necessary. For example, your -code may wish to override the hostname or port number of the generated URL. +but your code can perform arbitrary logic as necessary. For example, your code +may wish to override the hostname or port number of the generated URL. -Note that the URL generated by ``__resource_url__`` should be fully -qualified, should end in a slash, and should not contain any query string or -anchor elements (only path elements) to work with +Note that the URL generated by ``__resource_url__`` should be fully qualified, +should end in a slash, and should not contain any query string or anchor +elements (only path elements) to work with :meth:`~pyramid.request.Request.resource_url`. .. index:: @@ -350,9 +343,8 @@ Generating the Path To a Resource --------------------------------- :func:`pyramid.traversal.resource_path` returns a string object representing -the absolute physical path of the resource object based on its position in -the resource tree. Each segment of the path is separated with a slash -character. +the absolute physical path of the resource object based on its position in the +resource tree. Each segment of the path is separated with a slash character. .. code-block:: python :linenos: @@ -378,8 +370,8 @@ If ``resource`` in the example above was accessible in the tree as The resource passed in must be :term:`location`-aware. -The presence or absence of a :term:`virtual root` has no impact on the -behavior of :func:`~pyramid.traversal.resource_path`. +The presence or absence of a :term:`virtual root` has no impact on the behavior +of :func:`~pyramid.traversal.resource_path`. .. index:: pair: resource; finding by path @@ -387,8 +379,8 @@ behavior of :func:`~pyramid.traversal.resource_path`. Finding a Resource by Path -------------------------- -If you have a string path to a resource, you can grab the resource from -that place in the application's resource tree using +If you have a string path to a resource, you can grab the resource from that +place in the application's resource tree using :func:`pyramid.traversal.find_resource`. You can resolve an absolute path by passing a string prefixed with a ``/`` as @@ -400,8 +392,9 @@ the ``path`` argument: from pyramid.traversal import find_resource url = find_resource(anyresource, '/path') -Or you can resolve a path relative to the resource you pass in by passing a -string that isn't prefixed by ``/``: +Or you can resolve a path relative to the resource that you pass in to +:func:`pyramid.traversal.find_resource` by passing a string that isn't prefixed +by ``/``: .. code-block:: python :linenos: @@ -410,8 +403,8 @@ string that isn't prefixed by ``/``: url = find_resource(anyresource, 'path') Often the paths you pass to :func:`~pyramid.traversal.find_resource` are -generated by the :func:`~pyramid.traversal.resource_path` API. These APIs -are "mirrors" of each other. +generated by the :func:`~pyramid.traversal.resource_path` API. These APIs are +"mirrors" of each other. If the path cannot be resolved when calling :func:`~pyramid.traversal.find_resource` (if the respective resource in the @@ -427,10 +420,10 @@ Obtaining the Lineage of a Resource ----------------------------------- :func:`pyramid.location.lineage` returns a generator representing the -:term:`lineage` of the :term:`location` aware :term:`resource` object. +:term:`lineage` of the :term:`location`-aware :term:`resource` object. -The :func:`~pyramid.location.lineage` function returns the resource it is -passed, then each parent of the resource, in order. For example, if the +The :func:`~pyramid.location.lineage` function returns the resource that is +passed into it, then each parent of the resource in order. For example, if the resource tree is composed like so: .. code-block:: python @@ -451,18 +444,18 @@ list, we will get: list(lineage(thing2)) [ , ] -The generator returned by :func:`~pyramid.location.lineage` first returns the -resource it was passed unconditionally. Then, if the resource supplied a -``__parent__`` attribute, it returns the resource represented by -``resource.__parent__``. If *that* resource has a ``__parent__`` attribute, -return that resource's parent, and so on, until the resource being inspected -either has no ``__parent__`` attribute or has a ``__parent__`` attribute of -``None``. +The generator returned by :func:`~pyramid.location.lineage` first returns +unconditionally the resource that was passed into it. Then, if the resource +supplied a ``__parent__`` attribute, it returns the resource represented by +``resource.__parent__``. If *that* resource has a ``__parent__`` attribute, it +will return that resource's parent, and so on, until the resource being +inspected either has no ``__parent__`` attribute or has a ``__parent__`` +attribute of ``None``. See the documentation for :func:`pyramid.location.lineage` for more information. -Determining if a Resource is In The Lineage of Another Resource +Determining if a Resource is in the Lineage of Another Resource --------------------------------------------------------------- Use the :func:`pyramid.location.inside` function to determine if one resource @@ -479,12 +472,12 @@ For example, if the resource tree is: b = Thing() b.__parent__ = a -Calling ``inside(b, a)`` will return ``True``, because ``b`` has a lineage -that includes ``a``. However, calling ``inside(a, b)`` will return ``False`` +Calling ``inside(b, a)`` will return ``True``, because ``b`` has a lineage that +includes ``a``. However, calling ``inside(a, b)`` will return ``False`` because ``a`` does not have a lineage that includes ``b``. The argument list for :func:`~pyramid.location.inside` is ``(resource1, -resource2)``. ``resource1`` is 'inside' ``resource2`` if ``resource2`` is a +resource2)``. ``resource1`` is "inside" ``resource2`` if ``resource2`` is a :term:`lineage` ancestor of ``resource1``. It is a lineage ancestor if its parent (or one of its parent's parents, etc.) is an ancestor. @@ -497,9 +490,9 @@ Finding the Root Resource ------------------------- Use the :func:`pyramid.traversal.find_root` API to find the :term:`root` -resource. The root resource is the root resource of the :term:`resource -tree`. The API accepts a single argument: ``resource``. This is a resource -that is :term:`location` aware. It can be any resource in the tree for which +resource. The root resource is the resource at the root of the :term:`resource +tree`. The API accepts a single argument: ``resource``. This is a resource +that is :term:`location`-aware. It can be any resource in the tree for which you want to find the root. For example, if the resource tree is: @@ -518,9 +511,9 @@ Calling ``find_root(b)`` will return ``a``. The root resource is also available as ``request.root`` within :term:`view callable` code. -The presence or absence of a :term:`virtual root` has no impact on the -behavior of :func:`~pyramid.traversal.find_root`. The root object returned -is always the *physical* root object. +The presence or absence of a :term:`virtual root` has no impact on the behavior +of :func:`~pyramid.traversal.find_root`. The root object returned is always +the *physical* root object. .. index:: single: resource interfaces @@ -531,19 +524,18 @@ Resources Which Implement Interfaces ------------------------------------ Resources can optionally be made to implement an :term:`interface`. An -interface is used to tag a resource object with a "type" that can later be +interface is used to tag a resource object with a "type" that later can be referred to within :term:`view configuration` and by :func:`pyramid.traversal.find_interface`. Specifying an interface instead of a class as the ``context`` or ``containment`` predicate arguments within :term:`view configuration` statements makes it possible to use a single view callable for more than one -class of resource object. If your application is simple enough that you see -no reason to want to do this, you can skip reading this section of the -chapter. +class of resource objects. If your application is simple enough that you see +no reason to want to do this, you can skip reading this section of the chapter. -For example, here's some code which describes a blog entry which also -declares that the blog entry implements an :term:`interface`. +For example, here's some code which describes a blog entry which also declares +that the blog entry implements an :term:`interface`. .. code-block:: python :linenos: @@ -577,10 +569,10 @@ resource implements an interface by using the ``BlogEntry`` resource implements the ``IBlogEntry`` interface. You can also specify that a particular resource *instance* provides an -interface, as opposed to its class. When you declare that a class implements -an interface, all instances of that class will also provide that interface. -However, you can also just say that a single object provides the interface. -To do so, use the :func:`zope.interface.directlyProvides` function: +interface as opposed to its class. When you declare that a class implements an +interface, all instances of that class will also provide that interface. +However, you can also just say that a single object provides the interface. To +do so, use the :func:`zope.interface.directlyProvides` function: .. code-block:: python :linenos: @@ -603,9 +595,9 @@ To do so, use the :func:`zope.interface.directlyProvides` function: directlyProvides(entry, IBlogEntry) :func:`zope.interface.directlyProvides` will replace any existing interface -that was previously provided by an instance. If a resource object already -has instance-level interface declarations that you don't want to replace, use -the :func:`zope.interface.alsoProvides` function: +that was previously provided by an instance. If a resource object already has +instance-level interface declarations that you don't want to replace, use the +:func:`zope.interface.alsoProvides` function: .. code-block:: python :linenos: @@ -632,8 +624,8 @@ the :func:`zope.interface.alsoProvides` function: directlyProvides(entry, IBlogEntry1) alsoProvides(entry, IBlogEntry2) -:func:`zope.interface.alsoProvides` will augment the set of interfaces -directly provided by an instance instead of overwriting them like +:func:`zope.interface.alsoProvides` will augment the set of interfaces directly +provided by an instance instead of overwriting them like :func:`zope.interface.directlyProvides` does. For more information about how resource interfaces can be used by view @@ -642,7 +634,7 @@ configuration, see :ref:`using_resource_interfaces`. .. index:: pair: resource; finding by interface or class -Finding a Resource With a Class or Interface in Lineage +Finding a Resource with a Class or Interface in Lineage ------------------------------------------------------- Use the :func:`~pyramid.traversal.find_interface` API to locate a parent that @@ -662,18 +654,19 @@ For example, if your resource tree is composed as follows: Calling ``find_interface(a, Thing1)`` will return the ``a`` resource because ``a`` is of class ``Thing1`` (the resource passed as the first argument is -considered first, and is returned if the class or interface spec matches). +considered first, and is returned if the class or interface specification +matches). Calling ``find_interface(b, Thing1)`` will return the ``a`` resource because -``a`` is of class ``Thing1`` and ``a`` is the first resource in ``b``'s -lineage of this class. +``a`` is of class ``Thing1`` and ``a`` is the first resource in ``b``'s lineage +of this class. Calling ``find_interface(b, Thing2)`` will return the ``b`` resource. -The second argument to find_interface may also be a :term:`interface` instead -of a class. If it is an interface, each resource in the lineage is checked -to see if the resource implements the specificed interface (instead of seeing -if the resource is of a class). +The second argument to ``find_interface`` may also be a :term:`interface` +instead of a class. If it is an interface, each resource in the lineage is +checked to see if the resource implements the specificed interface (instead of +seeing if the resource is of a class). .. seealso:: @@ -690,18 +683,17 @@ A resource object is used as the :term:`context` provided to a view. See :ref:`traversal_chapter` and :ref:`urldispatch_chapter` for more information about how a resource object becomes the context. -The APIs provided by :ref:`traversal_module` are used against resource -objects. These functions can be used to find the "path" of a resource, the -root resource in a resource tree, or to generate a URL for a resource. +The APIs provided by :ref:`traversal_module` are used against resource objects. +These functions can be used to find the "path" of a resource, the root resource +in a resource tree, or to generate a URL for a resource. -The APIs provided by :ref:`location_module` are used against resources. -These can be used to walk down a resource tree, or conveniently locate one -resource "inside" another. - -Some APIs on the :class:`pyramid.request.Request` accept a resource object as a parameter. -For example, the :meth:`~pyramid.request.Request.has_permission` API accepts a -resource object as one of its arguments; the ACL is obtained from this -resource or one of its ancestors. Other security related APIs on the -:class:`pyramid.request.Request` class also accept :term:`context` as an argument, -and a context is always a resource. +The APIs provided by :ref:`location_module` are used against resources. These +can be used to walk down a resource tree, or conveniently locate one resource +"inside" another. +Some APIs on the :class:`pyramid.request.Request` accept a resource object as a +parameter. For example, the :meth:`~pyramid.request.Request.has_permission` API +accepts a resource object as one of its arguments; the ACL is obtained from +this resource or one of its ancestors. Other security related APIs on the +:class:`pyramid.request.Request` class also accept :term:`context` as an +argument, and a context is always a resource. -- cgit v1.2.3 From 573b56c177496918ab11e36ac51cf16bec057c80 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 25 Oct 2015 00:32:53 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/hellotraversal.rst | 67 ++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 36 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hellotraversal.rst b/docs/narr/hellotraversal.rst index 0a93b8f16..543e2171f 100644 --- a/docs/narr/hellotraversal.rst +++ b/docs/narr/hellotraversal.rst @@ -1,64 +1,60 @@ .. _hello_traversal_chapter: Hello Traversal World -====================== - +===================== .. index:: single: traversal quick example -Traversal is an alternative to URL dispatch which allows Pyramid -applications to map URLs to code. +Traversal is an alternative to URL dispatch which allows Pyramid applications +to map URLs to code. -If code speaks louder than words, maybe this will help. Here is a -single-file Pyramid application that uses traversal: +If code speaks louder than words, maybe this will help. Here is a single-file +Pyramid application that uses traversal: .. literalinclude:: hellotraversal.py :linenos: -You may notice that this application is intentionally very similar to -the "hello world" app from :doc:`firstapp`. +You may notice that this application is intentionally very similar to the +"hello world" application from :doc:`firstapp`. On lines 5-6, we create a trivial :term:`resource` class that's just a dictionary subclass. -On lines 8-9, we hard-code a :term:`resource tree` in our :term:`root -factory` function. +On lines 8-9, we hard-code a :term:`resource tree` in our :term:`root factory` +function. -On lines 11-13 we define a single :term:`view callable` that can -display a single instance of our Resource class, passed as the -``context`` argument. +On lines 11-13, we define a single :term:`view callable` that can display a +single instance of our ``Resource`` class, passed as the ``context`` argument. -The rest of the file sets up and serves our pyramid WSGI app. Line 18 -is where our view gets configured for use whenever the traversal ends -with an instance of our Resource class. +The rest of the file sets up and serves our :app:`Pyramid` WSGI app. Line 18 +is where our view gets configured for use whenever the traversal ends with an +instance of our ``Resource`` class. -Interestingly, there are no URLs explicitly configured in this -application. Instead, the URL space is defined entirely by the keys in -the resource tree. +Interestingly, there are no URLs explicitly configured in this application. +Instead, the URL space is defined entirely by the keys in the resource tree. Example requests ---------------- -If this example is running on http://localhost:8080, and the user -browses to http://localhost:8080/a/b, Pyramid will call -``get_root(request)`` to get the root resource, then traverse the tree -from there by key; starting from the root, it will find the child with -key ``"a"``, then its child with key ``"b"``; then use that as the -``context`` argument for calling ``hello_world_of_resources``. +If this example is running on http://localhost:8080, and the user browses to +http://localhost:8080/a/b, Pyramid will call ``get_root(request)`` to get the +root resource, then traverse the tree from there by key; starting from the +root, it will find the child with key ``"a"``, then its child with key ``"b"``; +then use that as the ``context`` argument for calling +``hello_world_of_resources``. -Or, if the user browses to http://localhost:8080/ , Pyramid will -stop at the root - the outermost Resource instance, in this case - and -use that as the ``context`` argument to the same view. +Or, if the user browses to http://localhost:8080/, Pyramid will stop at the +root—the outermost ``Resource`` instance, in this case—and use that as the +``context`` argument to the same view. -Or, if the user browses to a key that doesn't exist in this resource -tree, like http://localhost:8080/xyz or -http://localhost:8080/a/b/c/d, the traversal will end by raising a -KeyError, and Pyramid will turn that into a 404 HTTP response. +Or, if the user browses to a key that doesn't exist in this resource tree, like +http://localhost:8080/xyz or http://localhost:8080/a/b/c/d, the traversal will +end by raising a KeyError, and Pyramid will turn that into a 404 HTTP response. -A more complicated application could have many types of resources, -with different view callables defined for each type, and even multiple -views for each type. +A more complicated application could have many types of resources, with +different view callables defined for each type, and even multiple views for +each type. .. seealso:: @@ -66,4 +62,3 @@ views for each type. For more about *why* you might use traversal, see :doc:`muchadoabouttraversal`. - -- cgit v1.2.3 From 9dbba32a0895a4a56611a6db55b59e9e461a8c1c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 26 Oct 2015 03:01:59 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/muchadoabouttraversal.rst | 341 ++++++++++++++++++------------------ 1 file changed, 168 insertions(+), 173 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/muchadoabouttraversal.rst b/docs/narr/muchadoabouttraversal.rst index 483b1bb16..3e00a295a 100644 --- a/docs/narr/muchadoabouttraversal.rst +++ b/docs/narr/muchadoabouttraversal.rst @@ -4,44 +4,44 @@ Much Ado About Traversal ======================== -(Or, why you should care about it) +(Or, why you should care about it.) .. note:: - This chapter was adapted, with permission, from a blog post by `Rob - Miller `_, originally published at - http://blog.nonsequitarian.org/2010/much-ado-about-traversal/ . + This chapter was adapted, with permission, from a blog post by `Rob Miller + `_, originally published at + http://blog.nonsequitarian.org/2010/much-ado-about-traversal/. -Traversal is an alternative to :term:`URL dispatch` which allows -:app:`Pyramid` applications to map URLs to code. +Traversal is an alternative to :term:`URL dispatch` which allows :app:`Pyramid` +applications to map URLs to code. .. note:: Ex-Zope users who are already familiar with traversal and view lookup conceptually may want to skip directly to the :ref:`traversal_chapter` - chapter, which discusses technical details. This chapter is mostly aimed - at people who have previous :term:`Pylons` experience or experience in - another framework which does not provide traversal, and need an - introduction to the "why" of traversal. + chapter, which discusses technical details. This chapter is mostly aimed at + people who have previous :term:`Pylons` experience or experience in another + framework which does not provide traversal, and need an introduction to the + "why" of traversal. Some folks who have been using Pylons and its Routes-based URL matching for a long time are being exposed for the first time, via :app:`Pyramid`, to new ideas such as ":term:`traversal`" and ":term:`view lookup`" as a way to route incoming HTTP requests to callable code. Some of the same folks believe that -traversal is hard to understand. Others question its usefulness; URL -matching has worked for them so far, why should they even consider dealing -with another approach, one which doesn't fit their brain and which doesn't -provide any immediately obvious value? +traversal is hard to understand. Others question its usefulness; URL matching +has worked for them so far, so why should they even consider dealing with +another approach, one which doesn't fit their brain and which doesn't provide +any immediately obvious value? You can be assured that if you don't want to understand traversal, you don't have to. You can happily build :app:`Pyramid` applications with only -:term:`URL dispatch`. However, there are some straightforward, real-world -use cases that are much more easily served by a traversal-based approach than -by a pattern-matching mechanism. Even if you haven't yet hit one of these -use cases yourself, understanding these new ideas is worth the effort for any -web developer so you know when you might want to use them. :term:`Traversal` -is actually a straightforward metaphor easily comprehended by anyone who's -ever used a run-of-the-mill file system with folders and files. +:term:`URL dispatch`. However, there are some straightforward, real-world use +cases that are much more easily served by a traversal-based approach than by a +pattern-matching mechanism. Even if you haven't yet hit one of these use cases +yourself, understanding these new ideas is worth the effort for any web +developer so you know when you might want to use them. :term:`Traversal` is +actually a straightforward metaphor easily comprehended by anyone who's ever +used a run-of-the-mill file system with folders and files. .. index:: single: URL dispatch @@ -49,34 +49,33 @@ ever used a run-of-the-mill file system with folders and files. URL Dispatch ------------ -Let's step back and consider the problem we're trying to solve. An -HTTP request for a particular path has been routed to our web -application. The requested path will possibly invoke a specific -:term:`view callable` function defined somewhere in our app. We're -trying to determine *which* callable function, if any, should be -invoked for a given requested URL. +Let's step back and consider the problem we're trying to solve. An HTTP +request for a particular path has been routed to our web application. The +requested path will possibly invoke a specific :term:`view callable` function +defined somewhere in our app. We're trying to determine *which* callable +function, if any, should be invoked for a given requested URL. Many systems, including Pyramid, offer a simple solution. They offer the -concept of "URL matching". URL matching approaches this problem by parsing -the URL path and comparing the results to a set of registered "patterns", -defined by a set of regular expressions, or some other URL path templating -syntax. Each pattern is mapped to a callable function somewhere; if the -request path matches a specific pattern, the associated function is called. -If the request path matches more than one pattern, some conflict resolution -scheme is used, usually a simple order precedence so that the first match -will take priority over any subsequent matches. If a request path doesn't -match any of the defined patterns, a "404 Not Found" response is returned. - -In Pyramid, we offer an implementation of URL matching which we call -:term:`URL dispatch`. Using :app:`Pyramid` syntax, we might have a match -pattern such as ``/{userid}/photos/{photoid}``, mapped to a ``photo_view()`` -function defined somewhere in our code. Then a request for a path such as +concept of "URL matching". URL matching approaches this problem by parsing the +URL path and comparing the results to a set of registered "patterns", defined +by a set of regular expressions or some other URL path templating syntax. Each +pattern is mapped to a callable function somewhere; if the request path matches +a specific pattern, the associated function is called. If the request path +matches more than one pattern, some conflict resolution scheme is used, usually +a simple order precedence so that the first match will take priority over any +subsequent matches. If a request path doesn't match any of the defined +patterns, a "404 Not Found" response is returned. + +In Pyramid, we offer an implementation of URL matching which we call :term:`URL +dispatch`. Using :app:`Pyramid` syntax, we might have a match pattern such as +``/{userid}/photos/{photoid}``, mapped to a ``photo_view()`` function defined +somewhere in our code. Then a request for a path such as ``/joeschmoe/photos/photo1`` would be a match, and the ``photo_view()`` function would be invoked to handle the request. Similarly, -``/{userid}/blog/{year}/{month}/{postid}`` might map to a -``blog_post_view()`` function, so ``/joeschmoe/blog/2010/12/urlmatching`` -would trigger the function, which presumably would know how to find and -render the ``urlmatching`` blog post. +``/{userid}/blog/{year}/{month}/{postid}`` might map to a ``blog_post_view()`` +function, so ``/joeschmoe/blog/2010/12/urlmatching`` would trigger the +function, which presumably would know how to find and render the +``urlmatching`` blog post. Historical Refresher -------------------- @@ -88,65 +87,64 @@ time when we didn't have fancy web frameworks like :term:`Pylons` and :app:`Pyramid`. Instead, we had general purpose HTTP servers that primarily served files off of a file system. The "root" of a given site mapped to a particular folder somewhere on the file system. Each segment of the request -URL path represented a subdirectory. The final path segment would be either -a directory or a file, and once the server found the right file it would -package it up in an HTTP response and send it back to the client. So serving -up a request for ``/joeschmoe/photos/photo1`` literally meant that there was -a ``joeschmoe`` folder somewhere, which contained a ``photos`` folder, which -in turn contained a ``photo1`` file. If at any point along the way we find -that there is not a folder or file matching the requested path, we return a -404 response. +URL path represented a subdirectory. The final path segment would be either a +directory or a file, and once the server found the right file it would package +it up in an HTTP response and send it back to the client. So serving up a +request for ``/joeschmoe/photos/photo1`` literally meant that there was a +``joeschmoe`` folder somewhere, which contained a ``photos`` folder, which in +turn contained a ``photo1`` file. If at any point along the way we find that +there is not a folder or file matching the requested path, we return a 404 +response. As the web grew more dynamic, however, a little bit of extra complexity was -added. Technologies such as CGI and HTTP server modules were developed. -Files were still looked up on the file system, but if the file ended with -(for example) ``.cgi`` or ``.php``, or if it lived in a special folder, -instead of simply sending the file to the client the server would read the -file, execute it using an interpreter of some sort, and then send the output -from this process to the client as the final result. The server -configuration specified which files would trigger some dynamic code, with the -default case being to just serve the static file. +added. Technologies such as CGI and HTTP server modules were developed. Files +were still looked up on the file system, but if the file ended with (for +example) ``.cgi`` or ``.php``, or if it lived in a special folder, instead of +simply sending the file to the client the server would read the file, execute +it using an interpreter of some sort, and then send the output from this +process to the client as the final result. The server configuration specified +which files would trigger some dynamic code, with the default case being to +just serve the static file. .. index:: single: traversal -Traversal (aka Resource Location) ---------------------------------- +Traversal (a.k.a., Resource Location) +------------------------------------- Believe it or not, if you understand how serving files from a file system works, you understand traversal. And if you understand that a server might do -something different based on what type of file a given request specifies, -then you understand view lookup. +something different based on what type of file a given request specifies, then +you understand view lookup. The major difference between file system lookup and traversal is that a file -system lookup steps through nested directories and files in a file system -tree, while traversal steps through nested dictionary-type objects in a -:term:`resource tree`. Let's take a detailed look at one of our example -paths, so we can see what I mean: - -The path ``/joeschmoe/photos/photo1``, has four segments: ``/``, -``joeschmoe``, ``photos`` and ``photo1``. With file system lookup we might -have a root folder (``/``) containing a nested folder (``joeschmoe``), which -contains another nested folder (``photos``), which finally contains a JPG -file (``photo1``). With traversal, we instead have a dictionary-like root -object. Asking for the ``joeschmoe`` key gives us another dictionary-like -object. Asking this in turn for the ``photos`` key gives us yet another -mapping object, which finally (hopefully) contains the resource that we're -looking for within its values, referenced by the ``photo1`` key. - -In pure Python terms, then, the traversal or "resource location" -portion of satisfying the ``/joeschmoe/photos/photo1`` request -will look something like this pseudocode:: +system lookup steps through nested directories and files in a file system tree, +while traversal steps through nested dictionary-type objects in a +:term:`resource tree`. Let's take a detailed look at one of our example paths, +so we can see what I mean. + +The path ``/joeschmoe/photos/photo1``, has four segments: ``/``, ``joeschmoe``, +``photos`` and ``photo1``. With file system lookup we might have a root folder +(``/``) containing a nested folder (``joeschmoe``), which contains another +nested folder (``photos``), which finally contains a JPG file (``photo1``). +With traversal, we instead have a dictionary-like root object. Asking for the +``joeschmoe`` key gives us another dictionary-like object. Asking in turn for +the ``photos`` key gives us yet another mapping object, which finally +(hopefully) contains the resource that we're looking for within its values, +referenced by the ``photo1`` key. + +In pure Python terms, then, the traversal or "resource location" portion of +satisfying the ``/joeschmoe/photos/photo1`` request will look something like +this pseudocode:: get_root()['joeschmoe']['photos']['photo1'] -``get_root()`` is some function that returns a root traversal -:term:`resource`. If all of the specified keys exist, then the returned -object will be the resource that is being requested, analogous to the JPG -file that was retrieved in the file system example. If a :exc:`KeyError` is -generated anywhere along the way, :app:`Pyramid` will return 404. (This -isn't precisely true, as you'll see when we learn about view lookup below, -but the basic idea holds.) +``get_root()`` is some function that returns a root traversal :term:`resource`. +If all of the specified keys exist, then the returned object will be the +resource that is being requested, analogous to the JPG file that was retrieved +in the file system example. If a :exc:`KeyError` is generated anywhere along +the way, :app:`Pyramid` will return 404. (This isn't precisely true, as you'll +see when we learn about view lookup below, but the basic idea holds.) .. index:: single: resource @@ -159,10 +157,10 @@ nested dictionary things? Where do these objects, these 'resources', live? What *are* they?" Since :app:`Pyramid` is not a highly opinionated framework, it makes no -restriction on how a :term:`resource` is implemented; a developer can -implement them as he wishes. One common pattern used is to persist all of -the resources, including the root, in a database as a graph. The root object -is a dictionary-like object. Dictionary-like objects in Python supply a +restriction on how a :term:`resource` is implemented; a developer can implement +them as they wish. One common pattern used is to persist all of the resources, +including the root, in a database as a graph. The root object is a +dictionary-like object. Dictionary-like objects in Python supply a ``__getitem__`` method which is called when key lookup is done. Under the hood, when ``adict`` is a dictionary-like object, Python translates ``adict['a']`` to ``adict.__getitem__('a')``. Try doing this in a Python @@ -175,25 +173,24 @@ interpreter prompt if you don't believe us: >>> adict.__getitem__('a') 1 - The dictionary-like root object stores the ids of all of its subresources as keys, and provides a ``__getitem__`` implementation that fetches them. So ``get_root()`` fetches the unique root object, while ``get_root()['joeschmoe']`` returns a different object, also stored in the database, which in turn has its own subresources and ``__getitem__`` -implementation, etc. These resources might be persisted in a relational +implementation, and so on. These resources might be persisted in a relational database, one of the many "NoSQL" solutions that are becoming popular these -days, or anywhere else, it doesn't matter. As long as the returned objects -provide the dictionary-like API (i.e. as long as they have an appropriately -implemented ``__getitem__`` method) then traversal will work. - -In fact, you don't need a "database" at all. You could use plain -dictionaries, with your site's URL structure hard-coded directly in -the Python source. Or you could trivially implement a set of objects -with ``__getitem__`` methods that search for files in specific -directories, and thus precisely recreate the traditional mechanism of -having the URL path mapped directly to a folder structure on the file -system. Traversal is in fact a superset of file system lookup. +days, or anywhere else; it doesn't matter. As long as the returned objects +provide the dictionary-like API (i.e., as long as they have an appropriately +implemented ``__getitem__`` method), then traversal will work. + +In fact, you don't need a "database" at all. You could use plain dictionaries, +with your site's URL structure hard-coded directly in the Python source. Or +you could trivially implement a set of objects with ``__getitem__`` methods +that search for files in specific directories, and thus precisely recreate the +traditional mechanism of having the URL path mapped directly to a folder +structure on the file system. Traversal is in fact a superset of file system +lookup. .. note:: See the chapter entitled :ref:`resources_chapter` for a more technical overview of resources. @@ -208,34 +205,33 @@ At this point we're nearly there. We've covered traversal, which is the process by which a specific resource is retrieved according to a specific URL path. But what is "view lookup"? -The need for view lookup is simple: there is more than one possible action -that you might want to take after finding a :term:`resource`. With our photo +The need for view lookup is simple: there is more than one possible action that +you might want to take after finding a :term:`resource`. With our photo example, for instance, you might want to view the photo in a page, but you might also want to provide a way for the user to edit the photo and any associated metadata. We'll call the former the ``view`` view, and the latter will be the ``edit`` view. (Original, I know.) :app:`Pyramid` has a centralized view :term:`application registry` where named views can be -associated with specific resource types. So in our example, we'll assume -that we've registered ``view`` and ``edit`` views for photo objects, and that -we've specified the ``view`` view as the default, so that +associated with specific resource types. So in our example, we'll assume that +we've registered ``view`` and ``edit`` views for photo objects, and that we've +specified the ``view`` view as the default, so that ``/joeschmoe/photos/photo1/view`` and ``/joeschmoe/photos/photo1`` are equivalent. The edit view would sensibly be provided by a request for ``/joeschmoe/photos/photo1/edit``. Hopefully it's clear that the first portion of the edit view's URL path is -going to resolve to the same resource as the non-edit version, specifically -the resource returned by ``get_root()['joeschmoe']['photos']['photo1']``. -But traveral ends there; the ``photo1`` resource doesn't have an ``edit`` -key. In fact, it might not even be a dictionary-like object, in which case +going to resolve to the same resource as the non-edit version, specifically the +resource returned by ``get_root()['joeschmoe']['photos']['photo1']``. But +traversal ends there; the ``photo1`` resource doesn't have an ``edit`` key. In +fact, it might not even be a dictionary-like object, in which case ``photo1['edit']`` would be meaningless. When the :app:`Pyramid` resource location has been resolved to a *leaf* resource, but the entire request path has not yet been expended, the *very next* path segment is treated as a -:term:`view name`. The registry is then checked to see if a view of the -given name has been specified for a resource of the given type. If so, the -view callable is invoked, with the resource passed in as the related -``context`` object (also available as ``request.context``). If a view -callable could not be found, :app:`Pyramid` will return a "404 Not Found" -response. +:term:`view name`. The registry is then checked to see if a view of the given +name has been specified for a resource of the given type. If so, the view +callable is invoked, with the resource passed in as the related ``context`` +object (also available as ``request.context``). If a view callable could not +be found, :app:`Pyramid` will return a "404 Not Found" response. You might conceptualize a request for ``/joeschmoe/photos/photo1/edit`` as ultimately converted into the following piece of Pythonic pseudocode:: @@ -246,8 +242,8 @@ ultimately converted into the following piece of Pythonic pseudocode:: view_callable(request) The ``get_root`` and ``get_view`` functions don't really exist. Internally, -:app:`Pyramid` does something more complicated. But the example above -is a reasonable approximation of the view lookup algorithm in pseudocode. +:app:`Pyramid` does something more complicated. But the example above is a +reasonable approximation of the view lookup algorithm in pseudocode. Use Cases --------- @@ -261,58 +257,57 @@ like this:: /{userid}/{typename}/{objectid}[/{view_name}] -In all of the examples thus far, we've hard coded the typename value, -assuming that we'd know at development time what names were going to be used -("photos", "blog", etc.). But what if we don't know what these names will -be? Or, worse yet, what if we don't know *anything* about the structure of -the URLs inside a user's folder? We could be writing a CMS where we want the -end user to be able to arbitrarily add content and other folders inside his -folder. He might decide to nest folders dozens of layers deep. How will you -construct matching patterns that could account for every possible combination -of paths that might develop? - -It might be possible, but it certainly won't be easy. The matching -patterns are going to become complex quickly as you try to handle all -of the edge cases. - -With traversal, however, it's straightforward. Twenty layers of nesting -would be no problem. :app:`Pyramid` will happily call ``__getitem__`` as -many times as it needs to, until it runs out of path segments or until a -resource raises a :exc:`KeyError`. Each resource only needs to know how to -fetch its immediate children, the traversal algorithm takes care of the rest. -Also, since the structure of the resource tree can live in the database and -not in the code, it's simple to let users modify the tree at runtime to set -up their own personalized "directory" structures. - -Another use case in which traversal shines is when there is a need to support -a context-dependent security policy. One example might be a document -management infrastructure for a large corporation, where members of different -departments have varying access levels to the various other departments' -files. Reasonably, even specific files might need to be made available to -specific individuals. Traversal does well here if your resources actually -represent the data objects related to your documents, because the idea of a -resource authorization is baked right into the code resolution and calling -process. Resource objects can store ACLs, which can be inherited and/or -overridden by the subresources. - -If each resource can thus generate a context-based ACL, then whenever view -code is attempting to perform a sensitive action, it can check against that -ACL to see whether the current user should be allowed to perform the action. -In this way you achieve so called "instance based" or "row level" security -which is considerably harder to model using a traditional tabular approach. +In all of the examples thus far, we've hard coded the typename value, assuming +that we'd know at development time what names were going to be used ("photos", +"blog", etc.). But what if we don't know what these names will be? Or, worse +yet, what if we don't know *anything* about the structure of the URLs inside a +user's folder? We could be writing a CMS where we want the end user to be able +to arbitrarily add content and other folders inside his folder. He might +decide to nest folders dozens of layers deep. How will you construct matching +patterns that could account for every possible combination of paths that might +develop? + +It might be possible, but it certainly won't be easy. The matching patterns +are going to become complex quickly as you try to handle all of the edge cases. + +With traversal, however, it's straightforward. Twenty layers of nesting would +be no problem. :app:`Pyramid` will happily call ``__getitem__`` as many times +as it needs to, until it runs out of path segments or until a resource raises a +:exc:`KeyError`. Each resource only needs to know how to fetch its immediate +children, and the traversal algorithm takes care of the rest. Also, since the +structure of the resource tree can live in the database and not in the code, +it's simple to let users modify the tree at runtime to set up their own +personalized "directory" structures. + +Another use case in which traversal shines is when there is a need to support a +context-dependent security policy. One example might be a document management +infrastructure for a large corporation, where members of different departments +have varying access levels to the various other departments' files. +Reasonably, even specific files might need to be made available to specific +individuals. Traversal does well here if your resources actually represent the +data objects related to your documents, because the idea of a resource +authorization is baked right into the code resolution and calling process. +Resource objects can store ACLs, which can be inherited and/or overridden by +the subresources. + +If each resource can thus generate a context-based ACL, then whenever view code +is attempting to perform a sensitive action, it can check against that ACL to +see whether the current user should be allowed to perform the action. In this +way you achieve so called "instance based" or "row level" security which is +considerably harder to model using a traditional tabular approach. :app:`Pyramid` actively supports such a scheme, and in fact if you register -your views with guard permissions and use an authorization policy, -:app:`Pyramid` can check against a resource's ACL when deciding whether or -not the view itself is available to the current user. +your views with guarded permissions and use an authorization policy, +:app:`Pyramid` can check against a resource's ACL when deciding whether or not +the view itself is available to the current user. -In summary, there are entire classes of problems that are more easily served -by traversal and view lookup than by :term:`URL dispatch`. If your problems -don't require it, great: stick with :term:`URL dispatch`. But if you're -using :app:`Pyramid` and you ever find that you *do* need to support one of -these use cases, you'll be glad you have traversal in your toolkit. +In summary, there are entire classes of problems that are more easily served by +traversal and view lookup than by :term:`URL dispatch`. If your problems don't +require it, great, stick with :term:`URL dispatch`. But if you're using +:app:`Pyramid` and you ever find that you *do* need to support one of these use +cases, you'll be glad you have traversal in your toolkit. .. note:: - It is even possible to mix and match :term:`traversal` with - :term:`URL dispatch` in the same :app:`Pyramid` application. See the + It is even possible to mix and match :term:`traversal` with :term:`URL + dispatch` in the same :app:`Pyramid` application. See the :ref:`hybrid_chapter` chapter for details. -- cgit v1.2.3 From 8bafd90d6143230391723e1a079f7914af2381ed Mon Sep 17 00:00:00 2001 From: Julien Cigar Date: Mon, 26 Oct 2015 23:55:45 +0100 Subject: .txt -> json --- docs/narr/renderers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst index cc5baf05e..50e85813a 100644 --- a/docs/narr/renderers.rst +++ b/docs/narr/renderers.rst @@ -609,8 +609,8 @@ Pyramid supports overriding almost every aspect of its setup through its :ref:`Conflict Resolution ` mechanism. This means that, in most cases, overriding a renderer is as simple as using the :meth:`pyramid.config.Configurator.add_renderer` method to redefine the -template extension. For example, if you would like to override the ``.txt`` -extension to specify a new renderer, you could do the following: +template extension. For example, if you would like to override the ``json`` +renderer to specify a new renderer, you could do the following: .. code-block:: python -- cgit v1.2.3 From c373a6a02261e1f60cda166160a85a7be1b50349 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 27 Oct 2015 00:10:57 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes --- docs/narr/traversal.rst | 425 +++++++++++++++++++++++------------------------- 1 file changed, 204 insertions(+), 221 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/traversal.rst b/docs/narr/traversal.rst index 454bb5620..cd8395eac 100644 --- a/docs/narr/traversal.rst +++ b/docs/narr/traversal.rst @@ -3,32 +3,30 @@ Traversal ========= -This chapter explains the technical details of how traversal works in -Pyramid. +This chapter explains the technical details of how traversal works in Pyramid. For a quick example, see :doc:`hellotraversal`. For more about *why* you might use traversal, see :doc:`muchadoabouttraversal`. A :term:`traversal` uses the URL (Universal Resource Locator) to find a -:term:`resource` located in a :term:`resource tree`, which is a set of -nested dictionary-like objects. Traversal is done by using each segment -of the path portion of the URL to navigate through the :term:`resource -tree`. You might think of this as looking up files and directories in a -file system. Traversal walks down the path until it finds a published -resource, analogous to a file system "directory" or "file". The -resource found as the result of a traversal becomes the -:term:`context` of the :term:`request`. Then, the :term:`view lookup` -subsystem is used to find some view code willing to "publish" this +:term:`resource` located in a :term:`resource tree`, which is a set of nested +dictionary-like objects. Traversal is done by using each segment of the path +portion of the URL to navigate through the :term:`resource tree`. You might +think of this as looking up files and directories in a file system. Traversal +walks down the path until it finds a published resource, analogous to a file +system "directory" or "file". The resource found as the result of a traversal +becomes the :term:`context` of the :term:`request`. Then, the :term:`view +lookup` subsystem is used to find some view code willing to "publish" this resource by generating a :term:`response`. .. note:: Using :term:`Traversal` to map a URL to code is optional. If you're creating - your first Pyramid application it probably makes more sense to use :term:`URL - dispatch` to map URLs to code instead of traversal, as new Pyramid developers - tend to find URL dispatch slightly easier to understand. If you use URL - dispatch, you needn't read this chapter. + your first Pyramid application, it probably makes more sense to use + :term:`URL dispatch` to map URLs to code instead of traversal, as new Pyramid + developers tend to find URL dispatch slightly easier to understand. If you + use URL dispatch, you needn't read this chapter. .. index:: single: traversal details @@ -36,33 +34,32 @@ resource by generating a :term:`response`. Traversal Details ----------------- -:term:`Traversal` is dependent on information in a :term:`request` -object. Every :term:`request` object contains URL path information in -the ``PATH_INFO`` portion of the :term:`WSGI` environment. The -``PATH_INFO`` string is the portion of a request's URL following the -hostname and port number, but before any query string elements or -fragment element. For example the ``PATH_INFO`` portion of the URL -``http://example.com:8080/a/b/c?foo=1`` is ``/a/b/c``. +:term:`Traversal` is dependent on information in a :term:`request` object. +Every :term:`request` object contains URL path information in the ``PATH_INFO`` +portion of the :term:`WSGI` environment. The ``PATH_INFO`` string is the +portion of a request's URL following the hostname and port number, but before +any query string elements or fragment element. For example the ``PATH_INFO`` +portion of the URL ``http://example.com:8080/a/b/c?foo=1`` is ``/a/b/c``. -Traversal treats the ``PATH_INFO`` segment of a URL as a sequence of -path segments. For example, the ``PATH_INFO`` string ``/a/b/c`` is -converted to the sequence ``['a', 'b', 'c']``. +Traversal treats the ``PATH_INFO`` segment of a URL as a sequence of path +segments. For example, the ``PATH_INFO`` string ``/a/b/c`` is converted to the +sequence ``['a', 'b', 'c']``. -This path sequence is then used to descend through the :term:`resource -tree`, looking up a resource for each path segment. Each lookup uses the +This path sequence is then used to descend through the :term:`resource tree`, +looking up a resource for each path segment. Each lookup uses the ``__getitem__`` method of a resource in the tree. For example, if the path info sequence is ``['a', 'b', 'c']``: - :term:`Traversal` starts by acquiring the :term:`root` resource of the - application by calling the :term:`root factory`. The :term:`root factory` - can be configured to return whatever object is appropriate as the - traversal root of your application. + application by calling the :term:`root factory`. The :term:`root factory` can + be configured to return whatever object is appropriate as the traversal root + of your application. -- Next, the first element (``'a'``) is popped from the path segment - sequence and is used as a key to lookup the corresponding resource - in the root. This invokes the root resource's ``__getitem__`` method - using that value (``'a'``) as an argument. +- Next, the first element (``'a'``) is popped from the path segment sequence + and is used as a key to lookup the corresponding resource in the root. This + invokes the root resource's ``__getitem__`` method using that value (``'a'``) + as an argument. - If the root resource "contains" a resource with key ``'a'``, its ``__getitem__`` method will return it. The :term:`context` temporarily @@ -72,29 +69,26 @@ For example, if the path info sequence is ``['a', 'b', 'c']``: resource's ``__getitem__`` is called with that value (``'b'``) as an argument; we'll presume it succeeds. -- The "A" resource's ``__getitem__`` returns another resource, which - we'll call "B". The :term:`context` temporarily becomes the "B" - resource. +- The "A" resource's ``__getitem__`` returns another resource, which we'll call + "B". The :term:`context` temporarily becomes the "B" resource. -Traversal continues until the path segment sequence is exhausted or a -path element cannot be resolved to a resource. In either case, the -:term:`context` resource is the last object that the traversal -successfully resolved. If any resource found during traversal lacks a -``__getitem__`` method, or if its ``__getitem__`` method raises a -:exc:`KeyError`, traversal ends immediately, and that resource becomes -the :term:`context`. +Traversal continues until the path segment sequence is exhausted or a path +element cannot be resolved to a resource. In either case, the :term:`context` +resource is the last object that the traversal successfully resolved. If any +resource found during traversal lacks a ``__getitem__`` method, or if its +``__getitem__`` method raises a :exc:`KeyError`, traversal ends immediately, +and that resource becomes the :term:`context`. The results of a :term:`traversal` also include a :term:`view name`. If -traversal ends before the path segment sequence is exhausted, the -:term:`view name` is the *next* remaining path segment element. If the -:term:`traversal` expends all of the path segments, then the :term:`view -name` is the empty string (``''``). +traversal ends before the path segment sequence is exhausted, the :term:`view +name` is the *next* remaining path segment element. If the :term:`traversal` +expends all of the path segments, then the :term:`view name` is the empty +string (``''``). -The combination of the context resource and the :term:`view name` found -via traversal is used later in the same request by the :term:`view -lookup` subsystem to find a :term:`view callable`. How :app:`Pyramid` -performs view lookup is explained within the :ref:`view_config_chapter` -chapter. +The combination of the context resource and the :term:`view name` found via +traversal is used later in the same request by the :term:`view lookup` +subsystem to find a :term:`view callable`. How :app:`Pyramid` performs view +lookup is explained within the :ref:`view_config_chapter` chapter. .. index:: single: object tree @@ -106,20 +100,20 @@ chapter. The Resource Tree ----------------- -The resource tree is a set of nested dictionary-like resource objects -that begins with a :term:`root` resource. In order to use -:term:`traversal` to resolve URLs to code, your application must supply -a :term:`resource tree` to :app:`Pyramid`. +The resource tree is a set of nested dictionary-like resource objects that +begins with a :term:`root` resource. In order to use :term:`traversal` to +resolve URLs to code, your application must supply a :term:`resource tree` to +:app:`Pyramid`. In order to supply a root resource for an application the :app:`Pyramid` -:term:`Router` is configured with a callback known as a :term:`root -factory`. The root factory is supplied by the application, at startup -time, as the ``root_factory`` argument to the :term:`Configurator`. +:term:`Router` is configured with a callback known as a :term:`root factory`. +The root factory is supplied by the application at startup time as the +``root_factory`` argument to the :term:`Configurator`. -The root factory is a Python callable that accepts a :term:`request` -object, and returns the root object of the :term:`resource tree`. A -function, or class is typically used as an application's root factory. -Here's an example of a simple root factory class: +The root factory is a Python callable that accepts a :term:`request` object, +and returns the root object of the :term:`resource tree`. A function or class +is typically used as an application's root factory. Here's an example of a +simple root factory class: .. code-block:: python :linenos: @@ -136,62 +130,60 @@ passing it to an instance of a :term:`Configurator` named ``config``: config = Configurator(root_factory=Root) -The ``root_factory`` argument to the -:class:`~pyramid.config.Configurator` constructor registers this root -factory to be called to generate a root resource whenever a request -enters the application. The root factory registered this way is also -known as the global root factory. A root factory can alternately be -passed to the ``Configurator`` as a :term:`dotted Python name` which can -refer to a root factory defined in a different module. +The ``root_factory`` argument to the :class:`~pyramid.config.Configurator` +constructor registers this root factory to be called to generate a root +resource whenever a request enters the application. The root factory +registered this way is also known as the global root factory. A root factory +can alternatively be passed to the ``Configurator`` as a :term:`dotted Python +name` which can refer to a root factory defined in a different module. -If no :term:`root factory` is passed to the :app:`Pyramid` -:term:`Configurator` constructor, or if the ``root_factory`` value -specified is ``None``, a :term:`default root factory` is used. The default -root factory always returns a resource that has no child resources; it -is effectively empty. +If no :term:`root factory` is passed to the :app:`Pyramid` :term:`Configurator` +constructor, or if the ``root_factory`` value specified is ``None``, a +:term:`default root factory` is used. The default root factory always returns +a resource that has no child resources; it is effectively empty. Usually a root factory for a traversal-based application will be more -complicated than the above ``Root`` class; in particular it may be associated +complicated than the above ``Root`` class. In particular it may be associated with a database connection or another persistence mechanism. The above ``Root`` class is analogous to the default root factory present in Pyramid. The default root factory is very simple and not very useful. .. note:: - If the items contained within the resource tree are "persistent" (they - have state that lasts longer than the execution of a single process), they - become analogous to the concept of :term:`domain model` objects used by - many other frameworks. + If the items contained within the resource tree are "persistent" (they have + state that lasts longer than the execution of a single process), they become + analogous to the concept of :term:`domain model` objects used by many other + frameworks. -The resource tree consists of *container* resources and *leaf* resources. -There is only one difference between a *container* resource and a *leaf* -resource: *container* resources possess a ``__getitem__`` method (making it +The resource tree consists of *container* resources and *leaf* resources. There +is only one difference between a *container* resource and a *leaf* resource: +*container* resources possess a ``__getitem__`` method (making it "dictionary-like") while *leaf* resources do not. The ``__getitem__`` method was chosen as the signifying difference between the two types of resources because the presence of this method is how Python itself typically determines whether an object is "containerish" or not (dictionary objects are "containerish"). -Each container resource is presumed to be willing to return a child resource -or raise a ``KeyError`` based on a name passed to its ``__getitem__``. +Each container resource is presumed to be willing to return a child resource or +raise a ``KeyError`` based on a name passed to its ``__getitem__``. -Leaf-level instances must not have a ``__getitem__``. If instances that -you'd like to be leaves already happen to have a ``__getitem__`` through some +Leaf-level instances must not have a ``__getitem__``. If instances that you'd +like to be leaves already happen to have a ``__getitem__`` through some historical inequity, you should subclass these resource types and cause their ``__getitem__`` methods to simply raise a ``KeyError``. Or just disuse them and think up another strategy. -Usually, the traversal root is a *container* resource, and as such it -contains other resources. However, it doesn't *need* to be a container. -Your resource tree can be as shallow or as deep as you require. +Usually the traversal root is a *container* resource, and as such it contains +other resources. However, it doesn't *need* to be a container. Your resource +tree can be as shallow or as deep as you require. -In general, the resource tree is traversed beginning at its root resource -using a sequence of path elements described by the ``PATH_INFO`` of the -current request; if there are path segments, the root resource's -``__getitem__`` is called with the next path segment, and it is expected to -return another resource. The resulting resource's ``__getitem__`` is called -with the very next path segment, and it is expected to return another -resource. This happens *ad infinitum* until all path segments are exhausted. +In general, the resource tree is traversed beginning at its root resource using +a sequence of path elements described by the ``PATH_INFO`` of the current +request. If there are path segments, the root resource's ``__getitem__`` is +called with the next path segment, and it is expected to return another +resource. The resulting resource's ``__getitem__`` is called with the very +next path segment, and it is expected to return another resource. This happens +*ad infinitum* until all path segments are exhausted. .. index:: single: traversal algorithm @@ -204,17 +196,17 @@ The Traversal Algorithm This section will attempt to explain the :app:`Pyramid` traversal algorithm. We'll provide a description of the algorithm, a diagram of how the algorithm -works, and some example traversal scenarios that might help you understand -how the algorithm operates against a specific resource tree. +works, and some example traversal scenarios that might help you understand how +the algorithm operates against a specific resource tree. We'll also talk a bit about :term:`view lookup`. The -:ref:`view_config_chapter` chapter discusses :term:`view lookup` in -detail, and it is the canonical source for information about views. -Technically, :term:`view lookup` is a :app:`Pyramid` subsystem that is -separated from traversal entirely. However, we'll describe the -fundamental behavior of view lookup in the examples in the next few -sections to give you an idea of how traversal and view lookup cooperate, -because they are almost always used together. +:ref:`view_config_chapter` chapter discusses :term:`view lookup` in detail, and +it is the canonical source for information about views. Technically, +:term:`view lookup` is a :app:`Pyramid` subsystem that is separated from +traversal entirely. However, we'll describe the fundamental behavior of view +lookup in the examples in the next few sections to give you an idea of how +traversal and view lookup cooperate, because they are almost always used +together. .. index:: single: view name @@ -223,26 +215,24 @@ because they are almost always used together. single: root factory single: default view -A Description of The Traversal Algorithm +A Description of the Traversal Algorithm ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a user requests a page from your traversal-powered application, the -system uses this algorithm to find a :term:`context` resource and a -:term:`view name`. +When a user requests a page from your traversal-powered application, the system +uses this algorithm to find a :term:`context` resource and a :term:`view name`. -#. The request for the page is presented to the :app:`Pyramid` - :term:`router` in terms of a standard :term:`WSGI` request, which is - represented by a WSGI environment and a WSGI ``start_response`` callable. +#. The request for the page is presented to the :app:`Pyramid` :term:`router` + in terms of a standard :term:`WSGI` request, which is represented by a WSGI + environment and a WSGI ``start_response`` callable. -#. The router creates a :term:`request` object based on the WSGI - environment. +#. The router creates a :term:`request` object based on the WSGI environment. -#. The :term:`root factory` is called with the :term:`request`. It returns - a :term:`root` resource. +#. The :term:`root factory` is called with the :term:`request`. It returns a + :term:`root` resource. #. The router uses the WSGI environment's ``PATH_INFO`` information to - determine the path segments to traverse. The leading slash is stripped - off ``PATH_INFO``, and the remaining path segments are split on the slash + determine the path segments to traverse. The leading slash is stripped off + ``PATH_INFO``, and the remaining path segments are split on the slash character to form a traversal sequence. The traversal algorithm by default attempts to first URL-unquote and then @@ -252,26 +242,26 @@ system uses this algorithm to find a :term:`context` resource and a Conversion from a URL-decoded string into Unicode is attempted using the UTF-8 encoding. If any URL-unquoted path segment in ``PATH_INFO`` is not decodeable using the UTF-8 decoding, a :exc:`TypeError` is raised. A - segment will be fully URL-unquoted and UTF8-decoded before it is passed - in to the ``__getitem__`` of any resource during traversal. + segment will be fully URL-unquoted and UTF8-decoded before it is passed in + to the ``__getitem__`` of any resource during traversal. - Thus, a request with a ``PATH_INFO`` variable of ``/a/b/c`` maps to the + Thus a request with a ``PATH_INFO`` variable of ``/a/b/c`` maps to the traversal sequence ``[u'a', u'b', u'c']``. -#. :term:`Traversal` begins at the root resource returned by the root - factory. For the traversal sequence ``[u'a', u'b', u'c']``, the root - resource's ``__getitem__`` is called with the name ``'a'``. Traversal - continues through the sequence. In our example, if the root resource's - ``__getitem__`` called with the name ``a`` returns a resource (aka +#. :term:`Traversal` begins at the root resource returned by the root factory. + For the traversal sequence ``[u'a', u'b', u'c']``, the root resource's + ``__getitem__`` is called with the name ``'a'``. Traversal continues + through the sequence. In our example, if the root resource's + ``__getitem__`` called with the name ``a`` returns a resource (a.k.a. resource "A"), that resource's ``__getitem__`` is called with the name ``'b'``. If resource "A" returns a resource "B" when asked for ``'b'``, resource B's ``__getitem__`` is then asked for the name ``'c'``, and may return resource "C". -#. Traversal ends when a) the entire path is exhausted or b) when any - resource raises a :exc:`KeyError` from its ``__getitem__`` or c) when any +#. Traversal ends when either (a) the entire path is exhausted, (b) when any + resource raises a :exc:`KeyError` from its ``__getitem__``, (c) when any non-final path element traversal does not have a ``__getitem__`` method - (resulting in a :exc:`AttributeError`) or d) when any path element is + (resulting in an :exc:`AttributeError`), or (d) when any path element is prefixed with the set of characters ``@@`` (indicating that the characters following the ``@@`` token should be treated as a :term:`view name`). @@ -279,13 +269,13 @@ system uses this algorithm to find a :term:`context` resource and a resource found during traversal is deemed to be the :term:`context`. If the path has been exhausted when traversal ends, the :term:`view name` is deemed to be the empty string (``''``). However, if the path was *not* - exhausted before traversal terminated, the first remaining path segment - is treated as the view name. + exhausted before traversal terminated, the first remaining path segment is + treated as the view name. #. Any subsequent path elements after the :term:`view name` is found are deemed the :term:`subpath`. The subpath is always a sequence of path - segments that come from ``PATH_INFO`` that are "left over" after - traversal has completed. + segments that come from ``PATH_INFO`` that are "left over" after traversal + has completed. Once the :term:`context` resource, the :term:`view name`, and associated attributes such as the :term:`subpath` are located, the job of @@ -297,20 +287,19 @@ The traversal algorithm exposes two special cases: - You will often end up with a :term:`view name` that is the empty string as the result of a particular traversal. This indicates that the view lookup - machinery should look up the :term:`default view`. The default view is a - view that is registered with no name or a view which is registered with a - name that equals the empty string. + machinery should lookup the :term:`default view`. The default view is a view + that is registered with no name or a view which is registered with a name + that equals the empty string. -- If any path segment element begins with the special characters ``@@`` - (think of them as goggles), the value of that segment minus the goggle - characters is considered the :term:`view name` immediately and traversal - stops there. This allows you to address views that may have the same names - as resource names in the tree unambiguously. +- If any path segment element begins with the special characters ``@@`` (think + of them as goggles), the value of that segment minus the goggle characters is + considered the :term:`view name` immediately and traversal stops there. This + allows you to address views that may have the same names as resource names in + the tree unambiguously. Finally, traversal is responsible for locating a :term:`virtual root`. A -virtual root is used during "virtual hosting"; see the -:ref:`vhosting_chapter` chapter for information. We won't speak more about -it in this chapter. +virtual root is used during "virtual hosting". See the :ref:`vhosting_chapter` +chapter for information. We won't speak more about it in this chapter. .. image:: resourcetreetraverser.png @@ -321,13 +310,13 @@ Traversal Algorithm Examples ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ No one can be expected to understand the traversal algorithm by analogy and -description alone, so let's examine some traversal scenarios that use -concrete URLs and resource tree compositions. +description alone, so let's examine some traversal scenarios that use concrete +URLs and resource tree compositions. -Let's pretend the user asks for -``http://example.com/foo/bar/baz/biz/buz.txt``. The request's ``PATH_INFO`` -in that case is ``/foo/bar/baz/biz/buz.txt``. Let's further pretend that -when this request comes in that we're traversing the following resource tree: +Let's pretend the user asks for ``http://example.com/foo/bar/baz/biz/buz.txt``. +The request's ``PATH_INFO`` in that case is ``/foo/bar/baz/biz/buz.txt``. +Let's further pretend that when this request comes in, we're traversing the +following resource tree: .. code-block:: text @@ -346,33 +335,32 @@ Here's what happens: finds. - :term:`traversal` traverses "bar", and attempts to find "baz", which it does - not find (the "bar" resource raises a :exc:`KeyError` when asked for - "baz"). + not find (the "bar" resource raises a :exc:`KeyError` when asked for "baz"). The fact that it does not find "baz" at this point does not signify an error -condition. It signifies that: +condition. It signifies the following: -- the :term:`context` is the "bar" resource (the context is the last resource +- The :term:`context` is the "bar" resource (the context is the last resource found during traversal). -- the :term:`view name` is ``baz`` +- The :term:`view name` is ``baz``. -- the :term:`subpath` is ``('biz', 'buz.txt')`` +- The :term:`subpath` is ``('biz', 'buz.txt')``. At this point, traversal has ended, and :term:`view lookup` begins. Because it's the "context" resource, the view lookup machinery examines "bar" -to find out what "type" it is. Let's say it finds that the context is a -``Bar`` type (because "bar" happens to be an instance of the class ``Bar``). -Using the :term:`view name` (``baz``) and the type, view lookup asks the +to find out what "type" it is. Let's say it finds that the context is a ``Bar`` +type (because "bar" happens to be an instance of the class ``Bar``). Using the +:term:`view name` (``baz``) and the type, view lookup asks the :term:`application registry` this question: - Please find me a :term:`view callable` registered using a :term:`view configuration` with the name "baz" that can be used for the class ``Bar``. -Let's say that view lookup finds no matching view type. In this -circumstance, the :app:`Pyramid` :term:`router` returns the result of the -:term:`Not Found View` and the request ends. +Let's say that view lookup finds no matching view type. In this circumstance, +the :app:`Pyramid` :term:`router` returns the result of the :term:`Not Found +View` and the request ends. However, for this tree: @@ -399,59 +387,58 @@ The user asks for ``http://example.com/foo/bar/baz/biz/buz.txt`` - :term:`traversal` traverses "baz", and attempts to find "biz", which it finds. -- :term:`traversal` traverses "biz", and attempts to find "buz.txt" which it +- :term:`traversal` traverses "biz", and attempts to find "buz.txt", which it does not find. The fact that it does not find a resource related to "buz.txt" at this point -does not signify an error condition. It signifies that: +does not signify an error condition. It signifies the following: -- the :term:`context` is the "biz" resource (the context is the last resource +- The :term:`context` is the "biz" resource (the context is the last resource found during traversal). -- the :term:`view name` is "buz.txt" +- The :term:`view name` is "buz.txt". -- the :term:`subpath` is an empty sequence ( ``()`` ). +- The :term:`subpath` is an empty sequence ( ``()`` ). At this point, traversal has ended, and :term:`view lookup` begins. Because it's the "context" resource, the view lookup machinery examines the "biz" resource to find out what "type" it is. Let's say it finds that the resource is a ``Biz`` type (because "biz" is an instance of the Python class -``Biz``). Using the :term:`view name` (``buz.txt``) and the type, view -lookup asks the :term:`application registry` this question: +``Biz``). Using the :term:`view name` (``buz.txt``) and the type, view lookup +asks the :term:`application registry` this question: - Please find me a :term:`view callable` registered with a :term:`view - configuration` with the name ``buz.txt`` that can be used for class - ``Biz``. + configuration` with the name ``buz.txt`` that can be used for class ``Biz``. -Let's say that question is answered by the application registry; in such a -situation, the application registry returns a :term:`view callable`. The -view callable is then called with the current :term:`WebOb` :term:`request` -as the sole argument: ``request``; it is expected to return a response. +Let's say that question is answered by the application registry. In such a +situation, the application registry returns a :term:`view callable`. The view +callable is then called with the current :term:`WebOb` :term:`request` as the +sole argument, ``request``. It is expected to return a response. -.. sidebar:: The Example View Callables Accept Only a Request; How Do I Access the Context Resource? +.. sidebar:: The Example View Callables Accept Only a Request; How Do I Access + the Context Resource? - Most of the examples in this book assume that a view callable is typically - passed only a :term:`request` object. Sometimes your view callables need - access to the :term:`context` resource, especially when you use - :term:`traversal`. You might use a supported alternate view callable + Most of the examples in this documentation assume that a view callable is + typically passed only a :term:`request` object. Sometimes your view + callables need access to the :term:`context` resource, especially when you + use :term:`traversal`. You might use a supported alternative view callable argument list in your view callables such as the ``(context, request)`` - calling convention described in - :ref:`request_and_context_view_definitions`. But you don't need to if you - don't want to. In view callables that accept only a request, the - :term:`context` resource found by traversal is available as the - ``context`` attribute of the request object, e.g. ``request.context``. - The :term:`view name` is available as the ``view_name`` attribute of the - request object, e.g. ``request.view_name``. Other :app:`Pyramid` - -specific request attributes are also available as described in - :ref:`special_request_attributes`. + calling convention described in :ref:`request_and_context_view_definitions`. + But you don't need to if you don't want to. In view callables that accept + only a request, the :term:`context` resource found by traversal is available + as the ``context`` attribute of the request object, e.g., + ``request.context``. The :term:`view name` is available as the ``view_name`` + attribute of the request object, e.g., ``request.view_name``. Other + :app:`Pyramid`-specific request attributes are also available as described + in :ref:`special_request_attributes`. .. index:: single: resource interfaces .. _using_resource_interfaces: -Using Resource Interfaces In View Configuration +Using Resource Interfaces in View Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Instead of registering your views with a ``context`` that names a Python @@ -460,18 +447,17 @@ resource *class*, you can optionally register a view callable with a arbitrarily to any resource object. View lookup treats context interfaces specially, and therefore the identity of a resource can be divorced from that of the class which implements it. As a result, associating a view with an -interface can provide more flexibility for sharing a single view between two -or more different implementations of a resource type. For example, if two -resource objects of different Python class types share the same interface, -you can use the same view configuration to specify both of them as a -``context``. +interface can provide more flexibility for sharing a single view between two or +more different implementations of a resource type. For example, if two +resource objects of different Python class types share the same interface, you +can use the same view configuration to specify both of them as a ``context``. In order to make use of interfaces in your application during view dispatch, you must create an interface and mark up your resource classes or instances with interface declarations that refer to this interface. -To attach an interface to a resource *class*, you define the interface and -use the :func:`zope.interface.implementer` class decorator to associate the +To attach an interface to a resource *class*, you define the interface and use +the :func:`zope.interface.implementer` class decorator to associate the interface with the class. .. code-block:: python @@ -488,9 +474,9 @@ interface with the class. pass To attach an interface to a resource *instance*, you define the interface and -use the :func:`zope.interface.alsoProvides` function to associate the -interface with the instance. This function mutates the instance in such a -way that the interface is attached to it. +use the :func:`zope.interface.alsoProvides` function to associate the interface +with the instance. This function mutates the instance in such a way that the +interface is attached to it. .. code-block:: python :linenos: @@ -509,13 +495,13 @@ way that the interface is attached to it. alsoProvides(hello, IHello) return hello -Regardless of how you associate an interface, with a resource instance, or a -resource class, the resulting code to associate that interface with a view +Regardless of how you associate an interface—with either a resource instance +or a resource class—the resulting code to associate that interface with a view callable is the same. Assuming the above code that defines an ``IHello`` interface lives in the root of your application, and its module is named "resources.py", the interface declaration below will associate the -``mypackage.views.hello_world`` view with resources that implement, or -provide, this interface. +``mypackage.views.hello_world`` view with resources that implement, or provide, +this interface. .. code-block:: python :linenos: @@ -525,20 +511,18 @@ provide, this interface. config.add_view('mypackage.views.hello_world', name='hello.html', context='mypackage.resources.IHello') -Any time a resource that is determined to be the :term:`context` provides -this interface, and a view named ``hello.html`` is looked up against it as -per the URL, the ``mypackage.views.hello_world`` view callable will be -invoked. - -Note, in cases where a view is registered against a resource class, and a -view is also registered against an interface that the resource class -implements, an ambiguity arises. Views registered for the resource class take -precedence over any views registered for any interface the resource class -implements. Thus, if one view configuration names a ``context`` of both the -class type of a resource, and another view configuration names a ``context`` -of interface implemented by the resource's class, and both view -configurations are otherwise identical, the view registered for the context's -class will "win". +Any time a resource that is determined to be the :term:`context` provides this +interface, and a view named ``hello.html`` is looked up against it as per the +URL, the ``mypackage.views.hello_world`` view callable will be invoked. + +Note, in cases where a view is registered against a resource class, and a view +is also registered against an interface that the resource class implements, an +ambiguity arises. Views registered for the resource class take precedence over +any views registered for any interface the resource class implements. Thus, if +one view configuration names a ``context`` of both the class type of a +resource, and another view configuration names a ``context`` of interface +implemented by the resource's class, and both view configurations are otherwise +identical, the view registered for the context's class will "win". For more information about defining resources with interfaces for use within view configuration, see :ref:`resources_which_implement_interfaces`. @@ -558,4 +542,3 @@ traversal, such as traversal invocation from within application code. The :meth:`pyramid.request.Request.resource_url` method generates a URL when given a resource retrieved from a resource tree. - -- cgit v1.2.3 From 4429b543d97712dbec1ce10e3489385ff16a3639 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 27 Oct 2015 12:23:15 -0400 Subject: Restore link target used by 'whatsnew-1.3.rst'. Should fix Jenkins breakage. --- docs/narr/commandline.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 430641a50..eb79dffb6 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -261,6 +261,8 @@ request is configured to generate urls from the host >>> request.route_url('home') 'https://www.example.com/' +.. _ipython_or_bpython: + Alternative Shells ~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From f3d20e19807bc1a86acccdd74cff10698d249350 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 28 Oct 2015 23:42:12 -0700 Subject: minor grammar, rewrap 79 columns, some .rst syntax fixes, add a header and index entry --- docs/narr/subrequest.rst | 152 ++++++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 74 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 4b4e99d41..13b00efb6 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -41,23 +41,22 @@ Here's an example application which uses a subrequest: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -When ``/view_one`` is visted in a browser, the text printed in the browser -pane will be ``This came from view_two``. The ``view_one`` view used the -:meth:`pyramid.request.Request.invoke_subrequest` API to obtain a response -from another view (``view_two``) within the same application when it -executed. It did so by constructing a new request that had a URL that it -knew would match the ``view_two`` view registration, and passed that new -request along to :meth:`pyramid.request.Request.invoke_subrequest`. The -``view_two`` view callable was invoked, and it returned a response. The -``view_one`` view callable then simply returned the response it obtained from -the ``view_two`` view callable. +When ``/view_one`` is visted in a browser, the text printed in the browser pane +will be ``This came from view_two``. The ``view_one`` view used the +:meth:`pyramid.request.Request.invoke_subrequest` API to obtain a response from +another view (``view_two``) within the same application when it executed. It +did so by constructing a new request that had a URL that it knew would match +the ``view_two`` view registration, and passed that new request along to +:meth:`pyramid.request.Request.invoke_subrequest`. The ``view_two`` view +callable was invoked, and it returned a response. The ``view_one`` view +callable then simply returned the response it obtained from the ``view_two`` +view callable. Note that it doesn't matter if the view callable invoked via a subrequest actually returns a *literal* Response object. Any view callable that uses a renderer or which returns an object that can be interpreted by a response adapter when found and invoked via -:meth:`pyramid.request.Request.invoke_subrequest` will return a Response -object: +:meth:`pyramid.request.Request.invoke_subrequest` will return a Response object: .. code-block:: python @@ -83,19 +82,19 @@ object: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -Even though the ``view_two`` view callable returned a string, it was invoked -in such a way that the ``string`` renderer associated with the view -registration that was found turned it into a "real" response object for -consumption by ``view_one``. +Even though the ``view_two`` view callable returned a string, it was invoked in +such a way that the ``string`` renderer associated with the view registration +that was found turned it into a "real" response object for consumption by +``view_one``. Being able to unconditionally obtain a response object by invoking a view callable indirectly is the main advantage to using -:meth:`pyramid.request.Request.invoke_subrequest` instead of simply importing -a view callable and executing it directly. Note that there's not much -advantage to invoking a view using a subrequest if you *can* invoke a view -callable directly. Subrequests are slower and are less convenient if you -actually do want just the literal information returned by a function that -happens to be a view callable. +:meth:`pyramid.request.Request.invoke_subrequest` instead of simply importing a +view callable and executing it directly. Note that there's not much advantage +to invoking a view using a subrequest if you *can* invoke a view callable +directly. Subrequests are slower and are less convenient if you actually do +want just the literal information returned by a function that happens to be a +view callable. Note that, by default, if a view callable invoked by a subrequest raises an exception, the exception will be raised to the caller of @@ -136,15 +135,21 @@ When we run the above code and visit ``/view_one`` in a browser, the ``excview`` :term:`exception view` will *not* be executed. Instead, the call to :meth:`~pyramid.request.Request.invoke_subrequest` will cause a :exc:`ValueError` exception to be raised and a response will never be -generated. We can change this behavior; how to do so is described below in -our discussion of the ``use_tweens`` argument. +generated. We can change this behavior; how to do so is described below in our +discussion of the ``use_tweens`` argument. + +.. index:: + pair: subrequest; use_tweens + +Subrequests with Tweens +----------------------- The :meth:`pyramid.request.Request.invoke_subrequest` API accepts two -arguments: a positional argument ``request`` that must be provided, and -``use_tweens`` keyword argument that is optional; it defaults to ``False``. +arguments: a required positional argument ``request``, and an optional keyword +argument ``use_tweens`` which defaults to ``False``. -The ``request`` object passed to the API must be an object that implements -the Pyramid request interface (such as a :class:`pyramid.request.Request` +The ``request`` object passed to the API must be an object that implements the +Pyramid request interface (such as a :class:`pyramid.request.Request` instance). If ``use_tweens`` is ``True``, the request will be sent to the :term:`tween` in the tween stack closest to the request ingress. If ``use_tweens`` is ``False``, the request will be sent to the main router @@ -153,9 +158,9 @@ handler, and no tweens will be invoked. In the example above, the call to :meth:`~pyramid.request.Request.invoke_subrequest` will always raise an exception. This is because it's using the default value for ``use_tweens``, -which is ``False``. You can pass ``use_tweens=True`` instead to ensure that -it will convert an exception to a Response if an :term:`exception view` is -configured instead of raising the exception. This is because exception views +which is ``False``. Alternatively, you can pass ``use_tweens=True`` to ensure +that it will convert an exception to a Response if an :term:`exception view` is +configured, instead of raising the exception. This is because exception views are called by the exception view :term:`tween` as described in :ref:`exception_views` when any view raises an exception. @@ -199,71 +204,70 @@ attempted invocation of ``view_two``, because the tween which invokes an exception view to generate a response is run, and therefore ``excview`` is executed. -This is one of the major differences between specifying the -``use_tweens=True`` and ``use_tweens=False`` arguments to +This is one of the major differences between specifying the ``use_tweens=True`` +and ``use_tweens=False`` arguments to :meth:`~pyramid.request.Request.invoke_subrequest`. ``use_tweens=True`` may -also imply invoking transaction commit/abort for the logic executed in the -subrequest if you've got ``pyramid_tm`` in the tween list, injecting debug -HTML if you've got ``pyramid_debugtoolbar`` in the tween list, and other +also imply invoking a transaction commit or abort for the logic executed in the +subrequest if you've got ``pyramid_tm`` in the tween list, injecting debug HTML +if you've got ``pyramid_debugtoolbar`` in the tween list, and other tween-related side effects as defined by your particular tween list. The :meth:`~pyramid.request.Request.invoke_subrequest` function also -unconditionally: - -- manages the threadlocal stack so that +unconditionally does the following: + +- It manages the threadlocal stack so that :func:`~pyramid.threadlocal.get_current_request` and - :func:`~pyramid.threadlocal.get_current_registry` work during a request - (they will return the subrequest instead of the original request) + :func:`~pyramid.threadlocal.get_current_registry` work during a request (they + will return the subrequest instead of the original request). -- Adds a ``registry`` attribute and a ``invoke_subrequest`` attribute (a - callable) to the request object it's handed. +- It adds a ``registry`` attribute and an ``invoke_subrequest`` attribute (a + callable) to the request object to which it is handed. -- sets request extensions (such as those added via +- It sets request extensions (such as those added via :meth:`~pyramid.config.Configurator.add_request_method` or :meth:`~pyramid.config.Configurator.set_request_property`) on the subrequest - object passed as ``request`` + object passed as ``request``. -- causes a :class:`~pyramid.events.NewRequest` event to be sent at the +- It causes a :class:`~pyramid.events.NewRequest` event to be sent at the beginning of request processing. -- causes a :class:`~pyramid.events.ContextFound` event to be sent when a +- It causes a :class:`~pyramid.events.ContextFound` event to be sent when a context resource is found. -- Ensures that the user implied by the request passed has the necessary - authorization to invoke view callable before calling it. +- It ensures that the user implied by the request passed in has the necessary + authorization to invoke the view callable before calling it. -- Calls any :term:`response callback` functions defined within the subrequest's - lifetime if a response is obtained from the Pyramid application. +- It calls any :term:`response callback` functions defined within the + subrequest's lifetime if a response is obtained from the Pyramid application. -- causes a :class:`~pyramid.events.NewResponse` event to be sent if a response - is obtained. +- It causes a :class:`~pyramid.events.NewResponse` event to be sent if a + response is obtained. -- Calls any :term:`finished callback` functions defined within the subrequest's - lifetime. +- It calls any :term:`finished callback` functions defined within the + subrequest's lifetime. -The invocation of a subrequest has more or less exactly the same effect as -the invocation of a request received by the Pyramid router from a web client +The invocation of a subrequest has more or less exactly the same effect as the +invocation of a request received by the :app:`Pyramid` router from a web client when ``use_tweens=True``. When ``use_tweens=False``, the tweens are skipped but all the other steps take place. It's a poor idea to use the original ``request`` object as an argument to -:meth:`~pyramid.request.Request.invoke_subrequest`. You should construct a -new request instead as demonstrated in the above example, using +:meth:`~pyramid.request.Request.invoke_subrequest`. You should construct a new +request instead as demonstrated in the above example, using :meth:`pyramid.request.Request.blank`. Once you've constructed a request -object, you'll need to massage it to match the view callable you'd like -to be executed during the subrequest. This can be done by adjusting the +object, you'll need to massage it to match the view callable that you'd like to +be executed during the subrequest. This can be done by adjusting the subrequest's URL, its headers, its request method, and other attributes. The documentation for :class:`pyramid.request.Request` exposes the methods you -should call and attributes you should set on the request you create to -massage it into something that will actually match the view you'd like to -call via a subrequest. - -We've demonstrated use of a subrequest from within a view callable, but you -can use the :meth:`~pyramid.request.Request.invoke_subrequest` API from -within a tween or an event handler as well. It's usually a poor idea to -invoke :meth:`~pyramid.request.Request.invoke_subrequest` from within a -tween, because tweens already by definition have access to a function that -will cause a subrequest (they are passed a ``handle`` function), but you can -do it. It's fine to invoke -:meth:`~pyramid.request.Request.invoke_subrequest` from within an event -handler, however. +should call and attributes you should set on the request that you create, then +massage it into something that will actually match the view you'd like to call +via a subrequest. + +We've demonstrated use of a subrequest from within a view callable, but you can +use the :meth:`~pyramid.request.Request.invoke_subrequest` API from within a +tween or an event handler as well. Even though you can do it, it's usually a +poor idea to invoke :meth:`~pyramid.request.Request.invoke_subrequest` from +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. -- cgit v1.2.3 From 33b89f5853aef30dfe4546083c62735ed3f96ef4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 30 Oct 2015 01:06:30 -0700 Subject: add linenos and emphasize-lines to code examples --- docs/narr/subrequest.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/subrequest.rst b/docs/narr/subrequest.rst index 13b00efb6..02ae14aa5 100644 --- a/docs/narr/subrequest.rst +++ b/docs/narr/subrequest.rst @@ -17,6 +17,7 @@ application. Here's an example application which uses a subrequest: .. code-block:: python + :linenos: from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -56,9 +57,12 @@ Note that it doesn't matter if the view callable invoked via a subrequest actually returns a *literal* Response object. Any view callable that uses a renderer or which returns an object that can be interpreted by a response adapter when found and invoked via -:meth:`pyramid.request.Request.invoke_subrequest` will return a Response object: +:meth:`pyramid.request.Request.invoke_subrequest` will return a Response +object: .. code-block:: python + :linenos: + :emphasize-lines: 11 from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -102,6 +106,8 @@ exception, the exception will be raised to the caller of :term:`exception view` configured: .. code-block:: python + :linenos: + :emphasize-lines: 11-16 from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -169,6 +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 from wsgiref.simple_server import make_server from pyramid.config import Configurator -- cgit v1.2.3 From cf9bdf33f450493b4dae7d00ec7687a3ebf3d977 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 31 Oct 2015 03:47:38 -0700 Subject: minor grammar, rewrap to 79 columns --- docs/narr/security.rst | 438 +++++++++++++++++++++++-------------------------- 1 file changed, 206 insertions(+), 232 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/security.rst b/docs/narr/security.rst index 75f4dc7c5..7cbea113c 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -6,64 +6,59 @@ Security ======== -:app:`Pyramid` provides an optional, declarative, security system. -Security in :app:`Pyramid` is separated into authentication and -authorization. The two systems communicate via :term:`principal` -identifiers. Authentication is merely the mechanism by which credentials -provided in the :term:`request` are resolved to one or more -:term:`principal` identifiers. These identifiers represent the users and -groups that are in effect during the request. Authorization then determines -access based on the :term:`principal` identifiers, the requested +:app:`Pyramid` provides an optional, declarative, security system. Security in +:app:`Pyramid` is separated into authentication and authorization. The two +systems communicate via :term:`principal` identifiers. Authentication is merely +the mechanism by which credentials provided in the :term:`request` are resolved +to one or more :term:`principal` identifiers. These identifiers represent the +users and groups that are in effect during the request. Authorization then +determines access based on the :term:`principal` identifiers, the requested :term:`permission`, and a :term:`context`. -The :app:`Pyramid` authorization system -can prevent a :term:`view` from being invoked based on an -:term:`authorization policy`. Before a view is invoked, the -authorization system can use the credentials in the :term:`request` -along with the :term:`context` resource to determine if access will be -allowed. Here's how it works at a high level: +The :app:`Pyramid` authorization system can prevent a :term:`view` from being +invoked based on an :term:`authorization policy`. Before a view is invoked, the +authorization system can use the credentials in the :term:`request` along with +the :term:`context` resource to determine if access will be allowed. Here's +how it works at a high level: -- A user may or may not have previously visited the application and - supplied authentication credentials, including a :term:`userid`. If - so, the application may have called - :func:`pyramid.security.remember` to remember these. +- A user may or may not have previously visited the application and supplied + authentication credentials, including a :term:`userid`. If so, the + application may have called :func:`pyramid.security.remember` to remember + these. - A :term:`request` is generated when a user visits the application. - Based on the request, a :term:`context` resource is located through :term:`resource location`. A context is located differently depending on - whether the application uses :term:`traversal` or :term:`URL dispatch`, but - a context is ultimately found in either case. See - the :ref:`urldispatch_chapter` chapter for more information. + whether the application uses :term:`traversal` or :term:`URL dispatch`, but a + context is ultimately found in either case. See the + :ref:`urldispatch_chapter` chapter for more information. -- A :term:`view callable` is located by :term:`view lookup` using the - context as well as other attributes of the request. +- A :term:`view callable` is located by :term:`view lookup` using the context + as well as other attributes of the request. -- If an :term:`authentication policy` is in effect, it is passed the - request. It will return some number of :term:`principal` identifiers. - To do this, the policy would need to determine the authenticated - :term:`userid` present in the request. +- If an :term:`authentication policy` is in effect, it is passed the request. + It will return some number of :term:`principal` identifiers. To do this, the + policy would need to determine the authenticated :term:`userid` present in + the request. - If an :term:`authorization policy` is in effect and the :term:`view - configuration` associated with the view callable that was found has - a :term:`permission` associated with it, the authorization policy is - passed the :term:`context`, some number of :term:`principal` - identifiers returned by the authentication policy, and the - :term:`permission` associated with the view; it will allow or deny - access. + configuration` associated with the view callable that was found has a + :term:`permission` associated with it, the authorization policy is passed the + :term:`context`, some number of :term:`principal` identifiers returned by the + authentication policy, and the :term:`permission` associated with the view; + it will allow or deny access. -- If the authorization policy allows access, the view callable is - invoked. +- If the authorization policy allows access, the view callable is invoked. -- If the authorization policy denies access, the view callable is not - invoked; instead the :term:`forbidden view` is invoked. +- If the authorization policy denies access, the view callable is not invoked. + Instead the :term:`forbidden view` is invoked. Authorization is enabled by modifying your application to include an -:term:`authentication policy` and :term:`authorization policy`. -:app:`Pyramid` comes with a variety of implementations of these -policies. To provide maximal flexibility, :app:`Pyramid` also -allows you to create custom authentication policies and authorization -policies. +:term:`authentication policy` and :term:`authorization policy`. :app:`Pyramid` +comes with a variety of implementations of these policies. To provide maximal +flexibility, :app:`Pyramid` also allows you to create custom authentication +policies and authorization policies. .. index:: single: authorization policy @@ -73,23 +68,22 @@ policies. Enabling an Authorization Policy -------------------------------- -:app:`Pyramid` does not enable any authorization policy by default. All -views are accessible by completely anonymous users. In order to begin -protecting views from execution based on security settings, you need -to enable an authorization policy. +:app:`Pyramid` does not enable any authorization policy by default. All views +are accessible by completely anonymous users. In order to begin protecting +views from execution based on security settings, you need to enable an +authorization policy. Enabling an Authorization Policy Imperatively ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Use the :meth:`~pyramid.config.Configurator.set_authorization_policy` method -of the :class:`~pyramid.config.Configurator` to enable an authorization -policy. +Use the :meth:`~pyramid.config.Configurator.set_authorization_policy` method of +the :class:`~pyramid.config.Configurator` to enable an authorization policy. You must also enable an :term:`authentication policy` in order to enable the -authorization policy. This is because authorization, in general, depends -upon authentication. Use the -:meth:`~pyramid.config.Configurator.set_authentication_policy` method -during application setup to specify the authentication policy. +authorization policy. This is because authorization, in general, depends upon +authentication. Use the +:meth:`~pyramid.config.Configurator.set_authentication_policy` method during +application setup to specify the authentication policy. For example: @@ -105,28 +99,27 @@ For example: config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) -.. note:: The ``authentication_policy`` and ``authorization_policy`` - arguments may also be passed to their respective methods mentioned above - as :term:`dotted Python name` values, each representing the dotted name - path to a suitable implementation global defined at Python module scope. +.. note:: The ``authentication_policy`` and ``authorization_policy`` arguments + may also be passed to their respective methods mentioned above as + :term:`dotted Python name` values, each representing the dotted name path to + a suitable implementation global defined at Python module scope. The above configuration enables a policy which compares the value of an "auth ticket" cookie passed in the request's environment which contains a reference -to a single :term:`userid` and matches that userid's -:term:`principals ` against the principals present in any -:term:`ACL` found in the resource tree when attempting to call some -:term:`view`. +to a single :term:`userid`, and matches that userid's :term:`principals +` against the principals present in any :term:`ACL` found in the +resource tree when attempting to call some :term:`view`. While it is possible to mix and match different authentication and -authorization policies, it is an error to configure a Pyramid application -with an authentication policy but without the authorization policy or vice -versa. If you do this, you'll receive an error at application startup time. +authorization policies, it is an error to configure a Pyramid application with +an authentication policy but without the authorization policy or vice versa. If +you do this, you'll receive an error at application startup time. .. seealso:: - See also the :mod:`pyramid.authorization` and - :mod:`pyramid.authentication` modules for alternate implementations of - authorization and authentication policies. + See also the :mod:`pyramid.authorization` and :mod:`pyramid.authentication` + modules for alternative implementations of authorization and authentication + policies. .. index:: single: permissions @@ -139,14 +132,13 @@ Protecting Views with Permissions To protect a :term:`view callable` from invocation based on a user's security settings when a particular type of resource becomes the :term:`context`, you -must pass a :term:`permission` to :term:`view configuration`. Permissions -are usually just strings, and they have no required composition: you can name +must pass a :term:`permission` to :term:`view configuration`. Permissions are +usually just strings, and they have no required composition: you can name permissions whatever you like. For example, the following view declaration protects the view named ``add_entry.html`` when the context resource is of type ``Blog`` with the -``add`` permission using the :meth:`pyramid.config.Configurator.add_view` -API: +``add`` permission using the :meth:`pyramid.config.Configurator.add_view` API: .. code-block:: python :linenos: @@ -158,8 +150,8 @@ API: context='mypackage.resources.Blog', permission='add') -The equivalent view registration including the ``add`` permission name -may be performed via the ``@view_config`` decorator: +The equivalent view registration including the ``add`` permission name may be +performed via the ``@view_config`` decorator: .. code-block:: python :linenos: @@ -173,11 +165,11 @@ may be performed via the ``@view_config`` decorator: pass As a result of any of these various view configuration statements, if an -authorization policy is in place when the view callable is found during -normal application operations, the requesting user will need to possess the -``add`` permission against the :term:`context` resource in order to be able -to invoke the ``blog_entry_add_view`` view. If he does not, the -:term:`Forbidden view` will be invoked. +authorization policy is in place when the view callable is found during normal +application operations, the requesting user will need to possess the ``add`` +permission against the :term:`context` resource in order to be able to invoke +the ``blog_entry_add_view`` view. If they do not, the :term:`Forbidden view` +will be invoked. .. index:: pair: permission; default @@ -187,18 +179,17 @@ to invoke the ``blog_entry_add_view`` view. If he does not, the Setting a Default Permission ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If a permission is not supplied to a view configuration, the registered -view will always be executable by entirely anonymous users: any -authorization policy in effect is ignored. +If a permission is not supplied to a view configuration, the registered view +will always be executable by entirely anonymous users: any authorization policy +in effect is ignored. -In support of making it easier to configure applications which are -"secure by default", :app:`Pyramid` allows you to configure a -*default* permission. If supplied, the default permission is used as -the permission string to all view registrations which don't otherwise -name a ``permission`` argument. +In support of making it easier to configure applications which are "secure by +default", :app:`Pyramid` allows you to configure a *default* permission. If +supplied, the default permission is used as the permission string to all view +registrations which don't otherwise name a ``permission`` argument. -The :meth:`pyramid.config.Configurator.set_default_permission` method -supports configuring a default permission for an application. +The :meth:`pyramid.config.Configurator.set_default_permission` method supports +configuring a default permission for an application. When a default permission is registered: @@ -207,8 +198,8 @@ When a default permission is registered: view-configuration-named permission is used. - If a view configuration names the permission - :data:`pyramid.security.NO_PERMISSION_REQUIRED`, the default permission - is ignored, and the view is registered *without* a permission (making it + :data:`pyramid.security.NO_PERMISSION_REQUIRED`, the default permission is + ignored, and the view is registered *without* a permission (making it available to all callers regardless of their credentials). .. warning:: @@ -226,19 +217,18 @@ When a default permission is registered: .. _assigning_acls: -Assigning ACLs to your Resource Objects +Assigning ACLs to Your Resource Objects --------------------------------------- -When the default :app:`Pyramid` :term:`authorization policy` determines -whether a user possesses a particular permission with respect to a resource, -it examines the :term:`ACL` associated with the resource. An ACL is -associated with a resource by adding an ``__acl__`` attribute to the resource -object. This attribute can be defined on the resource *instance* if you need +When the default :app:`Pyramid` :term:`authorization policy` determines whether +a user possesses a particular permission with respect to a resource, it +examines the :term:`ACL` associated with the resource. An ACL is associated +with a resource by adding an ``__acl__`` attribute to the resource object. +This attribute can be defined on the resource *instance* if you need instance-level security, or it can be defined on the resource *class* if you just need type-level security. -For example, an ACL might be attached to the resource for a blog via its -class: +For example, an ACL might be attached to the resource for a blog via its class: .. code-block:: python :linenos: @@ -273,11 +263,11 @@ Or, if your resources are persistent, an ACL might be specified via the (Allow, 'group:editors', 'edit'), ] -Whether an ACL is attached to a resource's class or an instance of the -resource itself, the effect is the same. It is useful to decorate individual -resource instances with an ACL (as opposed to just decorating their class) in -applications such as "CMS" systems where fine-grained access is required on -an object-by-object basis. +Whether an ACL is attached to a resource's class or an instance of the resource +itself, the effect is the same. It is useful to decorate individual resource +instances with an ACL (as opposed to just decorating their class) in +applications such as content management systems where fine-grained access is +required on an object-by-object basis. Dynamic ACLs are also possible by turning the ACL into a callable on the resource. This may allow the ACL to dynamically generate rules based on @@ -321,30 +311,27 @@ Here's an example ACL: (Allow, 'group:editors', 'edit'), ] -The example ACL indicates that the -:data:`pyramid.security.Everyone` principal -- a special -system-defined principal indicating, literally, everyone -- is allowed -to view the blog, the ``group:editors`` principal is allowed to add to -and edit the blog. +The example ACL indicates that the :data:`pyramid.security.Everyone` +principal—a special system-defined principal indicating, literally, everyone—is +allowed to view the blog, and the ``group:editors`` principal is allowed to add +to and edit the blog. -Each element of an ACL is an :term:`ACE` or access control entry. -For example, in the above code block, there are three ACEs: ``(Allow, -Everyone, 'view')``, ``(Allow, 'group:editors', 'add')``, and -``(Allow, 'group:editors', 'edit')``. +Each element of an ACL is an :term:`ACE`, or access control entry. For example, +in the above code block, there are three ACEs: ``(Allow, Everyone, 'view')``, +``(Allow, 'group:editors', 'add')``, and ``(Allow, 'group:editors', 'edit')``. -The first element of any ACE is either -:data:`pyramid.security.Allow`, or -:data:`pyramid.security.Deny`, representing the action to take when -the ACE matches. The second element is a :term:`principal`. The -third argument is a permission or sequence of permission names. +The first element of any ACE is either :data:`pyramid.security.Allow`, or +:data:`pyramid.security.Deny`, representing the action to take when the ACE +matches. The second element is a :term:`principal`. The third argument is a +permission or sequence of permission names. A principal is usually a user id, however it also may be a group id if your authentication system provides group information and the effective :term:`authentication policy` policy is written to respect group information. See :ref:`extending_default_authentication_policies`. -Each ACE in an ACL is processed by an authorization policy *in the -order dictated by the ACL*. So if you have an ACL like this: +Each ACE in an ACL is processed by an authorization policy *in the order +dictated by the ACL*. So if you have an ACL like this: .. code-block:: python :linenos: @@ -358,10 +345,9 @@ order dictated by the ACL*. So if you have an ACL like this: (Deny, Everyone, 'view'), ] -The default authorization policy will *allow* everyone the view -permission, even though later in the ACL you have an ACE that denies -everyone the view permission. On the other hand, if you have an ACL -like this: +The default authorization policy will *allow* everyone the view permission, +even though later in the ACL you have an ACE that denies everyone the view +permission. On the other hand, if you have an ACL like this: .. code-block:: python :linenos: @@ -375,14 +361,13 @@ like this: (Allow, Everyone, 'view'), ] -The authorization policy will deny everyone the view permission, even -though later in the ACL is an ACE that allows everyone. +The authorization policy will deny everyone the view permission, even though +later in the ACL, there is an ACE that allows everyone. -The third argument in an ACE can also be a sequence of permission -names instead of a single permission name. So instead of creating -multiple ACEs representing a number of different permission grants to -a single ``group:editors`` group, we can collapse this into a single -ACE, as below. +The third argument in an ACE can also be a sequence of permission names instead +of a single permission name. So instead of creating multiple ACEs representing +a number of different permission grants to a single ``group:editors`` group, we +can collapse this into a single ACE, as below. .. code-block:: python :linenos: @@ -403,23 +388,21 @@ ACE, as below. Special Principal Names ----------------------- -Special principal names exist in the :mod:`pyramid.security` -module. They can be imported for use in your own code to populate -ACLs, e.g. :data:`pyramid.security.Everyone`. +Special principal names exist in the :mod:`pyramid.security` module. They can +be imported for use in your own code to populate ACLs, e.g., +:data:`pyramid.security.Everyone`. :data:`pyramid.security.Everyone` - Literally, everyone, no matter what. This object is actually a - string "under the hood" (``system.Everyone``). Every user "is" the - principal named Everyone during every request, even if a security - policy is not in use. + Literally, everyone, no matter what. This object is actually a string under + the hood (``system.Everyone``). Every user *is* the principal named + "Everyone" during every request, even if a security policy is not in use. :data:`pyramid.security.Authenticated` - Any user with credentials as determined by the current security - policy. You might think of it as any user that is "logged in". - This object is actually a string "under the hood" - (``system.Authenticated``). + Any user with credentials as determined by the current security policy. You + might think of it as any user that is "logged in". This object is actually a + string under the hood (``system.Authenticated``). .. index:: single: permission names @@ -428,19 +411,19 @@ ACLs, e.g. :data:`pyramid.security.Everyone`. Special Permissions ------------------- -Special permission names exist in the :mod:`pyramid.security` -module. These can be imported for use in ACLs. +Special permission names exist in the :mod:`pyramid.security` module. These +can be imported for use in ACLs. .. _all_permissions: :data:`pyramid.security.ALL_PERMISSIONS` - An object representing, literally, *all* permissions. Useful in an - ACL like so: ``(Allow, 'fred', ALL_PERMISSIONS)``. The - ``ALL_PERMISSIONS`` object is actually a stand-in object that has a - ``__contains__`` method that always returns ``True``, which, for all - known authorization policies, has the effect of indicating that a - given principal "has" any permission asked for by the system. + An object representing, literally, *all* permissions. Useful in an ACL like + so: ``(Allow, 'fred', ALL_PERMISSIONS)``. The ``ALL_PERMISSIONS`` object is + actually a stand-in object that has a ``__contains__`` method that always + returns ``True``, which, for all known authorization policies, has the effect + of indicating that a given principal has any permission asked for by the + system. .. index:: single: special ACE @@ -451,11 +434,11 @@ Special ACEs A convenience :term:`ACE` is defined representing a deny to everyone of all permissions in :data:`pyramid.security.DENY_ALL`. This ACE is often used as -the *last* ACE of an ACL to explicitly cause inheriting authorization -policies to "stop looking up the traversal tree" (effectively breaking any -inheritance). For example, an ACL which allows *only* ``fred`` the view -permission for a particular resource despite what inherited ACLs may say when -the default authorization policy is in effect might look like so: +the *last* ACE of an ACL to explicitly cause inheriting authorization policies +to "stop looking up the traversal tree" (effectively breaking any inheritance). +For example, an ACL which allows *only* ``fred`` the view permission for a +particular resource, despite what inherited ACLs may say when the default +authorization policy is in effect, might look like so: .. code-block:: python :linenos: @@ -465,8 +448,8 @@ the default authorization policy is in effect might look like so: __acl__ = [ (Allow, 'fred', 'view'), DENY_ALL ] -"Under the hood", the :data:`pyramid.security.DENY_ALL` ACE equals -the following: +Under the hood, the :data:`pyramid.security.DENY_ALL` ACE equals the +following: .. code-block:: python :linenos: @@ -483,14 +466,14 @@ ACL Inheritance and Location-Awareness While the default :term:`authorization policy` is in place, if a resource object does not have an ACL when it is the context, its *parent* is consulted -for an ACL. If that object does not have an ACL, *its* parent is consulted -for an ACL, ad infinitum, until we've reached the root and there are no more +for an ACL. If that object does not have an ACL, *its* parent is consulted for +an ACL, ad infinitum, until we've reached the root and there are no more parents left. In order to allow the security machinery to perform ACL inheritance, resource objects must provide *location-awareness*. Providing *location-awareness* -means two things: the root object in the resource tree must have a -``__name__`` attribute and a ``__parent__`` attribute. +means two things: the root object in the resource tree must have a ``__name__`` +attribute and a ``__parent__`` attribute. .. code-block:: python :linenos: @@ -499,10 +482,10 @@ means two things: the root object in the resource tree must have a __name__ = '' __parent__ = None -An object with a ``__parent__`` attribute and a ``__name__`` attribute -is said to be *location-aware*. Location-aware objects define an -``__parent__`` attribute which points at their parent object. The -root object's ``__parent__`` is ``None``. +An object with a ``__parent__`` attribute and a ``__name__`` attribute is said +to be *location-aware*. Location-aware objects define a ``__parent__`` +attribute which points at their parent object. The root object's +``__parent__`` is ``None``. .. seealso:: @@ -519,12 +502,11 @@ root object's ``__parent__`` is ``None``. Changing the Forbidden View --------------------------- -When :app:`Pyramid` denies a view invocation due to an -authorization denial, the special ``forbidden`` view is invoked. "Out -of the box", this forbidden view is very plain. See -:ref:`changing_the_forbidden_view` within :ref:`hooks_chapter` for -instructions on how to create a custom forbidden view and arrange for -it to be called when view authorization is denied. +When :app:`Pyramid` denies a view invocation due to an authorization denial, +the special ``forbidden`` view is invoked. Out of the box, this forbidden view +is very plain. See :ref:`changing_the_forbidden_view` within +:ref:`hooks_chapter` for instructions on how to create a custom forbidden view +and arrange for it to be called when view authorization is denied. .. index:: single: debugging authorization failures @@ -534,8 +516,8 @@ it to be called when view authorization is denied. Debugging View Authorization Failures ------------------------------------- -If your application in your judgment is allowing or denying view -access inappropriately, start your application under a shell using the +If your application in your judgment is allowing or denying view access +inappropriately, start your application under a shell using the ``PYRAMID_DEBUG_AUTHORIZATION`` environment variable set to ``1``. For example: @@ -543,14 +525,13 @@ example: $ PYRAMID_DEBUG_AUTHORIZATION=1 $VENV/bin/pserve myproject.ini -When any authorization takes place during a top-level view rendering, -a message will be logged to the console (to stderr) about what ACE in -which ACL permitted or denied the authorization based on -authentication information. +When any authorization takes place during a top-level view rendering, a message +will be logged to the console (to stderr) about what ACE in which ACL permitted +or denied the authorization based on authentication information. -This behavior can also be turned on in the application ``.ini`` file -by setting the ``pyramid.debug_authorization`` key to ``true`` within the -application's configuration section, e.g.: +This behavior can also be turned on in the application ``.ini`` file by setting +the ``pyramid.debug_authorization`` key to ``true`` within the application's +configuration section, e.g.: .. code-block:: ini :linenos: @@ -559,26 +540,24 @@ application's configuration section, e.g.: use = egg:MyProject pyramid.debug_authorization = true -With this debug flag turned on, the response sent to the browser will -also contain security debugging information in its body. +With this debug flag turned on, the response sent to the browser will also +contain security debugging information in its body. Debugging Imperative Authorization Failures ------------------------------------------- The :meth:`pyramid.request.Request.has_permission` API is used to check -security within view functions imperatively. It returns instances of -objects that are effectively booleans. But these objects are not raw -``True`` or ``False`` objects, and have information attached to them -about why the permission was allowed or denied. The object will be -one of :data:`pyramid.security.ACLAllowed`, -:data:`pyramid.security.ACLDenied`, -:data:`pyramid.security.Allowed`, or -:data:`pyramid.security.Denied`, as documented in -:ref:`security_module`. At the very minimum these objects will have a -``msg`` attribute, which is a string indicating why the permission was -denied or allowed. Introspecting this information in the debugger or -via print statements when a call to -:meth:`~pyramid.request.Request.has_permission` fails is often useful. +security within view functions imperatively. It returns instances of objects +that are effectively booleans. But these objects are not raw ``True`` or +``False`` objects, and have information attached to them about why the +permission was allowed or denied. The object will be one of +:data:`pyramid.security.ACLAllowed`, :data:`pyramid.security.ACLDenied`, +:data:`pyramid.security.Allowed`, or :data:`pyramid.security.Denied`, as +documented in :ref:`security_module`. At the very minimum, these objects will +have a ``msg`` attribute, which is a string indicating why the permission was +denied or allowed. Introspecting this information in the debugger or via print +statements when a call to :meth:`~pyramid.request.Request.has_permission` fails +is often useful. .. index:: single: authentication policy (extending) @@ -588,27 +567,26 @@ via print statements when a call to Extending Default Authentication Policies ----------------------------------------- -Pyramid ships with some builtin authentication policies for use in your -applications. See :mod:`pyramid.authentication` for the available -policies. They differ on their mechanisms for tracking authentication -credentials between requests, however they all interface with your -application in mostly the same way. +Pyramid ships with some built in authentication policies for use in your +applications. See :mod:`pyramid.authentication` for the available policies. +They differ on their mechanisms for tracking authentication credentials between +requests, however they all interface with your application in mostly the same +way. -Above you learned about :ref:`assigning_acls`. Each :term:`principal` used -in the :term:`ACL` is matched against the list returned from +Above you learned about :ref:`assigning_acls`. Each :term:`principal` used in +the :term:`ACL` is matched against the list returned from :meth:`pyramid.interfaces.IAuthenticationPolicy.effective_principals`. Similarly, :meth:`pyramid.request.Request.authenticated_userid` maps to :meth:`pyramid.interfaces.IAuthenticationPolicy.authenticated_userid`. You may control these values by subclassing the default authentication policies. For example, below we subclass the -:class:`pyramid.authentication.AuthTktAuthenticationPolicy` and define -extra functionality to query our database before confirming that the -:term:`userid` is valid in order to avoid blindly trusting the value in the -cookie (what if the cookie is still valid but the user has deleted their -account?). We then use that :term:`userid` to augment the -``effective_principals`` with information about groups and other state for -that user. +:class:`pyramid.authentication.AuthTktAuthenticationPolicy` and define extra +functionality to query our database before confirming that the :term:`userid` +is valid in order to avoid blindly trusting the value in the cookie (what if +the cookie is still valid, but the user has deleted their account?). We then +use that :term:`userid` to augment the ``effective_principals`` with +information about groups and other state for that user. .. code-block:: python :linenos: @@ -630,8 +608,8 @@ that user. return principals In most instances ``authenticated_userid`` and ``effective_principals`` are -application-specific whereas ``unauthenticated_userid``, ``remember`` and -``forget`` are generic and focused on transport/serialization of data +application-specific, whereas ``unauthenticated_userid``, ``remember``, and +``forget`` are generic and focused on transport and serialization of data between consecutive requests. .. index:: @@ -642,12 +620,11 @@ between consecutive requests. Creating Your Own Authentication Policy --------------------------------------- -:app:`Pyramid` ships with a number of useful out-of-the-box -security policies (see :mod:`pyramid.authentication`). However, -creating your own authentication policy is often necessary when you -want to control the "horizontal and vertical" of how your users -authenticate. Doing so is a matter of creating an instance of something -that implements the following interface: +:app:`Pyramid` ships with a number of useful out-of-the-box security policies +(see :mod:`pyramid.authentication`). However, creating your own authentication +policy is often necessary when you want to control the "horizontal and +vertical" of how your users authenticate. Doing so is a matter of creating an +instance of something that implements the following interface: .. code-block:: python :linenos: @@ -717,21 +694,19 @@ Creating Your Own Authorization Policy -------------------------------------- An authorization policy is a policy that allows or denies access after a user -has been authenticated. Most :app:`Pyramid` applications will use the -default :class:`pyramid.authorization.ACLAuthorizationPolicy`. - -However, in some cases, it's useful to be able to use a different -authorization policy than the default -:class:`~pyramid.authorization.ACLAuthorizationPolicy`. For example, it -might be desirable to construct an alternate authorization policy which -allows the application to use an authorization mechanism that does not -involve :term:`ACL` objects. - -:app:`Pyramid` ships with only a single default authorization -policy, so you'll need to create your own if you'd like to use a -different one. Creating and using your own authorization policy is a -matter of creating an instance of an object that implements the -following interface: +has been authenticated. Most :app:`Pyramid` applications will use the default +:class:`pyramid.authorization.ACLAuthorizationPolicy`. + +However, in some cases, it's useful to be able to use a different authorization +policy than the default :class:`~pyramid.authorization.ACLAuthorizationPolicy`. +For example, it might be desirable to construct an alternate authorization +policy which allows the application to use an authorization mechanism that does +not involve :term:`ACL` objects. + +:app:`Pyramid` ships with only a single default authorization policy, so you'll +need to create your own if you'd like to use a different one. Creating and +using your own authorization policy is a matter of creating an instance of an +object that implements the following interface: .. code-block:: python :linenos: @@ -782,4 +757,3 @@ which would allow the attacker to control the content of the payload. Re-using a secret across two different subsystems might drop the security of signing to zero. Keys should not be re-used across different contexts where an attacker has the possibility of providing a chosen plaintext. - -- cgit v1.2.3 From 50d32d442b81f0e06bf3eee034f7b2eb8cdfb2ec Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 2 Nov 2015 00:09:06 -0800 Subject: - remove deprecated section in docs (Closes #2067) - minor grammar, rewrap to 79 columns --- docs/narr/hybrid.rst | 539 +++++++++++++++++++++------------------------------ 1 file changed, 217 insertions(+), 322 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hybrid.rst b/docs/narr/hybrid.rst index 1c324d22b..ff26d52ec 100644 --- a/docs/narr/hybrid.rst +++ b/docs/narr/hybrid.rst @@ -12,28 +12,26 @@ dispatch. However, to solve a limited set of problems, it's useful to use .. warning:: Reasoning about the behavior of a "hybrid" URL dispatch + traversal - application can be challenging. To successfully reason about using - URL dispatch and traversal together, you need to understand URL - pattern matching, root factories, and the :term:`traversal` - algorithm, and the potential interactions between them. Therefore, - we don't recommend creating an application that relies on hybrid - behavior unless you must. + application can be challenging. To successfully reason about using URL + dispatch and traversal together, you need to understand URL pattern + matching, root factories, and the :term:`traversal` algorithm, and the + potential interactions between them. Therefore, we don't recommend creating + an application that relies on hybrid behavior unless you must. A Review of Non-Hybrid Applications ----------------------------------- -When used according to the tutorials in its documentation -:app:`Pyramid` is a "dual-mode" framework: the tutorials explain -how to create an application in terms of using either :term:`url -dispatch` *or* :term:`traversal`. This chapter details how you might -combine these two dispatch mechanisms, but we'll review how they work -in isolation before trying to combine them. +When used according to the tutorials in its documentation, :app:`Pyramid` is a +"dual-mode" framework: the tutorials explain how to create an application in +terms of using either :term:`URL dispatch` *or* :term:`traversal`. This +chapter details how you might combine these two dispatch mechanisms, but we'll +review how they work in isolation before trying to combine them. URL Dispatch Only ~~~~~~~~~~~~~~~~~ -An application that uses :term:`url dispatch` exclusively to map URLs to code -will often have statements like this within application startup +An application that uses :term:`URL dispatch` exclusively to map URLs to code +will often have statements like this within its application startup configuration: .. code-block:: python @@ -48,11 +46,11 @@ configuration: config.add_view('myproject.views.bazbuz', route_name='bazbuz') Each :term:`route` corresponds to one or more view callables. Each view -callable is associated with a route by passing a ``route_name`` parameter -that matches its name during a call to -:meth:`~pyramid.config.Configurator.add_view`. When a route is matched -during a request, :term:`view lookup` is used to match the request to its -associated view callable. The presence of calls to +callable is associated with a route by passing a ``route_name`` parameter that +matches its name during a call to +:meth:`~pyramid.config.Configurator.add_view`. When a route is matched during +a request, :term:`view lookup` is used to match the request to its associated +view callable. The presence of calls to :meth:`~pyramid.config.Configurator.add_route` signify that an application is using URL dispatch. @@ -72,12 +70,11 @@ declarations that look like this: When the above configuration is applied to an application, the ``mypackage.views.foobar`` view callable above will be called when the URL -``/foobar`` is visited. Likewise, the view ``mypackage.views.bazbuz`` will -be called when the URL ``/bazbuz`` is visited. +``/foobar`` is visited. Likewise, the view ``mypackage.views.bazbuz`` will be +called when the URL ``/bazbuz`` is visited. Typically, an application that uses traversal exclusively won't perform any -calls to :meth:`pyramid.config.Configurator.add_route` in its startup -code. +calls to :meth:`pyramid.config.Configurator.add_route` in its startup code. .. index:: single: hybrid applications @@ -85,149 +82,139 @@ code. Hybrid Applications ------------------- -Either traversal or url dispatch alone can be used to create a -:app:`Pyramid` application. However, it is also possible to -combine the concepts of traversal and url dispatch when building an -application: the result is a hybrid application. In a hybrid -application, traversal is performed *after* a particular route has -matched. - -A hybrid application is a lot more like a "pure" traversal-based -application than it is like a "pure" URL-dispatch based application. -But unlike in a "pure" traversal-based application, in a hybrid -application, :term:`traversal` is performed during a request after a -route has already matched. This means that the URL pattern that -represents the ``pattern`` argument of a route must match the -``PATH_INFO`` of a request, and after the route pattern has matched, -most of the "normal" rules of traversal with respect to :term:`resource -location` and :term:`view lookup` apply. +Either traversal or URL dispatch alone can be used to create a :app:`Pyramid` +application. However, it is also possible to combine the concepts of traversal +and URL dispatch when building an application, the result of which is a hybrid +application. In a hybrid application, traversal is performed *after* a +particular route has matched. + +A hybrid application is a lot more like a "pure" traversal-based application +than it is like a "pure" URL-dispatch based application. But unlike in a "pure" +traversal-based application, in a hybrid application :term:`traversal` is +performed during a request after a route has already matched. This means that +the URL pattern that represents the ``pattern`` argument of a route must match +the ``PATH_INFO`` of a request, and after the route pattern has matched, most +of the "normal" rules of traversal with respect to :term:`resource location` +and :term:`view lookup` apply. There are only four real differences between a purely traversal-based application and a hybrid application: -- In a purely traversal based application, no routes are defined; in a - hybrid application, at least one route will be defined. +- In a purely traversal-based application, no routes are defined. In a hybrid + application, at least one route will be defined. -- In a purely traversal based application, the root object used is - global, implied by the :term:`root factory` provided at startup - time; in a hybrid application, the :term:`root` object at which - traversal begins may be varied on a per-route basis. +- In a purely traversal-based application, the root object used is global, + implied by the :term:`root factory` provided at startup time. In a hybrid + application, the :term:`root` object at which traversal begins may be varied + on a per-route basis. -- In a purely traversal-based application, the ``PATH_INFO`` of the - underlying :term:`WSGI` environment is used wholesale as a traversal - path; in a hybrid application, the traversal path is not the entire - ``PATH_INFO`` string, but a portion of the URL determined by a - matching pattern in the matched route configuration's pattern. +- In a purely traversal-based application, the ``PATH_INFO`` of the underlying + :term:`WSGI` environment is used wholesale as a traversal path. In a hybrid + application, the traversal path is not the entire ``PATH_INFO`` string, but a + portion of the URL determined by a matching pattern in the matched route + configuration's pattern. -- In a purely traversal based application, view configurations which - do not mention a ``route_name`` argument are considered during - :term:`view lookup`; in a hybrid application, when a route is - matched, only view configurations which mention that route's name as - a ``route_name`` are considered during :term:`view lookup`. +- In a purely traversal-based application, view configurations which do not + mention a ``route_name`` argument are considered during :term:`view lookup`. + In a hybrid application, when a route is matched, only view configurations + which mention that route's name as a ``route_name`` are considered during + :term:`view lookup`. -More generally, a hybrid application *is* a traversal-based -application except: +More generally, a hybrid application *is* a traversal-based application except: -- the traversal *root* is chosen based on the route configuration of - the route that matched instead of from the ``root_factory`` supplied - during application startup configuration. +- the traversal *root* is chosen based on the route configuration of the route + that matched, instead of from the ``root_factory`` supplied during + application startup configuration. -- the traversal *path* is chosen based on the route configuration of - the route that matched rather than from the ``PATH_INFO`` of a - request. +- the traversal *path* is chosen based on the route configuration of the route + that matched, rather than from the ``PATH_INFO`` of a request. -- the set of views that may be chosen during :term:`view lookup` when - a route matches are limited to those which specifically name a - ``route_name`` in their configuration that is the same as the - matched route's ``name``. +- the set of views that may be chosen during :term:`view lookup` when a route + matches are limited to those which specifically name a ``route_name`` in + their configuration that is the same as the matched route's ``name``. -To create a hybrid mode application, use a :term:`route configuration` -that implies a particular :term:`root factory` and which also includes -a ``pattern`` argument that contains a special dynamic part: either -``*traverse`` or ``*subpath``. +To create a hybrid mode application, use a :term:`route configuration` that +implies a particular :term:`root factory` and which also includes a ``pattern`` +argument that contains a special dynamic part: either ``*traverse`` or +``*subpath``. The Root Object for a Route Match ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A hybrid application implies that traversal is performed during a -request after a route has matched. Traversal, by definition, must -always begin at a root object. Therefore it's important to know -*which* root object will be traversed after a route has matched. +A hybrid application implies that traversal is performed during a request after +a route has matched. Traversal, by definition, must always begin at a root +object. Therefore it's important to know *which* root object will be traversed +after a route has matched. -Figuring out which :term:`root` object results from a particular route -match is straightforward. When a route is matched: +Figuring out which :term:`root` object results from a particular route match is +straightforward. When a route is matched: -- If the route's configuration has a ``factory`` argument which - points to a :term:`root factory` callable, that callable will be - called to generate a :term:`root` object. +- If the route's configuration has a ``factory`` argument which points to a + :term:`root factory` callable, that callable will be called to generate a + :term:`root` object. -- If the route's configuration does not have a ``factory`` - argument, the *global* :term:`root factory` will be called to - generate a :term:`root` object. The global root factory is the - callable implied by the ``root_factory`` argument passed to the - :class:`~pyramid.config.Configurator` at application - startup time. +- If the route's configuration does not have a ``factory`` argument, the + *global* :term:`root factory` will be called to generate a :term:`root` + object. The global root factory is the callable implied by the + ``root_factory`` argument passed to the :class:`~pyramid.config.Configurator` + at application startup time. - If a ``root_factory`` argument is not provided to the - :class:`~pyramid.config.Configurator` at startup time, a - *default* root factory is used. The default root factory is used to - generate a root object. + :class:`~pyramid.config.Configurator` at startup time, a *default* root + factory is used. The default root factory is used to generate a root object. .. note:: Root factories related to a route were explained previously within - :ref:`route_factories`. Both the global root factory and default - root factory were explained previously within - :ref:`the_resource_tree`. + :ref:`route_factories`. Both the global root factory and default root + factory were explained previously within :ref:`the_resource_tree`. .. index:: pair: hybrid applications; *traverse route pattern .. _using_traverse_in_a_route_pattern: -Using ``*traverse`` In a Route Pattern +Using ``*traverse`` in a Route Pattern ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A hybrid application most often implies the inclusion of a route -configuration that contains the special token ``*traverse`` at the end -of a route's pattern: +A hybrid application most often implies the inclusion of a route configuration +that contains the special token ``*traverse`` at the end of a route's pattern: .. code-block:: python :linenos: config.add_route('home', '{foo}/{bar}/*traverse') -A ``*traverse`` token at the end of the pattern in a route's -configuration implies a "remainder" *capture* value. When it is used, -it will match the remainder of the path segments of the URL. This -remainder becomes the path used to perform traversal. +A ``*traverse`` token at the end of the pattern in a route's configuration +implies a "remainder" *capture* value. When it is used, it will match the +remainder of the path segments of the URL. This remainder becomes the path +used to perform traversal. .. note:: - The ``*remainder`` route pattern syntax is explained in more - detail within :ref:`route_pattern_syntax`. + The ``*remainder`` route pattern syntax is explained in more detail within + :ref:`route_pattern_syntax`. A hybrid mode application relies more heavily on :term:`traversal` to do :term:`resource location` and :term:`view lookup` than most examples indicate within :ref:`urldispatch_chapter`. -Because the pattern of the above route ends with ``*traverse``, when this -route configuration is matched during a request, :app:`Pyramid` will attempt -to use :term:`traversal` against the :term:`root` object implied by the -:term:`root factory` that is implied by the route's configuration. Since no +Because the pattern of the above route ends with ``*traverse``, when this route +configuration is matched during a request, :app:`Pyramid` will attempt to use +:term:`traversal` against the :term:`root` object implied by the :term:`root +factory` that is implied by the route's configuration. Since no ``root_factory`` argument is explicitly specified for this route, this will -either be the *global* root factory for the application, or the *default* -root factory. Once :term:`traversal` has found a :term:`context` resource, +either be the *global* root factory for the application, or the *default* root +factory. Once :term:`traversal` has found a :term:`context` resource, :term:`view lookup` will be invoked in almost exactly the same way it would have been invoked in a "pure" traversal-based application. -Let's assume there is no *global* :term:`root factory` configured in -this application. The *default* :term:`root factory` cannot be traversed: -it has no useful ``__getitem__`` method. So we'll need to associate -this route configuration with a custom root factory in order to -create a useful hybrid application. To that end, let's imagine that -we've created a root factory that looks like so in a module named -``routes.py``: +Let's assume there is no *global* :term:`root factory` configured in this +application. The *default* :term:`root factory` cannot be traversed; it has no +useful ``__getitem__`` method. So we'll need to associate this route +configuration with a custom root factory in order to create a useful hybrid +application. To that end, let's imagine that we've created a root factory that +looks like so in a module named ``routes.py``: .. code-block:: python :linenos: @@ -246,7 +233,7 @@ we've created a root factory that looks like so in a module named def root_factory(request): return root -Above, we've defined a (bogus) resource tree that can be traversed, and a +Above we've defined a (bogus) resource tree that can be traversed, and a ``root_factory`` function that can be used as part of a particular route configuration statement: @@ -256,8 +243,8 @@ configuration statement: config.add_route('home', '{foo}/{bar}/*traverse', factory='mypackage.routes.root_factory') -The ``factory`` above points at the function we've defined. It will return -an instance of the ``Resource`` class as a root object whenever this route is +The ``factory`` above points at the function we've defined. It will return an +instance of the ``Resource`` class as a root object whenever this route is matched. Instances of the ``Resource`` class can be used for tree traversal because they have a ``__getitem__`` method that does something nominally useful. Since traversal uses ``__getitem__`` to walk the resources of a @@ -266,39 +253,37 @@ statement is a reasonable thing to do. .. note:: - We could have also used our ``root_factory`` function as the - ``root_factory`` argument of the - :class:`~pyramid.config.Configurator` constructor, instead - of associating it with a particular route inside the route's - configuration. Every hybrid route configuration that is matched but - which does *not* name a ``factory`` attribute will use the use - global ``root_factory`` function to generate a root object. + We could have also used our ``root_factory`` function as the ``root_factory`` + argument of the :class:`~pyramid.config.Configurator` constructor, instead of + associating it with a particular route inside the route's configuration. + Every hybrid route configuration that is matched, but which does *not* name a + ``factory`` attribute, will use the global ``root_factory`` function to + generate a root object. -When the route configuration named ``home`` above is matched during a -request, the matchdict generated will be based on its pattern: +When the route configuration named ``home`` above is matched during a request, +the matchdict generated will be based on its pattern: ``{foo}/{bar}/*traverse``. The "capture value" implied by the ``*traverse`` element in the pattern will be used to traverse the resource tree in order to find a context resource, starting from the root object returned from the root factory. In the above example, the :term:`root` object found will be the instance named ``root`` in ``routes.py``. -If the URL that matched a route with the pattern ``{foo}/{bar}/*traverse``, -is ``http://example.com/one/two/a/b/c``, the traversal path used -against the root object will be ``a/b/c``. As a result, -:app:`Pyramid` will attempt to traverse through the edges ``'a'``, -``'b'``, and ``'c'``, beginning at the root object. +If the URL that matched a route with the pattern ``{foo}/{bar}/*traverse`` is +``http://example.com/one/two/a/b/c``, the traversal path used against the root +object will be ``a/b/c``. As a result, :app:`Pyramid` will attempt to traverse +through the edges ``'a'``, ``'b'``, and ``'c'``, beginning at the root object. -In our above example, this particular set of traversal steps will mean that -the :term:`context` resource of the view would be the ``Resource`` object -we've named ``'c'`` in our bogus resource tree and the :term:`view name` -resulting from traversal will be the empty string; if you need a refresher -about why this outcome is presumed, see :ref:`traversal_algorithm`. +In our above example, this particular set of traversal steps will mean that the +:term:`context` resource of the view would be the ``Resource`` object we've +named ``'c'`` in our bogus resource tree, and the :term:`view name` resulting +from traversal will be the empty string. If you need a refresher about why +this outcome is presumed, see :ref:`traversal_algorithm`. -At this point, a suitable view callable will be found and invoked -using :term:`view lookup` as described in :ref:`view_configuration`, -but with a caveat: in order for view lookup to work, we need to define -a view configuration that will match when :term:`view lookup` is -invoked after a route matches: +At this point, a suitable view callable will be found and invoked using +:term:`view lookup` as described in :ref:`view_configuration`, but with a +caveat: in order for view lookup to work, we need to define a view +configuration that will match when :term:`view lookup` is invoked after a route +matches: .. code-block:: python :linenos: @@ -307,28 +292,28 @@ invoked after a route matches: factory='mypackage.routes.root_factory') config.add_view('mypackage.views.myview', route_name='home') -Note that the above call to -:meth:`~pyramid.config.Configurator.add_view` includes a ``route_name`` -argument. View configurations that include a ``route_name`` argument are -meant to associate a particular view declaration with a route, using the -route's name, in order to indicate that the view should *only be invoked when -the route matches*. +Note that the above call to :meth:`~pyramid.config.Configurator.add_view` +includes a ``route_name`` argument. View configurations that include a +``route_name`` argument are meant to associate a particular view declaration +with a route, using the route's name, in order to indicate that the view should +*only be invoked when the route matches*. Calls to :meth:`~pyramid.config.Configurator.add_view` may pass a ``route_name`` attribute, which refers to the value of an existing route's -``name`` argument. In the above example, the route name is ``home``, -referring to the name of the route defined above it. +``name`` argument. In the above example, the route name is ``home``, referring +to the name of the route defined above it. -The above ``mypackage.views.myview`` view callable will be invoked when: +The above ``mypackage.views.myview`` view callable will be invoked when the +following conditions are met: -- the route named "home" is matched +- The route named "home" is matched. -- the :term:`view name` resulting from traversal is the empty string. +- The :term:`view name` resulting from traversal is the empty string. -- the :term:`context` resource is any object. +- The :term:`context` resource is any object. -It is also possible to declare alternate views that may be invoked -when a hybrid route is matched: +It is also possible to declare alternative views that may be invoked when a +hybrid route is matched: .. code-block:: python :linenos: @@ -340,37 +325,37 @@ when a hybrid route is matched: name='another') The ``add_view`` call for ``mypackage.views.another_view`` above names a -different view and, more importantly, a different :term:`view name`. The -above ``mypackage.views.another_view`` view will be invoked when: +different view and, more importantly, a different :term:`view name`. The above +``mypackage.views.another_view`` view will be invoked when the following +conditions are met: -- the route named "home" is matched +- The route named "home" is matched. -- the :term:`view name` resulting from traversal is ``another``. +- The :term:`view name` resulting from traversal is ``another``. -- the :term:`context` resource is any object. +- The :term:`context` resource is any object. For instance, if the URL ``http://example.com/one/two/a/another`` is provided to an application that uses the previously mentioned resource tree, the -``mypackage.views.another`` view callable will be called instead of the -``mypackage.views.myview`` view callable because the :term:`view name` will -be ``another`` instead of the empty string. +``mypackage.views.another_view`` view callable will be called instead of the +``mypackage.views.myview`` view callable because the :term:`view name` will be +``another`` instead of the empty string. More complicated matching can be composed. All arguments to *route* -configuration statements and *view* configuration statements are -supported in hybrid applications (such as :term:`predicate` -arguments). +configuration statements and *view* configuration statements are supported in +hybrid applications (such as :term:`predicate` arguments). -Using the ``traverse`` Argument In a Route Definition +Using the ``traverse`` Argument in a Route Definition ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Rather than using the ``*traverse`` remainder marker in a pattern, you -can use the ``traverse`` argument to the -:meth:`~pyramid.config.Configurator.add_route` method. +Rather than using the ``*traverse`` remainder marker in a pattern, you can use +the ``traverse`` argument to the :meth:`~pyramid.config.Configurator.add_route` +method. -When you use the ``*traverse`` remainder marker, the traversal path is -limited to being the remainder segments of a request URL when a route -matches. However, when you use the ``traverse`` argument or -attribute, you have more control over how to compose a traversal path. +When you use the ``*traverse`` remainder marker, the traversal path is limited +to being the remainder segments of a request URL when a route matches. +However, when you use the ``traverse`` argument or attribute, you have more +control over how to compose a traversal path. Here's a use of the ``traverse`` pattern in a call to :meth:`~pyramid.config.Configurator.add_route`: @@ -381,30 +366,27 @@ Here's a use of the ``traverse`` pattern in a call to config.add_route('abc', '/articles/{article}/edit', traverse='/{article}') -The syntax of the ``traverse`` argument is the same as it is for -``pattern``. +The syntax of the ``traverse`` argument is the same as it is for ``pattern``. -If, as above, the ``pattern`` provided is ``/articles/{article}/edit``, -and the ``traverse`` argument provided is ``/{article}``, when a -request comes in that causes the route to match in such a way that the -``article`` match value is ``1`` (when the request URI is -``/articles/1/edit``), the traversal path will be generated as ``/1``. -This means that the root object's ``__getitem__`` will be called with -the name ``1`` during the traversal phase. If the ``1`` object -exists, it will become the :term:`context` of the request. -The :ref:`traversal_chapter` chapter has more information about traversal. +If, as above, the ``pattern`` provided is ``/articles/{article}/edit``, and the +``traverse`` argument provided is ``/{article}``, when a request comes in that +causes the route to match in such a way that the ``article`` match value is +``1`` (when the request URI is ``/articles/1/edit``), the traversal path will +be generated as ``/1``. This means that the root object's ``__getitem__`` will +be called with the name ``1`` during the traversal phase. If the ``1`` object +exists, it will become the :term:`context` of the request. The +:ref:`traversal_chapter` chapter has more information about traversal. -If the traversal path contains segment marker names which are not -present in the pattern argument, a runtime error will occur. The -``traverse`` pattern should not contain segment markers that do not -exist in the ``path``. +If the traversal path contains segment marker names which are not present in +the pattern argument, a runtime error will occur. The ``traverse`` pattern +should not contain segment markers that do not exist in the ``path``. -Note that the ``traverse`` argument is ignored when attached to a -route that has a ``*traverse`` remainder marker in its pattern. +Note that the ``traverse`` argument is ignored when attached to a route that +has a ``*traverse`` remainder marker in its pattern. -Traversal will begin at the root object implied by this route (either -the global root, or the object returned by the ``factory`` associated -with this route). +Traversal will begin at the root object implied by this route (either the +global root, or the object returned by the ``factory`` associated with this +route). .. index:: pair: hybrid applications; global views @@ -412,14 +394,13 @@ with this route). Making Global Views Match +++++++++++++++++++++++++ -By default, only view configurations that mention a ``route_name`` -will be found during view lookup when a route that has a ``*traverse`` -in its pattern matches. You can allow views without a ``route_name`` -attribute to match a route by adding the ``use_global_views`` flag to -the route definition. For example, the ``myproject.views.bazbuz`` -view below will be found if the route named ``abc`` below is matched -and the ``PATH_INFO`` is ``/abc/bazbuz``, even though the view -configuration statement does not have the ``route_name="abc"`` +By default, only view configurations that mention a ``route_name`` will be +found during view lookup when a route that has a ``*traverse`` in its pattern +matches. You can allow views without a ``route_name`` attribute to match a +route by adding the ``use_global_views`` flag to the route definition. For +example, the ``myproject.views.bazbuz`` view below will be found if the route +named ``abc`` below is matched and the ``PATH_INFO`` is ``/abc/bazbuz``, even +though the view configuration statement does not have the ``route_name="abc"`` attribute. .. code-block:: python @@ -445,10 +426,10 @@ traversal. For instance, the :func:`pyramid.wsgi.wsgiapp2` decorator and the from the request's subpath when its ``use_subpath`` argument is ``True``, so it's useful to be able to influence this value. -When ``*subpath`` exists in a pattern, no path is actually traversed, -but the traversal algorithm will return a :term:`subpath` list implied -by the capture value of ``*subpath``. You'll see this pattern most -commonly in route declarations that look like this: +When ``*subpath`` exists in a pattern, no path is actually traversed, but the +traversal algorithm will return a :term:`subpath` list implied by the capture +value of ``*subpath``. You'll see this pattern most commonly in route +declarations that look like this: .. code-block:: python :linenos: @@ -460,98 +441,13 @@ commonly in route declarations that look like this: config.add_route('static', '/static/*subpath') config.add_view(www, route_name='static') -``mypackage.views.www`` is an instance of -:class:`pyramid.static.static_view`. This effectively tells the static -helper to traverse everything in the subpath as a filename. - -.. index:: - pair: hybrid applications; corner cases - -Corner Cases ------------- - -A number of corner case "gotchas" exist when using a hybrid -application. We'll detail them here. - -Registering a Default View for a Route That Has a ``view`` Attribute -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. warning:: As of :app:`Pyramid` 1.1 this section is slated to be removed in - a later documentation release because the ability to add views - directly to the :term:`route configuration` by passing a ``view`` argument - to ``add_route`` has been deprecated. - -It is an error to provide *both* a ``view`` argument to a :term:`route -configuration` *and* a :term:`view configuration` which names a -``route_name`` that has no ``name`` value or the empty ``name`` value. For -example, this pair of declarations will generate a conflict error at startup -time. - -.. code-block:: python - :linenos: - - config.add_route('home', '{foo}/{bar}/*traverse', - view='myproject.views.home') - config.add_view('myproject.views.another', route_name='home') - -This is because the ``view`` argument to the -:meth:`~pyramid.config.Configurator.add_route` above is an *implicit* -default view when that route matches. ``add_route`` calls don't *need* to -supply a view attribute. For example, this ``add_route`` call: - -.. code-block:: python - :linenos: - - config.add_route('home', '{foo}/{bar}/*traverse', - view='myproject.views.home') +``mypackage.views.www`` is an instance of :class:`pyramid.static.static_view`. +This effectively tells the static helper to traverse everything in the subpath +as a filename. -Can also be spelled like so: - -.. code-block:: python - :linenos: - - config.add_route('home', '{foo}/{bar}/*traverse') - config.add_view('myproject.views.home', route_name='home') - -The two spellings are logically equivalent. In fact, the former is just a -syntactical shortcut for the latter. - -Binding Extra Views Against a Route Configuration that Doesn't Have a ``*traverse`` Element In Its Pattern -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Here's another corner case that just makes no sense: - -.. code-block:: python - :linenos: - - config.add_route('abc', '/abc', view='myproject.views.abc') - config.add_view('myproject.views.bazbuz', name='bazbuz', - route_name='abc') - -The above view declaration is useless, because it will never be matched when -the route it references has matched. Only the view associated with the route -itself (``myproject.views.abc``) will ever be invoked when the route matches, -because the default view is always invoked when a route matches and when no -post-match traversal is performed. - -To make the above view declaration useful, the special ``*traverse`` -token must end the route's pattern. For example: - -.. code-block:: python - :linenos: - - config.add_route('abc', '/abc/*traverse', view='myproject.views.abc') - config.add_view('myproject.views.bazbuz', name='bazbuz', - route_name='abc') - -With the above configuration, the ``myproject.views.bazbuz`` view will -be invoked when the request URI is ``/abc/bazbuz``, assuming there is -no object contained by the root object with the key ``bazbuz``. A -different request URI, such as ``/abc/foo/bar``, would invoke the -default ``myproject.views.abc`` view. .. index:: - pair: hybrid urls; generating + pair: hybrid URLs; generating .. _generating_hybrid_urls: @@ -560,16 +456,16 @@ Generating Hybrid URLs .. versionadded:: 1.5 -The :meth:`pyramid.request.Request.resource_url` method and the -:meth:`pyramid.request.Request.resource_path` method both accept optional +The :meth:`pyramid.request.Request.resource_url` method and the +:meth:`pyramid.request.Request.resource_path` method both accept optional keyword arguments that make it easier to generate route-prefixed URLs that -contain paths to traversal resources:``route_name``, ``route_kw``, and +contain paths to traversal resources: ``route_name``, ``route_kw``, and ``route_remainder_name``. Any route that has a pattern that contains a ``*remainder`` pattern (any -stararg remainder pattern, such as ``*traverse`` or ``*subpath`` or ``*fred``) -can be used as the target name for ``request.resource_url(..., route_name=)`` -and ``request.resource_path(..., route_name=)``. +stararg remainder pattern, such as ``*traverse``, ``*subpath``, or ``*fred``) +can be used as the target name for ``request.resource_url(..., route_name=)`` +and ``request.resource_path(..., route_name=)``. For example, let's imagine you have a route defined in your Pyramid application like so: @@ -578,7 +474,7 @@ like so: config.add_route('mysection', '/mysection*traverse') -If you'd like to generate the URL ``http://example.com/mysection/a/``, you can +If you'd like to generate the URL ``http://example.com/mysection/a/``, you can use the following incantation, assuming that the variable ``a`` below points to a resource that is a child of the root with a ``__name__`` of ``a``: @@ -592,14 +488,14 @@ You can generate only the path portion ``/mysection/a/`` assuming the same: request.resource_path(a, route_name='mysection') -The path is virtual host aware, so if the ``X-Vhm-Root`` environ variable is -present in the request, and it's set to ``/a``, the above call to -``request.resource_url`` would generate ``http://example.com/mysection/`` -and the above call to ``request.resource_path`` would generate ``/mysection/``. -See :ref:`virtual_root_support` for more information. +The path is virtual host aware, so if the ``X-Vhm-Root`` environment variable +is present in the request, and it's set to ``/a``, the above call to +``request.resource_url`` would generate ``http://example.com/mysection/``, and +the above call to ``request.resource_path`` would generate ``/mysection/``. See +:ref:`virtual_root_support` for more information. If the route you're trying to use needs simple dynamic part values to be filled -in to succesfully generate the URL, you can pass these as the ``route_kw`` +in to succesfully generate the URL, you can pass these as the ``route_kw`` argument to ``resource_url`` and ``resource_path``. For example, assuming that the route definition is like so: @@ -613,15 +509,15 @@ You can pass ``route_kw`` in to fill in ``{id}`` above: request.resource_url(a, route_name='mysection', route_kw={'id':'1'}) -If you pass ``route_kw`` but do not pass ``route_name``, ``route_kw`` will -be ignored. +If you pass ``route_kw`` but do not pass ``route_name``, ``route_kw`` will be +ignored. -By default this feature works by calling ``route_url`` under the hood, -and passing the value of the resource path to that function as ``traverse``. -If your route has a different ``*stararg`` remainder name (such as -``*subpath``), you can tell ``resource_url`` or ``resource_path`` to use that -instead of ``traverse`` by passing ``route_remainder_name``. For example, -if you have the following route: +By default this feature works by calling ``route_url`` under the hood, and +passing the value of the resource path to that function as ``traverse``. If +your route has a different ``*stararg`` remainder name (such as ``*subpath``), +you can tell ``resource_url`` or ``resource_path`` to use that instead of +``traverse`` by passing ``route_remainder_name``. For example, if you have the +following route: .. code-block:: python @@ -631,10 +527,10 @@ You can fill in the ``*subpath`` value using ``resource_url`` by doing: .. code-block:: python - request.resource_path(a, route_name='mysection', + request.resource_path(a, route_name='mysection', route_remainder_name='subpath') -If you pass ``route_remainder_name`` but do not pass ``route_name``, +If you pass ``route_remainder_name`` but do not pass ``route_name``, ``route_remainder_name`` will be ignored. If you try to use ``resource_path`` or ``resource_url`` when the ``route_name`` @@ -642,12 +538,11 @@ argument points at a route that does not have a remainder stararg, an error will not be raised, but the generated URL will not contain any remainder information either. -All other values that are normally passable to ``resource_path`` and -``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, and +All other values that are normally passable to ``resource_path`` and +``resource_url`` (such as ``query``, ``anchor``, ``host``, ``port``, and positional elements) work as you might expect in this configuration. Note that this feature is incompatible with the ``__resource_url__`` feature (see :ref:`overriding_resource_url_generation`) implemented on resource objects. Any ``__resource_url__`` supplied by your resource will be ignored when you pass ``route_name``. - -- cgit v1.2.3 From 8aa1c2a8bfed910a69aba974b611e21d9421e0e5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 3 Nov 2015 00:41:58 -0800 Subject: minor grammar, fix .rst markup, rewrap to 79 columns --- docs/narr/hooks.rst | 644 +++++++++++++++++++++++++--------------------------- 1 file changed, 312 insertions(+), 332 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 4fd7670b9..6aa1a99c2 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -14,12 +14,12 @@ in various ways. Changing the Not Found View --------------------------- -When :app:`Pyramid` can't map a URL to view code, it invokes a :term:`Not -Found View`, which is a :term:`view callable`. The default Not Found View -can be overridden through application configuration. +When :app:`Pyramid` can't map a URL to view code, it invokes a :term:`Not Found +View`, which is a :term:`view callable`. The default Not Found View can be +overridden through application configuration. -If your application uses :term:`imperative configuration`, you can replace -the Not Found View by using the +If your application uses :term:`imperative configuration`, you can replace the +Not Found View by using the :meth:`pyramid.config.Configurator.add_notfound_view` method: .. code-block:: python @@ -77,14 +77,14 @@ Views can carry predicates limiting their applicability. For example: config = Configurator() config.scan() -The ``notfound_get`` view will be called when a view could not be found and -the request method was ``GET``. The ``notfound_post`` view will be called -when a view could not be found and the request method was ``POST``. +The ``notfound_get`` view will be called when a view could not be found and the +request method was ``GET``. The ``notfound_post`` view will be called when a +view could not be found and the request method was ``POST``. Like any other view, the Not Found View must accept at least a ``request`` -parameter, or both ``context`` and ``request``. The ``request`` is the -current :term:`request` representing the denied action. The ``context`` (if -used in the call signature) will be the instance of the +parameter, or both ``context`` and ``request``. The ``request`` is the current +:term:`request` representing the denied action. The ``context`` (if used in +the call signature) will be the instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the view to be called. @@ -106,13 +106,13 @@ callable: .. note:: - When a Not Found View callable is invoked, it is passed a - :term:`request`. The ``exception`` attribute of the request will be an - instance of the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that - caused the Not Found View to be called. The value of - ``request.exception.message`` will be a value explaining why the Not Found - error was raised. This message has different values depending whether the - ``pyramid.debug_notfound`` environment setting is true or false. + When a Not Found View callable is invoked, it is passed a :term:`request`. + The ``exception`` attribute of the request will be an instance of the + :exc:`~pyramid.httpexceptions.HTTPNotFound` exception that caused the Not + Found View to be called. The value of ``request.exception.message`` will be + a value explaining why the Not Found exception was raised. This message has + different values depending on whether the ``pyramid.debug_notfound`` + environment setting is true or false. .. note:: @@ -124,9 +124,9 @@ callable: .. warning:: - When a Not Found View callable accepts an argument list as - described in :ref:`request_and_context_view_definitions`, the ``context`` - passed as the first argument to the view callable will be the + When a Not Found View callable accepts an argument list as described in + :ref:`request_and_context_view_definitions`, the ``context`` passed as the + first argument to the view callable will be the :exc:`~pyramid.httpexceptions.HTTPNotFound` exception instance. If available, the resource context will still be available as ``request.context``. @@ -140,13 +140,13 @@ Changing the Forbidden View --------------------------- When :app:`Pyramid` can't authorize execution of a view based on the -:term:`authorization policy` in use, it invokes a :term:`forbidden view`. -The default forbidden response has a 403 status code and is very plain, but -the view which generates it can be overridden as necessary. +:term:`authorization policy` in use, it invokes a :term:`forbidden view`. The +default forbidden response has a 403 status code and is very plain, but the +view which generates it can be overridden as necessary. The :term:`forbidden view` callable is a view callable like any other. The -:term:`view configuration` which causes it to be a "forbidden" view consists -of using the :meth:`pyramid.config.Configurator.add_forbidden_view` API or the +:term:`view configuration` which causes it to be a "forbidden" view consists of +using the :meth:`pyramid.config.Configurator.add_forbidden_view` API or the :class:`pyramid.view.forbidden_view_config` decorator. For example, you can add a forbidden view by using the @@ -181,14 +181,11 @@ as a forbidden view: config.scan() Like any other view, the forbidden view must accept at least a ``request`` -parameter, or both ``context`` and ``request``. If a forbidden view -callable accepts both ``context`` and ``request``, the HTTP Exception is passed -as context. The ``context`` as found by the router when view was -denied (that you normally would expect) is available as -``request.context``. The ``request`` is the current :term:`request` -representing the denied action. - - +parameter, or both ``context`` and ``request``. If a forbidden view callable +accepts both ``context`` and ``request``, the HTTP Exception is passed as +context. The ``context`` as found by the router when the view was denied (which +you normally would expect) is available as ``request.context``. The +``request`` is the current :term:`request` representing the denied action. Here's some sample code that implements a minimal forbidden view: @@ -203,15 +200,15 @@ Here's some sample code that implements a minimal forbidden view: .. note:: - When a forbidden view callable is invoked, it is passed a - :term:`request`. The ``exception`` attribute of the request will be an - instance of the :exc:`~pyramid.httpexceptions.HTTPForbidden` exception - that caused the forbidden view to be called. The value of - ``request.exception.message`` will be a value explaining why the forbidden - was raised and ``request.exception.result`` will be extended information - about the forbidden exception. These messages have different values - depending whether the ``pyramid.debug_authorization`` environment setting - is true or false. + When a forbidden view callable is invoked, it is passed a :term:`request`. + The ``exception`` attribute of the request will be an instance of the + :exc:`~pyramid.httpexceptions.HTTPForbidden` exception that caused the + forbidden view to be called. The value of ``request.exception.message`` + will be a value explaining why the forbidden exception was raised, and + ``request.exception.result`` will be extended information about the + forbidden exception. These messages have different values depending on + whether the ``pyramid.debug_authorization`` environment setting is true or + false. .. index:: single: request factory @@ -223,11 +220,11 @@ Changing the Request Factory Whenever :app:`Pyramid` handles a request from a :term:`WSGI` server, it creates a :term:`request` object based on the WSGI environment it has been -passed. By default, an instance of the :class:`pyramid.request.Request` -class is created to represent the request object. +passed. By default, an instance of the :class:`pyramid.request.Request` class +is created to represent the request object. -The class (aka "factory") that :app:`Pyramid` uses to create a request object -instance can be changed by passing a ``request_factory`` argument to the +The class (a.k.a., "factory") that :app:`Pyramid` uses to create a request +object instance can be changed by passing a ``request_factory`` argument to the constructor of the :term:`configurator`. This argument can be either a callable or a :term:`dotted Python name` representing a callable. @@ -242,7 +239,7 @@ callable or a :term:`dotted Python name` representing a callable. config = Configurator(request_factory=MyRequest) If you're doing imperative configuration, and you'd rather do it after you've -already constructed a :term:`configurator` it can also be registered via the +already constructed a :term:`configurator`, it can also be registered via the :meth:`pyramid.config.Configurator.set_request_factory` method: .. code-block:: python @@ -262,19 +259,19 @@ already constructed a :term:`configurator` it can also be registered via the .. _adding_request_method: -Adding Methods or Properties to Request Object ----------------------------------------------- +Adding Methods or Properties to a Request Object +------------------------------------------------ .. versionadded:: 1.4. Since each Pyramid application can only have one :term:`request` factory, -:ref:`changing the request factory ` -is not that extensible, especially if you want to build composable features -(e.g., Pyramid add-ons and plugins). +:ref:`changing the request factory ` is not that +extensible, especially if you want to build composable features (e.g., Pyramid +add-ons and plugins). A lazy property can be registered to the request object via the -:meth:`pyramid.config.Configurator.add_request_method` API. This allows you -to specify a callable that will be available on the request object, but will not +:meth:`pyramid.config.Configurator.add_request_method` API. This allows you to +specify a callable that will be available on the request object, but will not actually execute the function until accessed. .. warning:: @@ -298,9 +295,10 @@ actually execute the function until accessed. config.add_request_method(total) config.add_request_method(prop, reify=True) -In the above example, ``total`` is added as a method. However, ``prop`` is added -as a property and its result is cached per-request by setting ``reify=True``. -This way, we eliminate the overhead of running the function multiple times. +In the above example, ``total`` is added as a method. However, ``prop`` is +added as a property and its result is cached per-request by setting +``reify=True``. This way, we eliminate the overhead of running the function +multiple times. >>> request.total(1, 2, 3) 6 @@ -354,18 +352,18 @@ We attach and cache an object named ``extra`` to the ``request`` object. .. _changing_the_response_factory: Changing the Response Factory -------------------------------- +----------------------------- .. versionadded:: 1.6 -Whenever :app:`Pyramid` returns a response from a view it creates a +Whenever :app:`Pyramid` returns a response from a view, it creates a :term:`response` object. By default, an instance of the :class:`pyramid.response.Response` class is created to represent the response object. -The factory that :app:`Pyramid` uses to create a response object instance can be -changed by passing a :class:`pyramid.interfaces.IResponseFactory` argument to -the constructor of the :term:`configurator`. This argument can be either a +The factory that :app:`Pyramid` uses to create a response object instance can +be changed by passing a :class:`pyramid.interfaces.IResponseFactory` argument +to the constructor of the :term:`configurator`. This argument can be either a callable or a :term:`dotted Python name` representing a callable. The factory takes a single positional argument, which is a :term:`Request` @@ -381,8 +379,8 @@ object. The argument may be ``None``. config = Configurator(response_factory=lambda r: MyResponse()) -If you're doing imperative configuration, and you'd rather do it after you've -already constructed a :term:`configurator` it can also be registered via the +If you're doing imperative configuration and you'd rather do it after you've +already constructed a :term:`configurator`, it can also be registered via the :meth:`pyramid.config.Configurator.set_response_factory` method: .. code-block:: python @@ -403,13 +401,13 @@ already constructed a :term:`configurator` it can also be registered via the .. _beforerender_event: -Using The Before Render Event +Using the Before Render Event ----------------------------- Subscribers to the :class:`pyramid.events.BeforeRender` event may introspect and modify the set of :term:`renderer globals` before they are passed to a -:term:`renderer`. This event object iself has a dictionary-like interface -that can be used for this purpose. For example: +:term:`renderer`. This event object iself has a dictionary-like interface that +can be used for this purpose. For example: .. code-block:: python :linenos: @@ -421,22 +419,22 @@ that can be used for this purpose. For example: def add_global(event): event['mykey'] = 'foo' -An object of this type is sent as an event just before a :term:`renderer` -is invoked. +An object of this type is sent as an event just before a :term:`renderer` is +invoked. -If a subscriber attempts to add a key that already exist in the renderer +If a subscriber attempts to add a key that already exists in the renderer globals dictionary, a :exc:`KeyError` is raised. This limitation is enforced because event subscribers do not possess any relative ordering. The set of keys added to the renderer globals dictionary by all -:class:`pyramid.events.BeforeRender` subscribers and renderer globals -factories must be unique. +:class:`pyramid.events.BeforeRender` subscribers and renderer globals factories +must be unique. The dictionary returned from the view is accessible through the :attr:`rendering_val` attribute of a :class:`~pyramid.events.BeforeRender` event. -Suppose you return ``{'mykey': 'somevalue', 'mykey2': 'somevalue2'}`` from -your view callable, like so: +Suppose you return ``{'mykey': 'somevalue', 'mykey2': 'somevalue2'}`` from your +view callable, like so: .. code-block:: python :linenos: @@ -492,24 +490,23 @@ A response callback is a callable which accepts two positional parameters: response.cache_control.max_age = 360 request.add_response_callback(cache_callback) -No response callback is called if an unhandled exception happens in -application code, or if the response object returned by a :term:`view -callable` is invalid. Response callbacks *are*, however, invoked when a -:term:`exception view` is rendered successfully: in such a case, the -:attr:`request.exception` attribute of the request when it enters a response -callback will be an exception object instead of its default value of -``None``. +No response callback is called if an unhandled exception happens in application +code, or if the response object returned by a :term:`view callable` is invalid. +Response callbacks *are*, however, invoked when a :term:`exception view` is +rendered successfully. In such a case, the :attr:`request.exception` attribute +of the request when it enters a response callback will be an exception object +instead of its default value of ``None``. Response callbacks are called in the order they're added -(first-to-most-recently-added). All response callbacks are called *before* -the :class:`~pyramid.events.NewResponse` event is sent. Errors raised by -response callbacks are not handled specially. They will be propagated to the -caller of the :app:`Pyramid` router application. +(first-to-most-recently-added). All response callbacks are called *before* the +:class:`~pyramid.events.NewResponse` event is sent. Errors raised by response +callbacks are not handled specially. They will be propagated to the caller of +the :app:`Pyramid` router application. A response callback has a lifetime of a *single* request. If you want a response callback to happen as the result of *every* request, you must -re-register the callback into every new request (perhaps within a subscriber -of a :class:`~pyramid.events.NewRequest` event). +re-register the callback into every new request (perhaps within a subscriber of +a :class:`~pyramid.events.NewRequest` event). .. index:: single: finished callback @@ -520,15 +517,15 @@ Using Finished Callbacks ------------------------ A :term:`finished callback` is a function that will be called unconditionally -by the :app:`Pyramid` :term:`router` at the very end of request processing. -A finished callback can be used to perform an action at the end of a request +by the :app:`Pyramid` :term:`router` at the very end of request processing. A +finished callback can be used to perform an action at the end of a request unconditionally. The :meth:`pyramid.request.Request.add_finished_callback` method is used to register a finished callback. -A finished callback is a callable which accepts a single positional -parameter: ``request``. For example: +A finished callback is a callable which accepts a single positional parameter: +``request``. For example: .. code-block:: python :linenos: @@ -543,29 +540,27 @@ parameter: ``request``. For example: request.add_finished_callback(log_callback) Finished callbacks are called in the order they're added -(first-to-most-recently-added). Finished callbacks (unlike a -:term:`response callback`) are *always* called, even if an exception -happens in application code that prevents a response from being -generated. - -The set of finished callbacks associated with a request are called *very -late* in the processing of that request; they are essentially the very last -thing called by the :term:`router` before a request "ends". They are called -after response processing has already occurred in a top-level ``finally:`` -block within the router request processing code. As a result, mutations -performed to the ``request`` provided to a finished callback will have no -meaningful effect, because response processing will have already occurred, -and the request's scope will expire almost immediately after all finished -callbacks have been processed. - -Errors raised by finished callbacks are not handled specially. They -will be propagated to the caller of the :app:`Pyramid` router -application. +(first-to-most-recently-added). Finished callbacks (unlike a :term:`response +callback`) are *always* called, even if an exception happens in application +code that prevents a response from being generated. + +The set of finished callbacks associated with a request are called *very late* +in the processing of that request; they are essentially the very last thing +called by the :term:`router` before a request "ends". They are called after +response processing has already occurred in a top-level ``finally:`` block +within the router request processing code. As a result, mutations performed to +the ``request`` provided to a finished callback will have no meaningful effect, +because response processing will have already occurred, and the request's scope +will expire almost immediately after all finished callbacks have been +processed. + +Errors raised by finished callbacks are not handled specially. They will be +propagated to the caller of the :app:`Pyramid` router application. A finished callback has a lifetime of a *single* request. If you want a finished callback to happen as the result of *every* request, you must -re-register the callback into every new request (perhaps within a subscriber -of a :class:`~pyramid.events.NewRequest` event). +re-register the callback into every new request (perhaps within a subscriber of +a :class:`~pyramid.events.NewRequest` event). .. index:: single: traverser @@ -577,8 +572,8 @@ Changing the Traverser The default :term:`traversal` algorithm that :app:`Pyramid` uses is explained in :ref:`traversal_algorithm`. Though it is rarely necessary, this default -algorithm can be swapped out selectively for a different traversal pattern -via configuration. +algorithm can be swapped out selectively for a different traversal pattern via +configuration. .. code-block:: python :linenos: @@ -624,10 +619,10 @@ that implements the following interface: More than one traversal algorithm can be active at the same time. For instance, if your :term:`root factory` returns more than one type of object -conditionally, you could claim that an alternate traverser adapter is "for" +conditionally, you could claim that an alternative traverser adapter is "for" only one particular class or interface. When the root factory returned an object that implemented that class or interface, a custom traverser would be -used. Otherwise, the default traverser would be used. For example: +used. Otherwise the default traverser would be used. For example: .. code-block:: python :linenos: @@ -639,13 +634,13 @@ used. Otherwise, the default traverser would be used. For example: config.add_traverser(Traverser, MyRoot) If the above stanza was added to a Pyramid ``__init__.py`` file's ``main`` -function, :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only -when the application :term:`root factory` returned an instance of the +function, :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only when +the application :term:`root factory` returned an instance of the ``myapp.resources.MyRoot`` object. Otherwise it would use the default :app:`Pyramid` traverser to do traversal. .. index:: - single: url generator + single: URL generator .. _changing_resource_url: @@ -655,9 +650,8 @@ Changing How :meth:`pyramid.request.Request.resource_url` Generates a URL When you add a traverser as described in :ref:`changing_the_traverser`, it's often convenient to continue to use the :meth:`pyramid.request.Request.resource_url` API. However, since the way -traversal is done will have been modified, the URLs it generates by default -may be incorrect when used against resources derived from your custom -traverser. +traversal is done will have been modified, the URLs it generates by default may +be incorrect when used against resources derived from your custom traverser. If you've added a traverser, you can change how :meth:`~pyramid.request.Request.resource_url` generates a URL for a specific @@ -674,13 +668,13 @@ For example: config.add_resource_url_adapter(ResourceURLAdapter, MyRoot) -In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will -be used to provide services to :meth:`~pyramid.request.Request.resource_url` -any time the :term:`resource` passed to ``resource_url`` is of the class +In the above example, the ``myapp.traversal.ResourceURLAdapter`` class will be +used to provide services to :meth:`~pyramid.request.Request.resource_url` any +time the :term:`resource` passed to ``resource_url`` is of the class ``myapp.resources.MyRoot``. The ``resource_iface`` argument ``MyRoot`` represents the type of interface that must be possessed by the resource for this resource url factory to be found. If the ``resource_iface`` argument is -omitted, this resource url adapter will be used for *all* resources. +omitted, this resource URL adapter will be used for *all* resources. The API that must be implemented by a class that provides :class:`~pyramid.interfaces.IResourceURL` is as follows: @@ -693,8 +687,8 @@ The API that must be implemented by a class that provides resource """ def __init__(self, resource, request): - """ Accept the resource and request and set self.physical_path and - self.virtual_path""" + """ Accept the resource and request and set self.physical_path and + self.virtual_path """ self.virtual_path = some_function_of(resource, request) self.physical_path = some_other_function_of(resource, request) @@ -703,7 +697,8 @@ The default context URL generator is available for perusal as the class `_ of the :term:`Pylons` GitHub Pyramid repository. -See :meth:`pyramid.config.add_resource_url_adapter` for more information. +See :meth:`pyramid.config.Configurator.add_resource_url_adapter` for more +information. .. index:: single: IResponse @@ -721,25 +716,24 @@ callable on a per-type basis by using a hook involving :meth:`pyramid.config.Configurator.add_response_adapter` or the :class:`~pyramid.response.response_adapter` decorator. -Pyramid, in various places, adapts the result of calling a view callable to -the :class:`~pyramid.interfaces.IResponse` interface to ensure that the -object returned by the view callable is a "true" response object. The vast -majority of time, the result of this adaptation is the result object itself, -as view callables written by "civilians" who read the narrative documentation -contained in this manual will always return something that implements the -:class:`~pyramid.interfaces.IResponse` interface. Most typically, this will -be an instance of the :class:`pyramid.response.Response` class or a subclass. -If a civilian returns a non-Response object from a view callable that isn't -configured to use a :term:`renderer`, he will typically expect the router to +Pyramid, in various places, adapts the result of calling a view callable to the +:class:`~pyramid.interfaces.IResponse` interface to ensure that the object +returned by the view callable is a "true" response object. The vast majority +of time, the result of this adaptation is the result object itself, as view +callables written by "civilians" who read the narrative documentation contained +in this manual will always return something that implements the +:class:`~pyramid.interfaces.IResponse` interface. Most typically, this will be +an instance of the :class:`pyramid.response.Response` class or a subclass. If a +civilian returns a non-Response object from a view callable that isn't +configured to use a :term:`renderer`, they will typically expect the router to raise an error. However, you can hook Pyramid in such a way that users can return arbitrary values from a view callable by providing an adapter which converts the arbitrary return value into something that implements :class:`~pyramid.interfaces.IResponse`. For example, if you'd like to allow view callables to return bare string -objects (without requiring a :term:`renderer` to convert a string to a -response object), you can register an adapter which converts the string to a -Response: +objects (without requiring a :term:`renderer` to convert a string to a response +object), you can register an adapter which converts the string to a Response: .. code-block:: python :linenos: @@ -754,9 +748,9 @@ Response: config.add_response_adapter(string_response_adapter, str) -Likewise, if you want to be able to return a simplified kind of response -object from view callables, you can use the IResponse hook to register an -adapter to the more complex IResponse interface: +Likewise, if you want to be able to return a simplified kind of response object +from view callables, you can use the IResponse hook to register an adapter to +the more complex IResponse interface: .. code-block:: python :linenos: @@ -777,7 +771,7 @@ adapter to the more complex IResponse interface: If you want to implement your own Response object instead of using the :class:`pyramid.response.Response` object in any capacity at all, you'll have -to make sure the object implements every attribute and method outlined in +to make sure that the object implements every attribute and method outlined in :class:`pyramid.interfaces.IResponse` and you'll have to ensure that it uses ``zope.interface.implementer(IResponse)`` as a class decorator. @@ -789,7 +783,7 @@ to make sure the object implements every attribute and method outlined in @implementer(IResponse) class MyResponse(object): - # ... an implementation of every method and attribute + # ... an implementation of every method and attribute # documented in IResponse should follow ... When an alternate response object implementation is returned by a view @@ -804,8 +798,8 @@ startup time, as by their nature, instances of this class (and instances of subclasses of the class) will natively provide IResponse. The adapter registered for ``webob.Response`` simply returns the response object. -Instead of using :meth:`pyramid.config.Configurator.add_response_adapter`, -you can use the :class:`pyramid.response.response_adapter` decorator: +Instead of using :meth:`pyramid.config.Configurator.add_response_adapter`, you +can use the :class:`pyramid.response.response_adapter` decorator: .. code-block:: python :linenos: @@ -841,31 +835,29 @@ callables by employing a :term:`view mapper`. A view mapper is an object that accepts a set of keyword arguments and which returns a callable. The returned callable is called with the :term:`view -callable` object. The returned callable should itself return another -callable which can be called with the "internal calling protocol" ``(context, +callable` object. The returned callable should itself return another callable +which can be called with the "internal calling protocol" ``(context, request)``. You can use a view mapper in a number of ways: -- by setting a ``__view_mapper__`` attribute (which is the view mapper - object) on the view callable itself +- by setting a ``__view_mapper__`` attribute (which is the view mapper object) + on the view callable itself -- by passing the mapper object to - :meth:`pyramid.config.Configurator.add_view` (or its declarative/decorator - equivalents) as the ``mapper`` argument. +- by passing the mapper object to :meth:`pyramid.config.Configurator.add_view` + (or its declarative and decorator equivalents) as the ``mapper`` argument -- by registering a *default* view mapper. +- by registering a *default* view mapper Here's an example of a view mapper that emulates (somewhat) a Pylons "controller". The mapper is initialized with some keyword arguments. Its ``__call__`` method accepts the view object (which will be a class). It uses -the ``attr`` keyword argument it is passed to determine which attribute -should be used as an action method. The wrapper method it returns accepts -``(context, request)`` and returns the result of calling the action method -with keyword arguments implied by the :term:`matchdict` after popping the -``action`` out of it. This somewhat emulates the Pylons style of calling -action methods with routing parameters pulled out of the route matching dict -as keyword arguments. +the ``attr`` keyword argument it is passed to determine which attribute should +be used as an action method. The wrapper method it returns accepts ``(context, +request)`` and returns the result of calling the action method with keyword +arguments implied by the :term:`matchdict` after popping the ``action`` out of +it. This somewhat emulates the Pylons style of calling action methods with +routing parameters pulled out of the route matching dict as keyword arguments. .. code-block:: python :linenos: @@ -917,8 +909,8 @@ The :meth:`pyramid.config.Configurator.set_view_mapper` method can be used to set a *default* view mapper (overriding the superdefault view mapper used by Pyramid itself). -A *single* view registration can use a view mapper by passing the mapper as -the ``mapper`` argument to :meth:`~pyramid.config.Configurator.add_view`. +A *single* view registration can use a view mapper by passing the mapper as the +``mapper`` argument to :meth:`~pyramid.config.Configurator.add_view`. .. index:: single: configuration decorator @@ -928,14 +920,14 @@ the ``mapper`` argument to :meth:`~pyramid.config.Configurator.add_view`. Registering Configuration Decorators ------------------------------------ -Decorators such as :class:`~pyramid.view.view_config` don't change the -behavior of the functions or classes they're decorating. Instead, when a -:term:`scan` is performed, a modified version of the function or class is -registered with :app:`Pyramid`. +Decorators such as :class:`~pyramid.view.view_config` don't change the behavior +of the functions or classes they're decorating. Instead when a :term:`scan` is +performed, a modified version of the function or class is registered with +:app:`Pyramid`. You may wish to have your own decorators that offer such behaviour. This is -possible by using the :term:`Venusian` package in the same way that it is -used by :app:`Pyramid`. +possible by using the :term:`Venusian` package in the same way that it is used +by :app:`Pyramid`. By way of example, let's suppose you want to write a decorator that registers the function it wraps with a :term:`Zope Component Architecture` "utility" @@ -945,8 +937,7 @@ available once your application's configuration is at least partially completed. A normal decorator would fail as it would be executed before the configuration had even begun. -However, using :term:`Venusian`, the decorator could be written as -follows: +However, using :term:`Venusian`, the decorator could be written as follows: .. code-block:: python :linenos: @@ -968,18 +959,17 @@ follows: venusian.attach(wrapped, self.register) return wrapped -This decorator could then be used to register functions throughout -your code: +This decorator could then be used to register functions throughout your code: .. code-block:: python :linenos: @registerFunction('/some/path') def my_function(): - do_stuff() + do_stuff() -However, the utility would only be looked up when a :term:`scan` was -performed, enabling you to set up the utility in advance: +However, the utility would only be looked up when a :term:`scan` was performed, +enabling you to set up the utility in advance: .. code-block:: python :linenos: @@ -994,10 +984,10 @@ performed, enabling you to set up the utility in advance: class UtilityImplementation: def __init__(self): - self.registrations = {} + self.registrations = {} def register(self, path, callable_): - self.registrations[path] = callable_ + self.registrations[path] = callable_ if __name__ == '__main__': config = Configurator() @@ -1021,27 +1011,27 @@ Registering Tweens A :term:`tween` (a contraction of the word "between") is a bit of code that sits between the Pyramid router's main request handling function and the upstream WSGI component that uses :app:`Pyramid` as its "app". This is a -feature that may be used by Pyramid framework extensions, to provide, for +feature that may be used by Pyramid framework extensions to provide, for example, Pyramid-specific view timing support bookkeeping code that examines exceptions before they are returned to the upstream WSGI application. Tweens -behave a bit like :term:`WSGI` :term:`middleware` but they have the benefit of +behave a bit like :term:`WSGI` :term:`middleware`, but they have the benefit of running in a context in which they have access to the Pyramid :term:`request`, -:term:`response` and :term:`application registry` as well as the Pyramid +:term:`response`, and :term:`application registry`, as well as the Pyramid rendering machinery. Creating a Tween ~~~~~~~~~~~~~~~~ -To create a tween, you must write a "tween factory". A tween factory -must be a globally importable callable which accepts two arguments: -``handler`` and ``registry``. ``handler`` will be either the main -Pyramid request handling function or another tween. ``registry`` will be the -Pyramid :term:`application registry` represented by this Configurator. A -tween factory must return the tween (a callable object) when it is called. +To create a tween, you must write a "tween factory". A tween factory must be a +globally importable callable which accepts two arguments: ``handler`` and +``registry``. ``handler`` will be either the main Pyramid request handling +function or another tween. ``registry`` will be the Pyramid :term:`application +registry` represented by this Configurator. A tween factory must return the +tween (a callable object) when it is called. A tween is called with a single argument, ``request``, which is the -:term:`request` created by Pyramid's router when it receives a WSGI request. -A tween should return a :term:`response`, usually the one generated by the +:term:`request` created by Pyramid's router when it receives a WSGI request. A +tween should return a :term:`response`, usually the one generated by the downstream Pyramid application. You can write the tween factory as a simple closure-returning function: @@ -1089,14 +1079,14 @@ method: return response -You should avoid mutating any state on the tween instance. The tween is -invoked once per request and any shared mutable state needs to be carefully -handled to avoid any race conditions. +You should avoid mutating any state on the tween instance. The tween is invoked +once per request and any shared mutable state needs to be carefully handled to +avoid any race conditions. The closure style performs slightly better and enables you to conditionally omit the tween from the request processing pipeline (see the following timing tween example), whereas the class style makes it easier to have shared mutable -state, and it allows subclassing. +state and allows subclassing. Here's a complete example of a tween that logs the time spent processing each request: @@ -1131,13 +1121,12 @@ request: In the above example, the tween factory defines a ``timing_tween`` tween and returns it if ``asbool(registry.settings.get('do_timing'))`` is true. It -otherwise simply returns the handler it was given. The ``registry.settings`` -attribute is a handle to the deployment settings provided by the user -(usually in an ``.ini`` file). In this case, if the user has defined a -``do_timing`` setting, and that setting is ``True``, the user has said she -wants to do timing, so the tween factory returns the timing tween; it -otherwise just returns the handler it has been provided, preventing any -timing. +otherwise simply returns the handler which it was given. The +``registry.settings`` attribute is a handle to the deployment settings provided +by the user (usually in an ``.ini`` file). In this case, if the user has +defined a ``do_timing`` setting and that setting is ``True``, the user has said +they want to do timing, so the tween factory returns the timing tween; it +otherwise just returns the handler it has been provided, preventing any timing. The example timing tween simply records the start time, calls the downstream handler, logs the number of seconds consumed by the downstream handler, and @@ -1163,29 +1152,28 @@ Pyramid application: Note that you must use a :term:`dotted Python name` as the first argument to :meth:`pyramid.config.Configurator.add_tween`; this must point at a tween factory. You cannot pass the tween factory object itself to the method: it -must be :term:`dotted Python name` that points to a globally importable -object. In the above example, we assume that a ``timing_tween_factory`` -tween factory was defined in a module named ``myapp.tweens``, so the tween -factory is importable as ``myapp.tweens.timing_tween_factory``. - -When you use :meth:`pyramid.config.Configurator.add_tween`, you're -instructing the system to use your tween factory at startup time unless the -user has provided an explicit tween list in his configuration. This is -what's meant by an "implicit" tween. A user can always elect to supply an -explicit tween list, reordering or disincluding implicitly added tweens. See +must be :term:`dotted Python name` that points to a globally importable object. +In the above example, we assume that a ``timing_tween_factory`` tween factory +was defined in a module named ``myapp.tweens``, so the tween factory is +importable as ``myapp.tweens.timing_tween_factory``. + +When you use :meth:`pyramid.config.Configurator.add_tween`, you're instructing +the system to use your tween factory at startup time unless the user has +provided an explicit tween list in their configuration. This is what's meant +by an "implicit" tween. A user can always elect to supply an explicit tween +list, reordering or disincluding implicitly added tweens. See :ref:`explicit_tween_ordering` for more information about explicit tween ordering. -If more than one call to :meth:`pyramid.config.Configurator.add_tween` is -made within a single application configuration, the tweens will be chained -together at application startup time. The *first* tween factory added via -``add_tween`` will be called with the Pyramid exception view tween factory as -its ``handler`` argument, then the tween factory added directly after that -one will be called with the result of the first tween factory as its -``handler`` argument, and so on, ad infinitum until all tween factories have -been called. The Pyramid router will use the outermost tween produced by this -chain (the tween generated by the very last tween factory added) as its -request handler function. For example: +If more than one call to :meth:`pyramid.config.Configurator.add_tween` is made +within a single application configuration, the tweens will be chained together +at application startup time. The *first* tween factory added via ``add_tween`` +will be called with the Pyramid exception view tween factory as its ``handler`` +argument, then the tween factory added directly after that one will be called +with the result of the first tween factory as its ``handler`` argument, and so +on, ad infinitum until all tween factories have been called. The Pyramid router +will use the outermost tween produced by this chain (the tween generated by the +very last tween factory added) as its request handler function. For example: .. code-block:: python :linenos: @@ -1196,8 +1184,7 @@ request handler function. For example: config.add_tween('myapp.tween_factory1') config.add_tween('myapp.tween_factory2') -The above example will generate an implicit tween chain that looks like -this:: +The above example will generate an implicit tween chain that looks like this:: INGRESS (implicit) myapp.tween_factory2 @@ -1211,37 +1198,36 @@ Suggesting Implicit Tween Ordering By default, as described above, the ordering of the chain is controlled entirely by the relative ordering of calls to :meth:`pyramid.config.Configurator.add_tween`. However, the caller of -add_tween can provide an optional hint that can influence the implicit tween -chain ordering by supplying ``under`` or ``over`` (or both) arguments to -:meth:`~pyramid.config.Configurator.add_tween`. These hints are only -used when an explicit tween ordering is not used. See -:ref:`explicit_tween_ordering` for a description of how to set an explicit -tween ordering. +``add_tween`` can provide an optional hint that can influence the implicit +tween chain ordering by supplying ``under`` or ``over`` (or both) arguments to +:meth:`~pyramid.config.Configurator.add_tween`. These hints are only used when +an explicit tween ordering is not used. See :ref:`explicit_tween_ordering` for +a description of how to set an explicit tween ordering. Allowable values for ``under`` or ``over`` (or both) are: -- ``None`` (the default). +- ``None`` (the default), -- A :term:`dotted Python name` to a tween factory: a string representing the - predicted dotted name of a tween factory added in a call to ``add_tween`` - in the same configuration session. +- a :term:`dotted Python name` to a tween factory: a string representing the + predicted dotted name of a tween factory added in a call to ``add_tween`` in + the same configuration session, -- One of the constants :attr:`pyramid.tweens.MAIN`, - :attr:`pyramid.tweens.INGRESS`, or :attr:`pyramid.tweens.EXCVIEW`. +- one of the constants :attr:`pyramid.tweens.MAIN`, + :attr:`pyramid.tweens.INGRESS`, or :attr:`pyramid.tweens.EXCVIEW`, or -- An iterable of any combination of the above. This allows the user to specify +- an iterable of any combination of the above. This allows the user to specify fallbacks if the desired tween is not included, as well as compatibility with multiple other tweens. -Effectively, ``over`` means "closer to the request ingress than" and -``under`` means "closer to the main Pyramid application than". -You can think of an onion with outer layers over the inner layers, -the application being under all the layers at the center. +Effectively, ``over`` means "closer to the request ingress than" and ``under`` +means "closer to the main Pyramid application than". You can think of an onion +with outer layers over the inner layers, the application being under all the +layers at the center. For example, the following call to -:meth:`~pyramid.config.Configurator.add_tween` will attempt to place the -tween factory represented by ``myapp.tween_factory`` directly 'above' (in -``ptweens`` order) the main Pyramid request handler. +:meth:`~pyramid.config.Configurator.add_tween` will attempt to place the tween +factory represented by ``myapp.tween_factory`` directly "above" (in ``ptweens`` +order) the main Pyramid request handler. .. code-block:: python :linenos: @@ -1250,8 +1236,7 @@ tween factory represented by ``myapp.tween_factory`` directly 'above' (in config.add_tween('myapp.tween_factory', over=pyramid.tweens.MAIN) -The above example will generate an implicit tween chain that looks like -this:: +The above example will generate an implicit tween chain that looks like this:: INGRESS (implicit) pyramid.tweens.excview_tween_factory (implicit) @@ -1259,9 +1244,8 @@ this:: MAIN (implicit) Likewise, calling the following call to -:meth:`~pyramid.config.Configurator.add_tween` will attempt to place this -tween factory 'above' the main handler but 'below' a separately added tween -factory: +:meth:`~pyramid.config.Configurator.add_tween` will attempt to place this tween +factory "above" the main handler but "below" a separately added tween factory: .. code-block:: python :linenos: @@ -1274,8 +1258,7 @@ factory: over=pyramid.tweens.MAIN, under='myapp.tween_factory1') -The above example will generate an implicit tween chain that looks like -this:: +The above example will generate an implicit tween chain that looks like this:: INGRESS (implicit) pyramid.tweens.excview_tween_factory (implicit) @@ -1288,28 +1271,28 @@ Specifying neither ``over`` nor ``under`` is equivalent to specifying If all options for ``under`` (or ``over``) cannot be found in the current configuration, it is an error. If some options are specified purely for -compatibilty with other tweens, just add a fallback of MAIN or INGRESS. -For example, ``under=('someothertween', 'someothertween2', INGRESS)``. -This constraint will require the tween to be located under both the -'someothertween' tween, the 'someothertween2' tween, and INGRESS. If any of -these is not in the current configuration, this constraint will only organize -itself based on the tweens that are present. +compatibilty with other tweens, just add a fallback of ``MAIN`` or ``INGRESS``. +For example, ``under=('someothertween', 'someothertween2', INGRESS)``. This +constraint will require the tween to be located under the ``someothertween`` +tween, the ``someothertween2`` tween, and ``INGRESS``. If any of these is not +in the current configuration, this constraint will only organize itself based +on the tweens that are present. .. _explicit_tween_ordering: Explicit Tween Ordering ~~~~~~~~~~~~~~~~~~~~~~~ -Implicit tween ordering is obviously only best-effort. Pyramid will attempt -to provide an implicit order of tweens as best it can using hints provided by -calls to :meth:`~pyramid.config.Configurator.add_tween`, but because it's -only best-effort, if very precise tween ordering is required, the only -surefire way to get it is to use an explicit tween order. The deploying user -can override the implicit tween inclusion and ordering implied by calls to +Implicit tween ordering is obviously only best-effort. Pyramid will attempt to +provide an implicit order of tweens as best it can using hints provided by +calls to :meth:`~pyramid.config.Configurator.add_tween`. But because it's only +best-effort, if very precise tween ordering is required, the only surefire way +to get it is to use an explicit tween order. The deploying user can override +the implicit tween inclusion and ordering implied by calls to :meth:`~pyramid.config.Configurator.add_tween` entirely by using the ``pyramid.tweens`` settings value. When used, this settings value must be a -list of Python dotted names which will override the ordering (and inclusion) -of tween factories in the implicit tween chain. For example: +list of Python dotted names which will override the ordering (and inclusion) of +tween factories in the implicit tween chain. For example: .. code-block:: ini :linenos: @@ -1327,19 +1310,19 @@ of tween factories in the implicit tween chain. For example: In the above configuration, calls made during configuration to :meth:`pyramid.config.Configurator.add_tween` are ignored, and the user is telling the system to use the tween factories he has listed in the -``pyramid.tweens`` configuration setting (each is a :term:`dotted Python -name` which points to a tween factory) instead of any tween factories added -via :meth:`pyramid.config.Configurator.add_tween`. The *first* tween factory -in the ``pyramid.tweens`` list will be used as the producer of the effective +``pyramid.tweens`` configuration setting (each is a :term:`dotted Python name` +which points to a tween factory) instead of any tween factories added via +:meth:`pyramid.config.Configurator.add_tween`. The *first* tween factory in +the ``pyramid.tweens`` list will be used as the producer of the effective :app:`Pyramid` request handling function; it will wrap the tween factory -declared directly "below" it, ad infinitum. The "main" Pyramid request -handler is implicit, and always "at the bottom". +declared directly "below" it, ad infinitum. The "main" Pyramid request handler +is implicit, and always "at the bottom". .. note:: - Pyramid's own :term:`exception view` handling logic is implemented - as a tween factory function: :func:`pyramid.tweens.excview_tween_factory`. - If Pyramid exception view handling is desired, and tween factories are + Pyramid's own :term:`exception view` handling logic is implemented as a + tween factory function: :func:`pyramid.tweens.excview_tween_factory`. If + Pyramid exception view handling is desired, and tween factories are specified via the ``pyramid.tweens`` configuration setting, the :func:`pyramid.tweens.excview_tween_factory` function must be added to the ``pyramid.tweens`` configuration setting list explicitly. If it is not @@ -1348,30 +1331,30 @@ handler is implicit, and always "at the bottom". Tween Conflicts and Ordering Cycles ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid will prevent the same tween factory from being added to the tween -chain more than once using configuration conflict detection. If you wish to -add the same tween factory more than once in a configuration, you should -either: a) use a tween factory that is a separate globally importable -instance object from the factory that it conflicts with b) use a function or -class as a tween factory with the same logic as the other tween factory it -conflicts with but with a different ``__name__`` attribute or c) call +Pyramid will prevent the same tween factory from being added to the tween chain +more than once using configuration conflict detection. If you wish to add the +same tween factory more than once in a configuration, you should either: (a) +use a tween factory that is a separate globally importable instance object from +the factory that it conflicts with; (b) use a function or class as a tween +factory with the same logic as the other tween factory it conflicts with, but +with a different ``__name__`` attribute; or (c) call :meth:`pyramid.config.Configurator.commit` between calls to :meth:`pyramid.config.Configurator.add_tween`. If a cycle is detected in implicit tween ordering when ``over`` and ``under`` -are used in any call to "add_tween", an exception will be raised at startup +are used in any call to ``add_tween``, an exception will be raised at startup time. Displaying Tween Ordering ~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``ptweens`` command-line utility can be used to report the current -implict and explicit tween chains used by an application. See +The ``ptweens`` command-line utility can be used to report the current implict +and explicit tween chains used by an application. See :ref:`displaying_tweens`. .. _registering_thirdparty_predicates: -Adding A Third Party View, Route, or Subscriber Predicate +Adding a Third Party View, Route, or Subscriber Predicate --------------------------------------------------------- .. versionadded:: 1.4 @@ -1381,10 +1364,10 @@ Adding A Third Party View, Route, or Subscriber Predicate View and Route Predicates ~~~~~~~~~~~~~~~~~~~~~~~~~ -View and route predicates used during configuration allow you to narrow the -set of circumstances under which a view or route will match. For example, -the ``request_method`` view predicate can be used to ensure a view callable -is only invoked when the request's method is ``POST``: +View and route predicates used during configuration allow you to narrow the set +of circumstances under which a view or route will match. For example, the +``request_method`` view predicate can be used to ensure a view callable is only +invoked when the request's method is ``POST``: .. code-block:: python @@ -1398,9 +1381,9 @@ Likewise, a similar predicate can be used as a *route* predicate: config.add_route('name', '/foo', request_method='POST') -Many other built-in predicates exists (``request_param``, and others). You -can add third-party predicates to the list of available predicates by using -one of :meth:`pyramid.config.Configurator.add_view_predicate` or +Many other built-in predicates exists (``request_param``, and others). You can +add third-party predicates to the list of available predicates by using one of +:meth:`pyramid.config.Configurator.add_view_predicate` or :meth:`pyramid.config.Configurator.add_route_predicate`. The former adds a view predicate, the latter a route predicate. @@ -1428,7 +1411,7 @@ the name, is a string representing the name that is expected to be passed to The second argument is a view or route predicate factory, or a :term:`dotted Python name` which refers to a view or route predicate factory. A view or route predicate factory is most often a class with a constructor -(``__init__``), a ``text`` method, a ``phash`` method and a ``__call__`` +(``__init__``), a ``text`` method, a ``phash`` method, and a ``__call__`` method. For example: .. code-block:: python @@ -1448,27 +1431,27 @@ method. For example: The constructor of a predicate factory takes two arguments: ``val`` and ``config``. The ``val`` argument will be the argument passed to -``view_config`` (or ``add_view``). In the example above, it will be the -string ``File``. The second arg, ``config`` will be the Configurator -instance at the time of configuration. +``view_config`` (or ``add_view``). In the example above, it will be the string +``File``. The second argument, ``config``, will be the Configurator instance +at the time of configuration. -The ``text`` method must return a string. It should be useful to describe -the behavior of the predicate in error messages. +The ``text`` method must return a string. It should be useful to describe the +behavior of the predicate in error messages. -The ``phash`` method must return a string or a sequence of strings. It's -most often the same as ``text``, as long as ``text`` uniquely describes the -predicate's name and the value passed to the constructor. If ``text`` is -more general, or doesn't describe things that way, ``phash`` should return a -string with the name and the value serialized. The result of ``phash`` is -not seen in output anywhere, it just informs the uniqueness constraints for -view configuration. +The ``phash`` method must return a string or a sequence of strings. It's most +often the same as ``text``, as long as ``text`` uniquely describes the +predicate's name and the value passed to the constructor. If ``text`` is more +general, or doesn't describe things that way, ``phash`` should return a string +with the name and the value serialized. The result of ``phash`` is not seen in +output anywhere, it just informs the uniqueness constraints for view +configuration. The ``__call__`` method of a predicate factory must accept a resource -(``context``) and a request, and must return ``True`` or ``False``. It is -the "meat" of the predicate. +(``context``) and a request, and must return ``True`` or ``False``. It is the +"meat" of the predicate. -You can use the same predicate factory as both a view predicate and as a -route predicate, but you'll need to call ``add_view_predicate`` and +You can use the same predicate factory as both a view predicate and as a route +predicate, but you'll need to call ``add_view_predicate`` and ``add_route_predicate`` separately with the same factory. .. _subscriber_predicates: @@ -1476,16 +1459,16 @@ route predicate, but you'll need to call ``add_view_predicate`` and Subscriber Predicates ~~~~~~~~~~~~~~~~~~~~~ -Subscriber predicates work almost exactly like view and route predicates. -They narrow the set of circumstances in which a subscriber will be called. -There are several minor differences between a subscriber predicate and a -view/route predicate: +Subscriber predicates work almost exactly like view and route predicates. They +narrow the set of circumstances in which a subscriber will be called. There are +several minor differences between a subscriber predicate and a view or route +predicate: - There are no default subscriber predicates. You must register one to use one. -- The ``__call__`` method of a subscriber predicate accepts a single - ``event`` object instead of a ``context`` and a ``request``. +- The ``__call__`` method of a subscriber predicate accepts a single ``event`` + object instead of a ``context`` and a ``request``. - Not every subscriber predicate can be used with every event type. Some subscriber predicates will assume a certain event type. @@ -1519,8 +1502,8 @@ Once you've created a subscriber predicate, it may registered via Once a subscriber predicate is registered, you can use it in a call to :meth:`pyramid.config.Configurator.add_subscriber` or to -:class:`pyramid.events.subscriber`. Here's an example of using the -previously registered ``request_path_startswith`` predicate in a call to +:class:`pyramid.events.subscriber`. Here's an example of using the previously +registered ``request_path_startswith`` predicate in a call to :meth:`~pyramid.config.Configurator.add_subscriber`: .. code-block:: python @@ -1533,7 +1516,7 @@ previously registered ``request_path_startswith`` predicate in a call to # and at configuration time - config.add_subscriber(yosubscriber, NewRequest, + config.add_subscriber(yosubscriber, NewRequest, request_path_startswith='/add_yo') Here's the same subscriber/predicate/event-type combination used via @@ -1548,22 +1531,19 @@ Here's the same subscriber/predicate/event-type combination used via def yosubscriber(event): event.request.yo = 'YO!' -In either of the above configurations, the ``yosubscriber`` callable will -only be called if the request path starts with ``/add_yo``. Otherwise the -event subscriber will not be called. +In either of the above configurations, the ``yosubscriber`` callable will only +be called if the request path starts with ``/add_yo``. Otherwise the event +subscriber will not be called. Note that the ``request_path_startswith`` subscriber you defined can be used with events that have a ``request`` attribute, but not ones that do not. So, for example, the predicate can be used with subscribers registered for :class:`pyramid.events.NewRequest` and :class:`pyramid.events.ContextFound` events, but it cannot be used with subscribers registered for -:class:`pyramid.events.ApplicationCreated` because the latter type of event -has no ``request`` attribute. The point being: unlike route and view -predicates, not every type of subscriber predicate will necessarily be -applicable for use 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. - - - +:class:`pyramid.events.ApplicationCreated` because the latter type of event has +no ``request`` attribute. The point being, unlike route and view predicates, +not every type of subscriber predicate will necessarily be applicable for use +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. -- cgit v1.2.3 From 59a125a312db3cba9c488f53fef08272b387129e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 4 Nov 2015 04:40:29 -0800 Subject: update tb_introspector.png, minor grammar, fix .rst markup, rewrap to 79 columns --- docs/narr/introspector.rst | 121 ++++++++++++++++++++---------------------- docs/narr/tb_introspector.png | Bin 95962 -> 181225 bytes 2 files changed, 59 insertions(+), 62 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 8caba522c..9400b6cf3 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -20,8 +20,7 @@ configuration settings. Using the Introspector ---------------------- -Here's an example of using Pyramid's introspector from within a view -callable: +Here's an example of using Pyramid's introspector from within a view callable: .. code-block:: python :linenos: @@ -36,10 +35,10 @@ callable: route_intr = introspector.get('routes', route_name) return Response(str(route_intr['pattern'])) -This view will return a response that contains the "pattern" argument -provided to the ``add_route`` method of the route which matched when the view -was called. It uses the :meth:`pyramid.interfaces.IIntrospector.get` method -to return an introspectable in the category ``routes`` with a +This view will return a response that contains the "pattern" argument provided +to the ``add_route`` method of the route which matched when the view was +called. It uses the :meth:`pyramid.interfaces.IIntrospector.get` method to +return an introspectable in the category ``routes`` with a :term:`discriminator` equal to the matched route name. It then uses the returned introspectable to obtain a "pattern" value. @@ -56,9 +55,9 @@ can be used to query for introspectables. Introspectable Objects ---------------------- -Introspectable objects are returned from query methods of an introspector. -Each introspectable object implements the attributes and methods -documented at :class:`pyramid.interfaces.IIntrospectable`. +Introspectable objects are returned from query methods of an introspector. Each +introspectable object implements the attributes and methods documented at +:class:`pyramid.interfaces.IIntrospectable`. The important attributes shared by all introspectables are the following: @@ -74,12 +73,12 @@ The important attributes shared by all introspectables are the following: ``discriminator`` - A hashable object representing the unique value of this introspectable - within its category. + A hashable object representing the unique value of this introspectable within + its category. ``discriminator_hash`` - The integer hash of the discriminator (useful for using in HTML links). + The integer hash of the discriminator (useful in HTML links). ``type_name`` @@ -90,8 +89,8 @@ The important attributes shared by all introspectables are the following: ``action_info`` - An object describing the directive call site which caused this - introspectable to be registered; contains attributes described in + An object describing the directive call site which caused this introspectable + to be registered. It contains attributes described in :class:`pyramid.interfaces.IActionInfo`. Besides having the attributes described above, an introspectable is a @@ -116,7 +115,7 @@ introspectables in categories not described here. Each introspectable in the ``subscribers`` category represents a call to :meth:`pyramid.config.Configurator.add_subscriber` (or the decorator - equivalent); each will have the following data. + equivalent). Each will have the following data. ``subscriber`` @@ -149,7 +148,7 @@ introspectables in categories not described here. Each introspectable in the ``response adapters`` category represents a call to :meth:`pyramid.config.Configurator.add_response_adapter` (or a decorator - equivalent); each will have the following data. + equivalent). Each will have the following data. ``adapter`` @@ -158,15 +157,14 @@ introspectables in categories not described here. ``type`` - The resolved ``type_or_iface`` argument passed to - ``add_response_adapter``. + The resolved ``type_or_iface`` argument passed to ``add_response_adapter``. ``root factories`` Each introspectable in the ``root factories`` category represents a call to :meth:`pyramid.config.Configurator.set_root_factory` (or the Configurator constructor equivalent) *or* a ``factory`` argument passed to - :meth:`pyramid.config.Configurator.add_route`; each will have the following + :meth:`pyramid.config.Configurator.add_route`. Each will have the following data. ``factory`` @@ -184,7 +182,7 @@ introspectables in categories not described here. Only one introspectable will exist in the ``session factory`` category. It represents a call to :meth:`pyramid.config.Configurator.set_session_factory` - (or the Configurator constructor equivalent); it will have the following + (or the Configurator constructor equivalent). It will have the following data. ``factory`` @@ -196,7 +194,7 @@ introspectables in categories not described here. Only one introspectable will exist in the ``request factory`` category. It represents a call to :meth:`pyramid.config.Configurator.set_request_factory` - (or the Configurator constructor equivalent); it will have the following + (or the Configurator constructor equivalent). It will have the following data. ``factory`` @@ -206,10 +204,10 @@ introspectables in categories not described here. ``locale negotiator`` - Only one introspectable will exist in the ``locale negotiator`` category. - It represents a call to + Only one introspectable will exist in the ``locale negotiator`` category. It + represents a call to :meth:`pyramid.config.Configurator.set_locale_negotiator` (or the - Configurator constructor equivalent); it will have the following data. + Configurator constructor equivalent). It will have the following data. ``negotiator`` @@ -218,9 +216,9 @@ introspectables in categories not described here. ``renderer factories`` - Each introspectable in the ``renderer factories`` category represents a - call to :meth:`pyramid.config.Configurator.add_renderer` (or the - Configurator constructor equivalent); each will have the following data. + Each introspectable in the ``renderer factories`` category represents a call + to :meth:`pyramid.config.Configurator.add_renderer` (or the Configurator + constructor equivalent). Each will have the following data. ``name`` @@ -229,13 +227,12 @@ introspectables in categories not described here. ``factory`` - The factory object (the resolved ``factory`` argument to - ``add_renderer``). + The factory object (the resolved ``factory`` argument to ``add_renderer``). ``routes`` Each introspectable in the ``routes`` category represents a call to - :meth:`pyramid.config.Configurator.add_route`; each will have the following + :meth:`pyramid.config.Configurator.add_route`. Each will have the following data. ``name`` @@ -310,7 +307,7 @@ introspectables in categories not described here. There will be one and only one introspectable in the ``authentication policy`` category. It represents a call to the :meth:`pyramid.config.Configurator.set_authentication_policy` method (or - its Configurator constructor equivalent); it will have the following data. + its Configurator constructor equivalent). It will have the following data. ``policy`` @@ -319,10 +316,10 @@ introspectables in categories not described here. ``authorization policy`` - There will be one and only one introspectable in the ``authorization - policy`` category. It represents a call to the + There will be one and only one introspectable in the ``authorization policy`` + category. It represents a call to the :meth:`pyramid.config.Configurator.set_authorization_policy` method (or its - Configurator constructor equivalent); it will have the following data. + Configurator constructor equivalent). It will have the following data. ``policy`` @@ -334,7 +331,7 @@ introspectables in categories not described here. There will be one and only one introspectable in the ``default permission`` category. It represents a call to the :meth:`pyramid.config.Configurator.set_default_permission` method (or its - Configurator constructor equivalent); it will have the following data. + Configurator constructor equivalent). It will have the following data. ``value`` @@ -343,7 +340,7 @@ introspectables in categories not described here. ``views`` Each introspectable in the ``views`` category represents a call to - :meth:`pyramid.config.Configurator.add_view`; each will have the following + :meth:`pyramid.config.Configurator.add_view`. Each will have the following data. ``name`` @@ -423,8 +420,8 @@ introspectables in categories not described here. Each introspectable in the ``permissions`` category represents a call to :meth:`pyramid.config.Configurator.add_view` that has an explicit - ``permission`` argument to *or* a call to - :meth:`pyramid.config.Configurator.set_default_permission`; each will have + ``permission`` argument *or* a call to + :meth:`pyramid.config.Configurator.set_default_permission`. Each will have the following data. ``value`` @@ -435,7 +432,7 @@ introspectables in categories not described here. Each introspectable in the ``templates`` category represents a call to :meth:`pyramid.config.Configurator.add_view` that has a ``renderer`` - argument which points to a template; each will have the following data. + argument which points to a template. Each will have the following data. ``name`` @@ -447,15 +444,15 @@ introspectables in categories not described here. ``renderer`` - The :class:`pyramid.interfaces.IRendererInfo` object which represents - this template's renderer. + The :class:`pyramid.interfaces.IRendererInfo` object which represents this + template's renderer. ``view mappers`` Each introspectable in the ``view mappers`` category represents a call to - :meth:`pyramid.config.Configurator.add_view` that has an explicit - ``mapper`` argument to *or* a call to - :meth:`pyramid.config.Configurator.set_view_mapper`; each will have + :meth:`pyramid.config.Configurator.add_view` that has an explicit ``mapper`` + argument *or* a call to + :meth:`pyramid.config.Configurator.set_view_mapper`. Each will have the following data. ``mapper`` @@ -465,14 +462,13 @@ introspectables in categories not described here. ``asset overrides`` - Each introspectable in the ``asset overrides`` category represents a call - to :meth:`pyramid.config.Configurator.override_asset`; each will have the + Each introspectable in the ``asset overrides`` category represents a call to + :meth:`pyramid.config.Configurator.override_asset`. Each will have the following data. ``to_override`` - The ``to_override`` argument (an asset spec) passed to - ``override_asset``. + The ``to_override`` argument (an asset spec) passed to ``override_asset``. ``override_with`` @@ -481,10 +477,10 @@ introspectables in categories not described here. ``translation directories`` - Each introspectable in the ``translation directories`` category represents - an individual element in a ``specs`` argument passed to - :meth:`pyramid.config.Configurator.add_translation_dirs`; each will have - the following data. + Each introspectable in the ``translation directories`` category represents an + individual element in a ``specs`` argument passed to + :meth:`pyramid.config.Configurator.add_translation_dirs`. Each will have the + following data. ``directory`` @@ -497,13 +493,13 @@ introspectables in categories not described here. ``tweens`` Each introspectable in the ``tweens`` category represents a call to - :meth:`pyramid.config.Configurator.add_tween`; each will have the following + :meth:`pyramid.config.Configurator.add_tween`. Each will have the following data. ``name`` - The dotted name to the tween factory as a string (passed as - the ``tween_factory`` argument to ``add_tween``). + The dotted name to the tween factory as a string (passed as the + ``tween_factory`` argument to ``add_tween``). ``factory`` @@ -524,7 +520,7 @@ introspectables in categories not described here. ``static views`` Each introspectable in the ``static views`` category represents a call to - :meth:`pyramid.config.Configurator.add_static_view`; each will have the + :meth:`pyramid.config.Configurator.add_static_view`. Each will have the following data. ``name`` @@ -539,13 +535,13 @@ introspectables in categories not described here. ``traversers`` Each introspectable in the ``traversers`` category represents a call to - :meth:`pyramid.config.Configurator.add_traverser`; each will have the + :meth:`pyramid.config.Configurator.add_traverser`. Each will have the following data. ``iface`` The (resolved) interface or class object that represents the return value - of a root factory that this traverser will be used for. + of a root factory for which this traverser will be used. ``adapter`` @@ -554,7 +550,7 @@ introspectables in categories not described here. ``resource url adapters`` Each introspectable in the ``resource url adapters`` category represents a - call to :meth:`pyramid.config.Configurator.add_resource_url_adapter`; each + call to :meth:`pyramid.config.Configurator.add_resource_url_adapter`. Each will have the following data. ``adapter`` @@ -564,19 +560,20 @@ introspectables in categories not described here. ``resource_iface`` The (resolved) interface or class object that represents the resource - interface that this url adapter is registered for. + interface for which this URL adapter is registered. ``request_iface`` The (resolved) interface or class object that represents the request - interface that this url adapter is registered for. + interface for which this URL adapter is registered. Introspection in the Toolbar ---------------------------- The Pyramid debug toolbar (part of the ``pyramid_debugtoolbar`` package) provides a canned view of all registered introspectables and their -relationships. It looks something like this: +relationships. It is currently under the "Global" tab in the main navigation, +and it looks something like this: .. image:: tb_introspector.png diff --git a/docs/narr/tb_introspector.png b/docs/narr/tb_introspector.png index 4ae406a86..b00d36067 100644 Binary files a/docs/narr/tb_introspector.png and b/docs/narr/tb_introspector.png differ -- cgit v1.2.3 From edb8bcae06029543530a43ad99f1be91dedaf88b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 4 Nov 2015 05:02:02 -0800 Subject: add missing period (cherry picked from commit c7b1bff) --- docs/narr/introspector.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr') diff --git a/docs/narr/introspector.rst b/docs/narr/introspector.rst index 9400b6cf3..98315ac9f 100644 --- a/docs/narr/introspector.rst +++ b/docs/narr/introspector.rst @@ -136,7 +136,7 @@ introspectables in categories not described here. ``predicates`` The predicate objects created as the result of passing predicate arguments - to ``add_subscriber`` + to ``add_subscriber``. ``derived_predicates`` -- cgit v1.2.3 From 857511d2b575ed7d4d7fee9235d94802bc1bb584 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 5 Nov 2015 17:11:10 -0800 Subject: minor grammar, fix .rst markup, rewrap to 79 columns --- docs/narr/extending.rst | 194 ++++++++++++++++++++++++------------------------ 1 file changed, 95 insertions(+), 99 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extending.rst b/docs/narr/extending.rst index 8462a9da7..d28eb341d 100644 --- a/docs/narr/extending.rst +++ b/docs/narr/extending.rst @@ -1,13 +1,13 @@ .. _extending_chapter: -Extending An Existing :app:`Pyramid` Application -=================================================== +Extending an Existing :app:`Pyramid` Application +================================================ -If a :app:`Pyramid` developer has obeyed certain constraints while building -an application, a third party should be able to change the application's -behavior without needing to modify its source code. The behavior of a -:app:`Pyramid` application that obeys certain constraints can be *overridden* -or *extended* without modification. +If a :app:`Pyramid` developer has obeyed certain constraints while building an +application, a third party should be able to change the application's behavior +without needing to modify its source code. The behavior of a :app:`Pyramid` +application that obeys certain constraints can be *overridden* or *extended* +without modification. We'll define some jargon here for the benefit of identifying the parties involved in such an effort. @@ -16,10 +16,10 @@ Developer The original application developer. Integrator - Another developer who wishes to reuse the application written by the - original application developer in an unanticipated context. He may also - wish to modify the original application without changing the original - application's source code. + Another developer who wishes to reuse the application written by the original + application developer in an unanticipated context. They may also wish to + modify the original application without changing the original application's + source code. The Difference Between "Extensible" and "Pluggable" Applications ---------------------------------------------------------------- @@ -27,31 +27,31 @@ The Difference Between "Extensible" and "Pluggable" Applications Other web frameworks, such as :term:`Django`, advertise that they allow developers to create "pluggable applications". They claim that if you create an application in a certain way, it will be integratable in a sensible, -structured way into another arbitrarily-written application or project -created by a third-party developer. +structured way into another arbitrarily-written application or project created +by a third-party developer. :app:`Pyramid`, as a platform, does not claim to provide such a feature. The platform provides no guarantee that you can create an application and package it up such that an arbitrary integrator can use it as a subcomponent in a larger Pyramid application or project. Pyramid does not mandate the constraints necessary for such a pattern to work satisfactorily. Because -Pyramid is not very "opinionated", developers are able to use wildly -different patterns and technologies to build an application. A given Pyramid -application may happen to be reusable by a particular third party integrator, -because the integrator and the original developer may share similar base -technology choices (such as the use of a particular relational database or -ORM). But the same application may not be reusable by a different developer, -because he has made different technology choices which are incompatible with -the original developer's. +Pyramid is not very "opinionated", developers are able to use wildly different +patterns and technologies to build an application. A given Pyramid application +may happen to be reusable by a particular third party integrator because the +integrator and the original developer may share similar base technology choices +(such as the use of a particular relational database or ORM). But the same +application may not be reusable by a different developer, because they have +made different technology choices which are incompatible with the original +developer's. As a result, the concept of a "pluggable application" is left to layers built above Pyramid, such as a "CMS" layer or "application server" layer. Such -layers are apt to provide the necessary "opinions" (such as mandating a -storage layer, a templating system, and a structured, well-documented pattern -of registering that certain URLs map to certain bits of code) which makes the -concept of a "pluggable application" possible. "Pluggable applications", -thus, should not plug into Pyramid itself but should instead plug into a -system written atop Pyramid. +layers are apt to provide the necessary "opinions" (such as mandating a storage +layer, a templating system, and a structured, well-documented pattern of +registering that certain URLs map to certain bits of code) which makes the +concept of a "pluggable application" possible. "Pluggable applications", thus, +should not plug into Pyramid itself but should instead plug into a system +written atop Pyramid. Although it does not provide for "pluggable applications", Pyramid *does* provide a rich set of mechanisms which allows for the extension of a single @@ -64,13 +64,13 @@ Pyramid applications are *extensible*. .. _building_an_extensible_app: -Rules for Building An Extensible Application +Rules for Building an Extensible Application -------------------------------------------- There is only one rule you need to obey if you want to build a maximally extensible :app:`Pyramid` application: as a developer, you should factor any -overrideable :term:`imperative configuration` you've created into functions -which can be used via :meth:`pyramid.config.Configurator.include` rather than +overridable :term:`imperative configuration` you've created into functions +which can be used via :meth:`pyramid.config.Configurator.include`, rather than inlined as calls to methods of a :term:`Configurator` within the ``main`` function in your application's ``__init__.py``. For example, rather than: @@ -84,8 +84,8 @@ function in your application's ``__init__.py``. For example, rather than: config.add_view('myapp.views.view1', name='view1') config.add_view('myapp.views.view2', name='view2') -You should move the calls to ``add_view`` outside of the (non-reusable) -``if __name__ == '__main__'`` block, and into a reusable function: +You should move the calls to ``add_view`` outside of the (non-reusable) ``if +__name__ == '__main__'`` block, and into a reusable function: .. code-block:: python :linenos: @@ -100,13 +100,12 @@ You should move the calls to ``add_view`` outside of the (non-reusable) config.add_view('myapp.views.view1', name='view1') config.add_view('myapp.views.view2', name='view2') -Doing this allows an integrator to maximally reuse the configuration -statements that relate to your application by allowing him to selectively -include or disinclude the configuration functions you've created from an -"override package". +Doing this allows an integrator to maximally reuse the configuration statements +that relate to your application by allowing them to selectively include or +exclude the configuration functions you've created from an "override package". -Alternately, you can use :term:`ZCML` for the purpose of making configuration -extensible and overrideable. :term:`ZCML` declarations that belong to an +Alternatively you can use :term:`ZCML` for the purpose of making configuration +extensible and overridable. :term:`ZCML` declarations that belong to an application can be overridden and extended by integrators as necessary in a similar fashion. If you use only :term:`ZCML` to configure your application, it will automatically be maximally extensible without any manual effort. See @@ -115,16 +114,15 @@ it will automatically be maximally extensible without any manual effort. See Fundamental Plugpoints ~~~~~~~~~~~~~~~~~~~~~~ -The fundamental "plug points" of an application developed using -:app:`Pyramid` are *routes*, *views*, and *assets*. Routes are declarations -made using the :meth:`pyramid.config.Configurator.add_route` method. Views -are declarations made using the :meth:`pyramid.config.Configurator.add_view` -method. Assets are files that are -accessed by :app:`Pyramid` using the :term:`pkg_resources` API such as static -files and templates via a :term:`asset specification`. Other directives and -configurator methods also deal in routes, views, and assets. For example, the -``add_handler`` directive of the ``pyramid_handlers`` package adds a single -route, and some number of views. +The fundamental "plug points" of an application developed using :app:`Pyramid` +are *routes*, *views*, and *assets*. Routes are declarations made using the +:meth:`pyramid.config.Configurator.add_route` method. Views are declarations +made using the :meth:`pyramid.config.Configurator.add_view` method. Assets are +files that are accessed by :app:`Pyramid` using the :term:`pkg_resources` API +such as static files and templates via a :term:`asset specification`. Other +directives and configurator methods also deal in routes, views, and assets. +For example, the ``add_handler`` directive of the ``pyramid_handlers`` package +adds a single route and some number of views. .. index:: single: extending an existing application @@ -133,10 +131,9 @@ Extending an Existing Application --------------------------------- The steps for extending an existing application depend largely on whether the -application does or does not use configuration decorators and/or imperative -code. +application does or does not use configuration decorators or imperative code. -If The Application Has Configuration Decorations +If the Application Has Configuration Decorations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You've inherited a :app:`Pyramid` application which you'd like to extend or @@ -155,9 +152,9 @@ registers more views or routes. config.add_view('mypackage.views.myview', name='myview') If you want to *override* configuration in the application, you *may* need to -run :meth:`pyramid.config.Configurator.commit` after performing the scan of -the original package, then add additional configuration that registers more -views or routes which performs overrides. +run :meth:`pyramid.config.Configurator.commit` after performing the scan of the +original package, then add additional configuration that registers more views +or routes which perform overrides. .. code-block:: python :linenos: @@ -170,11 +167,11 @@ views or routes which performs overrides. Once this is done, you should be able to extend or override the application like any other (see :ref:`extending_the_application`). -You can alternately just prevent a :term:`scan` from happening (by omitting -any call to the :meth:`pyramid.config.Configurator.scan` method). This will +You can alternatively just prevent a :term:`scan` from happening by omitting +any call to the :meth:`pyramid.config.Configurator.scan` method. This will cause the decorators attached to objects in the target application to do -nothing. At this point, you will need to convert all the configuration done -in decorators into equivalent imperative configuration or ZCML and add that +nothing. At this point, you will need to convert all the configuration done in +decorators into equivalent imperative configuration or ZCML, and add that configuration or ZCML to a separate Python package as described in :ref:`extending_the_application`. @@ -183,37 +180,37 @@ configuration or ZCML to a separate Python package as described in Extending the Application ~~~~~~~~~~~~~~~~~~~~~~~~~ -To extend or override the behavior of an existing application, you will need -to create a new package which includes the configuration of the old package, -and you'll perhaps need to create implementations of the types of things -you'd like to override (such as views), which are referred to within the -original package. +To extend or override the behavior of an existing application, you will need to +create a new package which includes the configuration of the old package, and +you'll perhaps need to create implementations of the types of things you'd like +to override (such as views), to which they are referred within the original +package. -The general pattern for extending an existing application looks something -like this: +The general pattern for extending an existing application looks something like +this: - Create a new Python package. The easiest way to do this is to create a new :app:`Pyramid` application using the scaffold mechanism. See :ref:`creating_a_project` for more information. -- In the new package, create Python files containing views and other - overridden elements, such as templates and static assets as necessary. +- In the new package, create Python files containing views and other overridden + 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 + application (e.g., ``$VENV/bin/python setup.py develop`` or ``$VENV/bin/python setup.py install``). - Change the ``main`` function in the new package's ``__init__.py`` to include the original :app:`Pyramid` application's configuration functions via :meth:`pyramid.config.Configurator.include` statements or a :term:`scan`. -- Wire the new views and assets created in the new package up using - imperative registrations within the ``main`` function of the - ``__init__.py`` file of the new application. This wiring should happen - *after* including the configuration functions of the old application. - These registrations will extend or override any registrations performed by - the original application. See :ref:`overriding_views`, - :ref:`overriding_routes` and :ref:`overriding_resources`. +- Wire the new views and assets created in the new package up using imperative + registrations within the ``main`` function of the ``__init__.py`` file of the + new application. This wiring should happen *after* including the + configuration functions of the old application. These registrations will + extend or override any registrations performed by the original application. + See :ref:`overriding_views`, :ref:`overriding_routes`, and + :ref:`overriding_resources`. .. index:: pair: overriding; views @@ -221,17 +218,17 @@ like this: .. _overriding_views: Overriding Views -~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~ -The :term:`view configuration` declarations you make which *override* +The :term:`view configuration` declarations that you make which *override* application behavior will usually have the same :term:`view predicate` -attributes as the original you wish to override. These ```` -declarations will point at "new" view code, in the override package you've -created. The new view code itself will usually be cut-n-paste copies of view -callables from the original application with slight tweaks. +attributes as the original that you wish to override. These ```` +declarations will point at "new" view code in the override package that you've +created. The new view code itself will usually be copy-and-paste copies of +view callables from the original application with slight tweaks. -For example, if the original application has the following -``configure_views`` configuration method: +For example, if the original application has the following ``configure_views`` +configuration method: .. code-block:: python :linenos: @@ -254,13 +251,13 @@ configuration function: config.include(configure_views) config.add_view('theoverrideapp.views.theview', name='theview') -In this case, the ``theoriginalapp.views.theview`` view will never be -executed. Instead, a new view, ``theoverrideapp.views.theview`` will be -executed instead, when request circumstances dictate. +In this case, the ``theoriginalapp.views.theview`` view will never be executed. +Instead, a new view, ``theoverrideapp.views.theview`` will be executed when +request circumstances dictate. A similar pattern can be used to *extend* the application with ``add_view`` -declarations. Just register a new view against some other set of predicates -to make sure the URLs it implies are available on some other page rendering. +declarations. Just register a new view against some other set of predicates to +make sure the URLs it implies are available on some other page rendering. .. index:: pair: overriding; routes @@ -270,13 +267,13 @@ to make sure the URLs it implies are available on some other page rendering. Overriding Routes ~~~~~~~~~~~~~~~~~ -Route setup is currently typically performed in a sequence of ordered calls -to :meth:`~pyramid.config.Configurator.add_route`. Because these calls are +Route setup is currently typically performed in a sequence of ordered calls to +:meth:`~pyramid.config.Configurator.add_route`. Because these calls are ordered relative to each other, and because this ordering is typically important, you should retain their relative ordering when performing an -override. Typically, this means *copying* all the ``add_route`` statements -into the override package's file and changing them as necessary. Then -disinclude any ``add_route`` statements from the original application. +override. Typically this means *copying* all the ``add_route`` statements into +the override package's file and changing them as necessary. Then exclude any +``add_route`` statements from the original application. .. index:: pair: overriding; assets @@ -288,9 +285,8 @@ Overriding Assets Assets are files on the filesystem that are accessible within a Python *package*. An entire chapter is devoted to assets: :ref:`assets_chapter`. -Within this chapter is a section named :ref:`overriding_assets_section`. -This section of that chapter describes in detail how to override package -assets with other assets by using the -:meth:`pyramid.config.Configurator.override_asset` method. Add such -``override_asset`` calls to your override package's ``__init__.py`` to -perform overrides. +Within this chapter is a section named :ref:`overriding_assets_section`. This +section of that chapter describes in detail how to override package assets with +other assets by using the :meth:`pyramid.config.Configurator.override_asset` +method. Add such ``override_asset`` calls to your override package's +``__init__.py`` to perform overrides. -- cgit v1.2.3 From 1205ecbbb4e131b8eed0616a25e44cd3398b7a0f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 6 Nov 2015 00:05:11 -0800 Subject: minor grammar, fix .rst markup, add emphasize lines for diff, rewrap to 79 columns --- docs/narr/advconfig.rst | 133 +++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 68 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/advconfig.rst b/docs/narr/advconfig.rst index 9ceaaa495..ba9bd1352 100644 --- a/docs/narr/advconfig.rst +++ b/docs/narr/advconfig.rst @@ -6,12 +6,11 @@ Advanced Configuration ====================== -To support application extensibility, the :app:`Pyramid` -:term:`Configurator`, by default, detects configuration conflicts and allows -you to include configuration imperatively from other packages or modules. It -also, by default, performs configuration in two separate phases. This allows -you to ignore relative configuration statement ordering in some -circumstances. +To support application extensibility, the :app:`Pyramid` :term:`Configurator` +by default detects configuration conflicts and allows you to include +configuration imperatively from other packages or modules. It also by default +performs configuration in two separate phases. This allows you to ignore +relative configuration statement ordering in some circumstances. .. index:: pair: configuration; conflict detection @@ -70,11 +69,11 @@ try to add another view to the configuration with the same set of server = make_server('0.0.0.0', 8080, app) server.serve_forever() -The application now has two conflicting view configuration statements. When -we try to start it again, it won't start. Instead, we'll receive a traceback -that ends something like this: +The application now has two conflicting view configuration statements. When we +try to start it again, it won't start. Instead we'll receive a traceback that +ends something like this: -.. code-block:: guess +.. code-block:: text :linenos: Traceback (most recent call last): @@ -94,19 +93,19 @@ that ends something like this: This traceback is trying to tell us: -- We've got conflicting information for a set of view configuration - statements (The ``For:`` line). +- We've got conflicting information for a set of view configuration statements + (The ``For:`` line). - There are two statements which conflict, shown beneath the ``For:`` line: ``config.add_view(hello_world. 'hello')`` on line 14 of ``app.py``, and ``config.add_view(goodbye_world, 'hello')`` on line 17 of ``app.py``. -These two configuration statements are in conflict because we've tried to -tell the system that the set of :term:`predicate` values for both view +These two configuration statements are in conflict because we've tried to tell +the system that the set of :term:`predicate` values for both view configurations are exactly the same. Both the ``hello_world`` and ``goodbye_world`` views are configured to respond under the same set of -circumstances. This circumstance: the :term:`view name` (represented by the -``name=`` predicate) is ``hello``. +circumstances. This circumstance, the :term:`view name` represented by the +``name=`` predicate, is ``hello``. This presents an ambiguity that :app:`Pyramid` cannot resolve. Rather than allowing the circumstance to go unreported, by default Pyramid raises a @@ -138,8 +137,7 @@ made by your application. Use the detail provided in the modify your configuration code accordingly. If you're getting a conflict while trying to extend an existing application, -and that application has a function which performs configuration like this -one: +and that application has a function which performs configuration like this one: .. code-block:: python :linenos: @@ -147,8 +145,8 @@ one: def add_routes(config): config.add_route(...) -Don't call this function directly with ``config`` as an argument. Instead, -use :meth:`pyramid.config.Configurator.include`: +Don't call this function directly with ``config`` as an argument. Instead, use +:meth:`pyramid.config.Configurator.include`: .. code-block:: python :linenos: @@ -156,9 +154,9 @@ use :meth:`pyramid.config.Configurator.include`: config.include(add_routes) Using :meth:`~pyramid.config.Configurator.include` instead of calling the -function directly provides a modicum of automated conflict resolution, with -the configuration statements you define in the calling code overriding those -of the included function. +function directly provides a modicum of automated conflict resolution, with the +configuration statements you define in the calling code overriding those of the +included function. .. seealso:: @@ -169,10 +167,10 @@ Using ``config.commit()`` +++++++++++++++++++++++++ You can manually commit a configuration by using the -:meth:`~pyramid.config.Configurator.commit` method between configuration -calls. For example, we prevent conflicts from occurring in the application -we examined previously as the result of adding a ``commit``. Here's the -application that generates conflicts: +:meth:`~pyramid.config.Configurator.commit` method between configuration calls. +For example, we prevent conflicts from occurring in the application we examined +previously as the result of adding a ``commit``. Here's the application that +generates conflicts: .. code-block:: python :linenos: @@ -199,11 +197,12 @@ application that generates conflicts: server = make_server('0.0.0.0', 8080, app) server.serve_forever() -We can prevent the two ``add_view`` calls from conflicting by issuing a call -to :meth:`~pyramid.config.Configurator.commit` between them: +We can prevent the two ``add_view`` calls from conflicting by issuing a call to +:meth:`~pyramid.config.Configurator.commit` between them: .. code-block:: python :linenos: + :emphasize-lines: 16 from wsgiref.simple_server import make_server from pyramid.config import Configurator @@ -230,21 +229,20 @@ to :meth:`~pyramid.config.Configurator.commit` between them: server.serve_forever() In the above example we've issued a call to -:meth:`~pyramid.config.Configurator.commit` between the two ``add_view`` -calls. :meth:`~pyramid.config.Configurator.commit` will execute any pending +:meth:`~pyramid.config.Configurator.commit` between the two ``add_view`` calls. +:meth:`~pyramid.config.Configurator.commit` will execute any pending configuration statements. Calling :meth:`~pyramid.config.Configurator.commit` is safe at any time. It -executes all pending configuration actions and leaves the configuration -action list "clean". +executes all pending configuration actions and leaves the configuration action +list "clean". -Note that :meth:`~pyramid.config.Configurator.commit` has no effect when -you're using an *autocommitting* configurator (see -:ref:`autocommitting_configurator`). +Note that :meth:`~pyramid.config.Configurator.commit` has no effect when you're +using an *autocommitting* configurator (see :ref:`autocommitting_configurator`). .. _autocommitting_configurator: -Using An Autocommitting Configurator +Using an Autocommitting Configurator ++++++++++++++++++++++++++++++++++++ You can also use a heavy hammer to circumvent conflict detection by using a @@ -278,17 +276,17 @@ Automatic Conflict Resolution If your code uses the :meth:`~pyramid.config.Configurator.include` method to include external configuration, some conflicts are automatically resolved. Configuration statements that are made as the result of an "include" will be -overridden by configuration statements that happen within the caller of -the "include" method. +overridden by configuration statements that happen within the caller of the +"include" method. -Automatic conflict resolution supports this goal: if a user wants to reuse a +Automatic conflict resolution supports this goal. If a user wants to reuse a Pyramid application, and they want to customize the configuration of this application without hacking its code "from outside", they can "include" a configuration function from the package and override only some of its configuration statements within the code that does the include. No conflicts will be generated by configuration statements within the code that does the -including, even if configuration statements in the included code would -conflict if it was moved "up" to the calling code. +including, even if configuration statements in the included code would conflict +if it was moved "up" to the calling code. Methods Which Provide Conflict Detection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -312,9 +310,9 @@ These are the methods of the configurator which provide conflict detection: :meth:`~pyramid.config.Configurator.add_resource_url_adapter`, and :meth:`~pyramid.config.Configurator.add_response_adapter`. -:meth:`~pyramid.config.Configurator.add_static_view` also indirectly -provides conflict detection, because it's implemented in terms of the -conflict-aware ``add_route`` and ``add_view`` methods. +:meth:`~pyramid.config.Configurator.add_static_view` also indirectly provides +conflict detection, because it's implemented in terms of the conflict-aware +``add_route`` and ``add_view`` methods. .. index:: pair: configuration; including from external sources @@ -324,10 +322,10 @@ conflict-aware ``add_route`` and ``add_view`` methods. Including Configuration from External Sources --------------------------------------------- -Some application programmers will factor their configuration code in such a -way that it is easy to reuse and override configuration statements. For -example, such a developer might factor out a function used to add routes to -his application: +Some application programmers will factor their configuration code in such a way +that it is easy to reuse and override configuration statements. For example, +such a developer might factor out a function used to add routes to their +application: .. code-block:: python :linenos: @@ -335,8 +333,8 @@ his application: def add_routes(config): config.add_route(...) -Rather than calling this function directly with ``config`` as an argument. -Instead, use :meth:`pyramid.config.Configurator.include`: +Rather than calling this function directly with ``config`` as an argument, +instead use :meth:`pyramid.config.Configurator.include`: .. code-block:: python :linenos: @@ -363,21 +361,21 @@ the special name ``includeme``, which should perform configuration (like the :meth:`~pyramid.config.Configurator.include` can also accept a :term:`dotted Python name` to a function or a module. -.. note: See :ref:`the_include_tag` for a declarative alternative to - the :meth:`~pyramid.config.Configurator.include` method. +.. note:: See :ref:`the_include_tag` for a declarative alternative to the + :meth:`~pyramid.config.Configurator.include` method. .. _twophase_config: Two-Phase Configuration ----------------------- -When a non-autocommitting :term:`Configurator` is used to do configuration -(the default), configuration execution happens in two phases. In the first -phase, "eager" configuration actions (actions that must happen before all -others, such as registering a renderer) are executed, and *discriminators* -are computed for each of the actions that depend on the result of the eager -actions. In the second phase, the discriminators of all actions are compared -to do conflict detection. +When a non-autocommitting :term:`Configurator` is used to do configuration (the +default), configuration execution happens in two phases. In the first phase, +"eager" configuration actions (actions that must happen before all others, such +as registering a renderer) are executed, and *discriminators* are computed for +each of the actions that depend on the result of the eager actions. In the +second phase, the discriminators of all actions are compared to do conflict +detection. Due to this, for configuration methods that have no internal ordering constraints, execution order of configuration method calls is not important. @@ -401,15 +399,14 @@ Has the same result as: config.add_view('some.view', renderer='path_to_custom/renderer.rn') Even though the view statement depends on the registration of a custom -renderer, due to two-phase configuration, the order in which the -configuration statements are issued is not important. ``add_view`` will be -able to find the ``.rn`` renderer even if ``add_renderer`` is called after -``add_view``. +renderer, due to two-phase configuration, the order in which the configuration +statements are issued is not important. ``add_view`` will be able to find the +``.rn`` renderer even if ``add_renderer`` is called after ``add_view``. The same is untrue when you use an *autocommitting* configurator (see :ref:`autocommitting_configurator`). When an autocommitting configurator is -used, two-phase configuration is disabled, and configuration statements must -be ordered in dependency order. +used, two-phase configuration is disabled, and configuration statements must be +ordered in dependency order. Some configuration methods, such as :meth:`~pyramid.config.Configurator.add_route` have internal ordering @@ -420,7 +417,7 @@ added in configuration execution order. More Information ---------------- -For more information, see the article, `"A Whirlwind Tour of Advanced +For more information, see the article `"A Whirlwind Tour of Advanced Configuration Tactics" -`_, +`_ in the Pyramid Cookbook. -- cgit v1.2.3 From 6bc1bb06dd07e34a2f26cbb26bca6fc7a933b881 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 6 Nov 2015 00:55:11 -0800 Subject: minor grammar, fix .rst markup, insert versionchanged directive, rewrap to 79 columns --- docs/narr/extconfig.rst | 266 ++++++++++++++++++++++++------------------------ 1 file changed, 132 insertions(+), 134 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index a61eca7b7..5a46c8b9e 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -7,9 +7,9 @@ Extending Pyramid Configuration =============================== Pyramid allows you to extend its Configurator with custom directives. Custom -directives can use other directives, they can add a custom :term:`action`, -they can participate in :term:`conflict resolution`, and they can provide -some number of :term:`introspectable` objects. +directives can use other directives, they can add a custom :term:`action`, they +can participate in :term:`conflict resolution`, and they can provide some +number of :term:`introspectable` objects. .. index:: single: add_directive @@ -20,18 +20,17 @@ some number of :term:`introspectable` objects. Adding Methods to the Configurator via ``add_directive`` -------------------------------------------------------- -Framework extension writers can add arbitrary methods to a -:term:`Configurator` by using the -:meth:`pyramid.config.Configurator.add_directive` method of the configurator. -Using :meth:`~pyramid.config.Configurator.add_directive` makes it possible to -extend a Pyramid configurator in arbitrary ways, and allows it to perform -application-specific tasks more succinctly. +Framework extension writers can add arbitrary methods to a :term:`Configurator` +by using the :meth:`pyramid.config.Configurator.add_directive` method of the +configurator. Using :meth:`~pyramid.config.Configurator.add_directive` makes it +possible to extend a Pyramid configurator in arbitrary ways, and allows it to +perform application-specific tasks more succinctly. The :meth:`~pyramid.config.Configurator.add_directive` method accepts two -positional arguments: a method name and a callable object. The callable -object is usually a function that takes the configurator instance as its -first argument and accepts other arbitrary positional and keyword arguments. -For example: +positional arguments: a method name and a callable object. The callable object +is usually a function that takes the configurator instance as its first +argument and accepts other arbitrary positional and keyword arguments. For +example: .. code-block:: python :linenos: @@ -48,8 +47,8 @@ For example: add_newrequest_subscriber) Once :meth:`~pyramid.config.Configurator.add_directive` is called, a user can -then call the added directive by its given name as if it were a built-in -method of the Configurator: +then call the added directive by its given name as if it were a built-in method +of the Configurator: .. code-block:: python :linenos: @@ -59,9 +58,9 @@ method of the Configurator: config.add_newrequest_subscriber(mysubscriber) -A call to :meth:`~pyramid.config.Configurator.add_directive` is often -"hidden" within an ``includeme`` function within a "frameworky" package meant -to be included as per :ref:`including_configuration` via +A call to :meth:`~pyramid.config.Configurator.add_directive` is often "hidden" +within an ``includeme`` function within a "frameworky" package meant to be +included as per :ref:`including_configuration` via :meth:`~pyramid.config.Configurator.include`. For example, if you put this code in a package named ``pyramid_subscriberhelpers``: @@ -72,8 +71,8 @@ code in a package named ``pyramid_subscriberhelpers``: config.add_directive('add_newrequest_subscriber', add_newrequest_subscriber) -The user of the add-on package ``pyramid_subscriberhelpers`` would then be -able to install it and subsequently do: +The user of the add-on package ``pyramid_subscriberhelpers`` would then be able +to install it and subsequently do: .. code-block:: python :linenos: @@ -91,13 +90,12 @@ Using ``config.action`` in a Directive If a custom directive can't do its work exclusively in terms of existing configurator methods (such as -:meth:`pyramid.config.Configurator.add_subscriber`, as above), the directive -may need to make use of the :meth:`pyramid.config.Configurator.action` -method. This method adds an entry to the list of "actions" that Pyramid will -attempt to process when :meth:`pyramid.config.Configurator.commit` is called. -An action is simply a dictionary that includes a :term:`discriminator`, -possibly a callback function, and possibly other metadata used by Pyramid's -action system. +:meth:`pyramid.config.Configurator.add_subscriber` as above), the directive may +need to make use of the :meth:`pyramid.config.Configurator.action` method. This +method adds an entry to the list of "actions" that Pyramid will attempt to +process when :meth:`pyramid.config.Configurator.commit` is called. An action is +simply a dictionary that includes a :term:`discriminator`, possibly a callback +function, and possibly other metadata used by Pyramid's action system. Here's an example directive which uses the "action" method: @@ -122,15 +120,15 @@ closure function named ``register`` is passed as the second argument named When the :meth:`~pyramid.config.Configurator.action` method is called, it appends an action to the list of pending configuration actions. All pending -actions with the same discriminator value are potentially in conflict with -one another (see :ref:`conflict_detection`). When the +actions with the same discriminator value are potentially in conflict with one +another (see :ref:`conflict_detection`). When the :meth:`~pyramid.config.Configurator.commit` method of the Configurator is called (either explicitly or as the result of calling :meth:`~pyramid.config.Configurator.make_wsgi_app`), conflicting actions are -potentially automatically resolved as per -:ref:`automatic_conflict_resolution`. If a conflict cannot be automatically -resolved, a :exc:`pyramid.exceptions.ConfigurationConflictError` is raised -and application startup is prevented. +potentially automatically resolved as per :ref:`automatic_conflict_resolution`. +If a conflict cannot be automatically resolved, a +:exc:`pyramid.exceptions.ConfigurationConflictError` is raised and application +startup is prevented. In our above example, therefore, if a consumer of our ``add_jammyjam`` directive did this: @@ -146,14 +144,14 @@ generated by the two calls are in direct conflict. Automatic conflict resolution cannot resolve the conflict (because no ``config.include`` is involved), and the user provided no intermediate :meth:`pyramid.config.Configurator.commit` call between the calls to -``add_jammyjam`` to ensure that the successive calls did not conflict with -each other. +``add_jammyjam`` to ensure that the successive calls did not conflict with each +other. This demonstrates the purpose of the discriminator argument to the action method: it's used to indicate a uniqueness constraint for an action. Two actions with the same discriminator will conflict unless the conflict is -automatically or manually resolved. A discriminator can be any hashable -object, but it is generally a string or a tuple. *You use a discriminator to +automatically or manually resolved. A discriminator can be any hashable object, +but it is generally a string or a tuple. *You use a discriminator to declaratively ensure that the user doesn't provide ambiguous configuration statements.* @@ -169,21 +167,20 @@ appended to the pending actions list. When the pending configuration actions are processed during :meth:`~pyramid.config.Configurator.commit`, and no conflicts occur, the *callable* provided as the second argument to the :meth:`~pyramid.config.Configurator.action` method within ``add_jammyjam`` is -called with no arguments. The callable in ``add_jammyjam`` is the -``register`` closure function. It simply sets the value -``config.registry.jammyjam`` to whatever the user passed in as the -``jammyjam`` argument to the ``add_jammyjam`` function. Therefore, the -result of the user's call to our directive will set the ``jammyjam`` -attribute of the registry to the string ``first``. *A callable is used by a -directive to defer the result of a user's call to the directive until -conflict detection has had a chance to do its job*. +called with no arguments. The callable in ``add_jammyjam`` is the ``register`` +closure function. It simply sets the value ``config.registry.jammyjam`` to +whatever the user passed in as the ``jammyjam`` argument to the +``add_jammyjam`` function. Therefore, the result of the user's call to our +directive will set the ``jammyjam`` attribute of the registry to the string +``first``. *A callable is used by a directive to defer the result of a user's +call to the directive until conflict detection has had a chance to do its job*. Other arguments exist to the :meth:`~pyramid.config.Configurator.action` -method, including ``args``, ``kw``, ``order``, and ``introspectables``. +method, including ``args``, ``kw``, ``order``, and ``introspectables``. -``args`` and ``kw`` exist as values, which, if passed, will be used as -arguments to the ``callable`` function when it is called back. For example -our directive might use them like so: +``args`` and ``kw`` exist as values, which if passed will be used as arguments +to the ``callable`` function when it is called back. For example, our +directive might use them like so: .. code-block:: python :linenos: @@ -198,31 +195,34 @@ our directive might use them like so: In the above example, when this directive is used to generate an action, and that action is committed, ``config.registry.jammyjam_args`` will be set to ``('one',)`` and ``config.registry.jammyjam_kw`` will be set to -``{'two':'two'}``. ``args`` and ``kw`` are honestly not very useful when -your ``callable`` is a closure function, because you already usually have -access to every local in the directive without needing them to be passed -back. They can be useful, however, if you don't use a closure as a callable. +``{'two':'two'}``. ``args`` and ``kw`` are honestly not very useful when your +``callable`` is a closure function, because you already usually have access to +every local in the directive without needing them to be passed back. They can +be useful, however, if you don't use a closure as a callable. ``order`` is a crude order control mechanism. ``order`` defaults to the integer ``0``; it can be set to any other integer. All actions that share an order will be called before other actions that share a higher order. This makes it possible to write a directive with callable logic that relies on the -execution of the callable of another directive being done first. For -example, Pyramid's :meth:`pyramid.config.Configurator.add_view` directive -registers an action with a higher order than the +execution of the callable of another directive being done first. For example, +Pyramid's :meth:`pyramid.config.Configurator.add_view` directive registers an +action with a higher order than the :meth:`pyramid.config.Configurator.add_route` method. Due to this, the -``add_view`` method's callable can assume that, if a ``route_name`` was -passed to it, that a route by this name was already registered by -``add_route``, and if such a route has not already been registered, it's a -configuration error (a view that names a nonexistent route via its -``route_name`` parameter will never be called). As of Pyramid 1.6 it is -possible for one action to invoke another. See :ref:`ordering_actions` for -more information. - -``introspectables`` is a sequence of :term:`introspectable` objects. You can -pass a sequence of introspectables to the -:meth:`~pyramid.config.Configurator.action` method, which allows you to -augment Pyramid's configuration introspection system. +``add_view`` method's callable can assume that, if a ``route_name`` was passed +to it, that a route by this name was already registered by ``add_route``, and +if such a route has not already been registered, it's a configuration error (a +view that names a nonexistent route via its ``route_name`` parameter will never +be called). + +.. versionchanged:: 1.6 + As of Pyramid 1.6 it is possible for one action to invoke another. + +See :ref:`ordering_actions` for more information. + +Finally, ``introspectables`` is a sequence of :term:`introspectable` objects. +You can pass a sequence of introspectables to the +:meth:`~pyramid.config.Configurator.action` method, which allows you to augment +Pyramid's configuration introspection system. .. _ordering_actions: @@ -233,18 +233,17 @@ In Pyramid every :term:`action` has an inherent ordering relative to other actions. The logic within actions is deferred until a call to :meth:`pyramid.config.Configurator.commit` (which is automatically invoked by :meth:`pyramid.config.Configurator.make_wsgi_app`). This means you may call -``config.add_view(route_name='foo')`` **before** -``config.add_route('foo', '/foo')`` because nothing actually happens until -commit-time. During a commit cycle conflicts are resolved, actions are ordered -and executed. +``config.add_view(route_name='foo')`` **before** ``config.add_route('foo', +'/foo')`` because nothing actually happens until commit-time. During a commit +cycle, conflicts are resolved, and actions are ordered and executed. By default, almost every action in Pyramid has an ``order`` of :const:`pyramid.config.PHASE3_CONFIG`. Every action within the same order-level -will be executed in the order it was called. -This means that if an action must be reliably executed before or after another -action, the ``order`` must be defined explicitly to make this work. For -example, views are dependent on routes being defined. Thus the action created -by :meth:`pyramid.config.Configurator.add_route` has an ``order`` of +will be executed in the order it was called. This means that if an action must +be reliably executed before or after another action, the ``order`` must be +defined explicitly to make this work. For example, views are dependent on +routes being defined. Thus the action created by +:meth:`pyramid.config.Configurator.add_route` has an ``order`` of :const:`pyramid.config.PHASE2_CONFIG`. Pre-defined Phases @@ -252,8 +251,8 @@ Pre-defined Phases :const:`pyramid.config.PHASE0_CONFIG` -- This phase is reserved for developers who want to execute actions prior - to Pyramid's core directives. +- This phase is reserved for developers who want to execute actions prior to + Pyramid's core directives. :const:`pyramid.config.PHASE1_CONFIG` @@ -274,17 +273,17 @@ Pre-defined Phases - The default for all builtin or custom directives unless otherwise specified. -Calling Actions From Actions +Calling Actions from Actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 1.6 -Pyramid's configurator allows actions to be added during a commit-cycle as -long as they are added to the current or a later ``order`` phase. This means -that your custom action can defer decisions until commit-time and then do -things like invoke :meth:`pyramid.config.Configurator.add_route`. It can also -provide better conflict detection if your addon needs to call more than one -other action. +Pyramid's configurator allows actions to be added during a commit-cycle as long +as they are added to the current or a later ``order`` phase. This means that +your custom action can defer decisions until commit-time and then do things +like invoke :meth:`pyramid.config.Configurator.add_route`. It can also provide +better conflict detection if your addon needs to call more than one other +action. For example, let's make an addon that invokes ``add_route`` and ``add_view``, but we want it to conflict with any other call to our addon: @@ -304,12 +303,12 @@ but we want it to conflict with any other call to our addon: config.action(('auto route', name), register, order=PHASE0_CONFIG) Now someone else can use your addon and be informed if there is a conflict -between this route and another, or two calls to ``add_auto_route``. -Notice how we had to invoke our action **before** ``add_view`` or -``add_route``. If we tried to invoke this afterward, the subsequent calls to -``add_view`` and ``add_route`` would cause conflicts because that phase had -already been executed, and the configurator cannot go back in time to add more -views during that commit-cycle. +between this route and another, or two calls to ``add_auto_route``. Notice how +we had to invoke our action **before** ``add_view`` or ``add_route``. If we +tried to invoke this afterward, the subsequent calls to ``add_view`` and +``add_route`` would cause conflicts because that phase had already been +executed, and the configurator cannot go back in time to add more views during +that commit-cycle. .. code-block:: python :linenos: @@ -341,16 +340,16 @@ All built-in Pyramid directives (such as introspectables when called. For example, when you register a view via ``add_view``, the directive registers at least one introspectable: an introspectable about the view registration itself, providing human-consumable -values for the arguments it was passed. You can later use the introspection -query system to determine whether a particular view uses a renderer, or -whether a particular view is limited to a particular request method, or which -routes a particular view is registered against. The Pyramid "debug toolbar" -makes use of the introspection system in various ways to display information -to Pyramid developers. +values for the arguments passed into it. You can later use the introspection +query system to determine whether a particular view uses a renderer, or whether +a particular view is limited to a particular request method, or against which +routes a particular view is registered. The Pyramid "debug toolbar" makes use +of the introspection system in various ways to display information to Pyramid +developers. -Introspection values are set when a sequence of :term:`introspectable` -objects is passed to the :meth:`~pyramid.config.Configurator.action` method. -Here's an example of a directive which uses introspectables: +Introspection values are set when a sequence of :term:`introspectable` objects +is passed to the :meth:`~pyramid.config.Configurator.action` method. Here's an +example of a directive which uses introspectables: .. code-block:: python :linenos: @@ -370,9 +369,9 @@ Here's an example of a directive which uses introspectables: config.add_directive('add_jammyjam', add_jammyjam) If you notice, the above directive uses the ``introspectable`` attribute of a -Configurator (:attr:`pyramid.config.Configurator.introspectable`) to create -an introspectable object. The introspectable object's constructor requires -at least four arguments: the ``category_name``, the ``discriminator``, the +Configurator (:attr:`pyramid.config.Configurator.introspectable`) to create an +introspectable object. The introspectable object's constructor requires at +least four arguments: the ``category_name``, the ``discriminator``, the ``title``, and the ``type_name``. The ``category_name`` is a string representing the logical category for this @@ -392,19 +391,19 @@ The ``type_name`` is a value that can be used to subtype this introspectable within its category for sorting and presentation purposes. It can be any value. -An introspectable is also dictionary-like. It can contain any set of -key/value pairs, typically related to the arguments passed to its related -directive. While the category_name, discriminator, title and type_name are -*metadata* about the introspectable, the values provided as key/value pairs +An introspectable is also dictionary-like. It can contain any set of key/value +pairs, typically related to the arguments passed to its related directive. +While the ``category_name``, ``discriminator``, ``title``, and ``type_name`` +are *metadata* about the introspectable, the values provided as key/value pairs are the actual data provided by the introspectable. In the above example, we set the ``value`` key to the value of the ``value`` argument passed to the directive. Our directive above mutates the introspectable, and passes it in to the ``action`` method as the first element of a tuple as the value of the -``introspectable`` keyword argument. This associates this introspectable -with the action. Introspection tools will then display this introspectable -in their index. +``introspectable`` keyword argument. This associates this introspectable with +the action. Introspection tools will then display this introspectable in their +index. Introspectable Relationships ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -435,30 +434,29 @@ Two introspectables may have relationships between each other. config.add_directive('add_jammyjam', add_jammyjam) In the above example, the ``add_jammyjam`` directive registers two -introspectables. The first is related to the ``value`` passed to the -directive; the second is related to the ``template`` passed to the directive. -If you believe a concept within a directive is important enough to have its -own introspectable, you can cause the same directive to register more than -one introspectable, registering one introspectable for the "main idea" and -another for a related concept. +introspectables: the first is related to the ``value`` passed to the directive, +and the second is related to the ``template`` passed to the directive. If you +believe a concept within a directive is important enough to have its own +introspectable, you can cause the same directive to register more than one +introspectable, registering one introspectable for the "main idea" and another +for a related concept. The call to ``intr.relate`` above -(:meth:`pyramid.interfaces.IIntrospectable.relate`) is passed two arguments: -a category name and a directive. The example above effectively indicates -that the directive wishes to form a relationship between the ``intr`` -introspectable and the ``tmpl_intr`` introspectable; the arguments passed to -``relate`` are the category name and discriminator of the ``tmpl_intr`` -introspectable. - -Relationships need not be made between two introspectables created by the -same directive. Instead, a relationship can be formed between an -introspectable created in one directive and another introspectable created in -another by calling ``relate`` on either side with the other directive's -category name and discriminator. An error will be raised at configuration -commit time if you attempt to relate an introspectable with another -nonexistent introspectable, however. +(:meth:`pyramid.interfaces.IIntrospectable.relate`) is passed two arguments: a +category name and a directive. The example above effectively indicates that +the directive wishes to form a relationship between the ``intr`` introspectable +and the ``tmpl_intr`` introspectable; the arguments passed to ``relate`` are +the category name and discriminator of the ``tmpl_intr`` introspectable. + +Relationships need not be made between two introspectables created by the same +directive. Instead a relationship can be formed between an introspectable +created in one directive and another introspectable created in another by +calling ``relate`` on either side with the other directive's category name and +discriminator. An error will be raised at configuration commit time if you +attempt to relate an introspectable with another nonexistent introspectable, +however. Introspectable relationships will show up in frontend system renderings of -introspection values. For example, if a view registration names a route -name, the introspectable related to the view callable will show a reference -to the route to which it relates to and vice versa. +introspection values. For example, if a view registration names a route name, +the introspectable related to the view callable will show a reference to the +route to which it relates and vice versa. -- cgit v1.2.3 From 4434b479bcee4d32b8dacaf409bdd756dd7ff8e5 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 6 Nov 2015 01:12:46 -0800 Subject: minor grammar, fix .rst markup, insert versionchanged directive, rewrap to 79 columns --- docs/narr/extconfig.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 5a46c8b9e..fee8d0d3a 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -215,9 +215,8 @@ view that names a nonexistent route via its ``route_name`` parameter will never be called). .. versionchanged:: 1.6 - As of Pyramid 1.6 it is possible for one action to invoke another. - -See :ref:`ordering_actions` for more information. + As of Pyramid 1.6 it is possible for one action to invoke another. See + :ref:`ordering_actions` for more information. Finally, ``introspectables`` is a sequence of :term:`introspectable` objects. You can pass a sequence of introspectables to the -- cgit v1.2.3 From 31e9347d35ccdee5502672b4e301f51d864508a4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 9 Nov 2015 02:36:33 -0800 Subject: minor grammar, fix .rst markup, rewrap to 79 columns --- docs/narr/scaffolding.rst | 100 +++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 4fcdeb537..8677359de 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -4,8 +4,8 @@ Creating Pyramid Scaffolds ========================== You can extend Pyramid by creating a :term:`scaffold` template. A scaffold -template is useful if you'd like to distribute a customizable configuration -of Pyramid to other users. Once you've created a scaffold, and someone has +template is useful if you'd like to distribute a customizable configuration of +Pyramid to other users. Once you've created a scaffold, and someone has installed the distribution that houses the scaffold, they can use the ``pcreate`` script to create a custom version of your scaffold's template. Pyramid itself uses scaffolds to allow people to bootstrap new projects. For @@ -15,22 +15,22 @@ example, ``pcreate -s alchemy MyStuff`` causes Pyramid to render the Basics ------ -A scaffold template is just a bunch of source files and directories on disk. -A small definition class points at this directory; it is in turn pointed at -by a :term:`setuptools` "entry point" which registers the scaffold so it can -be found by the ``pcreate`` command. +A scaffold template is just a bunch of source files and directories on disk. A +small definition class points at this directory. It is in turn pointed at by a +:term:`setuptools` "entry point" which registers the scaffold so it can be +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 the sake of example, we'll pretend the -distribution you create is named ``CoolExtension``, and it has a package -directory within it named ``coolextension`` +`_ 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 -distribution's package directory, and create a file within that directory -named ``__init__.py`` with something like the following: +Once you've created the distribution, put a "scaffolds" directory within your +distribution's package directory, and create a file within that directory named +``__init__.py`` with something like the following: .. code-block:: python :linenos: @@ -54,12 +54,12 @@ As you create files and directories within the template directory, note that: the string value of the variable named ``var`` provided to the scaffold. - Files and directories with filenames that contain the string ``+var+`` will - have that string replaced with the value of the ``var`` variable provided - to the scaffold. + have that string replaced with the value of the ``var`` variable provided to + the scaffold. - Files that start with a dot (e.g., ``.env``) are ignored and will not be copied over to the destination directory. If you want to include a file with - a leading dot then you must replace the dot with ``+dot+`` (e.g., + a leading dot, then you must replace the dot with ``+dot+`` (e.g., ``+dot+env``). Otherwise, files and directories which live in the template directory will be @@ -67,14 +67,14 @@ copied directly without modification to the ``pcreate`` output location. The variables provided by the default ``PyramidTemplate`` include ``project`` (the project name provided by the user as an argument to ``pcreate``), -``package`` (a lowercasing and normalizing of the project name provided by -the user), ``random_string`` (a long random string), and ``package_logger`` -(the name of the package's logger). +``package`` (a lowercasing and normalizing of the project name provided by the +user), ``random_string`` (a long random string), and ``package_logger`` (the +name of the package's logger). See Pyramid's "scaffolds" package -(https://github.com/Pylons/pyramid/tree/master/pyramid/scaffolds) for -concrete examples of scaffold directories (``zodb``, ``alchemy``, and -``starter``, for example). +(https://github.com/Pylons/pyramid/tree/master/pyramid/scaffolds) for concrete +examples of scaffold directories (``zodb``, ``alchemy``, and ``starter``, for +example). After you've created the template directory, add the following to the ``entry_points`` value of your distribution's ``setup.py``: @@ -96,17 +96,16 @@ For example: """ ) -Run your distribution's ``setup.py develop`` or ``setup.py install`` -command. After that, you should be able to see your scaffolding template -listed when you run ``pcreate -l``. It will be named ``coolextension`` -because that's the name we gave it in the entry point setup. Running -``pcreate -s coolextension MyStuff`` will then render your scaffold to an -output directory named ``MyStuff``. +Run your distribution's ``setup.py develop`` or ``setup.py install`` command. +After that, you should be able to see your scaffolding template listed when you +run ``pcreate -l``. It will be named ``coolextension`` because that's the name +we gave it in the entry point setup. Running ``pcreate -s coolextension +MyStuff`` will then render your scaffold to an output directory named +``MyStuff``. -See the module documentation for :mod:`pyramid.scaffolds` for information -about the API of the :class:`pyramid.scaffolds.Template` class and -related classes. You can override methods of this class to get special -behavior. +See the module documentation for :mod:`pyramid.scaffolds` for information about +the API of the :class:`pyramid.scaffolds.Template` class and related classes. +You can override methods of this class to get special behavior. Supporting Older Pyramid Versions --------------------------------- @@ -139,21 +138,22 @@ defining your scaffold template: And then in the setup.py of the package that contains your scaffold, define the template as a target of both ``paste.paster_create_template`` (for -``paster create``) and ``pyramid.scaffold`` (for ``pcreate``):: +``paster create``) and ``pyramid.scaffold`` (for ``pcreate``). - [paste.paster_create_template] - coolextension=coolextension.scaffolds:CoolExtensionTemplate - [pyramid.scaffold] - coolextension=coolextension.scaffolds:CoolExtensionTemplate +.. code-block:: ini + + [paste.paster_create_template] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate -Doing this hideousness will allow your scaffold to work as a ``paster -create`` target (under 1.0, 1.1, or 1.2) or as a ``pcreate`` target (under -1.3). If an invoker tries to run ``paster create`` against a scaffold -defined this way under 1.3, an error is raised instructing them to use -``pcreate`` instead. +Doing this hideousness will allow your scaffold to work as a ``paster create`` +target (under 1.0, 1.1, or 1.2) or as a ``pcreate`` target (under 1.3). If an +invoker tries to run ``paster create`` against a scaffold defined this way +under 1.3, an error is raised instructing them to use ``pcreate`` instead. -If you want only to support Pyramid 1.3 only, it's much cleaner, and the API -is stable: +If you want to support Pyramid 1.3 only, it's much cleaner, and the API is +stable: .. code-block:: python :linenos: @@ -164,17 +164,17 @@ is stable: _template_dir = 'coolextension_scaffold' summary = 'My cool_extension' -You only need to specify a ``paste.paster_create_template`` entry point -target in your ``setup.py`` if you want your scaffold to be consumable by -users of Pyramid 1.0, 1.1, or 1.2. To support only 1.3, specifying only the +You only need to specify a ``paste.paster_create_template`` entry point target +in your ``setup.py`` if you want your scaffold to be consumable by users of +Pyramid 1.0, 1.1, or 1.2. To support only 1.3, specifying only the ``pyramid.scaffold`` entry point is good enough. If you want to support both -``paster create`` and ``pcreate`` (meaning you want to support Pyramid 1.2 -and some older version), you'll need to define both. +``paster create`` and ``pcreate`` (meaning you want to support Pyramid 1.2 and +some older version), you'll need to define both. Examples -------- Existing third-party distributions which house scaffolding are available via -:term:`PyPI`. The ``pyramid_jqm``, ``pyramid_zcml`` and ``pyramid_jinja2`` +:term:`PyPI`. The ``pyramid_jqm``, ``pyramid_zcml``, and ``pyramid_jinja2`` packages house scaffolds. You can install and examine these packages to see how they work in the quest to develop your own scaffolding. -- cgit v1.2.3 From 31f3d86d3bf5db3c4aa5085c7b7a4d6396f29931 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 12 Nov 2015 00:55:38 -0600 Subject: complete cache buster docs using manifest example --- docs/narr/assets.rst | 183 ++++++++++++++++++++++----------------------------- 1 file changed, 77 insertions(+), 106 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 397e0258d..d36fa49c0 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -356,14 +356,14 @@ may change, and then you'll want the client to load a new copy of the asset. Under normal circumstances you'd just need to wait for the client's cached copy to expire before they get the new version of the static resource. -A commonly used workaround to this problem is a technique known as "cache -busting". Cache busting schemes generally involve generating a URL for a -static asset that changes when the static asset changes. This way headers can -be sent along with the static asset instructing the client to cache the asset -for a very long time. When a static asset is changed, the URL used to refer to -it in a web page also changes, so the client sees it as a new resource and -requests the asset, regardless of any caching policy set for the resource's old -URL. +A commonly used workaround to this problem is a technique known as +:term:`cache busting`. Cache busting schemes generally involve generating a +URL for a static asset that changes when the static asset changes. This way +headers can be sent along with the static asset instructing the client to cache +the asset for a very long time. When a static asset is changed, the URL used +to refer to it in a web page also changes, so the client sees it as a new +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 @@ -397,7 +397,7 @@ 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. -.. warning:: +.. note:: Cache busting is an inherently complex topic as it integrates the asset pipeline and the web application. It is expected and desired that @@ -429,16 +429,14 @@ arbitrary token you provide to the query string of the asset's URL. This is almost never what you want in production as it does not allow fine-grained busting of individual assets. - In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` interface. Alternatively you may choose to subclass one of the existing implementations. One of the most likely scenarios is you'd want to change the -way the asset token is generated. To do this just subclass either -:class:`~pyramid.static.PathSegmentCacheBuster` or +way the asset token is generated. To do this just subclass :class:`~pyramid.static.QueryStringCacheBuster` and define a -``tokenize(pathspec)`` method. Here is an example which just uses Git to get -the hash of the currently checked out code: +``tokenize(pathspec)`` method. Here is an example which uses Git to get +the hash of the current commit: .. code-block:: python :linenos: @@ -466,26 +464,60 @@ the hash of the currently checked out code: Choosing a Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~ -The default cache buster implementation, -:class:`~pyramid.static.PathSegmentMd5CacheBuster`, works very well assuming -that you're using :app:`Pyramid` to serve your static assets. The md5 checksum -is fine grained enough that browsers should only request new versions of -specific assets that have changed. Many caching HTTP proxies will fail to -cache a resource if the URL contains a query string. In general, therefore, -you should prefer a cache busting strategy which modifies the path segment to a -strategy which adds a query string. - -It is possible, however, that your static assets are being served by another -web server or externally on a CDN. In these cases modifying the path segment -for a static asset URL would cause the external service to fail to find the -asset, causing your customer to get a 404. In these cases you would need to -fall back to a cache buster which adds a query string. It is even possible -that there isn't a copy of your static assets available to the :app:`Pyramid` -application, so a cache busting implementation that generates md5 checksums -would fail since it can't access the assets. In such a case, -:class:`~pyramid.static.QueryStringConstantCacheBuster` is a reasonable -fallback. The following code would set up a cachebuster that just uses the -time at start up as a cachebust token: +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 +strategy which modifies the path segment rather than methods which add a +token to the query string. + +You will need to consider whether the :app:`Pyramid` application will be +serving your static assets, whether you are using an external asset pipeline +to handle rewriting urls internal to the css/javascript, and how fine-grained +do you want the cache busting tokens to be. + +In many cases you will want to host the static assets on another web server +or externally on a CDN. In these cases your :app:`Pyramid` application may not +even have access to a copy of the static assets. In order to cache bust these +assets you will need some information about them. + +If you are using an external asset pipeline to generate your static files you +should consider using the :class:`~pyramid.static.ManifestCacheBuster`. +This cache buster can load a standard JSON formatted file generated by your +pipeline and use it to cache bust the assets. This has many performance +advantages as :app:`Pyramid` does not need to look at the files to generate +any cache busting tokens, but still supports fine-grained per-file tokens. + +Assuming an example ``manifest.json`` like: + +.. code-block:: json + + { + "css/main.css": "css/main-678b7c80.css", + "images/background.png": "images/background-a8169106.png" + } + +The following code would set up a cachebuster: + +.. code-block:: python + :linenos: + + from pyramid.path import AssetResolver + from pyramid.static import ManifestCacheBuster + + resolver = AssetResolver() + manifest = resolver.resolve('myapp:static/manifest.json') + config.add_static_view( + name='http://mycdn.example.com/', + path='mypackage:static', + cachebust=ManifestCacheBuster(manifest.abspath())) + +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: @@ -496,7 +528,7 @@ time at start up as a cachebust token: config.add_static_view( name='http://mycdn.example.com/', path='mypackage:static', - cachebust=QueryStringConstantCacheBuster(str(time.time()))) + cachebust=QueryStringConstantCacheBuster(str(int(time.time())))) .. index:: single: static assets view @@ -508,85 +540,24 @@ 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. +one needs to perform one of the following tasks: * Process the files by using a precompiler which rewrites URLs to their final - cache busted form. + 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. * Pass static URL references to CSS and JavaScript via other means. -Below are some simple approaches for CSS and JS programming which consider -asset cache busting. These approaches do not require additional tools or -packages. - -Relative cache busted URLs in CSS -+++++++++++++++++++++++++++++++++ - -Consider a CSS file ``/static/theme/css/site.css`` which contains the following -CSS code. - -.. code-block:: css - - body { - background: url(/static/theme/img/background.jpg); - } - -Any changes to ``background.jpg`` would not appear to the visitor because the -URL path is not cache busted as it is. Instead we would have to construct an -URL to the background image with the default ``PathSegmentCacheBuster`` cache -busting mechanism:: - - https://site/static/1eeb262c717/theme/img/background.jpg - -Every time the image is updated, the URL would need to be changed. It is not -practical to write this non-human readable URL into a CSS file. - -However, the CSS file itself is cache busted and is located under the path for -static assets. This lets us use relative references in our CSS to cache bust -the image. - -.. code-block:: css - - body { - background: url(../img/background.jpg); - } - -The browser would interpret this as having the CSS file hash in URL:: - - https://site/static/ab234b262c71/theme/css/../img/background.jpg - -The downside of this approach is that if the background image changes, one -needs to bump the CSS file. The CSS file hash change signals the caches that -the relative URL to the image in the CSS has been changed. When updating CSS -and related image assets, updates usually happen hand in hand, so this does not -add extra effort to theming workflow. - -Passing cache busted URLs to JavaScript -+++++++++++++++++++++++++++++++++++++++ - -For JavaScript, one can pass static asset URLs as function arguments or -globals. The globals can be generated in page template code, having access to -the ``request.static_url()`` function. - -Below is a simple example of passing a cached busted image URL in the Jinja2 -template language. Put the following code into the ```` section of the -relevant page. - -.. code-block:: html - - - -Then in your main ``site.js`` file, put the following code. - -.. code-block:: javascript - - var image = new Image(window.assets.backgroundImage); +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. .. _advanced_static: -- cgit v1.2.3 From 6f4e97603c2562914567a85bf18187299c3b543b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 12 Nov 2015 20:04:28 -0600 Subject: Revert "fix/remove-default-cachebusters" This reverts commit 7410250313f893e5952bb2697324a4d4e3d47d22. This reverts commit cbec33b898efffbfa6acaf91cae45ec0daed4d7a. This reverts commit 345ca3052c395545b90fef9104a16eed5ab051a5, reversing changes made to 47162533af84bb8d26db6d1c9ba1e63d70e9070f. --- docs/narr/assets.rst | 257 +++++++++++++++++++++++++++++---------------------- 1 file changed, 148 insertions(+), 109 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index d36fa49c0..020794062 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -356,14 +356,14 @@ may change, and then you'll want the client to load a new copy of the asset. Under normal circumstances you'd just need to wait for the client's cached copy to expire before they get the new version of the static resource. -A commonly used workaround to this problem is a technique known as -:term:`cache busting`. Cache busting schemes generally involve generating a -URL for a static asset that changes when the static asset changes. This way -headers can be sent along with the static asset instructing the client to cache -the asset for a very long time. When a static asset is changed, the URL used -to refer to it in a web page also changes, so the client sees it as a new -resource and requests the asset, regardless of any caching policy set for the -resource's old URL. +A commonly used workaround to this problem is a technique known as "cache +busting". Cache busting schemes generally involve generating a URL for a +static asset that changes when the static asset changes. This way headers can +be sent along with the static asset instructing the client to cache the asset +for a very long time. When a static asset is changed, the URL used to refer to +it in a web page also changes, so the client sees it as a new 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 @@ -372,38 +372,30 @@ assets by passing the optional argument, ``cachebust`` to .. code-block:: python :linenos: - import time - 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', + cachebust=True) 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: +busting scheme which adds the md5 checksum for a static asset as a path segment +in the asset's URL: .. code-block:: python :linenos: js_url = request.static_url('mypackage:folder/static/js/myapp.js') - # Returns: 'http://www.example.com/static/js/myapp.js?x=1445318121' + # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js' -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. +When the asset changes, so will its md5 checksum, 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. .. note:: - Cache busting is an inherently complex topic as it integrates the asset - pipeline and the web application. It is expected and desired that - application authors will write their own cache buster implementations - conforming to the properties of their own asset pipelines. See - :ref:`custom_cache_busters` for information on writing your own. + md5 checksums are cached in RAM, so if you change a static resource without + restarting your application, you may still generate URLs with a stale md5 + checksum. Disabling the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -414,45 +406,65 @@ configured cache busters without changing calls to ``PYRAMID_PREVENT_CACHEBUST`` environment variable or the ``pyramid.prevent_cachebust`` configuration value to a true value. -.. _custom_cache_busters: - 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`. +Revisiting from the previous section: + +.. code-block:: python + :linenos: + + # config is an instance of pyramid.config.Configurator + config.add_static_view(name='static', path='mypackage:folder/static', + cachebust=True) + +Setting ``cachebust`` to ``True`` instructs :app:`Pyramid` to use a default +cache busting implementation that should work for many situations. The +``cachebust`` may be set to any object that implements the interface +:class:`~pyramid.interfaces.ICacheBuster`. The above configuration is exactly +equivalent to: + +.. code-block:: python + :linenos: -:app:`Pyramid` ships with a very simplistic + from pyramid.static import PathSegmentMd5CacheBuster + + # config is an instance of pyramid.config.Configurator + config.add_static_view(name='static', path='mypackage:folder/static', + cachebust=PathSegmentMd5CacheBuster()) + +:app:`Pyramid` includes a handful of ready to use cache buster implementations: +:class:`~pyramid.static.PathSegmentMd5CacheBuster`, which inserts an md5 +checksum token in the path portion of the asset's URL, +:class:`~pyramid.static.QueryStringMd5CacheBuster`, which adds an md5 checksum +token to the query string of the asset's URL, and :class:`~pyramid.static.QueryStringConstantCacheBuster`, which adds an -arbitrary token you provide to the query string of the asset's URL. This -is almost never what you want in production as it does not allow fine-grained -busting of individual assets. +arbitrary token you provide to the query string of the asset's URL. In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` interface. Alternatively you may choose to subclass one of the existing implementations. One of the most likely scenarios is you'd want to change the -way the asset token is generated. To do this just subclass +way the asset token is generated. To do this just subclass either +:class:`~pyramid.static.PathSegmentCacheBuster` or :class:`~pyramid.static.QueryStringCacheBuster` and define a -``tokenize(pathspec)`` method. Here is an example which uses Git to get -the hash of the current commit: +``tokenize(pathspec)`` method. Here is an example which just uses Git to get +the hash of the currently checked out code: .. code-block:: python :linenos: import os import subprocess - from pyramid.static import QueryStringCacheBuster + from pyramid.static import PathSegmentCacheBuster - class GitCacheBuster(QueryStringCacheBuster): + class GitCacheBuster(PathSegmentCacheBuster): """ Assuming your code is installed as a Git checkout, as opposed to an egg 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'): - super(GitCacheBuster, self).__init__(param=param) + def __init__(self): here = os.path.dirname(os.path.abspath(__file__)) self.sha1 = subprocess.check_output( ['git', 'rev-parse', 'HEAD'], @@ -464,60 +476,26 @@ the hash of the current commit: 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 -strategy which modifies the path segment rather than methods which add a -token to the query string. - -You will need to consider whether the :app:`Pyramid` application will be -serving your static assets, whether you are using an external asset pipeline -to handle rewriting urls internal to the css/javascript, and how fine-grained -do you want the cache busting tokens to be. - -In many cases you will want to host the static assets on another web server -or externally on a CDN. In these cases your :app:`Pyramid` application may not -even have access to a copy of the static assets. In order to cache bust these -assets you will need some information about them. - -If you are using an external asset pipeline to generate your static files you -should consider using the :class:`~pyramid.static.ManifestCacheBuster`. -This cache buster can load a standard JSON formatted file generated by your -pipeline and use it to cache bust the assets. This has many performance -advantages as :app:`Pyramid` does not need to look at the files to generate -any cache busting tokens, but still supports fine-grained per-file tokens. - -Assuming an example ``manifest.json`` like: - -.. code-block:: json - - { - "css/main.css": "css/main-678b7c80.css", - "images/background.png": "images/background-a8169106.png" - } - -The following code would set up a cachebuster: - -.. code-block:: python - :linenos: - - from pyramid.path import AssetResolver - from pyramid.static import ManifestCacheBuster - - resolver = AssetResolver() - manifest = resolver.resolve('myapp:static/manifest.json') - config.add_static_view( - name='http://mycdn.example.com/', - path='mypackage:static', - cachebust=ManifestCacheBuster(manifest.abspath())) - -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: +The default cache buster implementation, +:class:`~pyramid.static.PathSegmentMd5CacheBuster`, works very well assuming +that you're using :app:`Pyramid` to serve your static assets. The md5 checksum +is fine grained enough that browsers should only request new versions of +specific assets that have changed. Many caching HTTP proxies will fail to +cache a resource if the URL contains a query string. In general, therefore, +you should prefer a cache busting strategy which modifies the path segment to a +strategy which adds a query string. + +It is possible, however, that your static assets are being served by another +web server or externally on a CDN. In these cases modifying the path segment +for a static asset URL would cause the external service to fail to find the +asset, causing your customer to get a 404. In these cases you would need to +fall back to a cache buster which adds a query string. It is even possible +that there isn't a copy of your static assets available to the :app:`Pyramid` +application, so a cache busting implementation that generates md5 checksums +would fail since it can't access the assets. In such a case, +:class:`~pyramid.static.QueryStringConstantCacheBuster` is a reasonable +fallback. The following code would set up a cachebuster that just uses the +time at start up as a cachebust token: .. code-block:: python :linenos: @@ -528,7 +506,7 @@ start up as a cachebust token: config.add_static_view( name='http://mycdn.example.com/', path='mypackage:static', - cachebust=QueryStringConstantCacheBuster(str(int(time.time())))) + cachebust=QueryStringConstantCacheBuster(str(time.time()))) .. index:: single: static assets view @@ -540,24 +518,85 @@ 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: +one needs to perform one of the following tasks. * 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. + cache busted form. * Templatize JS and CSS, and call ``request.static_url()`` inside their template code. * Pass static URL references to CSS and JavaScript via other means. -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. +Below are some simple approaches for CSS and JS programming which consider +asset cache busting. These approaches do not require additional tools or +packages. + +Relative cache busted URLs in CSS ++++++++++++++++++++++++++++++++++ + +Consider a CSS file ``/static/theme/css/site.css`` which contains the following +CSS code. + +.. code-block:: css + + body { + background: url(/static/theme/img/background.jpg); + } + +Any changes to ``background.jpg`` would not appear to the visitor because the +URL path is not cache busted as it is. Instead we would have to construct an +URL to the background image with the default ``PathSegmentCacheBuster`` cache +busting mechanism:: + + https://site/static/1eeb262c717/theme/img/background.jpg + +Every time the image is updated, the URL would need to be changed. It is not +practical to write this non-human readable URL into a CSS file. + +However, the CSS file itself is cache busted and is located under the path for +static assets. This lets us use relative references in our CSS to cache bust +the image. + +.. code-block:: css + + body { + background: url(../img/background.jpg); + } + +The browser would interpret this as having the CSS file hash in URL:: + + https://site/static/ab234b262c71/theme/css/../img/background.jpg + +The downside of this approach is that if the background image changes, one +needs to bump the CSS file. The CSS file hash change signals the caches that +the relative URL to the image in the CSS has been changed. When updating CSS +and related image assets, updates usually happen hand in hand, so this does not +add extra effort to theming workflow. + +Passing cache busted URLs to JavaScript ++++++++++++++++++++++++++++++++++++++++ + +For JavaScript, one can pass static asset URLs as function arguments or +globals. The globals can be generated in page template code, having access to +the ``request.static_url()`` function. + +Below is a simple example of passing a cached busted image URL in the Jinja2 +template language. Put the following code into the ```` section of the +relevant page. + +.. code-block:: html + + + +Then in your main ``site.js`` file, put the following code. + +.. code-block:: javascript + + var image = new Image(window.assets.backgroundImage); .. _advanced_static: -- cgit v1.2.3 From 3a41196208c7fd78cfb177bb5105c6a702436b78 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 20 Oct 2015 00:32:14 -0500 Subject: update cache buster prose and add ManifestCacheBuster redux of #2013 --- docs/narr/assets.rst | 257 ++++++++++++++++++++++----------------------------- 1 file changed, 109 insertions(+), 148 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index 020794062..d36fa49c0 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -356,14 +356,14 @@ may change, and then you'll want the client to load a new copy of the asset. Under normal circumstances you'd just need to wait for the client's cached copy to expire before they get the new version of the static resource. -A commonly used workaround to this problem is a technique known as "cache -busting". Cache busting schemes generally involve generating a URL for a -static asset that changes when the static asset changes. This way headers can -be sent along with the static asset instructing the client to cache the asset -for a very long time. When a static asset is changed, the URL used to refer to -it in a web page also changes, so the client sees it as a new resource and -requests the asset, regardless of any caching policy set for the resource's old -URL. +A commonly used workaround to this problem is a technique known as +:term:`cache busting`. Cache busting schemes generally involve generating a +URL for a static asset that changes when the static asset changes. This way +headers can be sent along with the static asset instructing the client to cache +the asset for a very long time. When a static asset is changed, the URL used +to refer to it in a web page also changes, so the client sees it as a new +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 @@ -372,30 +372,38 @@ assets by passing the optional argument, ``cachebust`` to .. code-block:: python :linenos: + import time + from pyramid.static import QueryStringConstantCacheBuster + # config is an instance of pyramid.config.Configurator - config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=True) + config.add_static_view( + name='static', path='mypackage:folder/static', + cachebust=QueryStringConstantCacheBuster(str(int(time.time()))), + ) Setting the ``cachebust`` argument instructs :app:`Pyramid` to use a cache -busting scheme which adds the md5 checksum for a static asset as a path segment -in the asset's URL: +busting scheme which adds the curent time for a static asset to the query +string in the asset's URL: .. code-block:: python :linenos: js_url = request.static_url('mypackage:folder/static/js/myapp.js') - # Returns: 'http://www.example.com/static/c9658b3c0a314a1ca21e5988e662a09e/js/myapp.js' + # Returns: 'http://www.example.com/static/js/myapp.js?x=1445318121' -When the asset changes, so will its md5 checksum, 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. +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. .. note:: - md5 checksums are cached in RAM, so if you change a static resource without - restarting your application, you may still generate URLs with a stale md5 - checksum. + Cache busting is an inherently complex topic as it integrates the asset + pipeline and the web application. It is expected and desired that + application authors will write their own cache buster implementations + conforming to the properties of their own asset pipelines. See + :ref:`custom_cache_busters` for information on writing your own. Disabling the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -406,65 +414,45 @@ configured cache busters without changing calls to ``PYRAMID_PREVENT_CACHEBUST`` environment variable or the ``pyramid.prevent_cachebust`` configuration value to a true value. +.. _custom_cache_busters: + Customizing the Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Revisiting from the previous section: - -.. code-block:: python - :linenos: - - # config is an instance of pyramid.config.Configurator - config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=True) - -Setting ``cachebust`` to ``True`` instructs :app:`Pyramid` to use a default -cache busting implementation that should work for many situations. The -``cachebust`` may be set to any object that implements the interface -:class:`~pyramid.interfaces.ICacheBuster`. The above configuration is exactly -equivalent to: - -.. code-block:: python - :linenos: +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`. - from pyramid.static import PathSegmentMd5CacheBuster - - # config is an instance of pyramid.config.Configurator - config.add_static_view(name='static', path='mypackage:folder/static', - cachebust=PathSegmentMd5CacheBuster()) - -:app:`Pyramid` includes a handful of ready to use cache buster implementations: -:class:`~pyramid.static.PathSegmentMd5CacheBuster`, which inserts an md5 -checksum token in the path portion of the asset's URL, -:class:`~pyramid.static.QueryStringMd5CacheBuster`, which adds an md5 checksum -token to the query string of the asset's URL, and +:app:`Pyramid` ships with a very simplistic :class:`~pyramid.static.QueryStringConstantCacheBuster`, which adds an -arbitrary token you provide to the query string of the asset's URL. +arbitrary token you provide to the query string of the asset's URL. This +is almost never what you want in production as it does not allow fine-grained +busting of individual assets. In order to implement your own cache buster, you can write your own class from scratch which implements the :class:`~pyramid.interfaces.ICacheBuster` interface. Alternatively you may choose to subclass one of the existing implementations. One of the most likely scenarios is you'd want to change the -way the asset token is generated. To do this just subclass either -:class:`~pyramid.static.PathSegmentCacheBuster` or +way the asset token is generated. To do this just subclass :class:`~pyramid.static.QueryStringCacheBuster` and define a -``tokenize(pathspec)`` method. Here is an example which just uses Git to get -the hash of the currently checked out code: +``tokenize(pathspec)`` method. Here is an example which uses Git to get +the hash of the current commit: .. code-block:: python :linenos: import os import subprocess - from pyramid.static import PathSegmentCacheBuster + from pyramid.static import QueryStringCacheBuster - class GitCacheBuster(PathSegmentCacheBuster): + class GitCacheBuster(QueryStringCacheBuster): """ Assuming your code is installed as a Git checkout, as opposed to an egg 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): + def __init__(self, param='x'): + super(GitCacheBuster, self).__init__(param=param) here = os.path.dirname(os.path.abspath(__file__)) self.sha1 = subprocess.check_output( ['git', 'rev-parse', 'HEAD'], @@ -476,26 +464,60 @@ the hash of the currently checked out code: Choosing a Cache Buster ~~~~~~~~~~~~~~~~~~~~~~~ -The default cache buster implementation, -:class:`~pyramid.static.PathSegmentMd5CacheBuster`, works very well assuming -that you're using :app:`Pyramid` to serve your static assets. The md5 checksum -is fine grained enough that browsers should only request new versions of -specific assets that have changed. Many caching HTTP proxies will fail to -cache a resource if the URL contains a query string. In general, therefore, -you should prefer a cache busting strategy which modifies the path segment to a -strategy which adds a query string. - -It is possible, however, that your static assets are being served by another -web server or externally on a CDN. In these cases modifying the path segment -for a static asset URL would cause the external service to fail to find the -asset, causing your customer to get a 404. In these cases you would need to -fall back to a cache buster which adds a query string. It is even possible -that there isn't a copy of your static assets available to the :app:`Pyramid` -application, so a cache busting implementation that generates md5 checksums -would fail since it can't access the assets. In such a case, -:class:`~pyramid.static.QueryStringConstantCacheBuster` is a reasonable -fallback. The following code would set up a cachebuster that just uses the -time at start up as a cachebust token: +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 +strategy which modifies the path segment rather than methods which add a +token to the query string. + +You will need to consider whether the :app:`Pyramid` application will be +serving your static assets, whether you are using an external asset pipeline +to handle rewriting urls internal to the css/javascript, and how fine-grained +do you want the cache busting tokens to be. + +In many cases you will want to host the static assets on another web server +or externally on a CDN. In these cases your :app:`Pyramid` application may not +even have access to a copy of the static assets. In order to cache bust these +assets you will need some information about them. + +If you are using an external asset pipeline to generate your static files you +should consider using the :class:`~pyramid.static.ManifestCacheBuster`. +This cache buster can load a standard JSON formatted file generated by your +pipeline and use it to cache bust the assets. This has many performance +advantages as :app:`Pyramid` does not need to look at the files to generate +any cache busting tokens, but still supports fine-grained per-file tokens. + +Assuming an example ``manifest.json`` like: + +.. code-block:: json + + { + "css/main.css": "css/main-678b7c80.css", + "images/background.png": "images/background-a8169106.png" + } + +The following code would set up a cachebuster: + +.. code-block:: python + :linenos: + + from pyramid.path import AssetResolver + from pyramid.static import ManifestCacheBuster + + resolver = AssetResolver() + manifest = resolver.resolve('myapp:static/manifest.json') + config.add_static_view( + name='http://mycdn.example.com/', + path='mypackage:static', + cachebust=ManifestCacheBuster(manifest.abspath())) + +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: @@ -506,7 +528,7 @@ time at start up as a cachebust token: config.add_static_view( name='http://mycdn.example.com/', path='mypackage:static', - cachebust=QueryStringConstantCacheBuster(str(time.time()))) + cachebust=QueryStringConstantCacheBuster(str(int(time.time())))) .. index:: single: static assets view @@ -518,85 +540,24 @@ 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. +one needs to perform one of the following tasks: * Process the files by using a precompiler which rewrites URLs to their final - cache busted form. + 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. * Pass static URL references to CSS and JavaScript via other means. -Below are some simple approaches for CSS and JS programming which consider -asset cache busting. These approaches do not require additional tools or -packages. - -Relative cache busted URLs in CSS -+++++++++++++++++++++++++++++++++ - -Consider a CSS file ``/static/theme/css/site.css`` which contains the following -CSS code. - -.. code-block:: css - - body { - background: url(/static/theme/img/background.jpg); - } - -Any changes to ``background.jpg`` would not appear to the visitor because the -URL path is not cache busted as it is. Instead we would have to construct an -URL to the background image with the default ``PathSegmentCacheBuster`` cache -busting mechanism:: - - https://site/static/1eeb262c717/theme/img/background.jpg - -Every time the image is updated, the URL would need to be changed. It is not -practical to write this non-human readable URL into a CSS file. - -However, the CSS file itself is cache busted and is located under the path for -static assets. This lets us use relative references in our CSS to cache bust -the image. - -.. code-block:: css - - body { - background: url(../img/background.jpg); - } - -The browser would interpret this as having the CSS file hash in URL:: - - https://site/static/ab234b262c71/theme/css/../img/background.jpg - -The downside of this approach is that if the background image changes, one -needs to bump the CSS file. The CSS file hash change signals the caches that -the relative URL to the image in the CSS has been changed. When updating CSS -and related image assets, updates usually happen hand in hand, so this does not -add extra effort to theming workflow. - -Passing cache busted URLs to JavaScript -+++++++++++++++++++++++++++++++++++++++ - -For JavaScript, one can pass static asset URLs as function arguments or -globals. The globals can be generated in page template code, having access to -the ``request.static_url()`` function. - -Below is a simple example of passing a cached busted image URL in the Jinja2 -template language. Put the following code into the ```` section of the -relevant page. - -.. code-block:: html - - - -Then in your main ``site.js`` file, put the following code. - -.. code-block:: javascript - - var image = new Image(window.assets.backgroundImage); +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. .. _advanced_static: -- cgit v1.2.3 From 63163f7bd71fba313bdab162201cb00a8dcc7c9b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 13 Nov 2015 13:31:40 -0800 Subject: minor grammar, .rst syntax, rewrap 79 cols --- docs/narr/upgrading.rst | 163 +++++++++++++++++++++++------------------------- 1 file changed, 79 insertions(+), 84 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/upgrading.rst b/docs/narr/upgrading.rst index eb3194a65..db9b5e090 100644 --- a/docs/narr/upgrading.rst +++ b/docs/narr/upgrading.rst @@ -12,26 +12,26 @@ applications keep working when you upgrade the Pyramid version you're using. .. sidebar:: About Release Numbering Conventionally, application version numbering in Python is described as - ``major.minor.micro``. If your Pyramid version is "1.2.3", it means - you're running a version of Pyramid with the major version "1", the minor - version "2" and the micro version "3". A "major" release is one that - increments the first-dot number; 2.X.X might follow 1.X.X. A "minor" - release is one that increments the second-dot number; 1.3.X might follow - 1.2.X. A "micro" release is one that increments the third-dot number; - 1.2.3 might follow 1.2.2. In general, micro releases are "bugfix-only", - and contain no new features, minor releases contain new features but are - largely backwards compatible with older versions, and a major release - indicates a large set of backwards incompatibilities. + ``major.minor.micro``. If your Pyramid version is "1.2.3", it means you're + running a version of Pyramid with the major version "1", the minor version + "2" and the micro version "3". A "major" release is one that increments the + first-dot number; 2.X.X might follow 1.X.X. A "minor" release is one that + increments the second-dot number; 1.3.X might follow 1.2.X. A "micro" + release is one that increments the third-dot number; 1.2.3 might follow + 1.2.2. In general, micro releases are "bugfix-only", and contain no new + features, minor releases contain new features but are largely backwards + compatible with older versions, and a major release indicates a large set of + backwards incompatibilities. The Pyramid core team is conservative when it comes to removing features. We -don't remove features unnecessarily, but we're human, and we make mistakes -which cause some features to be evolutionary dead ends. Though we are -willing to support dead-end features for some amount of time, some eventually -have to be removed when the cost of supporting them outweighs the benefit of -keeping them around, because each feature in Pyramid represents a certain -documentation and maintenance burden. - -Deprecation and Removal Policy +don't remove features unnecessarily, but we're human and we make mistakes which +cause some features to be evolutionary dead ends. Though we are willing to +support dead-end features for some amount of time, some eventually have to be +removed when the cost of supporting them outweighs the benefit of keeping them +around, because each feature in Pyramid represents a certain documentation and +maintenance burden. + +Deprecation and removal policy ------------------------------ When a feature is scheduled for removal from Pyramid or any of its official @@ -51,50 +51,49 @@ When a deprecated feature is eventually removed: - A note is added to the :ref:`changelog` about the removal. -Features are never removed in *micro* releases. They are only removed in -minor and major releases. Deprecated features are kept around for at least -*three* minor releases from the time the feature became deprecated. -Therefore, if a feature is added in Pyramid 1.0, but it's deprecated in -Pyramid 1.1, it will be kept around through all 1.1.X releases, all 1.2.X -releases and all 1.3.X releases. It will finally be removed in the first -1.4.X release. - -Sometimes features are "docs-deprecated" instead of formally deprecated. -This means that the feature will be kept around indefinitely, but it will be -removed from the documentation or a note will be added to the documentation -telling folks to use some other newer feature. This happens when the cost of -keeping an old feature around is very minimal and the support and -documentation burden is very low. For example, we might rename a function -that is an API without changing the arguments it accepts. In this case, -we'll often rename the function, and change the docs to point at the new -function name, but leave around a backwards compatibility alias to the old -function name so older code doesn't break. +Features are never removed in *micro* releases. They are only removed in minor +and major releases. Deprecated features are kept around for at least *three* +minor releases from the time the feature became deprecated. Therefore, if a +feature is added in Pyramid 1.0, but it's deprecated in Pyramid 1.1, it will be +kept around through all 1.1.X releases, all 1.2.X releases and all 1.3.X +releases. It will finally be removed in the first 1.4.X release. + +Sometimes features are "docs-deprecated" instead of formally deprecated. This +means that the feature will be kept around indefinitely, but it will be removed +from the documentation or a note will be added to the documentation telling +folks to use some other newer feature. This happens when the cost of keeping +an old feature around is very minimal and the support and documentation burden +is very low. For example, we might rename a function that is an API without +changing the arguments it accepts. In this case, we'll often rename the +function, and change the docs to point at the new function name, but leave +around a backwards compatibility alias to the old function name so older code +doesn't break. "Docs deprecated" features tend to work "forever", meaning that they won't be removed, and they'll never generate a deprecation warning. However, such 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. +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. -Consulting the Change History +Consulting the change history ----------------------------- -Your first line of defense against application failures caused by upgrading -to a newer Pyramid release is always to read the :ref:`changelog`. to find -the deprecations and removals for each release between the release you're -currently running and the one you wish to upgrade to. The change history -notes every deprecation within a ``Deprecation`` section and every removal -within a ``Backwards Incompatibilies`` section for each release. +Your first line of defense against application failures caused by upgrading to +a newer Pyramid release is always to read the :ref:`changelog` to find the +deprecations and removals for each release between the release you're currently +running and the one to which you wish to upgrade. The change history notes +every deprecation within a ``Deprecation`` section and every removal within a +``Backwards Incompatibilies`` section for each release. -The change history often contains instructions for changing your code to -avoid deprecation warnings and how to change docs-deprecated spellings to -newer ones. You can follow along with each deprecation explanation in the -change history, simply doing a grep or other code search to your application, -using the change log examples to remediate each potential problem. +The change history often contains instructions for changing your code to avoid +deprecation warnings and how to change docs-deprecated spellings to newer ones. +You can follow along with each deprecation explanation in the change history, +simply doing a grep or other code search to your application, using the change +log examples to remediate each potential problem. .. _testing_under_new_release: -Testing Your Application Under a New Pyramid Release +Testing your application under a new Pyramid release ---------------------------------------------------- Once you've upgraded your application to a new Pyramid release and you've @@ -106,25 +105,24 @@ you can see DeprecationWarnings printed to the console when the tests run. $ python -Wd setup.py test -q -The ``-Wd`` argument is an argument that tells Python to print deprecation -warnings to the console. Note that the ``-Wd`` flag is only required for -Python 2.7 and better: Python versions 2.6 and older print deprecation -warnings to the console by default. See `the Python -W flag documentation -`_ for more -information. +The ``-Wd`` argument tells Python to print deprecation warnings to the console. +Note that the ``-Wd`` flag is only required for Python 2.7 and better: Python +versions 2.6 and older print deprecation warnings to the console by default. +See `the Python -W flag documentation +`_ for more information. As your tests run, deprecation warnings will be printed to the console -explaining the deprecation and providing instructions about how to prevent -the deprecation warning from being issued. For example: +explaining the deprecation and providing instructions about how to prevent the +deprecation warning from being issued. For example: -.. code-block:: text +.. code-block:: bash $ python -Wd setup.py test -q # .. elided ... running build_ext - /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: - DeprecationWarning: static: The "pyramid.view.static" class is deprecated - as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with + /home/chrism/projects/pyramid/env27/myproj/myproj/views.py:3: + DeprecationWarning: static: The "pyramid.view.static" class is deprecated + as of Pyramid 1.1; use the "pyramid.static.static_view" class instead with the "use_subpath" argument set to True. from pyramid.view import static . @@ -144,8 +142,8 @@ pyramid.view import static``) that is causing the problem: from pyramid.view import static myview = static('static', 'static') -The deprecation warning tells me how to fix it, so I can change the code to -do things the newer way: +The deprecation warning tells me how to fix it, so I can change the code to do +things the newer way: .. code-block:: python :linenos: @@ -155,10 +153,10 @@ do things the newer way: from pyramid.static import static_view myview = static_view('static', 'static', use_subpath=True) -When I run the tests again, the deprecation warning is no longer printed to -my console: +When I run the tests again, the deprecation warning is no longer printed to my +console: -.. code-block:: text +.. code-block:: bash $ python -Wd setup.py test -q # .. elided ... @@ -170,7 +168,7 @@ my console: OK -My Application Doesn't Have Any Tests or Has Few Tests +My application doesn't have any tests or has few tests ------------------------------------------------------ If your application has no tests, or has only moderate test coverage, running @@ -178,8 +176,8 @@ tests won't tell you very much, because the Pyramid codepaths that generate deprecation warnings won't be executed. In this circumstance, you can start your application interactively under a -server run with the ``PYTHONWARNINGS`` environment variable set to -``default``. On UNIX, you can do that via: +server run with the ``PYTHONWARNINGS`` environment variable set to ``default``. +On UNIX, you can do that via: .. code-block:: bash @@ -194,16 +192,15 @@ On Windows, you need to issue two commands: At this point, it's ensured that deprecation warnings will be printed to the console whenever a codepath is hit that generates one. You can then click -around in your application interactively to try to generate them, and -remediate as explained in :ref:`testing_under_new_release`. +around in your application interactively to try to generate them, and remediate +as explained in :ref:`testing_under_new_release`. See `the PYTHONWARNINGS environment variable documentation `_ or `the Python -W flag documentation -`_ for more -information. +`_ for more information. -Upgrading to the Very Latest Pyramid Release +Upgrading to the very latest Pyramid release -------------------------------------------- When you upgrade your application to the most recent Pyramid release, @@ -220,15 +217,13 @@ advisable to do this: :ref:`testing_under_new_release`. Note any deprecation warnings and remediate. -- Upgrade to the most recent 1.3 release, 1.3.3. Run your application's - tests, note any deprecation warnings and remediate. +- Upgrade to the most recent 1.3 release, 1.3.3. Run your application's tests, + note any deprecation warnings, and remediate. - Upgrade to 1.4.4. Run your application's tests, note any deprecation - warnings and remediate. + warnings, and remediate. If you skip testing your application under each minor release (for example if -you upgrade directly from 1.2.1 to 1.4.4), you might miss a deprecation -warning and waste more time trying to figure out an error caused by a feature -removal than it would take to upgrade stepwise through each minor release. - - +you upgrade directly from 1.2.1 to 1.4.4), you might miss a deprecation warning +and waste more time trying to figure out an error caused by a feature removal +than it would take to upgrade stepwise through each minor release. -- cgit v1.2.3 From bdc3f28699c5fc6b127a1aa502b8372b149429f2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 15 Nov 2015 05:46:47 -0800 Subject: minor grammar, .rst syntax fixes, rewrap 79 cols --- docs/narr/threadlocals.rst | 226 +++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 120 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/threadlocals.rst b/docs/narr/threadlocals.rst index afe56de3e..7437a3a76 100644 --- a/docs/narr/threadlocals.rst +++ b/docs/narr/threadlocals.rst @@ -8,26 +8,24 @@ Thread Locals ============= -A :term:`thread local` variable is a variable that appears to be a -"global" variable to an application which uses it. However, unlike a -true global variable, one thread or process serving the application -may receive a different value than another thread or process when that -variable is "thread local". +A :term:`thread local` variable is a variable that appears to be a "global" +variable to an application which uses it. However, unlike a true global +variable, one thread or process serving the application may receive a different +value than another thread or process when that variable is "thread local". -When a request is processed, :app:`Pyramid` makes two :term:`thread -local` variables available to the application: a "registry" and a -"request". +When a request is processed, :app:`Pyramid` makes two :term:`thread local` +variables available to the application: a "registry" and a "request". Why and How :app:`Pyramid` Uses Thread Local Variables ---------------------------------------------------------- +------------------------------------------------------ -How are thread locals beneficial to :app:`Pyramid` and application -developers who use :app:`Pyramid`? Well, usually they're decidedly -**not**. Using a global or a thread local variable in any application -usually makes it a lot harder to understand for a casual reader. Use -of a thread local or a global is usually just a way to avoid passing -some value around between functions, which is itself usually a very -bad idea, at least if code readability counts as an important concern. +How are thread locals beneficial to :app:`Pyramid` and application developers +who use :app:`Pyramid`? Well, usually they're decidedly **not**. Using a +global or a thread local variable in any application usually makes it a lot +harder to understand for a casual reader. Use of a thread local or a global is +usually just a way to avoid passing some value around between functions, which +is itself usually a very bad idea, at least if code readability counts as an +important concern. For historical reasons, however, thread local variables are indeed consulted by various :app:`Pyramid` API functions. For example, the implementation of the @@ -40,119 +38,107 @@ application registry, from which it looks up the authentication policy; it then uses the authentication policy to retrieve the authenticated user id. This is how :app:`Pyramid` allows arbitrary authentication policies to be "plugged in". -When they need to do so, :app:`Pyramid` internals use two API -functions to retrieve the :term:`request` and :term:`application -registry`: :func:`~pyramid.threadlocal.get_current_request` and -:func:`~pyramid.threadlocal.get_current_registry`. The former -returns the "current" request; the latter returns the "current" -registry. Both ``get_current_*`` functions retrieve an object from a -thread-local data structure. These API functions are documented in -:ref:`threadlocal_module`. - -These values are thread locals rather than true globals because one -Python process may be handling multiple simultaneous requests or even -multiple :app:`Pyramid` applications. If they were true globals, -:app:`Pyramid` could not handle multiple simultaneous requests or -allow more than one :app:`Pyramid` application instance to exist in -a single Python process. - -Because one :app:`Pyramid` application is permitted to call -*another* :app:`Pyramid` application from its own :term:`view` code -(perhaps as a :term:`WSGI` app with help from the -:func:`pyramid.wsgi.wsgiapp2` decorator), these variables are -managed in a *stack* during normal system operations. The stack -instance itself is a :class:`threading.local`. +When they need to do so, :app:`Pyramid` internals use two API functions to +retrieve the :term:`request` and :term:`application registry`: +:func:`~pyramid.threadlocal.get_current_request` and +:func:`~pyramid.threadlocal.get_current_registry`. The former returns the +"current" request; the latter returns the "current" registry. Both +``get_current_*`` functions retrieve an object from a thread-local data +structure. These API functions are documented in :ref:`threadlocal_module`. + +These values are thread locals rather than true globals because one Python +process may be handling multiple simultaneous requests or even multiple +:app:`Pyramid` applications. If they were true globals, :app:`Pyramid` could +not handle multiple simultaneous requests or allow more than one :app:`Pyramid` +application instance to exist in a single Python process. + +Because one :app:`Pyramid` application is permitted to call *another* +:app:`Pyramid` application from its own :term:`view` code (perhaps as a +:term:`WSGI` app with help from the :func:`pyramid.wsgi.wsgiapp2` decorator), +these variables are managed in a *stack* during normal system operations. The +stack instance itself is a :class:`threading.local`. During normal operations, the thread locals stack is managed by a -:term:`Router` object. At the beginning of a request, the Router -pushes the application's registry and the request on to the stack. At -the end of a request, the stack is popped. The topmost request and -registry on the stack are considered "current". Therefore, when the -system is operating normally, the very definition of "current" is -defined entirely by the behavior of a pyramid :term:`Router`. +:term:`Router` object. At the beginning of a request, the Router pushes the +application's registry and the request on to the stack. At the end of a +request, the stack is popped. The topmost request and registry on the stack +are considered "current". Therefore, when the system is operating normally, +the very definition of "current" is defined entirely by the behavior of a +pyramid :term:`Router`. However, during unit testing, no Router code is ever invoked, and the -definition of "current" is defined by the boundary between calls to -the :meth:`pyramid.config.Configurator.begin` and -:meth:`pyramid.config.Configurator.end` methods (or between -calls to the :func:`pyramid.testing.setUp` and -:func:`pyramid.testing.tearDown` functions). These functions push -and pop the threadlocal stack when the system is under test. See -:ref:`test_setup_and_teardown` for the definitions of these functions. - -Scripts which use :app:`Pyramid` machinery but never actually start -a WSGI server or receive requests via HTTP such as scripts which use -the :mod:`pyramid.scripting` API will never cause any Router code -to be executed. However, the :mod:`pyramid.scripting` APIs also -push some values on to the thread locals stack as a matter of course. -Such scripts should expect the -:func:`~pyramid.threadlocal.get_current_request` function to always -return ``None``, and should expect the -:func:`~pyramid.threadlocal.get_current_registry` function to return -exactly the same :term:`application registry` for every request. +definition of "current" is defined by the boundary between calls to the +:meth:`pyramid.config.Configurator.begin` and +:meth:`pyramid.config.Configurator.end` methods (or between calls to the +:func:`pyramid.testing.setUp` and :func:`pyramid.testing.tearDown` functions). +These functions push and pop the threadlocal stack when the system is under +test. See :ref:`test_setup_and_teardown` for the definitions of these +functions. + +Scripts which use :app:`Pyramid` machinery but never actually start a WSGI +server or receive requests via HTTP, such as scripts which use the +:mod:`pyramid.scripting` API, will never cause any Router code to be executed. +However, the :mod:`pyramid.scripting` APIs also push some values on to the +thread locals stack as a matter of course. Such scripts should expect the +:func:`~pyramid.threadlocal.get_current_request` function to always return +``None``, and should expect the +:func:`~pyramid.threadlocal.get_current_registry` function to return exactly +the same :term:`application registry` for every request. Why You Shouldn't Abuse Thread Locals ------------------------------------- You probably should almost never use the :func:`~pyramid.threadlocal.get_current_request` or -:func:`~pyramid.threadlocal.get_current_registry` functions, except -perhaps in tests. In particular, it's almost always a mistake to use -``get_current_request`` or ``get_current_registry`` in application -code because its usage makes it possible to write code that can be -neither easily tested nor scripted. Inappropriate usage is defined as -follows: +:func:`~pyramid.threadlocal.get_current_registry` functions, except perhaps in +tests. In particular, it's almost always a mistake to use +``get_current_request`` or ``get_current_registry`` in application code because +its usage makes it possible to write code that can be neither easily tested nor +scripted. Inappropriate usage is defined as follows: - ``get_current_request`` should never be called within the body of a - :term:`view callable`, or within code called by a view callable. - View callables already have access to the request (it's passed in to - each as ``request``). - -- ``get_current_request`` should never be called in :term:`resource` code. - If a resource needs access to the request, it should be passed the request - by a :term:`view callable`. - -- ``get_current_request`` function should never be called because it's - "easier" or "more elegant" to think about calling it than to pass a - request through a series of function calls when creating some API - design. Your application should instead almost certainly pass data - derived from the request around rather than relying on being able to - call this function to obtain the request in places that actually - have no business knowing about it. Parameters are *meant* to be - passed around as function arguments, this is why they exist. Don't - try to "save typing" or create "nicer APIs" by using this function - in the place where a request is required; this will only lead to - sadness later. - -- Neither ``get_current_request`` nor ``get_current_registry`` should - ever be called within application-specific forks of third-party - library code. The library you've forked almost certainly has - nothing to do with :app:`Pyramid`, and making it dependent on - :app:`Pyramid` (rather than making your :app:`pyramid` - application depend upon it) means you're forming a dependency in the - wrong direction. - -Use of the :func:`~pyramid.threadlocal.get_current_request` function -in application code *is* still useful in very limited circumstances. -As a rule of thumb, usage of ``get_current_request`` is useful -**within code which is meant to eventually be removed**. For -instance, you may find yourself wanting to deprecate some API that -expects to be passed a request object in favor of one that does not -expect to be passed a request object. But you need to keep -implementations of the old API working for some period of time while -you deprecate the older API. So you write a "facade" implementation -of the new API which calls into the code which implements the older -API. Since the new API does not require the request, your facade -implementation doesn't have local access to the request when it needs -to pass it into the older API implementation. After some period of -time, the older implementation code is disused and the hack that uses -``get_current_request`` is removed. This would be an appropriate -place to use the ``get_current_request``. - -Use of the :func:`~pyramid.threadlocal.get_current_registry` -function should be limited to testing scenarios. The registry made -current by use of the -:meth:`pyramid.config.Configurator.begin` method during a -test (or via :func:`pyramid.testing.setUp`) when you do not pass -one in is available to you via this API. - + :term:`view callable`, or within code called by a view callable. View + callables already have access to the request (it's passed in to each as + ``request``). + +- ``get_current_request`` should never be called in :term:`resource` code. If a + resource needs access to the request, it should be passed the request by a + :term:`view callable`. + +- ``get_current_request`` function should never be called because it's "easier" + or "more elegant" to think about calling it than to pass a request through a + series of function calls when creating some API design. Your application + should instead, almost certainly, pass around data derived from the request + rather than relying on being able to call this function to obtain the request + in places that actually have no business knowing about it. Parameters are + *meant* to be passed around as function arguments; this is why they exist. + Don't try to "save typing" or create "nicer APIs" by using this function in + the place where a request is required; this will only lead to sadness later. + +- Neither ``get_current_request`` nor ``get_current_registry`` should ever be + called within application-specific forks of third-party library code. The + library you've forked almost certainly has nothing to do with :app:`Pyramid`, + and making it dependent on :app:`Pyramid` (rather than making your + :app:`pyramid` application depend upon it) means you're forming a dependency + in the wrong direction. + +Use of the :func:`~pyramid.threadlocal.get_current_request` function in +application code *is* still useful in very limited circumstances. As a rule of +thumb, usage of ``get_current_request`` is useful **within code which is meant +to eventually be removed**. For instance, you may find yourself wanting to +deprecate some API that expects to be passed a request object in favor of one +that does not expect to be passed a request object. But you need to keep +implementations of the old API working for some period of time while you +deprecate the older API. So you write a "facade" implementation of the new API +which calls into the code which implements the older API. Since the new API +does not require the request, your facade implementation doesn't have local +access to the request when it needs to pass it into the older API +implementation. After some period of time, the older implementation code is +disused and the hack that uses ``get_current_request`` is removed. This would +be an appropriate place to use the ``get_current_request``. + +Use of the :func:`~pyramid.threadlocal.get_current_registry` function should be +limited to testing scenarios. The registry made current by use of the +:meth:`pyramid.config.Configurator.begin` method during a test (or via +:func:`pyramid.testing.setUp`) when you do not pass one in is available to you +via this API. -- cgit v1.2.3 From 104870609e23edd1dba4d64869a068e883767552 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 15 Nov 2015 21:59:56 -0600 Subject: update docs to use asset specs with ManifestCacheBuster --- docs/narr/assets.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/assets.rst b/docs/narr/assets.rst index d36fa49c0..0f819570c 100644 --- a/docs/narr/assets.rst +++ b/docs/narr/assets.rst @@ -500,15 +500,12 @@ The following code would set up a cachebuster: .. code-block:: python :linenos: - from pyramid.path import AssetResolver from pyramid.static import ManifestCacheBuster - resolver = AssetResolver() - manifest = resolver.resolve('myapp:static/manifest.json') config.add_static_view( name='http://mycdn.example.com/', path='mypackage:static', - cachebust=ManifestCacheBuster(manifest.abspath())) + cachebust=ManifestCacheBuster('myapp:static/manifest.json')) A simpler approach is to use the :class:`~pyramid.static.QueryStringConstantCacheBuster` to generate a global -- cgit v1.2.3 From acfdc7085b836045e41568731e5f3223f34d635d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 4 Dec 2015 02:17:44 -0800 Subject: - add emphasize lines, minor grammar, rewrap 79 columns --- docs/narr/zca.rst | 257 +++++++++++++++++++++++++----------------------------- 1 file changed, 121 insertions(+), 136 deletions(-) (limited to 'docs/narr') diff --git a/docs/narr/zca.rst b/docs/narr/zca.rst index b0e9b1709..784886563 100644 --- a/docs/narr/zca.rst +++ b/docs/narr/zca.rst @@ -9,17 +9,16 @@ .. _zca_chapter: Using the Zope Component Architecture in :app:`Pyramid` -========================================================== +======================================================= -Under the hood, :app:`Pyramid` uses a :term:`Zope Component -Architecture` component registry as its :term:`application registry`. -The Zope Component Architecture is referred to colloquially as the -"ZCA." +Under the hood, :app:`Pyramid` uses a :term:`Zope Component Architecture` +component registry as its :term:`application registry`. The Zope Component +Architecture is referred to colloquially as the "ZCA." The ``zope.component`` API used to access data in a traditional Zope -application can be opaque. For example, here is a typical "unnamed -utility" lookup using the :func:`zope.component.getUtility` global API -as it might appear in a traditional Zope application: +application can be opaque. For example, here is a typical "unnamed utility" +lookup using the :func:`zope.component.getUtility` global API as it might +appear in a traditional Zope application: .. code-block:: python :linenos: @@ -28,23 +27,21 @@ as it might appear in a traditional Zope application: from zope.component import getUtility settings = getUtility(ISettings) -After this code runs, ``settings`` will be a Python dictionary. But -it's unlikely that any "civilian" will be able to figure this out just -by reading the code casually. When the ``zope.component.getUtility`` -API is used by a developer, the conceptual load on a casual reader of -code is high. +After this code runs, ``settings`` will be a Python dictionary. But it's +unlikely that any "civilian" will be able to figure this out just by reading +the code casually. When the ``zope.component.getUtility`` API is used by a +developer, the conceptual load on a casual reader of code is high. -While the ZCA is an excellent tool with which to build a *framework* -such as :app:`Pyramid`, it is not always the best tool with which -to build an *application* due to the opacity of the ``zope.component`` -APIs. Accordingly, :app:`Pyramid` tends to hide the presence of the -ZCA from application developers. You needn't understand the ZCA to -create a :app:`Pyramid` application; its use is effectively only a -framework implementation detail. +While the ZCA is an excellent tool with which to build a *framework* such as +:app:`Pyramid`, it is not always the best tool with which to build an +*application* due to the opacity of the ``zope.component`` APIs. Accordingly, +:app:`Pyramid` tends to hide the presence of the ZCA from application +developers. You needn't understand the ZCA to create a :app:`Pyramid` +application; its use is effectively only a framework implementation detail. -However, developers who are already used to writing :term:`Zope` -applications often still wish to use the ZCA while building a -:app:`Pyramid` application; :app:`Pyramid` makes this possible. +However, developers who are already used to writing :term:`Zope` applications +often still wish to use the ZCA while building a :app:`Pyramid` application. +:app:`Pyramid` makes this possible. .. index:: single: get_current_registry @@ -52,87 +49,81 @@ applications often still wish to use the ZCA while building a single: getSiteManager single: ZCA global API -Using the ZCA Global API in a :app:`Pyramid` Application ------------------------------------------------------------ - -:term:`Zope` uses a single ZCA registry -- the "global" ZCA registry --- for all Zope applications that run in the same Python process, -effectively making it impossible to run more than one Zope application -in a single process. - -However, for ease of deployment, it's often useful to be able to run more -than a single application per process. For example, use of a -:term:`PasteDeploy` "composite" allows you to run separate individual WSGI -applications in the same process, each answering requests for some URL -prefix. This makes it possible to run, for example, a TurboGears application -at ``/turbogears`` and a :app:`Pyramid` application at ``/pyramid``, both -served up using the same :term:`WSGI` server within a single Python process. - -Most production Zope applications are relatively large, making it -impractical due to memory constraints to run more than one Zope -application per Python process. However, a :app:`Pyramid` application -may be very small and consume very little memory, so it's a reasonable -goal to be able to run more than one :app:`Pyramid` application per -process. - -In order to make it possible to run more than one :app:`Pyramid` -application in a single process, :app:`Pyramid` defaults to using a -separate ZCA registry *per application*. - -While this services a reasonable goal, it causes some issues when -trying to use patterns which you might use to build a typical -:term:`Zope` application to build a :app:`Pyramid` application. -Without special help, ZCA "global" APIs such as -:func:`zope.component.getUtility` and :func:`zope.component.getSiteManager` -will use the ZCA "global" registry. Therefore, these APIs -will appear to fail when used in a :app:`Pyramid` application, -because they'll be consulting the ZCA global registry rather than the -component registry associated with your :app:`Pyramid` application. - -There are three ways to fix this: by disusing the ZCA global API -entirely, by using -:meth:`pyramid.config.Configurator.hook_zca` or by passing -the ZCA global registry to the :term:`Configurator` constructor at -startup time. We'll describe all three methods in this section. +Using the ZCA global API in a :app:`Pyramid` application +-------------------------------------------------------- + +:term:`Zope` uses a single ZCA registry—the "global" ZCA registry—for all Zope +applications that run in the same Python process, effectively making it +impossible to run more than one Zope application in a single process. + +However, for ease of deployment, it's often useful to be able to run more than +a single application per process. For example, use of a :term:`PasteDeploy` +"composite" allows you to run separate individual WSGI applications in the same +process, each answering requests for some URL prefix. This makes it possible +to run, for example, a TurboGears application at ``/turbogears`` and a +:app:`Pyramid` application at ``/pyramid``, both served up using the same +:term:`WSGI` server within a single Python process. + +Most production Zope applications are relatively large, making it impractical +due to memory constraints to run more than one Zope application per Python +process. However, a :app:`Pyramid` application may be very small and consume +very little memory, so it's a reasonable goal to be able to run more than one +:app:`Pyramid` application per process. + +In order to make it possible to run more than one :app:`Pyramid` application in +a single process, :app:`Pyramid` defaults to using a separate ZCA registry *per +application*. + +While this services a reasonable goal, it causes some issues when trying to use +patterns which you might use to build a typical :term:`Zope` application to +build a :app:`Pyramid` application. Without special help, ZCA "global" APIs +such as :func:`zope.component.getUtility` and +:func:`zope.component.getSiteManager` will use the ZCA "global" registry. +Therefore, these APIs will appear to fail when used in a :app:`Pyramid` +application, because they'll be consulting the ZCA global registry rather than +the component registry associated with your :app:`Pyramid` application. + +There are three ways to fix this: by disusing the ZCA global API entirely, by +using :meth:`pyramid.config.Configurator.hook_zca` or by passing the ZCA global +registry to the :term:`Configurator` constructor at startup time. We'll +describe all three methods in this section. .. index:: single: request.registry .. _disusing_the_global_zca_api: -Disusing the Global ZCA API +Disusing the global ZCA API +++++++++++++++++++++++++++ ZCA "global" API functions such as ``zope.component.getSiteManager``, ``zope.component.getUtility``, :func:`zope.component.getAdapter`, and :func:`zope.component.getMultiAdapter` aren't strictly necessary. Every -component registry has a method API that offers the same -functionality; it can be used instead. For example, presuming the -``registry`` value below is a Zope Component Architecture component -registry, the following bit of code is equivalent to -``zope.component.getUtility(IFoo)``: +component registry has a method API that offers the same functionality; it can +be used instead. For example, presuming the ``registry`` value below is a Zope +Component Architecture component registry, the following bit of code is +equivalent to ``zope.component.getUtility(IFoo)``: .. code-block:: python registry.getUtility(IFoo) -The full method API is documented in the ``zope.component`` package, -but it largely mirrors the "global" API almost exactly. +The full method API is documented in the ``zope.component`` package, but it +largely mirrors the "global" API almost exactly. -If you are willing to disuse the "global" ZCA APIs and use the method -interface of a registry instead, you need only know how to obtain the -:app:`Pyramid` component registry. +If you are willing to disuse the "global" ZCA APIs and use the method interface +of a registry instead, you need only know how to obtain the :app:`Pyramid` +component registry. There are two ways of doing so: -- use the :func:`pyramid.threadlocal.get_current_registry` - function within :app:`Pyramid` view or resource code. This will - always return the "current" :app:`Pyramid` application registry. +- use the :func:`pyramid.threadlocal.get_current_registry` function within + :app:`Pyramid` view or resource code. This will always return the "current" + :app:`Pyramid` application registry. -- use the attribute of the :term:`request` object named ``registry`` - in your :app:`Pyramid` view code, eg. ``request.registry``. This - is the ZCA component registry related to the running - :app:`Pyramid` application. +- use the attribute of the :term:`request` object named ``registry`` in your + :app:`Pyramid` view code, e.g., ``request.registry``. This is the ZCA + component registry related to the running :app:`Pyramid` application. See :ref:`threadlocals_chapter` for more information about :func:`pyramid.threadlocal.get_current_registry`. @@ -142,7 +133,7 @@ See :ref:`threadlocals_chapter` for more information about .. _hook_zca: -Enabling the ZCA Global API by Using ``hook_zca`` +Enabling the ZCA global API by using ``hook_zca`` +++++++++++++++++++++++++++++++++++++++++++++++++ Consider the following bit of idiomatic :app:`Pyramid` startup code: @@ -157,34 +148,31 @@ Consider the following bit of idiomatic :app:`Pyramid` startup code: config.include('some.other.package') return config.make_wsgi_app() -When the ``app`` function above is run, a :term:`Configurator` is -constructed. When the configurator is created, it creates a *new* -:term:`application registry` (a ZCA component registry). A new -registry is constructed whenever the ``registry`` argument is omitted -when a :term:`Configurator` constructor is called, or when a -``registry`` argument with a value of ``None`` is passed to a -:term:`Configurator` constructor. - -During a request, the application registry created by the Configurator -is "made current". This means calls to -:func:`~pyramid.threadlocal.get_current_registry` in the thread -handling the request will return the component registry associated -with the application. - -As a result, application developers can use ``get_current_registry`` -to get the registry and thus get access to utilities and such, as per -:ref:`disusing_the_global_zca_api`. But they still cannot use the -global ZCA API. Without special treatment, the ZCA global APIs will -always return the global ZCA registry (the one in -``zope.component.globalregistry.base``). - -To "fix" this and make the ZCA global APIs use the "current" -:app:`Pyramid` registry, you need to call -:meth:`~pyramid.config.Configurator.hook_zca` within your setup code. -For example: +When the ``app`` function above is run, a :term:`Configurator` is constructed. +When the configurator is created, it creates a *new* :term:`application +registry` (a ZCA component registry). A new registry is constructed whenever +the ``registry`` argument is omitted, when a :term:`Configurator` constructor +is called, or when a ``registry`` argument with a value of ``None`` is passed +to a :term:`Configurator` constructor. + +During a request, the application registry created by the Configurator is "made +current". This means calls to +:func:`~pyramid.threadlocal.get_current_registry` in the thread handling the +request will return the component registry associated with the application. + +As a result, application developers can use ``get_current_registry`` to get the +registry and thus get access to utilities and such, as per +:ref:`disusing_the_global_zca_api`. But they still cannot use the global ZCA +API. Without special treatment, the ZCA global APIs will always return the +global ZCA registry (the one in ``zope.component.globalregistry.base``). + +To "fix" this and make the ZCA global APIs use the "current" :app:`Pyramid` +registry, you need to call :meth:`~pyramid.config.Configurator.hook_zca` within +your setup code. For example: .. code-block:: python :linenos: + :emphasize-lines: 5 from pyramid.config import Configurator @@ -194,9 +182,9 @@ For example: config.include('some.other.application') return config.make_wsgi_app() -We've added a line to our original startup code, line number 6, which -calls ``config.hook_zca()``. The effect of this line under the hood -is that an analogue of the following code is executed: +We've added a line to our original startup code, line number 5, which calls +``config.hook_zca()``. The effect of this line under the hood is that an +analogue of the following code is executed: .. code-block:: python :linenos: @@ -205,17 +193,15 @@ is that an analogue of the following code is executed: from pyramid.threadlocal import get_current_registry getSiteManager.sethook(get_current_registry) -This causes the ZCA global API to start using the :app:`Pyramid` -application registry in threads which are running a :app:`Pyramid` -request. +This causes the ZCA global API to start using the :app:`Pyramid` application +registry in threads which are running a :app:`Pyramid` request. -Calling ``hook_zca`` is usually sufficient to "fix" the problem of -being able to use the global ZCA API within a :app:`Pyramid` -application. However, it also means that a Zope application that is -running in the same process may start using the :app:`Pyramid` -global registry instead of the Zope global registry, effectively -inverting the original problem. In such a case, follow the steps in -the next section, :ref:`using_the_zca_global_registry`. +Calling ``hook_zca`` is usually sufficient to "fix" the problem of being able +to use the global ZCA API within a :app:`Pyramid` application. However, it +also means that a Zope application that is running in the same process may +start using the :app:`Pyramid` global registry instead of the Zope global +registry, effectively inverting the original problem. In such a case, follow +the steps in the next section, :ref:`using_the_zca_global_registry`. .. index:: single: get_current_registry @@ -224,14 +210,15 @@ the next section, :ref:`using_the_zca_global_registry`. .. _using_the_zca_global_registry: -Enabling the ZCA Global API by Using The ZCA Global Registry +Enabling the ZCA global API by using the ZCA global registry ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -You can tell your :app:`Pyramid` application to use the ZCA global -registry at startup time instead of constructing a new one: +You can tell your :app:`Pyramid` application to use the ZCA global registry at +startup time instead of constructing a new one: .. code-block:: python :linenos: + :emphasize-lines: 5-7 from zope.component import getGlobalSiteManager from pyramid.config import Configurator @@ -243,16 +230,14 @@ registry at startup time instead of constructing a new one: config.include('some.other.application') return config.make_wsgi_app() -Lines 5, 6, and 7 above are the interesting ones. Line 5 retrieves -the global ZCA component registry. Line 6 creates a -:term:`Configurator`, passing the global ZCA registry into its -constructor as the ``registry`` argument. Line 7 "sets up" the global -registry with Pyramid-specific registrations; this is code that is -normally executed when a registry is constructed rather than created, +Lines 5, 6, and 7 above are the interesting ones. Line 5 retrieves the global +ZCA component registry. Line 6 creates a :term:`Configurator`, passing the +global ZCA registry into its constructor as the ``registry`` argument. Line 7 +"sets up" the global registry with Pyramid-specific registrations; this is code +that is normally executed when a registry is constructed rather than created, but we must call it "by hand" when we pass an explicit registry. -At this point, :app:`Pyramid` will use the ZCA global registry -rather than creating a new application-specific registry; since by -default the ZCA global API will use this registry, things will work as -you might expect a Zope app to when you use the global ZCA API. - +At this point, :app:`Pyramid` will use the ZCA global registry rather than +creating a new application-specific registry. Since by default the ZCA global +API will use this registry, things will work as you might expect in a Zope app +when you use the global ZCA API. -- cgit v1.2.3 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.