summaryrefslogtreecommitdiff
path: root/docs/quick_tutorial/ini.rst
blob: 630b1faa5cee825fd832944ec911da69f55e49ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
.. _qtut_ini:

=================================================
03: Application Configuration with ``.ini`` Files
=================================================

Use Pyramid's ``pserve`` command with a ``.ini`` configuration file for
simpler, better application running.

Background
==========

Pyramid has a first-class concept of
:ref:`configuration <configuration_narr>` distinct from code.
This approach is optional, but its presence makes it distinct from
other Python web frameworks. It taps into Python's ``setuptools``
library, which establishes conventions for how Python projects can be
installed and provide "entry points". Pyramid uses an entry point to
let a Pyramid application it where to find the WSGI app.

Objectives
==========

- Modify our ``setup.py`` to have an entry point telling Pyramid the
  location of the WSGI app

- Create an application driven by a ``.ini`` file

- Startup the application with Pyramid's ``pserve`` command

- Move code into the package's ``__init__.py``

Steps
=====

#. First we copy the results of the previous step:

   .. code-block:: bash

    $ cd ..; cp -r package ini; cd ini

#. Our ``ini/setup.py`` needs a setuptools "entry point" in the
   ``setup()`` function:

   .. literalinclude:: ini/setup.py
    :linenos:

#. We can now install our project, thus generating (or re-generating) an
    "egg" at ``ini/tutorial.egg-info``:

   .. code-block:: bash

    $ $VENV/bin/python setup.py develop

#. Let's make a file ``ini/development.ini`` for our configuration:

   .. literalinclude:: ini/development.ini
    :language: ini
    :linenos:

#. We can refactor our startup code from the previous step's ``app.py``
   into ``ini/tutorial/__init__.py``:

   .. literalinclude:: ini/tutorial/__init__.py
    :linenos:

#. Now that ``ini/tutorial/app.py`` isn't used, let's remove it:

   .. code-block:: bash

    $ rm tutorial/app.py

#. Run your Pyramid application with:

   .. code-block:: bash

    $ $VENV/bin/pserve development.ini --reload

#. Open http://localhost:6543/.

Analysis
========

Our ``development.ini`` file is read by ``pserve`` and serves to
bootstrap our application. Processing then proceeds as described in
the Pyramid chapter on
:ref:`application startup <startup_chapter>`:

- ``pserve`` looks for ``[app:main]`` and finds ``use = egg:tutorial``

- The projects's ``setup.py`` has defined an "entry point" (lines 9-10)
  for the project  "main" entry point of ``tutorial:main``

- The ``tutorial`` package's ``__init__`` has a ``main`` function

- This function is invoked, with the values from certain ``.ini``
  sections passed in

The ``.ini`` file is also used for two other functions:

- *Choice of WSGI server*. ``[server:main]`` wires up the choice of WSGI
  *server* for your WSGI *application*. In this case, we are using
  ``wsgiref`` bundled in the Python library.

- *Python logging*. Pyramid uses Python standard logging, which needs a
  number of configuration values. The ``.ini`` serves this function.
  This provides the console log output that you see on startup and each
  request.

- *Port number*. ``port = 6543`` tells ``wsgiref`` to listen on port
  6543.

We moved our startup code from ``app.py`` to the package's
``tutorial/__init__.py``. This isn't necessary,
but it is a common style in Pyramid to take the WSGI app bootstrapping
out of your module's code and put it in the package's ``__init__.py``.

The ``pserve`` application runner has a number of command-line arguments
and options. We are using ``--reload`` which tells ``pserve`` to watch
the filesystem for changes to relevant code (Python files, the INI file,
etc.) and, when something changes, restart the application. Very handy
during development.

Extra Credit
============

#. If you don't like configuration and/or ``.ini`` files,
   could you do this yourself in Python code?

#. Can we have multiple ``.ini`` configuration files for a project? Why
   might you want to do that?

#. The entry point in ``setup.py`` didn't mention ``__init__.py`` when
   it the ``main`` function. Why not?

.. seealso::
   :ref:`project_narr`,
   :ref:`scaffolding_chapter`,
   :ref:`what_is_this_pserve_thing`,
   :ref:`environment_chapter`,
   :ref:`paste_chapter`

Extra Credit
============

#. What is the purpose of ``**settings``? What does the ``**`` signify?