1from pyramid.config import global_registries 2from pyramid.exceptions import ConfigurationError 3 4from pyramid.interfaces import ( 5 IRequestFactory, 6 IRootFactory, 7 ) 8from pyramid.request import Request 9from pyramid.request import apply_request_extensions 10 11from pyramid.threadlocal import manager as threadlocal_manager 12from pyramid.traversal import DefaultRootFactory 13 14def get_root(app, request=None): 15 """ Return a tuple composed of ``(root, closer)`` when provided a 16 :term:`router` instance as the ``app`` argument. The ``root`` 17 returned is the application root object. The ``closer`` returned 18 is a callable (accepting no arguments) that should be called when 19 your scripting application is finished using the root. 20 21 ``request`` is passed to the :app:`Pyramid` application root 22 factory to compute the root. If ``request`` is None, a default 23 will be constructed using the registry's :term:`Request Factory` 24 via the :meth:`pyramid.interfaces.IRequestFactory.blank` method. 25 """ 26 registry = app.registry 27 if request is None: 28 request = _make_request('/', registry) 29 threadlocals = {'registry':registry, 'request':request} 30 app.threadlocal_manager.push(threadlocals) 31 def closer(request=request): # keep request alive via this function default 32 app.threadlocal_manager.pop() 33 root = app.root_factory(request) 34 return root, closer 35 36def prepare(request=None, registry=None): 37 """ This function pushes data onto the Pyramid threadlocal stack 38 (request and registry), making those objects 'current'. It 39 returns a dictionary useful for bootstrapping a Pyramid 40 application in a scripting environment. 41 42 ``request`` is passed to the :app:`Pyramid` application root 43 factory to compute the root. If ``request`` is None, a default 44 will be constructed using the registry's :term:`Request Factory` 45 via the :meth:`pyramid.interfaces.IRequestFactory.blank` method. 46 47 If ``registry`` is not supplied, the last registry loaded from 48 :attr:`pyramid.config.global_registries` will be used. If you 49 have loaded more than one :app:`Pyramid` application in the 50 current process, you may not want to use the last registry 51 loaded, thus you can search the ``global_registries`` and supply 52 the appropriate one based on your own criteria. 53 54 The function returns a dictionary composed of ``root``, 55 ``closer``, ``registry``, ``request`` and ``root_factory``. The 56 ``root`` returned is the application's root resource object. The 57 ``closer`` returned is a callable (accepting no arguments) that 58 should be called when your scripting application is finished 59 using the root. ``registry`` is the registry object passed or 60 the last registry loaded into 61 :attr:`pyramid.config.global_registries` if no registry is passed. 62 ``request`` is the request object passed or the constructed request 63 if no request is passed. ``root_factory`` is the root factory used 64 to construct the root. 65 """ 66 if registry is None: 67 registry = getattr(request, 'registry', global_registries.last) 68 if registry is None: 69 raise ConfigurationError('No valid Pyramid applications could be ' 70 'found, make sure one has been created ' 71 'before trying to activate it.') 72 if request is None: 73 request = _make_request('/', registry) 74 # NB: even though _make_request might have already set registry on 75 # request, we reset it in case someone has passed in their own 76 # request. 77 request.registry = registry 78 threadlocals = {'registry':registry, 'request':request} 79 threadlocal_manager.push(threadlocals) 80 apply_request_extensions(request) 81 def closer(): 82 threadlocal_manager.pop() 83 root_factory = registry.queryUtility(IRootFactory, 84 default=DefaultRootFactory) 85 root = root_factory(request) 86 if getattr(request, 'context', None) is None: 87 request.context = root 88 return {'root':root, 'closer':closer, 'registry':registry, 89 'request':request, 'root_factory':root_factory} 90 91def _make_request(path, registry=None): 92 """ Return a :meth:`pyramid.request.Request` object anchored at a 93 given path. The object returned will be generated from the supplied 94 registry's :term:`Request Factory` using the 95 :meth:`pyramid.interfaces.IRequestFactory.blank` method. 96 97 This request object can be passed to :meth:`pyramid.scripting.get_root` 98 or :meth:`pyramid.scripting.prepare` to initialize an application in 99 preparation for executing a script with a proper environment setup. 100 URLs can then be generated with the object, as well as rendering 101 templates. 102 103 If ``registry`` is not supplied, the last registry loaded from 104 :attr:`pyramid.config.global_registries` will be used. If you have 105 loaded more than one :app:`Pyramid` application in the current 106 process, you may not want to use the last registry loaded, thus 107 you can search the ``global_registries`` and supply the appropriate 108 one based on your own criteria. 109 """ 110 if registry is None: 111 registry = global_registries.last 112 request_factory = registry.queryUtility(IRequestFactory, default=Request) 113 request = request_factory.blank(path) 114 request.registry = registry 115 return request 116