add an IExecutionPolicy that can wrap the router
| | |
| | | .. automethod:: add_subscriber_predicate |
| | | .. automethod:: add_view_predicate |
| | | .. automethod:: add_view_deriver |
| | | .. automethod:: set_execution_policy |
| | | .. automethod:: set_request_factory |
| | | .. automethod:: set_root_factory |
| | | .. automethod:: set_session_factory |
| | |
| | | .. autointerface:: IResponseFactory |
| | | :members: |
| | | |
| | | .. autointerface:: IRouter |
| | | :members: |
| | | |
| | | .. autointerface:: IViewMapperFactory |
| | | :members: |
| | | |
| | |
| | | |
| | | coverage |
| | | A measurement of code coverage, usually expressed as a percentage of which lines of code have been executed over which lines are executable, typically run during test execution. |
| | | execution policy |
| | | A policy which wraps the :term:`router` by creating the request object |
| | | and sending it through the request pipeline. |
| | | See :class:`pyramid.config.Configurator.set_execution_policy`. |
| | |
| | | |
| | | from pyramid.interfaces import ( |
| | | IDefaultRootFactory, |
| | | IExecutionPolicy, |
| | | IRequestFactory, |
| | | IResponseFactory, |
| | | IRequestExtensions, |
| | |
| | | ISessionFactory, |
| | | ) |
| | | |
| | | from pyramid.router import default_execution_policy |
| | | from pyramid.traversal import DefaultRootFactory |
| | | |
| | | from pyramid.util import ( |
| | |
| | | 'set_request_propery() is deprecated as of Pyramid 1.5; use ' |
| | | 'add_request_method() with the property=True argument instead') |
| | | |
| | | @action_method |
| | | def set_execution_policy(self, policy): |
| | | """ |
| | | Override the :app:`Pyramid` :term:`execution policy` in the |
| | | current configuration. The ``policy`` argument must be an instance |
| | | of an :class:`pyramid.interfaces.IExecutionPolicy` or a |
| | | :term:`dotted Python name` that points at an instance of an |
| | | execution policy. |
| | | |
| | | """ |
| | | policy = self.maybe_dotted(policy) |
| | | if policy is None: |
| | | policy = default_execution_policy |
| | | |
| | | def register(): |
| | | self.registry.registerUtility(policy, IExecutionPolicy) |
| | | |
| | | intr = self.introspectable('execution policy', None, |
| | | self.object_description(policy), |
| | | 'execution policy') |
| | | intr['policy'] = policy |
| | | self.action(IExecutionPolicy, register, introspectables=(intr,)) |
| | | |
| | | |
| | | @implementer(IRequestExtensions) |
| | | class _RequestExtensions(object): |
| | |
| | | registry = Attribute( |
| | | """Component architecture registry local to this application.""") |
| | | |
| | | class ISettings(Interface): |
| | | def make_request(environ): |
| | | """ |
| | | Create a new request object. |
| | | |
| | | This method initializes a new :class:`pyramid.interfaces.IRequest` |
| | | object using the application's |
| | | :class:`pyramid.interfaces.IRequestFactory`. |
| | | """ |
| | | |
| | | def invoke_request(request): |
| | | """ |
| | | Invoke the :app:`Pyramid` request pipeline. |
| | | |
| | | See :ref:`router_chapter` for information on the request pipeline. |
| | | """ |
| | | |
| | | class IExecutionPolicy(Interface): |
| | | def __call__(environ, router): |
| | | """ |
| | | This callable triggers the router to process a raw WSGI environ dict |
| | | into a response and controls the :app:`Pyramid` request pipeline. |
| | | |
| | | The ``environ`` is the raw WSGI environ. |
| | | |
| | | The ``router`` is an :class:`pyramid.interfaces.IRouter` object which |
| | | should be used to create a request object and send it into the |
| | | processing pipeline. |
| | | |
| | | The return value should be a :class:`pyramid.interfaces.IResponse` |
| | | object or an exception that will be handled by WSGI middleware. |
| | | |
| | | The default execution policy simple creates a request and sends it |
| | | through the pipeline: |
| | | |
| | | .. code-block:: python |
| | | |
| | | def simple_execution_policy(environ, router): |
| | | request = router.make_request(environ) |
| | | return router.invoke_request(request) |
| | | """ |
| | | |
| | | class ISettings(IDict): |
| | | """ Runtime settings utility for pyramid; represents the |
| | | deployment settings for the application. Implements a mapping |
| | | interface.""" |
| | |
| | | |
| | | from pyramid.interfaces import ( |
| | | IDebugLogger, |
| | | IExecutionPolicy, |
| | | IRequest, |
| | | IRequestExtensions, |
| | | IRootFactory, |
| | |
| | | self.routes_mapper = q(IRoutesMapper) |
| | | self.request_factory = q(IRequestFactory, default=Request) |
| | | self.request_extensions = q(IRequestExtensions) |
| | | self.execution_policy = q( |
| | | IExecutionPolicy, default=default_execution_policy) |
| | | self.orig_handle_request = self.handle_request |
| | | tweens = q(ITweens) |
| | | if tweens is not None: |
| | |
| | | :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. |
| | | |
| | | |
| | | See the API for pyramid.request for complete documentation. |
| | | """ |
| | | request.registry = self.registry |
| | | request.invoke_subrequest = self.invoke_subrequest |
| | | return self.invoke_request( |
| | | request, |
| | | _use_tweens=use_tweens, |
| | | _apply_extensions=True, |
| | | ) |
| | | |
| | | def make_request(self, environ): |
| | | request = self.request_factory(environ) |
| | | request.registry = self.registry |
| | | request.invoke_subrequest = self.invoke_subrequest |
| | | extensions = self.request_extensions |
| | | if extensions is not None: |
| | | apply_request_extensions(request, extensions=extensions) |
| | | return request |
| | | |
| | | def invoke_request(self, request, |
| | | _use_tweens=True, _apply_extensions=False): |
| | | registry = self.registry |
| | | has_listeners = self.registry.has_listeners |
| | | notify = self.registry.notify |
| | | threadlocals = {'registry':registry, 'request':request} |
| | | threadlocals = {'registry': registry, 'request': request} |
| | | manager = self.threadlocal_manager |
| | | manager.push(threadlocals) |
| | | request.registry = registry |
| | | request.invoke_subrequest = self.invoke_subrequest |
| | | |
| | | if use_tweens: |
| | | |
| | | if _use_tweens: |
| | | handle_request = self.handle_request |
| | | else: |
| | | handle_request = self.orig_handle_request |
| | |
| | | |
| | | try: |
| | | extensions = self.request_extensions |
| | | if extensions is not None: |
| | | if _apply_extensions and extensions is not None: |
| | | apply_request_extensions(request, extensions=extensions) |
| | | response = handle_request(request) |
| | | |
| | |
| | | request._process_response_callbacks(response) |
| | | |
| | | has_listeners and notify(NewResponse(request, response)) |
| | | |
| | | |
| | | return response |
| | | |
| | | finally: |
| | |
| | | within the application registry; call ``start_response`` and |
| | | return an iterable. |
| | | """ |
| | | request = self.request_factory(environ) |
| | | response = self.invoke_subrequest(request, use_tweens=True) |
| | | return response(request.environ, start_response) |
| | | response = self.execution_policy(environ, self) |
| | | return response(environ, start_response) |
| | | |
| | | |
| | | def default_execution_policy(environ, router): |
| | | request = router.make_request(environ) |
| | | return router.invoke_request(request) |
| | |
| | | return response |
| | | |
| | | def view_two(request): |
| | | return 'This came from view_two' |
| | | # check that request.foo is valid for a subrequest |
| | | return 'This came from view_two, foo=%s' % (request.foo,) |
| | | |
| | | def view_three(request): |
| | | subreq = Request.blank('/view_four') |
| | |
| | | config.add_view(view_three, route_name='three') |
| | | config.add_view(view_four, route_name='four') |
| | | config.add_view(view_five, route_name='five') |
| | | config.add_request_method(lambda r: 'bar', 'foo', property=True) |
| | | return config |
| | | |
| | |
| | | |
| | | self.assertRaises(ConfigurationError, get_bad_name) |
| | | |
| | | def test_set_execution_policy(self): |
| | | from pyramid.interfaces import IExecutionPolicy |
| | | config = self._makeOne(autocommit=True) |
| | | def dummy_policy(environ, router): pass |
| | | config.set_execution_policy(dummy_policy) |
| | | registry = config.registry |
| | | result = registry.queryUtility(IExecutionPolicy) |
| | | self.assertEqual(result, dummy_policy) |
| | | |
| | | def test_set_execution_policy_to_None(self): |
| | | from pyramid.interfaces import IExecutionPolicy |
| | | from pyramid.router import default_execution_policy |
| | | config = self._makeOne(autocommit=True) |
| | | config.set_execution_policy(None) |
| | | registry = config.registry |
| | | result = registry.queryUtility(IExecutionPolicy) |
| | | self.assertEqual(result, default_execution_policy) |
| | | |
| | | class TestDeprecatedFactoriesMixinMethods(unittest.TestCase): |
| | | def setUp(self): |
| | | from zope.deprecation import __show__ |
| | |
| | | config.set_request_property(bar, name='bar') |
| | | self.assertRaises(ConfigurationConflictError, config.commit) |
| | | |
| | | |
| | |
| | | |
| | | def test_one(self): |
| | | res = self.testapp.get('/view_one', status=200) |
| | | self.assertTrue(b'This came from view_two' in res.body) |
| | | self.assertTrue(b'This came from view_two, foo=bar' in res.body) |
| | | |
| | | def test_three(self): |
| | | res = self.testapp.get('/view_three', status=500) |
| | |
| | | start_response = DummyStartResponse() |
| | | self.assertRaises(PredicateMismatch, router, environ, start_response) |
| | | |
| | | def test_custom_execution_policy(self): |
| | | from pyramid.interfaces import IExecutionPolicy |
| | | from pyramid.request import Request |
| | | from pyramid.response import Response |
| | | registry = self.config.registry |
| | | def dummy_policy(environ, router): |
| | | return Response(status=200, body=b'foo') |
| | | registry.registerUtility(dummy_policy, IExecutionPolicy) |
| | | router = self._makeOne() |
| | | resp = Request.blank('/').get_response(router) |
| | | self.assertEqual(resp.status_code, 200) |
| | | self.assertEqual(resp.body, b'foo') |
| | | |
| | | class DummyPredicate(object): |
| | | def __call__(self, info, request): |
| | | return True |