View Configuration

View lookup is the Pyramid subsystem responsible for finding and invoking a view callable. View configuration controls how 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

A developer makes a view callable available for use within a Pyramid application via 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.

A view configuration statement is made about information present in the context resource and the request.

View configuration is performed in one of two ways:

View Configuration Parameters

All forms of view configuration accept the same general types of arguments.

Many arguments supplied during view configuration are view predicate arguments. View predicate arguments used during view configuration are used to narrow the set of circumstances in which view lookup will find a particular view callable.

View predicate attributes are an important part of view configuration that enables the 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 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, Pyramid will return an error to the user’s browser, representing a “not found” (404) page. See Changing the Not Found View for more information about changing the default notfound 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 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.

Non-Predicate Arguments

permission

The name of a permission that the user must possess in order to invoke the view callable. See Configuring View Security 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).

attr

The view machinery defaults to using the __call__ method of the 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’ __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).

renderer

Denotes the renderer implementation which will be used to construct a response from the associated view callable’s return value. (see also Renderers).

This is either a single string term (e.g. json) or a string implying a path or asset specification (e.g. templates/views.pt) naming a 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 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 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 Pyramid machinery unchanged). Note that if the view callable itself returns a response (see View Callable Responses), 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 view name of a different view configuration which will receive the response body of this view as the request.wrapped_body attribute of its own request, and the 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 View Configuration. 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 dotted Python name to a function (or the function itself) which will be used to decorate the registered 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).
mapper
A Python object or dotted Python name which refers to a 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 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 configured view.

name

The view name required to match this view callable. A name argument is typically only used when your application uses traversal. Read Traversal 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 context resource must be an instance of or the interface that the context resource must provide in order for this view to be found and called. This predicate is true when the context resource is an instance of the represented class or if the context resource provides the represented interface; it is otherwise false.

If context is not supplied, the value None, which matches any resource, is used.

route_name

If route_name is supplied, the view callable will be invoked only when the named route has matched.

This value must match the name of a route configuration declaration (see URL Dispatch) 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 traversal against the result of the route’s 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 resource location does not indicate it matched any configured route.

request_type

This value should be an interface that the 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.

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 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.

If request_method is not supplied, the view will be invoked regardless of the REQUEST_METHOD of the 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 request has a key in the request.params dictionary (an HTTP GET or POST variable) that has a name which matches the supplied value.

If the 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 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 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 request has key/value pairs in its matchdict that equal those supplied in the predicate. e.g. match_param="action=edit" would require the ``action parameter in the 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 interface that a parent object in the context resource’s 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.

See Location-Aware Resources for more information about location-awareness.

xhr

This value should be either True or False. If this value is specified and is True, the WSGI environment must possess an HTTP_X_REQUESTED_WITH (aka X-Requested-With) header 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.

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.

header

This value represents an HTTP header name or a header name/value pair.

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, 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.

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.

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.

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 associated view callable will be considered viable for a given request.

If custom_predicates is not specified, no custom predicates are used.

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 configuration declarations. For maximum startup performance, use the view configuration method described in Adding View Configuration Using add_view() instead.

The view_config decorator can be used to associate view configuration information with a function, method, or class that acts as a Pyramid view callable.

Here’s an example of the view_config decorator that lives within a Pyramid application module views.py:

1
2
3
4
5
6
7
from resources import MyResource
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='ok', request_method='POST', permission='read')
def my_view(request):
    return Response('OK')

Using this decorator as above replaces the need to add this imperative configuration stanza:

1
2
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:

1
2
3
4
5
6
7
from pyramid.response import Response
from pyramid.view import view_config

@view_config()
def my_view(request):
    """ My view """
    return Response()

Such a registration as the one directly above implies that the view name will be my_view, registered with a context argument that matches any resource type, using no permission, registered against requests with any 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 Pyramid process your pyramid.view.view_config declarations, you must use the scan method of a pyramid.config.Configurator:

1
2
3
# config is assumed to be an instance of the
# pyramid.config.Configurator class
config.scan()

Please see Declarative Configuration for detailed information about what happens when code is scanned for configuration declarations resulting from use of decorators like view_config.

See pyramid.config for additional API arguments to the scan() method. For example, the method allows you to supply a package argument to better control exactly which code will be scanned.

All arguments to the view_config decorator mean precisely the same thing as they would if they were passed as arguments to the pyramid.config.Configurator.add_view() method save for the view argument. Usage of the view_config decorator is a form of declarative configuration, while pyramid.config.Configurator.add_view() is a form of imperative configuration. However, they both do the same thing.

@view_config Placement

A view_config decorator can be placed in various points in your application.

If your view callable is a function, it may be used as a function decorator:

1
2
3
4
5
6
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='edit')
def edit(request):
    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 against a class as when they are applied against a function. For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.response import Response
from pyramid.view import view_config

@view_config(route_name='hello')
class MyView(object):
    def __init__(self, request):
        self.request = request

    def __call__(self):
        return Response('hello')

You can use the 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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 view_config decorator can be stacked on top of any number of others. Each decorator creates a separate view registration. For example:

1
2
3
4
5
6
7
from pyramid.view import view_config
from pyramid.response import Response

@view_config(route_name='edit')
@view_config(route_name='change')
def edit(request):
    return Response('edited!')

This registers the same view under two different names.

The decorator can also be used against a method of a class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.response import Response
from pyramid.view import view_config

class MyView(object):
    def __init__(self, request):
        self.request = request

    @view_config(route_name='hello')
    def amethod(self):
        return Response('hello')

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.

The method which is decorated must return a 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from pyramid.response import Response
from pyramid.view import view_config

@view_config(attr='amethod', route_name='hello')
class MyView(object):
    def __init__(self, request):
        self.request = request

    def amethod(self):
        return Response('hello')

Adding View Configuration Using add_view()

The pyramid.config.Configurator.add_view() method within pyramid.config is used to configure a view “imperatively” (without a view_config decorator). The arguments to this method are very similar to the arguments that you provide to the view_config decorator. For example:

1
2
3
4
5
6
7
8
from pyramid.response import Response

def hello_world(request):
    return Response('hello!')

# config is assumed to be an instance of 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 dotted Python name to such an object. In the above example, view is the hello_world function. All other arguments are optional. See pyramid.config.Configurator.add_view() for more information.

When you use only add_view() to add view configurations, you don’t need to issue a scan in order for the view configuration to take effect.

Configuring View Security

If an authorization policy is active, any permission attached to a view configuration found during view lookup will be verified. This will ensure that the currently authenticated user possesses that permission against the context resource before the view function is actually called. Here’s an example of specifying a permission in a view configuration using add_view():

1
2
3
4
5
# config is an instance of pyramid.config.Configurator

config.add_route('add', '/add.html', factory='mypackage.Blog')
config.add_view('myproject.views.add_entry', route_name='add',
                permission='add')

When an 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 context. Instead the forbidden view result will be returned to the client as per Protecting Views with Permissions.

NotFound Errors

It’s useful to be able to debug 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 Environment Variables and .ini File Settings for more information about how, and where to set these values.

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 Non-Predicate Arguments 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:

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 pyramid.prevent_http_cache configuration value setting to a true value. For more information, see 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.

Debugging View Configuration

See Displaying Matching Views for a Given URL 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.