If you haven't read Part 1 of this series, I recommend you do that before continuing with this article. In Part 1, we looked at the installation of the Python framework, along with creating your first scaffolding app.
This article dives deeper into how the Pyramid framework works from a configuration standpoint. I'll outline the process of initializing an application by connecting a web server to an application server instance, along with how to add application views. The web server on which the framework runs is called Waitress. It's a production-quality server for hosting web applications.
To get started, we'll first examine types of application configuration used by Pyramid. The Pyramid documentation covers some of this information; however, the purpose of this article is not only to clarify these concepts further, but to address some missing analysis. Often, the documentation leaves gaps in coverage and isn't concise or understandable. If you continue reading and using these articles as a reference, you'll be on the fast track to developing web applications using Python Pyramid.
Python has two types of application configuration: Imperative Configuration (IC) and Declarative Configuration (DC). As with most other languages, you can either configure the app settings programmatically or by using the configuration files. IC and DC are both done programmatically as part of the application's code base. I'm not a big fan of this approach because it doesn't loosely couple the configuration settings from the application code. However, this approach is just as commonly used to create static settings in a configuration file. IC refers to the process of configuring an app by using simple Python statements with the Configurator object, as in the following example:
from wsgiref.simple_server import make_server from pyramid.config import Configurator from pyramid.response import Response def hello_world(request): return Response('Hello world!') if __name__ == '__main__': config = Configurator() config.add_view(hello_world) app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever()
The important thing to note here is the Configurator object, which is used to configure the application registry. This registry is a repository of configuration information for the application. An application can only have one registry. The add_view method of the Configurator object maps a request object to a callable response object, using the hello_world method. These objects are similar to the HTTP Request and Response objects in Java or .NET.
The make_wsgi_app() method returns a Web Server Gateway Interface (WSGI) application instance for the application. The instance is returned as a result of connecting the web server to the application. However, the hosting process isn't complete without the make_server object. This object creates an instance of an application server on which the application can run. The app object is passed in to connect the application server to the web server, much like Java Servlets do for Java. The port that the web server will use, 8080, is also passed to this method. The serve_forever() method will keep serving requests until Ctrl-C is used to stop the server.
The second type of configuration, Declarative Configuration, uses metadata invocations for setting up view directives, as in the following example:
from pyramid.response import Response from pyramid.view import view_config @view_config(name='hello', request_method='GET') def hello(request): return Response('Hello')
In this example, DC uses the view_config decorator, which allows us to add the @view_config attribute to represent our hello function. Attributes in this context are similar to .NET attributes and Java annotations. They essentially serve the same purpose, which is to mark up methods in your application that later inject code where the attribute is used. However, the Python version of using attributes is incomplete until the Configuration object's scan method is used. Here's a more complete example using scan:
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() def hello(request): return Response('Hello') if __name__ == '__main__': from pyramid.config import Configurator config = Configurator() config.scan() app = config.make_wsgi_app() server = make_server('0.0.0.0', 8080, app) server.serve_forever()
Using a configuration decoration and scan together is referred to as a Declarative Configuration. The scan method scans for attributes and registers them to the application registry. DC ends up being shorthand for IC. In these examples, the DC version doesn't have to make a call to the add_view method, as the IC version does. Once scanned, it's called implicitly through the attribute. IC and DC achieve equivalent functionality with a view configuration. In simple terms, a view configuration is the process of mapping a request to a view. In the Model-View-Controller (MVC) world of application design, you can think of it as the View.
In this article, you learned the basics of configuration for Python Pyramid web applications using Declarative and Imperative view configuration approaches. The two approaches are essentially the same, but the DC approach uses attributes to substitute for view-configuration method calls. Neither approach is better than the other; use whichever you prefer. You should also be aware that using these programmatic methods of configuring your app replaces static configuration files such as development.ini and production.ini. In Part 3 of this series, I'll go over the detailed startup lifecycle of a Pyramid application and the anatomy of the .ini files.
At this stage, you should be quite comfortable setting up Pyramid web applications. But this article is only meant to serve as a simple starting point for configuring Pyramid applications. You should do some research and exploring on your own as well. When you do, you'll find that Python Pyramid is a powerful platform for web application development.