Python Pyramid - Url Routing



Before the advent of MVC architecture, web applications used the mechanism of mapping the URL entered by the user in the browser, to a program file whose output was rendered as HTML to as a response back to the browser. Pyramid framework uses a routing mechanism where the endpoint of the URL is matched with different URL patterns registered in the application's registry, invokes its mapped view and renders the response.

A typical URL comprises of three parts: The protocol (such as http:// or https://) followed by the IP address or hostname. The remaining part of the URL after first / after the hostname is called as the path or endpoint.

Mysite

The endpoint followed by one or more variable parts forms the route. The variable part identifiers are surrounded by curly brackets. For example, for the above URL, the route is /blog/{id}

The WSGI application acts as a router. It checks the incoming request against the URL patterns present in the route map. If a match is found, its associated view callable is executed and the response is returned.

Route Configuration

A new route is added to the application by invoking add_route() method of the Configurator object. A route has a name, which acts as an identifier to be used for URL generation and a pattern that is meant to match against the PATH_INFO portion of a URL (the portion following the scheme and port, e.g., /blog/1 in the URL http://example.com/blog/1).

As mentioned earlier, the pattern parameter of add_route() method can have one or more placeholder identifiers surrounded by curly brackets and separated by /. Following statement assigns 'index' as the name of route given to '/{name}/{age}' pattern.

config.add_route('index', '/{name}/{age}')

To associate a view callable to this route, we use add_view() function as follows −

config.add_view(index, route_name='index')

The index() function should be available for the route to be matched to it.

def index(request):
   return Response('Root Configuration Example')

Example

We put these statements in the program below −

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

def index(request):
   return Response('Root Configuration Example')
   
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('index', '/{name}/{age}')
      config.add_view(index, route_name='index')
      app = config.make_wsgi_app()
server = make_server('0.0.0.0', 6543, app)
server.serve_forever()

Output

Run the above code and visit http://localhost:6543/Ravi/21 in the browser. As the URL's PATH_INFO matches with the index route, the following output is displayed −

Root Configuration

The pattern used in route configuration usually starts with a forward slash (/) character. A pattern segment (an individual item between / characters in the pattern) may either be a literal string, or it may be a placeholder marker (e.g., {name}), or a certain combination of both. A replacement marker does not need to be preceded by a / character.

Here are some examples of route patterns

/student/{name}/{marks}
/{id}/student/{name}/{marks}
/customer/{id}/item/{itemno}
/{name}/{age}

The place holder identifier must be a valid Python identifier. Hence, it must begin with an uppercase or lowercase ASCII letter or an underscore, and it can only have uppercase or lowercase ASCII letters, underscores, and numbers.

Route Matching

When the incoming request matches with the URL pattern associated with a particular route configuration, a dictionary object named matchdict is added as an attribute of the request object.

The request.matchdict contains the values that match replacement patterns in the pattern element. The keys in a matchdict are strings, while their values are Unicode objects.

In the previous example, change the index() view function to following −

def index(request):
   return Response(str(request.matchdict))

The browser displays the path parameters in the form of a dict object.

Parameters

When the request matches a route pattern, the request object passed to the view function also includes a matched_route attribute. The name of the matched route can be obtained from its name property.

Example

In the following example, we have two view functions student_view() and book_view() defined with the help of @view.config() decorator.

The application's registry is configured to have two corresponding routes – 'student' mapped to '/student/{name}/{age}' pattern and 'book' mapped to '/book/{title}/{price}' pattern. We call the scan() method of configurator object to add the views.

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='student')
def student_view(request):
   return Response(str(request.matchdict))
@view_config(route_name='book')
def book_view(request):
   title=request.matchdict['title']
   price=request.matchdict['price']
   return Response('Title: {}, Price: {}'.format(title,price))
if __name__ == '__main__':
   with Configurator() as config:
      config.add_route('student', '/student/{name}/{age}')
      config.add_route('book', '/book/{title}/{price}')
      config.scan()
      app = config.make_wsgi_app()
   server = make_server('0.0.0.0', 6543, app)
   server.serve_forever()

Output

When the browser is given http://localhost:6543/student/Ravi/21 URL, the output is

{'name': 'Ravi', 'age': '21'}

If the URL entered is http://localhost:6543/book/Python/300, the output is

Title: Python, Price: 300
Advertisements