1from zope.deprecation import deprecated
2
3from zope.interface import (
4    Attribute,
5    Interface,
6    )
7
8from pyramid.compat import PY2
9
10# public API interfaces
11
12class IContextFound(Interface):
13    """ An event type that is emitted after :app:`Pyramid` finds a
14    :term:`context` object but before it calls any view code.  See the
15    documentation attached to :class:`pyramid.events.ContextFound`
16    for more information.
17
18    .. note::
19
20       For backwards compatibility with versions of
21       :app:`Pyramid` before 1.0, this event interface can also be
22       imported as :class:`pyramid.interfaces.IAfterTraversal`.
23    """
24    request = Attribute('The request object')
25
26IAfterTraversal = IContextFound
27
28class IBeforeTraversal(Interface):
29    """
30    An event type that is emitted after :app:`Pyramid` attempted to find a
31    route but before it calls any traversal or view code. See the documentation
32    attached to :class:`pyramid.events.Routefound` for more information.
33    """
34    request = Attribute('The request object')
35
36class INewRequest(Interface):
37    """ An event type that is emitted whenever :app:`Pyramid`
38    begins to process a new request.  See the documentation attached
39    to :class:`pyramid.events.NewRequest` for more information."""
40    request = Attribute('The request object')
41
42class INewResponse(Interface):
43    """ An event type that is emitted whenever any :app:`Pyramid`
44    view returns a response. See the
45    documentation attached to :class:`pyramid.events.NewResponse`
46    for more information."""
47    request = Attribute('The request object')
48    response = Attribute('The response object')
49
50class IApplicationCreated(Interface):
51    """ Event issued when the
52    :meth:`pyramid.config.Configurator.make_wsgi_app` method
53    is called.  See the documentation attached to
54    :class:`pyramid.events.ApplicationCreated` for more
55    information.
56
57    .. note::
58
59       For backwards compatibility with :app:`Pyramid`
60       versions before 1.0, this interface can also be imported as
61       :class:`pyramid.interfaces.IWSGIApplicationCreatedEvent`.
62    """
63    app = Attribute("Created application")
64
65IWSGIApplicationCreatedEvent = IApplicationCreated # b /c
66
67class IResponse(Interface):
68    """ Represents a WSGI response using the WebOb response interface.
69    Some attribute and method documentation of this interface references
70    :rfc:`2616`.
71
72    This interface is most famously implemented by
73    :class:`pyramid.response.Response` and the HTTP exception classes in
74    :mod:`pyramid.httpexceptions`."""
75
76    RequestClass = Attribute(
77        """ Alias for :class:`pyramid.request.Request` """)
78
79    def __call__(environ, start_response):
80        """ :term:`WSGI` call interface, should call the start_response
81        callback and should return an iterable"""
82
83    accept_ranges = Attribute(
84        """Gets and sets and deletes the Accept-Ranges header. For more
85        information on Accept-Ranges see RFC 2616, section 14.5""")
86
87    age = Attribute(
88        """Gets and sets and deletes the Age header. Converts using int.
89        For more information on Age see RFC 2616, section 14.6.""")
90
91    allow = Attribute(
92        """Gets and sets and deletes the Allow header. Converts using
93        list. For more information on Allow see RFC 2616, Section 14.7.""")
94
95    app_iter = Attribute(
96        """Returns the app_iter of the response.
97
98        If body was set, this will create an app_iter from that body
99        (a single-item list)""")
100
101    def app_iter_range(start, stop):
102        """ Return a new app_iter built from the response app_iter that
103        serves up only the given start:stop range. """
104
105    body = Attribute(
106        """The body of the response, as a str. This will read in the entire
107        app_iter if necessary.""")
108
109    body_file = Attribute(
110        """A file-like object that can be used to write to the body. If you
111        passed in a list app_iter, that app_iter will be modified by writes.""")
112
113    cache_control = Attribute(
114        """Get/set/modify the Cache-Control header (RFC 2616 section 14.9)""")
115
116    cache_expires = Attribute(
117        """ Get/set the Cache-Control and Expires headers. This sets the
118            response to expire in the number of seconds passed when set. """)
119
120    charset = Attribute(
121        """Get/set the charset (in the Content-Type)""")
122
123    def conditional_response_app(environ, start_response):
124        """ Like the normal __call__ interface, but checks conditional
125        headers:
126
127        - If-Modified-Since (304 Not Modified; only on GET, HEAD)
128
129        - If-None-Match (304 Not Modified; only on GET, HEAD)
130
131        - Range (406 Partial Content; only on GET, HEAD)"""
132
133    content_disposition = Attribute(
134        """Gets and sets and deletes the Content-Disposition header.
135        For more information on Content-Disposition see RFC 2616 section
136        19.5.1.""")
137
138    content_encoding = Attribute(
139        """Gets and sets and deletes the Content-Encoding header.  For more
140        information about Content-Encoding see RFC 2616 section 14.11.""")
141
142    content_language = Attribute(
143        """Gets and sets and deletes the Content-Language header. Converts
144        using list.  For more information about Content-Language see RFC 2616
145        section 14.12.""")
146
147    content_length = Attribute(
148        """Gets and sets and deletes the Content-Length header. For more
149        information on Content-Length see RFC 2616 section 14.17.
150        Converts using int. """)
151
152    content_location = Attribute(
153        """Gets and sets and deletes the Content-Location header. For more
154        information on Content-Location see RFC 2616 section 14.14.""")
155
156    content_md5 = Attribute(
157        """Gets and sets and deletes the Content-MD5 header. For more
158        information on Content-MD5 see RFC 2616 section 14.14.""")
159
160    content_range = Attribute(
161        """Gets and sets and deletes the Content-Range header. For more
162        information on Content-Range see section 14.16. Converts using
163        ContentRange object.""")
164
165    content_type = Attribute(
166        """Get/set the Content-Type header (or None), without the charset
167        or any parameters. If you include parameters (or ; at all) when
168        setting the content_type, any existing parameters will be deleted;
169        otherwise they will be preserved.""")
170
171    content_type_params = Attribute(
172        """A dictionary of all the parameters in the content type.  This is
173        not a view, set to change, modifications of the dict would not
174        be applied otherwise.""")
175
176    def copy():
177        """ Makes a copy of the response and returns the copy. """
178
179    date = Attribute(
180        """Gets and sets and deletes the Date header. For more information on
181        Date see RFC 2616 section 14.18. Converts using HTTP date.""")
182
183    def delete_cookie(key, path='/', domain=None):
184        """ Delete a cookie from the client. Note that path and domain must
185        match how the cookie was originally set.  This sets the cookie to the
186        empty string, and max_age=0 so that it should expire immediately. """
187
188    def encode_content(encoding='gzip', lazy=False):
189        """ Encode the content with the given encoding (only gzip and
190        identity are supported)."""
191
192    environ = Attribute(
193        """Get/set the request environ associated with this response,
194        if any.""")
195
196    etag = Attribute(
197        """ Gets and sets and deletes the ETag header. For more information
198        on ETag see RFC 2616 section 14.19. Converts using Entity tag.""")
199
200    expires = Attribute(
201        """ Gets and sets and deletes the Expires header. For more
202        information on Expires see RFC 2616 section 14.21. Converts using
203        HTTP date.""")
204
205    headerlist = Attribute(
206        """ The list of response headers. """)
207
208    headers = Attribute(
209        """ The headers in a dictionary-like object """)
210
211    last_modified = Attribute(
212        """ Gets and sets and deletes the Last-Modified header. For more
213        information on Last-Modified see RFC 2616 section 14.29. Converts
214        using HTTP date.""")
215
216    location = Attribute(
217        """ Gets and sets and deletes the Location header. For more
218        information on Location see RFC 2616 section 14.30.""")
219
220    def md5_etag(body=None, set_content_md5=False):
221        """ Generate an etag for the response object using an MD5 hash of the
222        body (the body parameter, or self.body if not given).  Sets self.etag.
223        If set_content_md5 is True sets self.content_md5 as well """
224
225    def merge_cookies(resp):
226        """ Merge the cookies that were set on this response with the given
227        resp object (which can be any WSGI application).  If the resp is a
228        webob.Response object, then the other object will be modified
229        in-place. """
230
231    pragma = Attribute(
232        """ Gets and sets and deletes the Pragma header. For more information
233        on Pragma see RFC 2616 section 14.32. """)
234
235    request = Attribute(
236        """ Return the request associated with this response if any. """)
237
238    retry_after = Attribute(
239        """ Gets and sets and deletes the Retry-After header. For more
240        information on Retry-After see RFC 2616 section 14.37. Converts
241        using HTTP date or delta seconds.""")
242
243    server = Attribute(
244        """ Gets and sets and deletes the Server header. For more information
245        on Server see RFC216 section 14.38. """)
246
247    def set_cookie(key, value='', max_age=None, path='/', domain=None,
248                   secure=False, httponly=False, comment=None, expires=None,
249                   overwrite=False):
250        """ Set (add) a cookie for the response """
251
252    status = Attribute(
253        """ The status string. """)
254
255    status_int = Attribute(
256        """ The status as an integer """)
257
258    unicode_body = Attribute(
259        """ Get/set the unicode value of the body (using the charset of
260        the Content-Type)""")
261
262    def unset_cookie(key, strict=True):
263        """ Unset a cookie with the given name (remove it from the
264        response)."""
265
266    vary = Attribute(
267        """Gets and sets and deletes the Vary header. For more information
268        on Vary see section 14.44. Converts using list.""")
269
270    www_authenticate = Attribute(
271        """ Gets and sets and deletes the WWW-Authenticate header. For more
272        information on WWW-Authenticate see RFC 2616 section 14.47. Converts
273        using 'parse_auth' and 'serialize_auth'. """)
274
275class IException(Interface): # not an API
276    """ An interface representing a generic exception """
277
278class IExceptionResponse(IException, IResponse):
279    """ An interface representing a WSGI response which is also an exception
280    object.  Register an exception view using this interface as a ``context``
281    to apply the registered view for all exception types raised by
282    :app:`Pyramid` internally (any exception that inherits from
283    :class:`pyramid.response.Response`, including
284    :class:`pyramid.httpexceptions.HTTPNotFound` and
285    :class:`pyramid.httpexceptions.HTTPForbidden`)."""
286    def prepare(environ):
287        """ Prepares the response for being called as a WSGI application """
288
289class IDict(Interface):
290    # Documentation-only interface
291
292    def __contains__(k):
293        """ Return ``True`` if key ``k`` exists in the dictionary."""
294
295    def __setitem__(k, value):
296        """ Set a key/value pair into the dictionary"""
297
298    def __delitem__(k):
299        """ Delete an item from the dictionary which is passed to the
300        renderer as the renderer globals dictionary."""
301
302    def __getitem__(k):
303        """ Return the value for key ``k`` from the dictionary or raise a
304        KeyError if the key doesn't exist"""
305
306    def __iter__():
307        """ Return an iterator over the keys of this dictionary """
308
309    def get(k, default=None):
310        """ Return the value for key ``k`` from the renderer dictionary, or
311        the default if no such value exists."""
312
313    def items():
314        """ Return a list of [(k,v)] pairs from the dictionary """
315
316    def keys():
317        """ Return a list of keys from the dictionary """
318
319    def values():
320        """ Return a list of values from the dictionary """
321
322    if PY2:
323
324        def iterkeys():
325            """ Return an iterator of keys from the dictionary """
326
327        def iteritems():
328            """ Return an iterator of (k,v) pairs from the dictionary """
329
330        def itervalues():
331            """ Return an iterator of values from the dictionary """
332
333        has_key = __contains__
334
335    def pop(k, default=None):
336        """ Pop the key k from the dictionary and return its value.  If k
337        doesn't exist, and default is provided, return the default.  If k
338        doesn't exist and default is not provided, raise a KeyError."""
339
340    def popitem():
341        """ Pop the item with key k from the dictionary and return it as a
342        two-tuple (k, v).  If k doesn't exist, raise a KeyError."""
343
344    def setdefault(k, default=None):
345        """ Return the existing value for key ``k`` in the dictionary.  If no
346         value with ``k`` exists in the dictionary, set the ``default``
347         value into the dictionary under the k name passed.  If a value already
348         existed in the dictionary, return it.  If a value did not exist in
349         the dictionary, return the default"""
350
351    def update(d):
352        """ Update the renderer dictionary with another dictionary ``d``."""
353
354    def clear():
355        """ Clear all values from the dictionary """
356
357class IBeforeRender(IDict):
358    """
359    Subscribers to this event may introspect and modify the set of
360    :term:`renderer globals` before they are passed to a :term:`renderer`.
361    The event object itself provides a dictionary-like interface for adding
362    and removing :term:`renderer globals`.  The keys and values of the
363    dictionary are those globals.  For example::
364
365      from repoze.events import subscriber
366      from pyramid.interfaces import IBeforeRender
367
368      @subscriber(IBeforeRender)
369      def add_global(event):
370          event['mykey'] = 'foo'
371
372    .. seealso::
373
374        See also :ref:`beforerender_event`.
375    """
376    rendering_val = Attribute('The value returned by a view or passed to a '
377                              '``render`` method for this rendering. '
378                              'This feature is new in Pyramid 1.2.')
379
380class IRendererInfo(Interface):
381    """ An object implementing this interface is passed to every
382    :term:`renderer factory` constructor as its only argument (conventionally
383    named ``info``)"""
384    name = Attribute('The value passed by the user as the renderer name')
385    package = Attribute('The "current package" when the renderer '
386                        'configuration statement was found')
387    type = Attribute('The renderer type name')
388    registry = Attribute('The "current" application registry when the '
389                         'renderer was created')
390    settings = Attribute('The deployment settings dictionary related '
391                         'to the current application')
392
393    def clone():
394        """ Return a shallow copy that does not share any mutable state."""
395
396class IRendererFactory(Interface):
397    def __call__(info):
398        """ Return an object that implements
399        :class:`pyramid.interfaces.IRenderer`. ``info`` is an
400        object that implements :class:`pyramid.interfaces.IRendererInfo`.
401        """
402
403class IRenderer(Interface):
404    def __call__(value, system):
405        """ Call the renderer with the result of the
406        view (``value``) passed in and return a result (a string or
407        unicode object useful as a response body).  Values computed by
408        the system are passed by the system in the ``system``
409        parameter, which is a dictionary.  Keys in the dictionary
410        include: ``view`` (the view callable that returned the value),
411        ``renderer_name`` (the template name or simple name of the
412        renderer), ``context`` (the context object passed to the
413        view), and ``request`` (the request object passed to the
414        view)."""
415
416class ITemplateRenderer(IRenderer):
417    def implementation():
418        """ Return the object that the underlying templating system
419        uses to render the template; it is typically a callable that
420        accepts arbitrary keyword arguments and returns a string or
421        unicode object """
422
423deprecated(
424    'ITemplateRenderer',
425    'As of Pyramid 1.5 the, "pyramid.interfaces.ITemplateRenderer" interface '
426    'is scheduled to be removed. It was used by the Mako and Chameleon '
427    'renderers which have been split into their own packages.'
428    )
429
430class IViewMapper(Interface):
431    def __call__(self, object):
432        """ Provided with an arbitrary object (a function, class, or
433        instance), returns a callable with the call signature ``(context,
434        request)``.  The callable returned should itself return a Response
435        object.  An IViewMapper is returned by
436        :class:`pyramid.interfaces.IViewMapperFactory`."""
437
438class IViewMapperFactory(Interface):
439    def __call__(self, **kw):
440        """
441        Return an object which implements
442        :class:`pyramid.interfaces.IViewMapper`.  ``kw`` will be a dictionary
443        containing view-specific arguments, such as ``permission``,
444        ``predicates``, ``attr``, ``renderer``, and other items.  An
445        IViewMapperFactory is used by
446        :meth:`pyramid.config.Configurator.add_view` to provide a plugpoint
447        to extension developers who want to modify potential view callable
448        invocation signatures and response values.
449        """
450
451class IAuthenticationPolicy(Interface):
452    """ An object representing a Pyramid authentication policy. """
453
454    def authenticated_userid(request):
455        """ Return the authenticated :term:`userid` or ``None`` if
456        no authenticated userid can be found. This method of the
457        policy should ensure that a record exists in whatever
458        persistent store is used related to the user (the user
459        should not have been deleted); if a record associated with
460        the current id does not exist in a persistent store, it
461        should return ``None``.
462
463        """
464
465    def unauthenticated_userid(request):
466        """ Return the *unauthenticated* userid.  This method
467        performs the same duty as ``authenticated_userid`` but is
468        permitted to return the userid based only on data present
469        in the request; it needn't (and shouldn't) check any
470        persistent store to ensure that the user record related to
471        the request userid exists.
472
473        This method is intended primarily a helper to assist the
474        ``authenticated_userid`` method in pulling credentials out
475        of the request data, abstracting away the specific headers,
476        query strings, etc that are used to authenticate the request.
477
478        """
479
480    def effective_principals(request):
481        """ Return a sequence representing the effective principals
482        typically including the :term:`userid` and any groups belonged
483        to by the current user, always including 'system' groups such
484        as ``pyramid.security.Everyone`` and
485        ``pyramid.security.Authenticated``.
486
487        """
488
489    def remember(request, userid, **kw):
490        """ Return a set of headers suitable for 'remembering' the
491        :term:`userid` named ``userid`` when set in a response.  An
492        individual authentication policy and its consumers can
493        decide on the composition and meaning of ``**kw``.
494
495        """
496
497    def forget(request):
498        """ Return a set of headers suitable for 'forgetting' the
499        current user on subsequent requests.
500
501        """
502
503class IAuthorizationPolicy(Interface):
504    """ An object representing a Pyramid authorization policy. """
505    def permits(context, principals, permission):
506        """ Return ``True`` if any of the ``principals`` is allowed the
507        ``permission`` in the current ``context``, else return ``False``
508        """
509
510    def principals_allowed_by_permission(context, permission):
511        """ Return a set of principal identifiers allowed by the
512        ``permission`` in ``context``.  This behavior is optional; if you
513        choose to not implement it you should define this method as
514        something which raises a ``NotImplementedError``.  This method
515        will only be called when the
516        ``pyramid.security.principals_allowed_by_permission`` API is
517        used."""
518
519class IMultiDict(IDict): # docs-only interface
520    """
521    An ordered dictionary that can have multiple values for each key. A
522    multidict adds the methods ``getall``, ``getone``, ``mixed``, ``extend``,
523    ``add``, and ``dict_of_lists`` to the normal dictionary interface.  A
524    multidict data structure is used as ``request.POST``, ``request.GET``,
525    and ``request.params`` within an :app:`Pyramid` application.
526    """
527
528    def add(key, value):
529        """ Add the key and value, not overwriting any previous value. """
530
531    def dict_of_lists():
532        """
533        Returns a dictionary where each key is associated with a list of
534        values.
535        """
536
537    def extend(other=None, **kwargs):
538        """ Add a set of keys and values, not overwriting any previous
539        values.  The ``other`` structure may be a list of two-tuples or a
540        dictionary.  If ``**kwargs`` is passed, its value *will* overwrite
541        existing values."""
542
543    def getall(key):
544        """ Return a list of all values matching the key (may be an empty
545        list) """
546
547    def getone(key):
548        """ Get one value matching the key, raising a KeyError if multiple
549        values were found. """
550
551    def mixed():
552        """ Returns a dictionary where the values are either single values,
553        or a list of values when a key/value appears more than once in this
554        dictionary. This is similar to the kind of dictionary often used to
555        represent the variables in a web request. """
556
557# internal interfaces
558
559class IRequest(Interface):
560    """ Request type interface attached to all request objects """
561
562class ITweens(Interface):
563    """ Marker interface for utility registration representing the ordered
564    set of a configuration's tween factories"""
565
566class IRequestHandler(Interface):
567    """ """
568    def __call__(self, request):
569        """ Must return a tuple of IReqest, IResponse or raise an exception.
570        The ``request`` argument will be an instance of an object that
571        provides IRequest."""
572
573IRequest.combined = IRequest # for exception view lookups
574
575class IRequestExtensions(Interface):
576    """ Marker interface for storing request extensions (properties and
577    methods) which will be added to the request object."""
578    descriptors = Attribute(
579        """A list of descriptors that will be added to each request.""")
580    methods = Attribute(
581        """A list of methods to be added to each request.""")
582
583class IRouteRequest(Interface):
584    """ *internal only* interface used as in a utility lookup to find
585    route-specific interfaces.  Not an API."""
586
587class IStaticURLInfo(Interface):
588    """ A policy for generating URLs to static assets """
589    def add(config, name, spec, **extra):
590        """ Add a new static info registration """
591
592    def generate(path, request, **kw):
593        """ Generate a URL for the given path """
594
595    def add_cache_buster(config, spec, cache_buster):
596        """ Add a new cache buster to a particular set of assets """
597
598class IResponseFactory(Interface):
599    """ A utility which generates a response """
600    def __call__(request):
601        """ Return a response object implementing IResponse,
602        e.g. :class:`pyramid.response.Response`). It should handle the
603        case when ``request`` is ``None``."""
604
605class IRequestFactory(Interface):
606    """ A utility which generates a request """
607    def __call__(environ):
608        """ Return an instance of ``pyramid.request.Request``"""
609
610    def blank(path):
611        """ Return an empty request object (see
612        :meth:`pyramid.request.Request.blank`)"""
613
614class IViewClassifier(Interface):
615    """ *Internal only* marker interface for views."""
616
617class IExceptionViewClassifier(Interface):
618    """ *Internal only* marker interface for exception views."""
619
620class IView(Interface):
621    def __call__(context, request):
622        """ Must return an object that implements IResponse. """
623
624class ISecuredView(IView):
625    """ *Internal only* interface.  Not an API. """
626    def __call_permissive__(context, request):
627        """ Guaranteed-permissive version of __call__ """
628
629    def __permitted__(context, request):
630        """ Return True if view execution will be permitted using the
631        context and request, False otherwise"""
632
633class IMultiView(ISecuredView):
634    """ *internal only*.  A multiview is a secured view that is a
635    collection of other views.  Each of the views is associated with
636    zero or more predicates.  Not an API."""
637    def add(view, predicates, order, accept=None, phash=None):
638        """ Add a view to the multiview. """
639
640class IRootFactory(Interface):
641    def __call__(request):
642        """ Return a root object based on the request """
643
644class IDefaultRootFactory(Interface):
645    def __call__(request):
646        """ Return the *default* root object for an application """
647
648class ITraverser(Interface):
649    def __call__(request):
650        """ Return a dictionary with (at least) the keys ``root``,
651        ``context``, ``view_name``, ``subpath``, ``traversed``,
652        ``virtual_root``, and ``virtual_root_path``.  These values are
653        typically the result of an object graph traversal.  ``root`` is the
654        physical root object, ``context`` will be a model object,
655        ``view_name`` will be the view name used (a Unicode name),
656        ``subpath`` will be a sequence of Unicode names that followed the
657        view name but were not traversed, ``traversed`` will be a sequence of
658        Unicode names that were traversed (including the virtual root path,
659        if any) ``virtual_root`` will be a model object representing the
660        virtual root (or the physical root if traversal was not performed),
661        and ``virtual_root_path`` will be a sequence representing the virtual
662        root path (a sequence of Unicode names) or ``None`` if traversal was
663        not performed.
664
665        Extra keys for special purpose functionality can be returned as
666        necessary.
667
668        All values returned in the dictionary will be made available
669        as attributes of the ``request`` object by the :term:`router`.
670        """
671
672ITraverserFactory = ITraverser # b / c for 1.0 code
673
674class IViewPermission(Interface):
675    def __call__(context, request):
676        """ Return True if the permission allows, return False if it denies.
677        """
678
679class IRouter(Interface):
680    """ WSGI application which routes requests to 'view' code based on
681    a view registry."""
682    registry = Attribute(
683        """Component architecture registry local to this application.""")
684
685class ISettings(Interface):
686    """ Runtime settings utility for pyramid; represents the
687    deployment settings for the application.  Implements a mapping
688    interface."""
689
690# this interface, even if it becomes unused within Pyramid, is
691# imported by other packages (such as traversalwrapper)
692class ILocation(Interface):
693    """Objects that have a structural location"""
694    __parent__ = Attribute("The parent in the location hierarchy")
695    __name__ = Attribute("The name within the parent")
696
697class IDebugLogger(Interface):
698    """ Interface representing a PEP 282 logger """
699
700ILogger = IDebugLogger # b/c
701
702class IRoutePregenerator(Interface):
703    def __call__(request, elements, kw):
704
705        """ A pregenerator is a function associated by a developer with a
706        :term:`route`. The pregenerator for a route is called by
707        :meth:`pyramid.request.Request.route_url` in order to adjust the set
708        of arguments passed to it by the user for special purposes, such as
709        Pylons 'subdomain' support.  It will influence the URL returned by
710        ``route_url``.
711
712        A pregenerator should return a two-tuple of ``(elements, kw)``
713        after examining the originals passed to this function, which
714        are the arguments ``(request, elements, kw)``.  The simplest
715        pregenerator is::
716
717            def pregenerator(request, elements, kw):
718                return elements, kw
719
720        You can employ a pregenerator by passing a ``pregenerator``
721        argument to the
722        :meth:`pyramid.config.Configurator.add_route`
723        function.
724
725        """
726
727class IRoute(Interface):
728    """ Interface representing the type of object returned from
729    ``IRoutesMapper.get_route``"""
730    name = Attribute('The route name')
731    pattern = Attribute('The route pattern')
732    factory = Attribute(
733        'The :term:`root factory` used by the :app:`Pyramid` router '
734        'when this route matches (or ``None``)')
735    predicates = Attribute(
736        'A sequence of :term:`route predicate` objects used to '
737        'determine if a request matches this route or not after '
738        'basic pattern matching has been completed.')
739    pregenerator = Attribute('This attribute should either be ``None`` or '
740                             'a callable object implementing the '
741                             '``IRoutePregenerator`` interface')
742
743    def match(path):
744        """
745        If the ``path`` passed to this function can be matched by the
746        ``pattern`` of this route, return a dictionary (the
747        'matchdict'), which will contain keys representing the dynamic
748        segment markers in the pattern mapped to values extracted from
749        the provided ``path``.
750
751        If the ``path`` passed to this function cannot be matched by
752        the ``pattern`` of this route, return ``None``.
753        """
754    def generate(kw):
755        """
756        Generate a URL based on filling in the dynamic segment markers
757        in the pattern using the ``kw`` dictionary provided.
758        """
759
760class IRoutesMapper(Interface):
761    """ Interface representing a Routes ``Mapper`` object """
762    def get_routes():
763        """ Return a sequence of Route objects registered in the mapper.
764        Static routes will not be returned in this sequence."""
765
766    def has_routes():
767        """ Returns ``True`` if any route has been registered. """
768
769    def get_route(name):
770        """ Returns an ``IRoute`` object if a route with the name ``name``
771        was registered, otherwise return ``None``."""
772
773    def connect(name, pattern, factory=None, predicates=(), pregenerator=None,
774                static=True):
775        """ Add a new route. """
776
777    def generate(name, kw):
778        """ Generate a URL using the route named ``name`` with the
779        keywords implied by kw"""
780
781    def __call__(request):
782        """ Return a dictionary containing matching information for
783        the request; the ``route`` key of this dictionary will either
784        be a Route object or ``None`` if no route matched; the
785        ``match`` key will be the matchdict or ``None`` if no route
786        matched.  Static routes will not be considered for matching.  """
787
788class IResourceURL(Interface):
789    virtual_path = Attribute(
790        'The virtual url path of the resource as a string.'
791        )
792    physical_path = Attribute(
793        'The physical url path of the resource as a string.'
794        )
795    virtual_path_tuple = Attribute(
796        'The virtual url path of the resource as a tuple.  (New in 1.5)'
797        )
798    physical_path_tuple = Attribute(
799        'The physical url path of the resource as a tuple. (New in 1.5)'
800        )
801
802class IContextURL(IResourceURL):
803    """
804    .. deprecated:: 1.3
805        An adapter which deals with URLs related to a context.  Use
806        :class:`pyramid.interfaces.IResourceURL` instead.
807    """
808    # this class subclasses IResourceURL because request.resource_url looks
809    # for IResourceURL via queryAdapter.  queryAdapter will find a deprecated
810    # IContextURL registration if no registration for IResourceURL exists.
811    # In reality, however, IContextURL objects were never required to have
812    # the virtual_path or physical_path attributes spelled in IResourceURL.
813    # The inheritance relationship is purely to benefit adapter lookup,
814    # not to imply an inheritance relationship of interface attributes
815    # and methods.
816    #
817    # Mechanics:
818    #
819    # class Fudge(object):
820    #     def __init__(self, one, two):
821    #         print(one, two)
822    # class Another(object):
823    #     def __init__(self, one, two):
824    #         print(one, two)
825    # ob = object()
826    # r.registerAdapter(Fudge, (Interface, Interface), IContextURL)
827    # print(r.queryMultiAdapter((ob, ob), IResourceURL))
828    # r.registerAdapter(Another, (Interface, Interface), IResourceURL)
829    # print(r.queryMultiAdapter((ob, ob), IResourceURL))
830    #
831    # prints
832    #
833    # <object object at 0x7fa678f3e2a0> <object object at 0x7fa678f3e2a0>
834    # <__main__.Fudge object at 0x1cda890>
835    # <object object at 0x7fa678f3e2a0> <object object at 0x7fa678f3e2a0>
836    # <__main__.Another object at 0x1cda850>
837
838    def virtual_root():
839        """ Return the virtual root related to a request and the
840        current context"""
841
842    def __call__():
843        """ Return a URL that points to the context. """
844
845deprecated(
846    'IContextURL',
847    'As of Pyramid 1.3 the, "pyramid.interfaces.IContextURL" interface is '
848    'scheduled to be removed.   Use the '
849    '"pyramid.config.Configurator.add_resource_url_adapter" method to register '
850    'a class that implements "pyramid.interfaces.IResourceURL" instead. '
851    'See the "What\'s new In Pyramid 1.3" document for more details.'
852    )
853
854class IPEP302Loader(Interface):
855    """ See http://www.python.org/dev/peps/pep-0302/#id30.
856    """
857    def get_data(path):
858        """ Retrieve data for and arbitrary "files" from storage backend.
859
860        Raise IOError for not found.
861
862        Data is returned as bytes.
863        """
864
865    def is_package(fullname):
866        """ Return True if the module specified by 'fullname' is a package.
867        """
868
869    def get_code(fullname):
870        """ Return the code object for the module identified by 'fullname'.
871
872        Return 'None' if it's a built-in or extension module.
873
874        If the loader doesn't have the code object but it does have the source
875        code, return the compiled source code.
876
877        Raise ImportError if the module can't be found by the importer at all.
878        """
879
880    def get_source(fullname):
881        """ Return the source code for the module identified by 'fullname'.
882
883        Return a string, using newline characters for line endings, or None
884        if the source is not available.
885
886        Raise ImportError if the module can't be found by the importer at all.
887        """
888
889    def get_filename(fullname):
890        """ Return the value of '__file__' if the named module was loaded.
891
892        If the module is not found, raise ImportError.
893        """
894
895
896class IPackageOverrides(IPEP302Loader):
897    """ Utility for pkg_resources overrides """
898
899# VH_ROOT_KEY is an interface; its imported from other packages (e.g.
900# traversalwrapper)
901VH_ROOT_KEY = 'HTTP_X_VHM_ROOT'
902
903class ILocalizer(Interface):
904    """ Localizer for a specific language """
905
906class ILocaleNegotiator(Interface):
907    def __call__(request):
908        """ Return a locale name """
909
910class ITranslationDirectories(Interface):
911    """ A list object representing all known translation directories
912    for an application"""
913
914class IDefaultPermission(Interface):
915    """ A string object representing the default permission to be used
916    for all view configurations which do not explicitly declare their
917    own."""
918
919class IDefaultCSRFOptions(Interface):
920    """ An object representing the default CSRF settings to be used for
921    all view configurations which do not explicitly declare their own."""
922    require_csrf = Attribute(
923        'Boolean attribute. If ``True``, then CSRF checks will be enabled by '
924        'default for the view unless overridden.')
925    token = Attribute('The key to be matched in the body of the request.')
926    header = Attribute('The header to be matched with the CSRF token.')
927    safe_methods = Attribute('A set of safe methods that skip CSRF checks.')
928
929class ISessionFactory(Interface):
930    """ An interface representing a factory which accepts a request object and
931    returns an ISession object """
932    def __call__(request):
933        """ Return an ISession object """
934
935class ISession(IDict):
936    """ An interface representing a session (a web session object,
937    usually accessed via ``request.session``.
938
939    Keys and values of a session must be pickleable.
940    """
941
942    # attributes
943
944    created = Attribute('Integer representing Epoch time when created.')
945    new = Attribute('Boolean attribute.  If ``True``, the session is new.')
946
947    # special methods
948
949    def invalidate():
950        """ Invalidate the session.  The action caused by
951        ``invalidate`` is implementation-dependent, but it should have
952        the effect of completely dissociating any data stored in the
953        session with the current request.  It might set response
954        values (such as one which clears a cookie), or it might not.
955
956        An invalidated session may be used after the call to ``invalidate``
957        with the effect that a new session is created to store the data. This
958        enables workflows requiring an entirely new session, such as in the
959        case of changing privilege levels or preventing fixation attacks.
960        """
961
962    def changed():
963        """ Mark the session as changed. A user of a session should
964        call this method after he or she mutates a mutable object that
965        is *a value of the session* (it should not be required after
966        mutating the session itself).  For example, if the user has
967        stored a dictionary in the session under the key ``foo``, and
968        he or she does ``session['foo'] = {}``, ``changed()`` needn't
969        be called.  However, if subsequently he or she does
970        ``session['foo']['a'] = 1``, ``changed()`` must be called for
971        the sessioning machinery to notice the mutation of the
972        internal dictionary."""
973
974    def flash(msg, queue='', allow_duplicate=True):
975        """ Push a flash message onto the end of the flash queue represented
976        by ``queue``.  An alternate flash message queue can used by passing
977        an optional ``queue``, which must be a string.  If
978        ``allow_duplicate`` is false, if the ``msg`` already exists in the
979        queue, it will not be re-added."""
980
981    def pop_flash(queue=''):
982        """ Pop a queue from the flash storage.  The queue is removed from
983        flash storage after this message is called.  The queue is returned;
984        it is a list of flash messages added by
985        :meth:`pyramid.interfaces.ISession.flash`"""
986
987    def peek_flash(queue=''):
988        """ Peek at a queue in the flash storage.  The queue remains in
989        flash storage after this message is called.  The queue is returned;
990        it is a list of flash messages added by
991        :meth:`pyramid.interfaces.ISession.flash`
992        """
993
994    def new_csrf_token():
995        """ Create and set into the session a new, random cross-site request
996        forgery protection token.  Return the token.  It will be a string."""
997
998    def get_csrf_token():
999        """ Return a random cross-site request forgery protection token.  It
1000        will be a string.  If a token was previously added to the session via
1001        ``new_csrf_token``, that token will be returned.  If no CSRF token
1002        was previously set into the session, ``new_csrf_token`` will be
1003        called, which will create and set a token, and this token will be
1004        returned.
1005        """
1006
1007class IIntrospector(Interface):
1008    def get(category_name, discriminator, default=None):
1009        """ Get the IIntrospectable related to the category_name and the
1010        discriminator (or discriminator hash) ``discriminator``.  If it does
1011        not exist in the introspector, return the value of ``default`` """
1012
1013    def get_category(category_name, default=None, sort_key=None):
1014        """ Get a sequence of dictionaries in the form
1015        ``[{'introspectable':IIntrospectable, 'related':[sequence of related
1016        IIntrospectables]}, ...]`` where each introspectable is part of the
1017        category associated with ``category_name`` .
1018
1019        If the category named ``category_name`` does not exist in the
1020        introspector the value passed as ``default`` will be returned.
1021
1022        If ``sort_key`` is ``None``, the sequence will be returned in the
1023        order the introspectables were added to the introspector.  Otherwise,
1024        sort_key should be a function that accepts an IIntrospectable and
1025        returns a value from it (ala the ``key`` function of Python's
1026        ``sorted`` callable)."""
1027
1028    def categories():
1029        """ Return a sorted sequence of category names known by
1030         this introspector """
1031
1032    def categorized(sort_key=None):
1033        """ Get a sequence of tuples in the form ``[(category_name,
1034        [{'introspectable':IIntrospectable, 'related':[sequence of related
1035        IIntrospectables]}, ...])]`` representing all known
1036        introspectables.  If ``sort_key`` is ``None``, each introspectables
1037        sequence will be returned in the order the introspectables were added
1038        to the introspector.  Otherwise, sort_key should be a function that
1039        accepts an IIntrospectable and returns a value from it (ala the
1040        ``key`` function of Python's ``sorted`` callable)."""
1041
1042    def remove(category_name, discriminator):
1043        """ Remove the IIntrospectable related to ``category_name`` and
1044        ``discriminator`` from the introspector, and fix up any relations
1045        that the introspectable participates in. This method will not raise
1046        an error if an introspectable related to the category name and
1047        discriminator does not exist."""
1048
1049    def related(intr):
1050        """ Return a sequence of IIntrospectables related to the
1051        IIntrospectable ``intr``. Return the empty sequence if no relations
1052        for exist."""
1053
1054    def add(intr):
1055        """ Add the IIntrospectable ``intr`` (use instead of
1056        :meth:`pyramid.interfaces.IIntrospector.add` when you have a custom
1057        IIntrospectable). Replaces any existing introspectable registered
1058        using the same category/discriminator.
1059
1060        This method is not typically called directly, instead it's called
1061        indirectly by :meth:`pyramid.interfaces.IIntrospector.register`"""
1062
1063    def relate(*pairs):
1064        """ Given any number of ``(category_name, discriminator)`` pairs
1065        passed as positional arguments, relate the associated introspectables
1066        to each other. The introspectable related to each pair must have
1067        already been added via ``.add`` or ``.add_intr``; a :exc:`KeyError`
1068        will result if this is not true.  An error will not be raised if any
1069        pair has already been associated with another.
1070
1071        This method is not typically called directly, instead it's called
1072        indirectly by :meth:`pyramid.interfaces.IIntrospector.register`
1073        """
1074
1075    def unrelate(*pairs):
1076        """ Given any number of ``(category_name, discriminator)`` pairs
1077        passed as positional arguments, unrelate the associated introspectables
1078        from each other. The introspectable related to each pair must have
1079        already been added via ``.add`` or ``.add_intr``; a :exc:`KeyError`
1080        will result if this is not true.  An error will not be raised if any
1081        pair is not already related to another.
1082
1083        This method is not typically called directly, instead it's called
1084        indirectly by :meth:`pyramid.interfaces.IIntrospector.register`
1085        """
1086
1087
1088class IIntrospectable(Interface):
1089    """ An introspectable object used for configuration introspection.  In
1090    addition to the methods below, objects which implement this interface
1091    must also implement all the methods of Python's
1092    ``collections.MutableMapping`` (the "dictionary interface"), and must be
1093    hashable."""
1094
1095    title = Attribute('Text title describing this introspectable')
1096    type_name = Attribute('Text type name describing this introspectable')
1097    order = Attribute('integer order in which registered with introspector '
1098                      '(managed by introspector, usually)')
1099    category_name = Attribute('introspection category name')
1100    discriminator = Attribute('introspectable discriminator (within category) '
1101                              '(must be hashable)')
1102    discriminator_hash = Attribute('an integer hash of the discriminator')
1103    action_info = Attribute('An IActionInfo object representing the caller '
1104                            'that invoked the creation of this introspectable '
1105                            '(usually a sentinel until updated during '
1106                            'self.register)')
1107
1108    def relate(category_name, discriminator):
1109        """ Indicate an intent to relate this IIntrospectable with another
1110        IIntrospectable (the one associated with the ``category_name`` and
1111        ``discriminator``) during action execution.
1112        """
1113
1114    def unrelate(category_name, discriminator):
1115        """ Indicate an intent to break the relationship between this
1116        IIntrospectable with another IIntrospectable (the one associated with
1117        the ``category_name`` and ``discriminator``) during action execution.
1118        """
1119
1120    def register(introspector, action_info):
1121        """ Register this IIntrospectable with an introspector.  This method
1122        is invoked during action execution.  Adds the introspectable and its
1123        relations to the introspector.  ``introspector`` should be an object
1124        implementing IIntrospector.  ``action_info`` should be a object
1125        implementing the interface :class:`pyramid.interfaces.IActionInfo`
1126        representing the call that registered this introspectable.
1127        Pseudocode for an implementation of this method:
1128
1129        .. code-block:: python
1130
1131            def register(self, introspector, action_info):
1132                self.action_info = action_info
1133                introspector.add(self)
1134                for methodname, category_name, discriminator in self._relations:
1135                    method = getattr(introspector, methodname)
1136                    method((i.category_name, i.discriminator),
1137                           (category_name, discriminator))
1138        """
1139
1140    def __hash__():
1141
1142        """ Introspectables must be hashable.  The typical implementation of
1143        an introsepectable's __hash__ is::
1144
1145          return hash((self.category_name,) + (self.discriminator,))
1146        """
1147
1148class IActionInfo(Interface):
1149    """ Class which provides code introspection capability associated with an
1150    action.  The ParserInfo class used by ZCML implements the same interface."""
1151    file = Attribute(
1152        'Filename of action-invoking code as a string')
1153    line = Attribute(
1154        'Starting line number in file (as an integer) of action-invoking code.'
1155        'This will be ``None`` if the value could not be determined.')
1156
1157    def __str__():
1158        """ Return a representation of the action information (including
1159        source code from file, if possible) """
1160
1161class IAssetDescriptor(Interface):
1162    """
1163    Describes an :term:`asset`.
1164    """
1165
1166    def absspec():
1167        """
1168        Returns the absolute asset specification for this asset
1169        (e.g. ``mypackage:templates/foo.pt``).
1170        """
1171
1172    def abspath():
1173        """
1174        Returns an absolute path in the filesystem to the asset.
1175        """
1176
1177    def stream():
1178        """
1179        Returns an input stream for reading asset contents.  Raises an
1180        exception if the asset is a directory or does not exist.
1181        """
1182
1183    def isdir():
1184        """
1185        Returns True if the asset is a directory, otherwise returns False.
1186        """
1187
1188    def listdir():
1189        """
1190        Returns iterable of filenames of directory contents.  Raises an
1191        exception if asset is not a directory.
1192        """
1193
1194    def exists():
1195        """
1196        Returns True if asset exists, otherwise returns False.
1197        """
1198
1199class IJSONAdapter(Interface):
1200    """
1201    Marker interface for objects that can convert an arbitrary object
1202    into a JSON-serializable primitive.
1203    """
1204
1205class IPredicateList(Interface):
1206    """ Interface representing a predicate list """
1207
1208class IViewDeriver(Interface):
1209    options = Attribute('A list of supported options to be passed to '
1210                        ':meth:`pyramid.config.Configurator.add_view`. '
1211                        'This attribute is optional.')
1212
1213    def __call__(view, info):
1214        """
1215        Derive a new view from the supplied view.
1216
1217        View options, package information and registry are available on
1218        ``info``, an instance of :class:`pyramid.interfaces.IViewDeriverInfo`.
1219
1220        The ``view`` is a callable accepting ``(context, request)``.
1221
1222        """
1223
1224class IViewDeriverInfo(Interface):
1225    """ An object implementing this interface is passed to every
1226    :term:`view deriver` during configuration."""
1227    registry = Attribute('The "current" application registry where the '
1228                         'view was created')
1229    package = Attribute('The "current package" where the view '
1230                        'configuration statement was found')
1231    settings = Attribute('The deployment settings dictionary related '
1232                         'to the current application')
1233    options = Attribute('The view options passed to the view, including any '
1234                        'default values that were not overriden')
1235    predicates = Attribute('The list of predicates active on the view')
1236    original_view = Attribute('The original view object being wrapped')
1237
1238class IViewDerivers(Interface):
1239    """ Interface for view derivers list """
1240
1241class ICacheBuster(Interface):
1242    """
1243    A cache buster modifies the URL generation machinery for
1244    :meth:`~pyramid.request.Request.static_url`. See :ref:`cache_busting`.
1245
1246    .. versionadded:: 1.6
1247    """
1248    def __call__(request, subpath, kw):
1249        """
1250        Modifies a subpath and/or keyword arguments from which a static asset
1251        URL will be computed during URL generation.
1252
1253        The ``subpath`` argument is a path of ``/``-delimited segments that
1254        represent the portion of the asset URL which is used to find the asset.
1255        The ``kw`` argument is a dict of keywords that are to be passed
1256        eventually to :meth:`~pyramid.request.Request.static_url` for URL
1257        generation.  The return value should be a two-tuple of
1258        ``(subpath, kw)`` where ``subpath`` is the relative URL from where the
1259        file is served and ``kw`` is the same input argument. The return value
1260        should be modified to include the cache bust token in the generated
1261        URL.
1262
1263        The ``kw`` dictionary contains extra arguments passed to
1264        :meth:`~pyramid.request.Request.static_url` as well as some extra
1265        items that may be usful including:
1266
1267          - ``pathspec`` is the path specification for the resource
1268            to be cache busted.
1269
1270          - ``rawspec`` is the original location of the file, ignoring
1271            any calls to :meth:`pyramid.config.Configurator.override_asset`.
1272
1273        The ``pathspec`` and ``rawspec`` values are only different in cases
1274        where an asset has been mounted into a virtual location using
1275        :meth:`pyramid.config.Configurator.override_asset`. For example, with
1276        a call to ``request.static_url('myapp:static/foo.png'), the
1277        ``pathspec`` is ``myapp:static/foo.png`` whereas the ``rawspec`` may
1278        be ``themepkg:bar.png``, assuming a call to
1279        ``config.override_asset('myapp:static/foo.png', 'themepkg:bar.png')``.
1280        """
1281
1282# configuration phases: a lower phase number means the actions associated
1283# with this phase will be executed earlier than those with later phase
1284# numbers.  The default phase number is 0, FTR.
1285
1286PHASE0_CONFIG = -30
1287PHASE1_CONFIG = -20
1288PHASE2_CONFIG = -10
1289PHASE3_CONFIG = 0
1290