Startup¶
When you cause a Pyramid application to start up in a console window, you'll see something much like this show up on the console:
$VENV/bin/pserve development.ini
Starting server in PID 16305.
Serving on http://localhost:6543
Serving on http://localhost:6543
This chapter explains what happens between the time you press the "Return" key
on your keyboard after typing pserve development.ini
and the time the lines
Serving on http://localhost:6543
are output to your console.
The Startup Process¶
The easiest and best-documented way to start and serve a Pyramid
application is to use the pserve
command against a PasteDeploy
.ini
file. This uses the .ini
file to infer settings and starts a
server listening on a port. For the purposes of this discussion, we'll assume
that you are using this command to run your Pyramid application.
Here's a high-level time-ordered overview of what happens when you press
return
after running pserve development.ini
.
The
pserve
command is invoked under your shell with the argumentdevelopment.ini
. As a result, Pyramid recognizes that it is meant to begin to run and serve an application using the information contained within thedevelopment.ini
file.pserve
passes thedevelopment.ini
path to plaster which finds an available configuration loader that recognizes theini
format.plaster finds the
plaster_pastedeploy
library which binds the PasteDeploy library and returns a parser that can understand the format.The PasteDeploy finds a section named either
[app:main]
,[pipeline:main]
, or[composite:main]
in the.ini
file. This section configures the WSGI webserver which serves your application. As such it is theini
section for your application and can be the source for many of your application's settings.If you're using a simple application (e.g.,
[app:main]
), the application'spaste.app_factory
entry point will be named on theuse=
line within the section's configuration. If instead of a simple application, you're using a WSGI pipeline (e.g., a[pipeline:main]
section), the application named on the "last" element will refer to your Pyramid application. If instead of a simple application or a pipeline, you're using a "composite" (e.g.,[composite:main]
), refer to the documentation for that particular composite to understand how to make it refer to your Pyramid application. In most cases, a Pyramid application built from a cookiecutter will have a single[app:main]
section in it, and this will be the application served.The framework finds all
logging
related configuration in the.ini
file and uses it to configure the Python standard library logging system for the application. See Logging Configuration for more information.The application's entry point, usually the entry point referenced on the above mentioned
use=
line, is the application's constructor. It is passed the key/value parameters in the application's .ini section. The constructor should return a router instance, which is a WSGI application.For Pyramid applications, the constructor is a function named
main
in the__init__.py
file within the package in which your application lives. If this function succeeds, it will return a Pyramid router instance. Here's the contents of an example__init__.py
module:1from pyramid.config import Configurator 2 3 4def main(global_config, **settings): 5 """ This function returns a Pyramid WSGI application. 6 """ 7 with Configurator(settings=settings) as config: 8 config.include('pyramid_jinja2') 9 config.include('.routes') 10 config.scan() 11 return config.make_wsgi_app()
Note that the constructor function accepts a
global_config
argument, which is a dictionary of key/value pairs mentioned in the[DEFAULT]
section of an.ini
file (if [DEFAULT] is present). It also accepts a**settings
argument, which collects another set of arbitrary key/value pairs. The arbitrary key/value pairs received by this function in**settings
will be composed of all the key/value pairs that are present in the[app:main]
section (except for theuse=
setting) when this function is called when you runpserve
.Our generated
development.ini
file looks like so:1### 2# app configuration 3# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html 4### 5 6[app:main] 7use = egg:myproject 8 9pyramid.reload_templates = true 10pyramid.debug_authorization = false 11pyramid.debug_notfound = false 12pyramid.debug_routematch = false 13pyramid.default_locale_name = en 14pyramid.includes = 15 pyramid_debugtoolbar 16 17# By default, the toolbar only appears for clients from IP addresses 18# '127.0.0.1' and '::1'. 19# debugtoolbar.hosts = 127.0.0.1 ::1 20 21### 22# wsgi server configuration 23### 24 25[server:main] 26use = egg:waitress#main 27listen = localhost:6543 28 29### 30# logging configuration 31# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html 32### 33 34[loggers] 35keys = root, myproject 36 37[handlers] 38keys = console 39 40[formatters] 41keys = generic 42 43[logger_root] 44level = INFO 45handlers = console 46 47[logger_myproject] 48level = DEBUG 49handlers = 50qualname = myproject 51 52[handler_console] 53class = StreamHandler 54args = (sys.stderr,) 55level = NOTSET 56formatter = generic 57 58[formatter_generic] 59format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
In this case, the
myproject.__init__:main
function referred to by the entry point URIegg:myproject
(see development.ini for more information about entry point URIs, and how they relate to callables) will receive the key/value pairs{pyramid.reload_templates = true, pyramid.debug_authorization = false, pyramid.debug_notfound = false, pyramid.debug_routematch = false, pyramid.default_locale_name = en, and pyramid.includes = pyramid_debugtoolbar}
. See Environment Variables and .ini File Settings for the meanings of these keys.The
main
function begins by making a configurator. The dictionary captured via the**settings
kwarg is passed to theConfigurator
constructor in itssettings
argument. The new configurator holds the application's settings and is able to commit any configuration declarations the settings contain.The
settings
dictionary contains all the options in the[app:main]
section of our .ini file except theuse
option (which is internal to PasteDeploy) such aspyramid.reload_templates
,pyramid.debug_authorization
, etc. It is available for use in your code.The
main
function then calls various methods on the instance of the classConfigurator
created in the previous step. The intent of calling these methods is to populate an application registry, which represents the Pyramid configuration related to the application.The
make_wsgi_app()
method is called. The result is a router instance. The router is associated with the application registry implied by the configurator previously populated by other methods run against the Configurator. The router is a WSGI application.An
ApplicationCreated
event is emitted (see Using Events for more information about events).Assuming there were no errors, the
main
function inmyproject
returns the router instance created bypyramid.config.Configurator.make_wsgi_app()
back topserve
. As far aspserve
is concerned, it is "just another WSGI application".pserve
starts the WSGI server defined within the[server:main]
section. In our case, this is the Waitress server (use = egg:waitress#main
), and it will listen on all interfaces on port 6543 for both IPv4 and IPv6 (listen = localhost:6543
). The server code itself is what printsServing on http://localhost:6543
. The server serves the application, and the application is running, waiting to receive requests.
参考
Logging configuration is described in the Logging chapter. There, in Request Logging with Paste's TransLogger, you will also find an example of how to configure middleware to add pre-packaged functionality to your application.
Deployment Settings¶
Note that an augmented version of the values passed as **settings
to the Configurator
constructor is available in Pyramid view callable code as request.registry.settings
.
You can create objects you wish to access later from view code, and put them into the dictionary you pass to the configurator as settings
.
They will then be present in the request.registry.settings
dictionary at application runtime.