An Introduction to Python Web Development Using the Pyramid Framework, Part 4
If you haven't read Part 3 of this series, I recommend you do that before continuing with this article. In Part 3, we looked at the project structure and what it means to an application.
This article covers the startup process , configuration files, and request processing. By taking a closer look at the application startup process, we can learn more about the configuration files as well. The request process is an artifact created by the startup process for handling user requests.
To get started, we'll first examine the startup process, which can be outlined in several steps that the pserve.exe command (Python server) takes to initialize an application.
Catch Up on All of the Articles in this Python Series
Jesse Smith has written four articles in this series. Here are the earlier installments:
Startup Process
Figure 1 shows a simple workflow diagram of the system startup process.
The process begins by issuing a pserve.exe command from the command line:
pserver.exe \myproject development.ini –reload
pserve uses a library called PasteDeploy to create Web Server Gateway Interface (WSGI) application instances.
The first thing pserve.exe does is look at the information in the development.ini file. Next, pserve finds the main (that is, app:main) sections in the file. The most common applications use the [app:main] section to define the application's entry point. The entry point will be defined in this section's use= property. A sample [app:main] section is shown below:
[app:main] use = egg:MyProject pyramid.reload_templates = true pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar
In this example, the value egg:MyProject tells the paste.app_factory method (used by pserve) that the starting point of the application will be in a project named MyProject.
Next, pserve configures logging for the application defined by the [loggers], [loggers:root], and [logger:<project_name>] sections of the .ini file. An example of these three sections appears below:
[loggers] keys = root, myproject [logger_root] level = INFO handlers = console [logger_myproject] level = DEBUG handlers = qualname = myproject
Next, the __init__.py file is located, and a dictionary of key/value pairs from sections in the development.ini file are passed into the main function. For example:
def main(global_config, **settings): config = Configurator(settings=settings) config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') config.scan() return config.make_wsgi_app()
Part 2 of this series covered the __init_.py file. The global_config parameter is a set of dictionary values that are obtained from the [DEFAULT] section (if it exists) of the development.ini file. The **settings parameter is a dictionary of the other settings needed to return a WSGI application instance provided by the [app:main] section.
A Configurator instance is created next, which creates the application's registry containing the configuration information.
Next, the config.make_wsgi_app() function returns a router instance that's used to connect the application server to the web server, thus creating the WSGI application instance.
Finally, the WSGI instance is returned to pserve, which calls the make_server method (not shown here) in the application's __init__.py file.
The server is now ready to serve requests.
Request Processing
Request processing details the lifecycle of a request to the application. From a high-level overview, this process is a basic one, as shown in the following steps to handle a request:
- A request is made from the browser to the server and port number defined in the application's __init__.py file.
- The router instance creates a request object by mapping the request URL to URL patterns provided by the route mapper.
- If a routing match is found, the request is passed into a view_callable matching the route.<
- The view_callable returns a response object that provides the response to the user. It could be simple text, custom text, or a template page.
The process of matching a route to a view is referred to as URL dispatching, which is discussed in the next section.
URL Dispatching
URL dispatching is actually part of the request-processing lifecycle, but should be explored further so you'll understand how Python associates a request to a view.
Typically, a Pyramid application will have a routing configuration. This configuration provides an ordered set of URLs that the application will use to map a request to a view. The code to achieve this goal is similar to the block of code below:
from views import myview config.add_route('myroute', '/register/') config.add_view(myview, route_name='myroute')
This code uses the add_route method to give the route a name. The add_view method associates that route to a view; However, the add_view method may be replaced with the scan method if you're using a Declarative Configuration (discussed in Part 2 of this series). The second parameter to the add_view method is the pattern. Of course, this can be more complicated than in the code example. For example, you could use replacement markers:
config.add_route('myroute', '/books/{id}')
The {id} segment in the pattern will accept any numbers or letters as a substitute.
Conclusion
In this article, you learned about the application startup, request, and URL dispatching processes. The startup process is mainly concerned with initializing the application and getting it ready to handle requests. The request process is the lifecycle of a request from a user to the application, which ends in a response. The URL dispatching process helps to fulfill the request process by matching the incoming URL to a view.
The development.ini file has several sections with settings that are used by the application startup process. These settings also include turning on debugging options; whereas, with the production.ini file, these options are disabled.
After learning about these core processing units, the next logical step is to move into the last part of the presentation layer of a Pyramid application, which is working with views. Part 5 of this series covers view concepts in more detail.