Python Pyramid - View Configuration



The term "View Configuration" refers to the mechanism of associating a view callable (a function, method or a class) with the information of route configuration. Pyramid finds the best callable for the given URL pattern.

There are three ways to configure a view

  • Using add_view() method

  • Using @view_config() decorator

  • Using @view_defaults () class decorator

Using add_view() Method

This is the simplest method of configuring a view imperatively by calling the add_view() method of the Configurator object.

This method uses the following arguments −

  • name − The view name required to match this view callable. If name is not supplied, the empty string is used (implying the default view).

  • context − This resource must be an object of a Python class in order for this view to be found and called. If context is not supplied, the value None, which matches any resource, is used.

  • route_name − This value must match the name of a route configuration declaration that must match before this view will be called. If route_name is supplied, the view callable will be invoked only when the named route has matched.

  • request_type − an interface that the request must provide in order for this view to be found and called.

  • request_method − a string (such as "GET", "POST", "PUT", "DELETE", "HEAD", or "OPTIONS") representing an HTTP REQUEST_METHOD or a tuple containing one or more of these strings. The view will be called only when the method attribute of the request matches a supplied value.

  • request_param − This argument can be any string or a sequence of strings. The view will only be called when the request.params dictionary has a key which matches the supplied value.

Example

In the following example, two functions getview() and postview() are defined and associated with two routes of the same name. These functions just return the name of the HTTP method by which they are called.

The getview() function is called when the URL /get is requested using GET method. Similarly, the postview() function is executed when /post path id requested by POST method.

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def getview(request):
   ret=request.method
   return Response('Method: {}'.format(ret))
def postview(request):
   ret=request.method
   return Response('Method: {}'.format(ret))
   
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('getview', '/get')
      config.add_route('postview', '/post')
      config.add_view(getview, route_name='getview',request_method='GET')
      config.add_view(postview,route_name='postview', request_method='POST')
      app = config.make_wsgi_app()
      server = make_server('0.0.0.0', 6543, app)
      server.serve_forever()

While the GET request can be sent by using the web browser as HTTP client, it is not possible to use it for POST request. Hence, we use the CURL command line utility.

C:\Users\Acer>curl localhost:6543/get
Method: GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/post
Method: POST

As mentioned earlier, the request_method parameter can be a list of one or more HTTP methods. Let us modify the above program and define a single oneview() function that identifies the HTTP method that causes its execution.

def oneview(request):
   ret=request.method
   return Response('Method: {}'.format(ret))

This function is registered in the application's configuration for all the HTTP methods.

config.add_route('oneview', '/view')
config.add_view(oneview, route_name='oneview',
   request_method=['GET','POST', 'PUT', 'DELETE'])

Output

The CURL output is shown as below −

C:\Users\Acer>curl localhost:6543/view
Method: GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/view
Method: POST
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X PUT http://localhost:6543/view
Method: PUT
C:\Users\Acer>curl -X DELETE http://localhost:6543/view
Method: DELETE

Using @view_config() Decorator

Instead of adding views imperatively, the @view_config decorator can be used to associate the configured routes with a function, a method or even a callable class.

Example

As described in the Declarative Configuration section, a registered route can be associated with a function as in the following example −

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
@view_config(route_name='hello')
def hello_world(request):
   return Response('Hello World!')
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('hello', '/')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

Note that the views are added into the application configuration only after calling the scan() method. While removes the need for imperatively adding the views, the performance may be slightly slower.

Output

The view_config() decorator can also be given same arguments as that of add_view() method. All arguments may be omitted.

@view_config()
def hello_world(request):
   return Response('Hello World!')

In such a case, the function will be registered with any route name, any request method or parameters.

The view_config decorator is placed just before the definition of callable view function, as in the above example. It can also be put on top of a class if it is to be used as the view callable. Such a class must have a __call__() method.

In the following Pyramid application code, the MyView class is used as a callable and is decorated by the @view_config decorator.

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config

@view_config(route_name='hello')
class MyView(object):
   def __init__(self, request):
      self.request = request
      
   def __call__(self):
      return Response('hello World')
      
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('hello', '/')
      #config.add_view(MyView, route_name='hello')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

Note that instead of scanning for view configurations, we can add views by explicitly calling the add_view() method.

Example

If the methods in a class have to be associated with different routes, separate @view_config() should be used on top of each one of them, as done in the following example. Here, we have two methods bound to two separate routes.

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import 

class MyView(object):
   def __init__(self, request):
      self.request = request
      
   @view_config(route_name='getview', request_method='GET')
   def getview(self):
      return Response('hello GET')
   @view_config(route_name='postview', request_method='POST')
   def postview(self):
      return Response('hello POST')
      
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('getview', '/get')
      config.add_route('postview', '/post')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

Output

Here's the output of CURL commands −

C:\Users\Acer>curl localhost:6543/get
hello GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/post
hello POST

Using @view_defaults() Decorator

view_defaults() is a class decorator. If you have to add the methods in a class as view with some common parameters and some specific parameters, the common parameters can be specified in the view_defaults() decorator on top of the class, performing configuration of each method by a separate view_config() before each one of them.

Example

In the following code, we have different methods responding to the same route but with different request_method. Hence we define the rout name as default, and specify the request_method in each view configuration.

from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
from pyramid.view import view_config
from pyramid.view import view_defaults

@view_defaults(route_name='myview')
class MyView(object):
   def __init__(self, request):
      self.request = request
      
   @view_config( request_method='GET')
   def getview(self):
      return Response('hello GET')
   @view_config(request_method='POST')
   def postview(self):
      return Response('hello POST')
   @view_config(request_method='PUT')
   def putview(self):
      return Response('hello PUT')
   @view_config(request_method='DELETE')
   def delview(self):
      return Response('hello DELETE')
      
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('myview', '/view')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

Output

The CURL commands with different HTTP requests to the server are as follows −

C:\Users\Acer>curl localhost:6543/view
hello GET
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X POST http://localhost:6543/view
hello POST
C:\Users\Acer>curl -d "param1=value1" -H "Content-Type: application/json" -X PUT http://localhost:6543/view
hello PUT
C:\Users\Acer>curl -X DELETE http://localhost:6543/view
hello DELETE
Advertisements