diff options
Diffstat (limited to 'docs/narr/project.rst')
| -rw-r--r-- | docs/narr/project.rst | 1360 |
1 files changed, 680 insertions, 680 deletions
diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 631412f42..81fc9acf4 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -1,166 +1,135 @@ .. _project_narr: Creating a :app:`Pyramid` Project -==================================== +================================= -As we saw in :ref:`firstapp_chapter`, it's possible to create a -:app:`Pyramid` application completely manually. However, it's usually more -convenient to use a *scaffold* to generate a basic :app:`Pyramid` -:term:`project`. +As we saw in :ref:`firstapp_chapter`, it's possible to create a :app:`Pyramid` +application completely manually. However, it's usually more convenient to use +a :term:`scaffold` to generate a basic :app:`Pyramid` :term:`project`. A project is a directory that contains at least one Python :term:`package`. You'll use a scaffold to create a project, and you'll create your application -logic within a package that lives inside the project. Even if your -application is extremely simple, it is useful to place code that drives the -application within a package, because a package is more easily extended with -new code. An application that lives inside a package can also be distributed -more easily than one which does not live within a package. +logic within a package that lives inside the project. Even if your application +is extremely simple, it is useful to place code that drives the application +within a package, because (1) a package is more easily extended with new code, +and (2) an application that lives inside a package can also be distributed more +easily than one which does not live within a package. -:app:`Pyramid` comes with a variety of scaffolds that you can use to generate -a project. Each scaffold makes different configuration assumptions about -what type of application you're trying to construct. +:app:`Pyramid` comes with a variety of scaffolds that you can use to generate a +project. Each scaffold makes different configuration assumptions about what +type of application you're trying to construct. -These scaffolds are rendered using the :term:`PasteDeploy` ``paster`` script. +These scaffolds are rendered using the ``pcreate`` command that is installed as +part of Pyramid. .. index:: single: scaffolds - single: pyramid_starter scaffold - single: pyramid_zodb scaffold - single: pyramid_alchemy scaffold - single: pyramid_routesalchemy scaffold + single: starter scaffold + single: zodb scaffold + single: alchemy scaffold .. _additional_paster_scaffolds: Scaffolds Included with :app:`Pyramid` ------------------------------------------------- +-------------------------------------- -The convenience scaffolds included with :app:`Pyramid` differ from -each other on a number of axes: +The convenience scaffolds included with :app:`Pyramid` differ from each other +on a number of axes: -- the persistence mechanism they offer (no persistence mechanism, - :term:`ZODB`, or :term:`SQLAlchemy`). +- the persistence mechanism they offer (no persistence mechanism, :term:`ZODB`, + or :term:`SQLAlchemy`) - the mechanism they use to map URLs to code (:term:`traversal` or :term:`URL - dispatch`). - -- whether or not the ``pyramid_beaker`` library is relied upon as the - sessioning implementation (as opposed to no sessioning or default - sessioning). + dispatch`) The included scaffolds are these: -``pyramid_starter`` - URL mapping via :term:`traversal` and no persistence mechanism. - -``pyramid_zodb`` - URL mapping via :term:`traversal` and persistence via :term:`ZODB`. +``starter`` + URL mapping via :term:`URL dispatch` and no persistence mechanism -``pyramid_routesalchemy`` - URL mapping via :term:`URL dispatch` and persistence via - :term:`SQLAlchemy` +``zodb`` + URL mapping via :term:`traversal` and persistence via :term:`ZODB` -``pyramid_alchemy`` - URL mapping via :term:`traversal` and persistence via - :term:`SQLAlchemy` +``alchemy`` + URL mapping via :term:`URL dispatch` and persistence via :term:`SQLAlchemy` -.. note:: At this time, each of these scaffolds uses the :term:`Chameleon` - templating system, which is incompatible with Jython. To use scaffolds to - build applications which will run on Jython, you can try the - ``pyramid_jinja2_starter`` scaffold which ships as part of the - :term:`pyramid_jinja2` package. You can also just use any above scaffold - and replace the Chameleon template it includes with a :term:`Mako` - analogue. - -Rather than use any of the above scaffolds, Pylons 1 users may feel more -comfortable installing the :term:`Akhet` development environment, which -provides a scaffold named ``akhet``. This scaffold configures a Pyramid -application in a "Pylons-esque" way, including the use of a :term:`view -handler` to map URLs to code (a handler is much like a Pylons "controller"). .. index:: single: creating a project single: project + single: pcreate .. _creating_a_project: Creating the Project -------------------- -In :ref:`installing_chapter`, you created a virtual Python environment via -the ``virtualenv`` command. To start a :app:`Pyramid` :term:`project`, use -the ``paster`` facility installed within the virtualenv. In -:ref:`installing_chapter` we called the virtualenv directory ``env``; the -following command assumes that our current working directory is that -directory. +.. seealso:: See also the output of :ref:`pcreate --help <pcreate_script>`. -We'll choose the ``pyramid_starter`` scaffold for this purpose. +In :ref:`installing_chapter`, you created a virtual Python environment via the +``venv`` command. To start a :app:`Pyramid` :term:`project`, use the +``pcreate`` command installed within the virtual environment. We'll choose the +``starter`` scaffold for this purpose. When we invoke ``pcreate``, it will +create a directory that represents our project. -.. code-block:: text +In :ref:`installing_chapter` we called the virtual environment directory +``env``. The following commands assume that our current working directory is +the ``env`` directory. - $ bin/paster create -t pyramid_starter +The below example uses the ``pcreate`` command to create a project with the +``starter`` scaffold. -The above command uses the ``paster`` command to create a project using the -``pyramid_starter`` scaffold. The ``paster create`` command creates project -from a scaffold. To use a different scaffold, such as -``pyramid_routesalchemy``, you'd just change the last argument. For example: +On UNIX: -.. code-block:: text +.. code-block:: bash - $ bin/paster create -t pyramid_routesalchemy + $ $VENV/bin/pcreate -s starter MyProject -``paster create`` will ask you a single question: the *name* of the -project. You should use a string without spaces and with only letters -in it. Here's sample output from a run of ``paster create`` for a -project we name ``MyProject``: +Or on Windows: .. code-block:: text - $ bin/paster create -t pyramid_starter - Selected and implied templates: - pyramid#pyramid_starter pyramid starter project - - Enter project name: MyProject - Variables: - egg: MyProject - package: myproject - project: MyProject - Creating template pyramid - Creating directory ./MyProject - # ... more output ... - Running /Users/chrism/projects/pyramid/bin/python setup.py egg_info - -.. note:: You can skip the interrogative question about a project - name during ``paster create`` by adding the project name to the - command line, e.g. ``paster create -t pyramid_starter MyProject``. - -.. note:: You may encounter an error when using ``paster create`` if a - dependent Python package is not installed. This will result in a traceback - ending in ``pkg_resources.DistributionNotFound: <package name>``. - Simply run ``bin/easy_install``, with the missing package name from the - error message to work around this issue. - -As a result of invoking the ``paster create`` command, a project is created -in a directory named ``MyProject``. That directory is a :term:`project` -directory. The ``setup.py`` file in that directory can be used to distribute -your application, or install your application for deployment or development. - -A :term:`PasteDeploy` ``.ini`` file named ``development.ini`` will be created -in the project directory. You will use this ``.ini`` file to configure a -server, to run your application, and to debug your application. It sports -configuration that enables an interactive debugger and settings optimized for -development. - -Another :term:`PasteDeploy` ``.ini`` file named ``production.ini`` will also -be created in the project directory. It sports configuration that disables -any interactive debugger (to prevent inappropriate access and disclosure), -and turns off a number of debugging settings. You can use this file to put -your application into production, and you can modify it to do things like -send email when an exception occurs. + > %VENV%\Scripts\pcreate -s starter MyProject + +As a result of invoking the ``pcreate`` command, a directory named +``MyProject`` is created. That directory is a :term:`project` directory. The +``setup.py`` file in that directory can be used to distribute your application, +or install your application for deployment or development. + +An ``.ini`` file named ``development.ini`` will be created in the project +directory. You will use this ``.ini`` file to configure a server, to run your +application, and to debug your application. It contains configuration that +enables an interactive debugger and settings optimized for development. + +Another ``.ini`` file named ``production.ini`` will also be created in the +project directory. It contains configuration that disables any interactive +debugger (to prevent inappropriate access and disclosure), and turns off a +number of debugging settings. You can use this file to put your application +into production. The ``MyProject`` project directory contains an additional subdirectory named -``myproject`` (note the case difference) representing a Python -:term:`package` which holds very simple :app:`Pyramid` sample code. This is -where you'll edit your application's Python code and templates. +``myproject`` (note the case difference) representing a Python :term:`package` +which holds very simple :app:`Pyramid` sample code. This is where you'll edit +your application's Python code and templates. + +We created this project within an ``env`` virtual environment directory. +However, note that this is not mandatory. The project directory can go more or +less anywhere on your filesystem. You don't need to put it in a special "web +server" directory, and you don't need to put it within a virtual environment +directory. The author uses Linux mainly, and tends to put project directories +which he creates within his ``~/projects`` directory. On Windows, it's a good +idea to put project directories within a directory that contains no space +characters, so it's wise to *avoid* a path that contains, i.e., ``My +Documents``. As a result, the author, when he uses Windows, just puts his +projects in ``C:\projects``. + +.. warning:: + + You'll need to avoid using ``pcreate`` to create a project with the same + name as a Python standard library component. In particular, this means you + should avoid using the names ``site`` or ``test``, both of which conflict + with Python standard library packages. You should also avoid using the name + ``pyramid``, which will conflict with Pyramid itself. .. index:: single: setup.py develop @@ -171,271 +140,316 @@ Installing your Newly Created Project for Development To install a newly created project for development, you should ``cd`` to the newly created project directory and use the Python interpreter from the -:term:`virtualenv` you created during :ref:`installing_chapter` to invoke the -command ``python setup.py develop`` +:term:`virtual environment` you created during :ref:`installing_chapter` to +invoke the command ``pip install -e .``, which installs the project in +development mode (``-e`` is for "editable") into the current directory (``.``). -The file named ``setup.py`` will be in the root of the paster-generated -project directory. The ``python`` you're invoking should be the one that -lives in the ``bin`` directory of your virtual Python environment. Your -terminal's current working directory *must* the the newly created project -directory. For example: +The file named ``setup.py`` will be in the root of the pcreate-generated +project directory. The ``python`` you're invoking should be the one that lives +in the ``bin`` (or ``Scripts`` on Windows) directory of your virtual Python +environment. Your terminal's current working directory *must* be the newly +created project directory. -.. code-block:: text +On UNIX: - $ ../bin/python setup.py develop +.. code-block:: bash -Elided output from a run of this command is shown below: + $ cd MyProject + $ $VENV/bin/pip install -e . -.. code-block:: text +Or on Windows: + +.. code-block:: doscon + + > cd MyProject + > %VENV%\Scripts\pip install -e . + +Elided output from a run of this command on UNIX is shown below: + +.. code-block:: bash - $ ../bin/python setup.py develop + $ cd MyProject + $ $VENV/bin/pip install -e . ... - Finished processing dependencies for MyProject==0.0 + Successfully installed Chameleon-2.24 Mako-1.0.4 MyProject \ + pyramid-chameleon-0.3 pyramid-debugtoolbar-2.4.2 pyramid-mako-1.0.2 This will install a :term:`distribution` representing your project into the -interpreter's library set so it can be found by ``import`` statements and by -:term:`PasteDeploy` commands such as ``paster serve`` and ``paster pshell``. +virtual environment interpreter's library set so it can be found by ``import`` +statements and by other console scripts such as ``pserve``, ``pshell``, +``proutes``, and ``pviews``. .. index:: single: running tests single: tests (running) -Running The Tests For Your Application +Running the Tests for Your Application -------------------------------------- -To run unit tests for your application, you should invoke them using the -Python interpreter from the :term:`virtualenv` you created during -:ref:`installing_chapter` (the ``python`` command that lives in the ``bin`` -directory of your virtualenv): +To run unit tests for your application, you must first install the testing +dependencies. -.. code-block:: text - - $ ../bin/python setup.py test -q - -Here's sample output from a test run: - -.. code-block:: text - - $ python setup.py test -q - running test - running egg_info - writing requirements to MyProject.egg-info/requires.txt - writing MyProject.egg-info/PKG-INFO - writing top-level names to MyProject.egg-info/top_level.txt - writing dependency_links to MyProject.egg-info/dependency_links.txt - writing entry points to MyProject.egg-info/entry_points.txt - reading manifest file 'MyProject.egg-info/SOURCES.txt' - writing manifest file 'MyProject.egg-info/SOURCES.txt' - running build_ext - .. - ---------------------------------------------------------------------- - Ran 1 test in 0.108s - - OK - -.. note:: +On UNIX: - The ``-q`` option is passed to the ``setup.py test`` command to limit the - output to a stream of dots. If you don't pass ``-q``, you'll see more - verbose test result output (which normally isn't very useful). +.. code-block:: bash -The tests themselves are found in the ``tests.py`` module in your ``paster -create`` -generated project. Within a project generated by the -``pyramid_starter`` scaffold, a single sample test exists. + $ $VENV/bin/pip install -e ".[testing]" -.. index:: - single: interactive shell - single: IPython - single: paster pshell +On Windows: -.. _interactive_shell: +.. code-block:: doscon -The Interactive Shell ---------------------- + > %VENV%\Scripts\pip install -e ".[testing]" -Once you've installed your program for development using ``setup.py -develop``, you can use an interactive Python shell to examine your -:app:`Pyramid` project's :term:`resource` and :term:`view` objects from a -Python prompt. To do so, use your virtualenv's ``paster pshell`` command. +Once the testing requirements are installed, then you can run the tests using +the ``py.test`` command that was just installed in the ``bin`` directory of +your virtual environment. -The first argument to ``pshell`` is the path to your application's ``.ini`` -file. The second is the ``app`` section name inside the ``.ini`` file which -points to *your application* as opposed to any other section within the -``.ini`` file. For example, if your application ``.ini`` file might have a -``[app:MyProject]`` section that looks like so: +On UNIX: -.. code-block:: ini - :linenos: +.. code-block:: bash - [app:MyProject] - use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en + $ $VENV/bin/py.test myproject/tests.py -q -If so, you can use the following command to invoke a debug shell using the -name ``MyProject`` as a section name: +On Windows: -.. code-block:: text - - [chrism@vitaminf shellenv]$ ../bin/paster pshell development.ini MyProject - Python 2.4.5 (#1, Aug 29 2008, 12:27:37) - [GCC 4.0.1 (Apple Inc. build 5465)] on darwin - Type "help" for more information. "root" is the Pyramid app root object, - "registry" is the Pyramid registry object. - >>> root - <myproject.resources.MyResource object at 0x445270> - >>> registry - <Registry myproject> - >>> registry.settings['debug_notfound'] - False - >>> from myproject.views import my_view - >>> from pyramid.request import Request - >>> r = Request.blank('/') - >>> my_view(r) - {'project': 'myproject'} - -Two names are made available to the pshell user as globals: ``root`` and -``registry``. ``root`` is the the object returned by the default :term:`root -factory` in your application. ``registry`` is the :term:`application -registry` object associated with your project's application (often accessed -within view code as ``request.registry``). - -If you have `IPython <http://en.wikipedia.org/wiki/IPython>`_ installed in -the interpreter you use to invoke the ``paster`` command, the ``pshell`` -command will use an IPython interactive shell instead of a standard Python -interpreter shell. If you don't want this to happen, even if you have -IPython installed, you can pass the ``--disable-ipython`` flag to the -``pshell`` command to use a standard Python interpreter shell -unconditionally. - -.. code-block:: text +.. code-block:: doscon - [chrism@vitaminf shellenv]$ ../bin/paster pshell --disable-ipython \ - development.ini MyProject + > %VENV%\Scripts\py.test myproject\tests.py -q -You should always use a section name argument that refers to the actual -``app`` section within the Paste configuration file that points at your -:app:`Pyramid` application *without any middleware wrapping*. In particular, -a section name is inappropriate as the second argument to ``pshell`` if the -configuration section it names is a ``pipeline`` rather than an ``app``. For -example, if you have the following ``.ini`` file content: +Here's sample output from a test run on UNIX: -.. code-block:: ini - :linenos: +.. code-block:: bash - [app:MyProject] - use = egg:MyProject - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_templates = true - default_locale_name = en + $ $VENV/bin/py.test myproject/tests.py -q + .. + 2 passed in 0.47 seconds - [pipeline:main] - pipeline = - egg:WebError#evalerror - MyProject +The tests themselves are found in the ``tests.py`` module in your ``pcreate`` +generated project. Within a project generated by the ``starter`` scaffold, +only two sample tests exist. -Use ``MyProject`` instead of ``main`` as the section name argument to -``pshell`` against the above ``.ini`` file (e.g. ``paster pshell -development.ini MyProject``). If you use ``main`` instead, an error will -occur. Use the most specific reference to your application within the -``.ini`` file possible as the section name argument. +.. note:: -Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). + The ``-q`` option is passed to the ``py.test`` command to limit the output + to a stream of dots. If you don't pass ``-q``, you'll see verbose test + result output (which normally isn't very useful). .. index:: single: running an application - single: paster serve + single: pserve single: reload single: startup - single: mod_wsgi -Running The Project Application +.. _running_the_project_application: + +Running the Project Application ------------------------------- +.. seealso:: See also the output of :ref:`pserve --help <pserve_script>`. + Once a project is installed for development, you can run the application it -represents using the ``paster serve`` command against the generated -configuration file. In our case, this file is named ``development.ini``: +represents using the ``pserve`` command against the generated configuration +file. In our case, this file is named ``development.ini``. -.. code-block:: text +On UNIX: - $ ../bin/paster serve development.ini +.. code-block:: bash -Here's sample output from a run of ``paster serve``: + $ $VENV/bin/pserve development.ini + +On Windows: .. code-block:: text - $ ../bin/paster serve development.ini - Starting server in PID 16601. - serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 + > %VENV%\Scripts\pserve development.ini -By default, :app:`Pyramid` applications generated from a scaffold -will listen on TCP port 6543. You can shut down a server started this way by -pressing ``Ctrl-C``. +Here's sample output from a run of ``pserve`` on UNIX: -During development, it's often useful to run ``paster serve`` using its -``--reload`` option. When ``--reload`` is passed to ``paster serve``, -changes to any Python module your project uses will cause the server to -restart. This typically makes development easier, as changes to Python code -made within a :app:`Pyramid` application is not put into effect until the -server restarts. +.. code-block:: bash -For example: + $ $VENV/bin/pserve development.ini + Starting server in PID 16208. + serving on http://127.0.0.1:6543 -.. code-block:: text +Access is restricted such that only a browser running on the same machine as +Pyramid will be able to access your Pyramid application. However, if you want +to open access to other machines on the same network, then edit the +``development.ini`` file, and replace the ``host`` value in the +``[server:main]`` section, changing it from ``127.0.0.1`` to ``0.0.0.0``. For +example: - $ ../bin/paster serve development.ini --reload - Starting subprocess with file monitor - Starting server in PID 16601. - serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 +.. code-block:: ini + + [server:main] + use = egg:waitress#main + host = 0.0.0.0 + port = 6543 + +Now when you use ``pserve`` to start the application, it will respond to +requests on *all* IP addresses possessed by your system, not just requests to +``localhost``. This is what the ``0.0.0.0`` in +``serving on http://0.0.0.0:6543`` means. The server will respond to requests +made to ``127.0.0.1`` and on any external IP address. For example, your system +might be configured to have an external IP address ``192.168.1.50``. If that's +the case, if you use a browser running on the same system as Pyramid, it will +be able to access the application via ``http://127.0.0.1:6543/`` as well as via +``http://192.168.1.50:6543/``. However, *other people* on other computers on +the same network will also be able to visit your Pyramid application in their +browser by visiting ``http://192.168.1.50:6543/``. + +You can change the port on which the server runs on by changing the same +portion of the ``development.ini`` file. For example, you can change the +``port = 6543`` line in the ``development.ini`` file's ``[server:main]`` +section to ``port = 8080`` to run the server on port 8080 instead of port 6543. + +You can shut down a server started this way by pressing ``Ctrl-C`` (or +``Ctrl-Break`` on Windows). + +The default server used to run your Pyramid application when a project is +created from a scaffold is named :term:`Waitress`. This server is what prints +the ``serving on...`` line when you run ``pserve``. It's a good idea to use +this server during development because it's very simple. It can also be used +for light production. Setting your application up under a different server is +not advised until you've done some development work under the default server, +particularly if you're not yet experienced with Python web development. Python +web server setup can be complex, and you should get some confidence that your +application works in a default environment before trying to optimize it or make +it "more like production". It's awfully easy to get sidetracked trying to set +up a non-default server for hours without actually starting to do any +development. One of the nice things about Python web servers is that they're +largely interchangeable, so if your application works under the default server, +it will almost certainly work under any other server in production if you +eventually choose to use a different one. Don't worry about it right now. For more detailed information about the startup process, see :ref:`startup_chapter`. For more information about environment variables and configuration file settings that influence startup and runtime behavior, see :ref:`environment_chapter`. +.. _reloading_code: + +Reloading Code +~~~~~~~~~~~~~~ + +During development, it's often useful to run ``pserve`` using its ``--reload`` +option. When ``--reload`` is passed to ``pserve``, changes to any Python +module your project uses will cause the server to restart. This typically +makes development easier, as changes to Python code made within a +:app:`Pyramid` application is not put into effect until the server restarts. + +For example, on UNIX: + +.. code-block:: text + + $ $VENV/bin/pserve development.ini --reload + Starting subprocess with file monitor + Starting server in PID 16601. + serving on http://127.0.0.1:6543 + +Now if you make a change to any of your project's ``.py`` files or ``.ini`` +files, you'll see the server restart automatically: + +.. code-block:: text + + development.ini changed; reloading... + -------------------- Restarting -------------------- + Starting server in PID 16602. + serving on http://127.0.0.1:6543 + +Changes to template files (such as ``.pt`` or ``.mak`` files) won't cause the +server to restart. Changes to template files don't require a server restart as +long as the ``pyramid.reload_templates`` setting in the ``development.ini`` +file is ``true``. Changes made to template files when this setting is true +will take effect immediately without a server restart. + +.. index:: + single: WSGI + Viewing the Application ----------------------- -Once your application is running via ``paster serve``, you may visit +Once your application is running via ``pserve``, you may visit ``http://localhost:6543/`` in your browser. You will see something in your browser like what is displayed in the following image: .. image:: project.png -This is the page shown by default when you visit an unmodified ``paster -create`` -generated ``pyramid_starter`` application in a browser. - -.. sidebar:: Using an Alternate WSGI Server - - The code generated by a :app:`Pyramid` scaffold assumes that you - will be using the ``paster serve`` command to start your application while - you do development. However, ``paster serve`` is by no means the only way - to start up and serve a :app:`Pyramid` application. As we saw in - :ref:`firstapp_chapter`, ``paster serve`` needn't be invoked at all to run - a :app:`Pyramid` application. The use of ``paster serve`` to run a - :app:`Pyramid` application is purely conventional based on the output of - its scaffold. - - Any :term:`WSGI` server is capable of running a :app:`Pyramid` - application. Some WSGI servers don't require the :term:`PasteDeploy` - framework's ``paster serve`` command to do server process management at - all. Each :term:`WSGI` server has its own documentation about how it - creates a process to run an application, and there are many of them, so we - cannot provide the details for each here. But the concepts are largely - the same, whatever server you happen to use. - - One popular production alternative to a ``paster``-invoked server is - :term:`mod_wsgi`. You can also use :term:`mod_wsgi` to serve your - :app:`Pyramid` application using the Apache web server rather than any - "pure-Python" server that is started as a result of ``paster serve``. See - :ref:`modwsgi_tutorial` for details. However, it is usually easier to - *develop* an application using a ``paster serve`` -invoked webserver, as - exception and debugging output will be sent to the console. +This is the page shown by default when you visit an unmodified ``pcreate`` +generated ``starter`` application in a browser. + +.. index:: + single: debug toolbar + +.. _debug_toolbar: + +The Debug Toolbar +~~~~~~~~~~~~~~~~~ + +.. image:: project-show-toolbar.png + +If you click on the :app:`Pyramid` logo at the top right of the page, a new +target window will open to present a debug toolbar that provides various +niceties while you're developing. This logo will float above every HTML page +served by :app:`Pyramid` while you develop an application, and allows you to +show the toolbar as necessary. + +.. image:: project-debug.png + +If you don't see the Pyramid logo on the top right of the page, it means you're +browsing from a system that does not have debugging access. By default, for +security reasons, only a browser originating from ``localhost`` (``127.0.0.1``) +can see the debug toolbar. To allow your browser on a remote system to access +the server, add a line within the ``[app:main]`` section of the +``development.ini`` file in the form ``debugtoolbar.hosts = X .X.X.X``. For +example, if your Pyramid application is running on a remote system, and you're +browsing from a host with the IP address ``192.168.1.1``, you'd add something +like this to enable the toolbar when your system contacts Pyramid: + +.. code-block:: ini + + [app:main] + # .. other settings ... + debugtoolbar.hosts = 192.168.1.1 + +For more information about what the debug toolbar allows you to do, see the +:ref:`documentation for pyramid_debugtoolbar <toolbar:overview>`. + +The debug toolbar will not be shown (and all debugging will be turned off) when +you use the ``production.ini`` file instead of the ``development.ini`` ini file +to run the application. + +You can also turn the debug toolbar off by editing ``development.ini`` and +commenting out a line. For example, instead of: + +.. code-block:: ini + :linenos: + + [app:main] + # ... elided configuration + pyramid.includes = + pyramid_debugtoolbar + +Put a hash mark at the beginning of the ``pyramid_debugtoolbar`` line: + +.. code-block:: ini + :linenos: + + [app:main] + # ... elided configuration + pyramid.includes = + # pyramid_debugtoolbar + +Then restart the application to see that the toolbar has been turned off. + +Note that if you comment out the ``pyramid_debugtoolbar`` line, the ``#`` +*must* be in the first column. If you put it anywhere else, and then attempt +to restart the application, you'll receive an error that ends something like +this: + +.. code-block:: text + + ImportError: No module named #pyramid_debugtoolbar .. index:: single: project structure @@ -443,15 +457,13 @@ create`` -generated ``pyramid_starter`` application in a browser. The Project Structure --------------------- -The ``pyramid_starter`` scaffold generated a :term:`project` (named -``MyProject``), which contains a Python :term:`package`. The package is -*also* named ``myproject``, but it's lowercased; the scaffold -generates a project which contains a package that shares its name except for -case. +The ``starter`` scaffold generated a :term:`project` (named ``MyProject``), +which contains a Python :term:`package`. The package is *also* named +``myproject``, but it's lowercased; the scaffold generates a project which +contains a package that shares its name except for case. -All :app:`Pyramid` ``paster`` -generated projects share a similar structure. -The ``MyProject`` project we've generated has the following directory -structure: +All :app:`Pyramid` ``pcreate``-generated projects share a similar structure. +The ``MyProject`` project we've generated has the following directory structure: .. code-block:: text @@ -461,49 +473,45 @@ structure: |-- MANIFEST.in |-- myproject | |-- __init__.py - | |-- resources.py | |-- static - | | |-- favicon.ico - | | |-- logo.png - | | `-- pylons.css + | | |-- pyramid-16x16.png + | | |-- pyramid.png + | | |-- theme.css + | | `-- theme.min.css | |-- templates | | `-- mytemplate.pt | |-- tests.py | `-- views.py |-- production.ini |-- README.txt - |-- setup.cfg `-- setup.py The ``MyProject`` :term:`Project` --------------------------------- -The ``MyProject`` :term:`project` directory is the distribution and -deployment wrapper for your application. It contains both the ``myproject`` +The ``MyProject`` :term:`project` directory is the distribution and deployment +wrapper for your application. It contains both the ``myproject`` :term:`package` representing your application as well as files used to describe, run, and test your application. -#. ``CHANGES.txt`` describes the changes you've made to the application. It - is conventionally written in :term:`ReStructuredText` format. +#. ``CHANGES.txt`` describes the changes you've made to the application. It is + conventionally written in :term:`ReStructuredText` format. #. ``README.txt`` describes the application in general. It is conventionally written in :term:`ReStructuredText` format. -#. ``development.ini`` is a :term:`PasteDeploy` configuration file that can - be used to execute your application during development. - -#. ``production.ini`` is a :term:`PasteDeploy` configuration file that can - be used to execute your application in a production configuration. +#. ``development.ini`` is a :term:`PasteDeploy` configuration file that can be + used to execute your application during development. -#. ``setup.cfg`` is a :term:`setuptools` configuration file used by - ``setup.py``. +#. ``production.ini`` is a :term:`PasteDeploy` configuration file that can be + used to execute your application in a production configuration. #. ``MANIFEST.in`` is a :term:`distutils` "manifest" file, naming which files should be included in a source distribution of the package when ``python setup.py sdist`` is run. -#. ``setup.py`` is the file you'll use to test and distribute your - application. It is a standard :term:`setuptools` ``setup.py`` file. +#. ``setup.py`` is the file you'll use to test and distribute your application. + It is a standard :term:`setuptools` ``setup.py`` file. .. index:: single: PasteDeploy @@ -514,127 +522,98 @@ describe, run, and test your application. ``development.ini`` ~~~~~~~~~~~~~~~~~~~ -The ``development.ini`` file is a :term:`PasteDeploy` configuration file. -Its purpose is to specify an application to run when you invoke ``paster -serve``, as well as the deployment settings provided to that application. +The ``development.ini`` file is a :term:`PasteDeploy` configuration file. Its +purpose is to specify an application to run when you invoke ``pserve``, as well +as the deployment settings provided to that application. The generated ``development.ini`` file looks like so: -.. latexbroken? - .. literalinclude:: MyProject/development.ini :language: ini :linenos: -This file contains several "sections" including ``[app:MyProject]``, -``[pipeline:main]``, and ``[server:main]``. - -The ``[app:MyProject]`` section represents configuration for your -application. This section name represents the ``MyProject`` application (and -it's an ``app`` -lication, thus ``app:MyProject``) - -The ``use`` setting is required in the ``[app:MyProject]`` section. The -``use`` setting points at a :term:`setuptools` :term:`entry point` named -``MyProject`` (the ``egg:`` prefix in ``egg:MyProject`` indicates that this -is an entry point *URI* specifier, where the "scheme" is "egg"). -``egg:MyProject`` is actually shorthand for a longer spelling: -``egg:MyProject#main``. The ``#main`` part is omitted for brevity, as it is -the default. - -.. sidebar:: ``setuptools`` Entry Points and PasteDeploy ``.ini`` Files - - This part of configuration can be confusing so let's try to clear things - up a bit. Take a look at the generated ``setup.py`` file for this - project. Note that the ``entry_point`` line in ``setup.py`` points at a - string which looks a lot like an ``.ini`` file. This string - representation of an ``.ini`` file has a section named - ``[paste.app_factory]``. Within this section, there is a key named - ``main`` (the entry point name) which has a value ``myproject:main``. The - *key* ``main`` is what our ``egg:MyProject#main`` value of the ``use`` - section in our config file is pointing at (although it is actually - shortened to ``egg:MyProject`` there). The value represents a - :term:`dotted Python name` path, which refers to a callable in our - ``myproject`` package's ``__init__.py`` module. In English, this entry - point can thus be referred to as a "Paste application factory in the - ``MyProject`` project which has the entry point named ``main`` where the - entry point refers to a ``main`` function in the ``mypackage`` module". - If indeed if you open up the ``__init__.py`` module generated within the - ``myproject`` package, you'll see a ``main`` function. This is the - function called by :term:`PasteDeploy` when the ``paster serve`` command - is invoked against our application. It accepts a global configuration - object and *returns* an instance of our application. - -The ``use`` setting is the only setting *required* in the ``[app:MyProject]`` -section unless you've changed the callable referred to by the -``egg:MyProject`` entry point to accept more arguments: other settings you -add to this section are passed as keywords arguments to the callable -represented by this entry point (``main`` in our ``__init__.py`` module). -You can provide startup-time configuration parameters to your application by -adding more settings to this section. - -The ``reload_templates`` setting in the ``[app:MyProject]`` section is a -:app:`Pyramid` -specific setting which is passed into the framework. If it -exists, and its value is ``true``, :term:`Chameleon` and :term:`Mako` -template changes will not require an application restart to be detected. See -:ref:`reload_templates_section` for more information. - -The ``debug_templates`` setting in the ``[app:MyProject]`` section is a -:app:`Pyramid` -specific setting which is passed into the framework. If it -exists, and its value is ``true``, :term:`Chameleon` template exceptions will -contained more detailed and helpful information about the error than when -this value is ``false``. See :ref:`debug_templates_section` for more -information. - -.. warning:: The ``reload_templates`` and ``debug_templates`` options should - be turned off for production applications, as template rendering is slowed - when either is turned on. - -Various other settings may exist in this section having to do with debugging -or influencing runtime behavior of a :app:`Pyramid` application. See +This file contains several sections including ``[app:main]``, +``[server:main]``, and several other sections related to logging configuration. + +The ``[app:main]`` section represents configuration for your :app:`Pyramid` +application. The ``use`` setting is the only setting required to be present in +the ``[app:main]`` section. Its default value, ``egg:MyProject``, indicates +that our MyProject project contains the application that should be served. +Other settings added to this section are passed as keyword arguments to the +function named ``main`` in our package's ``__init__.py`` module. You can +provide startup-time configuration parameters to your application by adding +more settings to this section. + +.. seealso:: See :ref:`pastedeploy_entry_points` for more information about the + meaning of the ``use = egg:MyProject`` value in this section. + +The ``pyramid.reload_templates`` setting in the ``[app:main]`` section is a +:app:`Pyramid`-specific setting which is passed into the framework. If it +exists, and its value is ``true``, supported template changes will not require +an application restart to be detected. See :ref:`reload_templates_section` for +more information. + +.. warning:: The ``pyramid.reload_templates`` option should be turned off for + production applications, as template rendering is slowed when it is turned + on. + +The ``pyramid.includes`` setting in the ``[app:main]`` section tells Pyramid to +"include" configuration from another package. In this case, the line +``pyramid.includes = pyramid_debugtoolbar`` tells Pyramid to include +configuration from the ``pyramid_debugtoolbar`` package. This turns on a +debugging panel in development mode which can be opened by clicking on the +:app:`Pyramid` logo on the top right of the screen. Including the debug +toolbar will also make it possible to interactively debug exceptions when an +error occurs. + +Various other settings may exist in this section having to do with debugging or +influencing runtime behavior of a :app:`Pyramid` application. See :ref:`environment_chapter` for more information about these settings. -``[pipeline:main]``, has the name ``main`` signifying that this is the -default 'application' (although it's actually a pipeline of middleware and an -application) run by ``paster serve`` when it is invoked against this -configuration file. The name ``main`` is a convention used by PasteDeploy -signifying that it is the default application. +The name ``main`` in ``[app:main]`` signifies that this is the default +application run by ``pserve`` when it is invoked against this configuration +file. The name ``main`` is a convention used by PasteDeploy signifying that it +is the default application. The ``[server:main]`` section of the configuration file configures a WSGI -server which listens on TCP port 6543. It is configured to listen on all -interfaces (``0.0.0.0``). The ``Paste#http`` server will create a new thread -for each request. +server which listens on TCP port 6543. It is configured to listen on localhost +only (``127.0.0.1``). -.. note:: +.. _MyProject_ini_logging: - In general, :app:`Pyramid` applications generated from scaffolds - should be threading-aware. It is not required that a :app:`Pyramid` - application be nonblocking as all application code will run in its own - thread, provided by the server you're using. +The sections after ``# logging configuration`` represent Python's standard +library :mod:`logging` module configuration for your application. These +sections are passed to the `logging module's config file configuration engine +<http://docs.python.org/howto/logging.html#configuring-logging>`_ when the +``pserve`` or ``pshell`` commands are executed. The default configuration +sends application logging output to the standard error output of your terminal. +For more information about logging configuration, see :ref:`logging_chapter`. See the :term:`PasteDeploy` documentation for more information about other types of things you can put into this ``.ini`` file, such as other -applications, :term:`middleware` and alternate :term:`WSGI` server +applications, :term:`middleware`, and alternate :term:`WSGI` server implementations. -.. note:: - - You can add a ``[DEFAULT]`` section to your ``development.ini`` file. - Such a section should consists of global parameters that are shared by all - the applications, servers and :term:`middleware` defined within the - configuration file. The values in a ``[DEFAULT]`` section will be passed - to your application's ``main`` function as ``global_config`` (see - the reference to the ``main`` function in :ref:`init_py`). +.. index:: + single: production.ini ``production.ini`` -~~~~~~~~~~~~~~~~~~~ - -The ``production.ini`` file is a :term:`PasteDeploy` configuration file with -a purpose much like that of ``development.ini``. However, it disables the -WebError interactive debugger, replacing it with a logger which outputs -exception messages to ``stderr`` by default. It also turns off template -development options such that templates are not automatically reloaded when -changed, and turns off all debugging options. You can use this file instead -of ``development.ini`` when you put your application into production. +~~~~~~~~~~~~~~~~~~ + +The ``production.ini`` file is a :term:`PasteDeploy` configuration file with a +purpose much like that of ``development.ini``. However, it disables the debug +toolbar, and filters all log messages except those above the WARN level. It +also turns off template development options such that templates are not +automatically reloaded when changed, and turns off all debugging options. This +file is appropriate to use instead of ``development.ini`` when you put your +application into production. + +It's important to use ``production.ini`` (and *not* ``development.ini``) to +benchmark your application and put it into production. ``development.ini`` +configures your system with a debug toolbar that helps development, but the +inclusion of this toolbar slows down page rendering times by over an order of +magnitude. The debug toolbar is also a potential security risk if you have it +configured incorrectly. .. index:: single: MANIFEST.in @@ -646,12 +625,41 @@ The ``MANIFEST.in`` file is a :term:`distutils` configuration file which specifies the non-Python files that should be included when a :term:`distribution` of your Pyramid project is created when you run ``python setup.py sdist``. Due to the information contained in the default -``MANIFEST.in``, an sdist of your Pyramid project will include ``.txt`` -files, ``.ini`` files, ``.rst`` files, graphics files, and template files, as -well as ``.py`` files. See +``MANIFEST.in``, an sdist of your Pyramid project will include ``.txt`` files, +``.ini`` files, ``.rst`` files, graphics files, and template files, as well as +``.py`` files. See http://docs.python.org/distutils/sourcedist.html#the-manifest-in-template for more information about the syntax and usage of ``MANIFEST.in``. +Without the presence of a ``MANIFEST.in`` file or without checking your source +code into a version control repository, ``setup.py sdist`` places only *Python +source files* (files ending with a ``.py`` extension) into tarballs generated +by ``python setup.py sdist``. This means, for example, if your project was not +checked into a setuptools-compatible source control system, and your project +directory didn't contain a ``MANIFEST.in`` file that told the ``sdist`` +machinery to include ``*.pt`` files, the ``myproject/templates/mytemplate.pt`` +file would not be included in the generated tarball. + +Projects generated by Pyramid scaffolds include a default ``MANIFEST.in`` file. +The ``MANIFEST.in`` file contains declarations which tell it to include files +like ``*.pt``, ``*.css`` and ``*.js`` in the generated tarball. If you include +files with extensions other than the files named in the project's +``MANIFEST.in`` and you don't make use of a setuptools-compatible version +control system, you'll need to edit the ``MANIFEST.in`` file and include the +statements necessary to include your new files. See +http://docs.python.org/distutils/sourcedist.html#principle for more information +about how to do this. + +You can also delete ``MANIFEST.in`` from your project and rely on a setuptools +feature which simply causes all files checked into a version control system to +be put into the generated tarball. To allow this to happen, check all the +files that you'd like to be distributed along with your application's Python +files into Subversion. After you do this, when you rerun ``setup.py sdist``, +all files checked into the version control system will be included in the +tarball. If you don't use Subversion, and instead use a different version +control system, you may need to install a setuptools add-on such as +``setuptools-git`` or ``setuptools-hg`` for this behavior to work properly. + .. index:: single: setup.py @@ -659,15 +667,16 @@ more information about the syntax and usage of ``MANIFEST.in``. ~~~~~~~~~~~~ The ``setup.py`` file is a :term:`setuptools` setup file. It is meant to be -run directly from the command line to perform a variety of functions, such as -testing your application, packaging, and distributing your application. +used to define requirements for installing dependencies for your package and +testing, as well as distributing your application. .. note:: - ``setup.py`` is the defacto standard which Python developers use to - distribute their reusable code. You can read more about ``setup.py`` files - and their usage in the `Setuptools documentation - <http://peak.telecommunity.com/DevCenter/setuptools>`_. + ``setup.py`` is the de facto standard which Python developers use to + distribute their reusable code. You can read more about ``setup.py`` files + and their usage in the `Python Packaging User Guide + <https://packaging.python.org/en/latest/>`_ and `Setuptools documentation + <http://pythonhosted.org/setuptools/>`_. Our generated ``setup.py`` looks like this: @@ -676,94 +685,46 @@ Our generated ``setup.py`` looks like this: :linenos: The ``setup.py`` file calls the setuptools ``setup`` function, which does -various things depending on the arguments passed to ``setup.py`` on the -command line. +various things depending on the arguments passed to ``pip`` on the command +line. -Within the arguments to this function call, information about your -application is kept. While it's beyond the scope of this documentation to -explain everything about setuptools setup files, we'll provide a whirlwind -tour of what exists in this file in this section. +Within the arguments to this function call, information about your application +is kept. While it's beyond the scope of this documentation to explain +everything about setuptools setup files, we'll provide a whirlwind tour of what +exists in this file in this section. Your application's name can be any string; it is specified in the ``name`` field. The version number is specified in the ``version`` value. A short -description is provided in the ``description`` field. The -``long_description`` is conventionally the content of the README and CHANGES -file appended together. The ``classifiers`` field is a list of `Trove +description is provided in the ``description`` field. The ``long_description`` +is conventionally the content of the ``README`` and ``CHANGES`` files appended +together. The ``classifiers`` field is a list of `Trove <http://pypi.python.org/pypi?%3Aaction=list_classifiers>`_ classifiers describing your application. ``author`` and ``author_email`` are text fields which probably don't need any description. ``url`` is a field that should -point at your application project's URL (if any). -``packages=find_packages()`` causes all packages within the project to be -found when packaging the application. ``include_package_data`` will include -non-Python files when the application is packaged if those files are checked -into version control. ``zip_safe`` indicates that this package is not safe -to use as a zipped egg; instead it will always unpack as a directory, which -is more convenient. ``install_requires`` and ``tests_require`` indicate that -this package depends on the ``pyramid`` package. ``test_suite`` points at -the package for our application, which means all tests found in the package -will be run when ``setup.py test`` is invoked. We examined ``entry_points`` -in our discussion of the ``development.ini`` file; this file defines the -``main`` entry point that represents our project's application. - -Usually you only need to think about the contents of the ``setup.py`` file -when distributing your application to other people, or when versioning your -application for your own use. For fun, you can try this command now: +point at your application project's URL (if any). ``packages=find_packages()`` +causes all packages within the project to be found when packaging the +application. ``include_package_data`` will include non-Python files when the +application is packaged if those files are checked into version control. +``zip_safe=False`` indicates that this package is not safe to use as a zipped +egg; instead it will always unpack as a directory, which is more convenient. +``install_requires`` indicate that this package depends on the ``pyramid`` +package. ``extras_require`` is a Python dictionary that defines what is +required to be installed for running tests. We examined ``entry_points`` in our +discussion of the ``development.ini`` file; this file defines the ``main`` +entry point that represents our project's application. + +Usually you only need to think about the contents of the ``setup.py`` file when +distributing your application to other people, when adding Python package +dependencies, or when versioning your application for your own use. For fun, +you can try this command now: .. code-block:: text - $ python setup.py sdist - -This will create a tarball of your application in a ``dist`` subdirectory -named ``MyProject-0.1.tar.gz``. You can send this tarball to other people -who want to use your application. - -.. warning:: - - Without the presence of a ``MANIFEST.in`` file or without checking your - source code into a version control repository, ``setup.py sdist`` places - only *Python source files* (files ending with a ``.py`` extension) into - tarballs generated by ``python setup.py sdist``. This means, for example, - if your project was not checked into a setuptools-compatible source - control system, and your project directory didn't contain a ``MANIFEST.in`` - file that told the ``sdist`` machinery to include ``*.pt`` files, the - ``myproject/templates/mytemplate.pt`` file would not be included in the - generated tarball. - - Projects generated by Pyramid scaffolds include a default - ``MANIFEST.in`` file. The ``MANIFEST.in`` file contains declarations - which tell it to include files like ``*.pt``, ``*.css`` and ``*.js`` in - the generated tarball. If you include files with extensions other than - the files named in the project's ``MANIFEST.in`` and you don't make use of - a setuptools-compatible version control system, you'll need to edit the - ``MANIFEST.in`` file and include the statements necessary to include your - new files. See http://docs.python.org/distutils/sourcedist.html#principle - for more information about how to do this. - - You can also delete ``MANIFEST.in`` from your project and rely on a - setuptools feature which simply causes all files checked into a version - control system to be put into the generated tarball. To allow this to - happen, check all the files that you'd like to be distributed along with - your application's Python files into Subversion. After you do this, when - you rerun ``setup.py sdist``, all files checked into the version control - system will be included in the tarball. If you don't use Subversion, and - instead use a different version control system, you may need to install a - setuptools add-on such as ``setuptools-git`` or ``setuptools-hg`` for this - behavior to work properly. - -``setup.cfg`` -~~~~~~~~~~~~~ - -The ``setup.cfg`` file is a :term:`setuptools` configuration file. It -contains various settings related to testing and internationalization: - -Our generated ``setup.cfg`` looks like this: - -.. literalinclude:: MyProject/setup.cfg - :language: guess - :linenos: + $ $VENV/bin/python setup.py sdist -The values in the default setup file allow various commonly-used -internationalization commands and testing commands to work more smoothly. +This will create a tarball of your application in a ``dist`` subdirectory named +``MyProject-0.0.tar.gz``. You can send this tarball to other people who want +to install and use your application. .. index:: single: package @@ -774,26 +735,22 @@ The ``myproject`` :term:`Package` The ``myproject`` :term:`package` lives inside the ``MyProject`` :term:`project`. It contains: -#. An ``__init__.py`` file signifies that this is a Python :term:`package`. - It also contains code that helps users run the application, including a - ``main`` function which is used as a Paste entry point. +#. An ``__init__.py`` file signifies that this is a Python :term:`package`. It + also contains code that helps users run the application, including a + ``main`` function which is used as a entry point for commands such as + ``pserve``, ``pshell``, ``pviews``, and others. -#. A ``resources.py`` module, which contains :term:`resource` code. +#. A ``templates`` directory, which contains :term:`Chameleon` (or other types + of) templates. -#. A ``templates`` directory, which contains :term:`Chameleon` (or - other types of) templates. +#. A ``tests.py`` module, which contains unit test code for the application. -#. A ``tests.py`` module, which contains unit test code for the - application. +#. A ``views.py`` module, which contains view code for the application. -#. A ``views.py`` module, which contains view code for the - application. - -These are purely conventions established by the scaffold: -:app:`Pyramid` doesn't insist that you name things in any particular way. -However, it's generally a good idea to follow Pyramid standards for naming, -so that other Pyramid developers can get up to speed quickly on your code -when you need help. +These are purely conventions established by the scaffold. :app:`Pyramid` +doesn't insist that you name things in any particular way. However, it's +generally a good idea to follow Pyramid standards for naming, so that other +Pyramid developers can get up to speed quickly on your code when you need help. .. index:: single: __init__.py @@ -815,105 +772,110 @@ also informs Python that the directory which contains it is a *package*. #. Line 1 imports the :term:`Configurator` class from :mod:`pyramid.config` that we use later. -#. Line 2 imports the ``Root`` class from :mod:`myproject.resources` that we - use later. - #. Lines 4-12 define a function named ``main`` that returns a :app:`Pyramid` WSGI application. This function is meant to be called by the - :term:`PasteDeploy` framework as a result of running ``paster serve``. + :term:`PasteDeploy` framework as a result of running ``pserve``. Within this function, application configuration is performed. - Lines 8-10 register a "default view" (a view that has no ``name`` - attribute). It is registered so that it will be found when the - :term:`context` of the request is an instance of the - :class:`myproject.resources.Root` class. The first argument to - ``add_view`` points at a Python function that does all the work for this - view, also known as a :term:`view callable`, via a :term:`dotted Python - name`. The view declaration also names a ``renderer``, which in this case - is a template that will be used to render the result of the view callable. - This particular view declaration points at - ``myproject:templates/mytemplate.pt``, which is a :term:`asset - specification` that specifies the ``mytemplate.pt`` file within the - ``templates`` directory of the ``myproject`` package. The template file - it actually points to is a :term:`Chameleon` ZPT template file. - - Line 11 registers a static view, which will serve up the files from the - ``mypackage:static`` :term:`asset specification` (the ``static`` - directory of the ``mypackage`` package). + Line 7 creates an instance of a :term:`Configurator`. + + Line 8 adds support for Chameleon templating bindings, allowing us to + specify renderers with the ``.pt`` extension. + + Line 9 registers a static view, which will serve up the files from the + ``myproject:static`` :term:`asset specification` (the ``static`` directory + of the ``myproject`` package). + + Line 10 adds a :term:`route` to the configuration. This route is later used + by a view in the ``views`` module. + + Line 11 calls ``config.scan()``, which picks up view registrations declared + elsewhere in the package (in this case, in the ``views.py`` module). Line 12 returns a :term:`WSGI` application to the caller of the function - (Paste). + (Pyramid's pserve). + +.. index:: + single: views.py ``views.py`` ~~~~~~~~~~~~ Much of the heavy lifting in a :app:`Pyramid` application is done by *view callables*. A :term:`view callable` is the main tool of a :app:`Pyramid` web -application developer; it is a bit of code which accepts a :term:`request` -and which returns a :term:`response`. +application developer; it is a bit of code which accepts a :term:`request` and +which returns a :term:`response`. .. literalinclude:: MyProject/myproject/views.py :language: python :linenos: -This bit of code was registered as the view callable within ``__init__.py`` -(via ``add_view``). ``add_view`` said that the default URL for instances -that are of the class :class:`myproject.resources.Root` should run this -:func:`myproject.views.my_view` function. +Lines 4-6 define and register a :term:`view callable` named ``my_view``. The +function named ``my_view`` is decorated with a ``view_config`` decorator (which +is processed by the ``config.scan()`` line in our ``__init__.py``). The +view_config decorator asserts that this view be found when a :term:`route` +named ``home`` is matched. In our case, because our ``__init__.py`` maps the +route named ``home`` to the URL pattern ``/``, this route will match when a +visitor visits the root URL. The view_config decorator also names a +``renderer``, which in this case is a template that will be used to render the +result of the view callable. This particular view declaration points at +``templates/mytemplate.pt``, which is an :term:`asset specification` that +specifies the ``mytemplate.pt`` file within the ``templates`` directory of the +``myproject`` package. The asset specification could have also been specified +as ``myproject:templates/mytemplate.pt``; the leading package name and colon is +optional. The template file pointed to is a :term:`Chameleon` ZPT template +file (``templates/my_template.pt``). This view callable function is handed a single piece of information: the -:term:`request`. The *request* is an instance of the :term:`WebOb` -``Request`` class representing the browser's request to our server. - -This view returns a dictionary. When this view is invoked, a -:term:`renderer` converts the dictionary returned by the view into HTML, and -returns the result as the :term:`response`. This view is configured to -invoke a renderer which uses a :term:`Chameleon` ZPT template -(``mypackage:templates/my_template.pt``, as specified in the ``__init__.py`` -file call to ``add_view``). - -See :ref:`views_which_use_a_renderer` for more information about how views, -renderers, and templates relate and cooperate. - -.. note:: Because our ``development.ini`` has a ``reload_templates = - true`` directive indicating that templates should be reloaded when - they change, you won't need to restart the application server to - see changes you make to templates. During development, this is - handy. If this directive had been ``false`` (or if the directive - did not exist), you would need to restart the application server - for each template change. For production applications, you should - set your project's ``reload_templates`` to ``false`` to increase - the speed at which templates may be rendered. +:term:`request`. The *request* is an instance of the :term:`WebOb` ``Request`` +class representing the browser's request to our server. -.. index:: - single: resources.py +This view is configured to invoke a :term:`renderer` on a template. The +dictionary the view returns (on line 6) provides the value the renderer +substitutes into the template when generating HTML. The renderer then returns +the HTML in a :term:`response`. -.. _resourcespy_project_section: +.. note:: Dictionaries provide values to :term:`template`\s. -``resources.py`` -~~~~~~~~~~~~~~~~ +.. note:: When the application is run with the scaffold's :ref:`default + development.ini <MyProject_ini>` configuration, :ref:`logging is set up + <MyProject_ini_logging>` to aid debugging. If an exception is raised, + uncaught tracebacks are displayed after the startup messages on :ref:`the + console running the server <running_the_project_application>`. Also + ``print()`` statements may be inserted into the application for debugging to + send output to this console. -The ``resources.py`` module provides the :term:`resource` data and behavior -for our application. Resources are objects which exist to provide site -structure in applications which use :term:`traversal` to map URLs to code. -We write a class named ``Root`` that provides the behavior for the root -resource. +.. note:: ``development.ini`` has a setting that controls how templates are + reloaded, ``pyramid.reload_templates``. -.. literalinclude:: MyProject/myproject/resources.py - :language: python - :linenos: + - When set to ``True`` (as in the scaffold ``development.ini``), changed + templates automatically reload without a server restart. This is + convenient while developing, but slows template rendering speed. + + - When set to ``False`` (the default value), changing templates requires a + server restart to reload them. Production applications should use + ``pyramid.reload_templates = False``. + +.. seealso:: + + See also :ref:`views_which_use_a_renderer` for more information about how + views, renderers, and templates relate and cooperate. -#. Lines 1-3 define the Root class. The Root class is a "root resource - factory" function that will be called by the :app:`Pyramid` *Router* for - each request when it wants to find the root of the resource tree. +.. seealso:: -In a "real" application, the Root object would likely not be such a simple -object. Instead, it might be an object that could access some persistent -data store, such as a database. :app:`Pyramid` doesn't make any assumption -about which sort of data storage you'll want to use, so the sample -application uses an instance of :class:`myproject.resources.Root` to -represent the root. + Pyramid can also dynamically reload changed Python files. See also + :ref:`reloading_code`. + +.. seealso:: + + See also the :ref:`debug_toolbar`, which provides interactive access to + your application's internals and, should an exception occur, allows + interactive access to traceback execution stack frames from the Python + interpreter. + +.. index:: + single: static directory ``static`` ~~~~~~~~~~ @@ -924,11 +886,11 @@ template. It includes CSS and images. ``templates/mytemplate.pt`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The single :term:`Chameleon` template exists in the project. Its contents -are too long to show here, but it displays a default page when rendered. It -is referenced by the call to ``add_view`` as the ``renderer`` attribute in -the ``__init__`` file. See :ref:`views_which_use_a_renderer` for more -information about renderers. +This is the single :term:`Chameleon` template that exists in the project. Its +contents are too long to show here, but it displays a default page when +rendered. It is referenced by the call to ``@view_config`` as the ``renderer`` +of the ``my_view`` view callable in the ``views.py`` file. See +:ref:`views_which_use_a_renderer` for more information about renderers. Templates are accessed and used by view configurations and sometimes by view functions themselves. See :ref:`templates_used_directly` and @@ -946,82 +908,120 @@ The ``tests.py`` module includes unit tests for your application. :language: python :linenos: -This sample ``tests.py`` file has a single unit test defined within it. This -test is executed when you run ``python setup.py test``. You may add more -tests here as you build your application. You are not required to write -tests to use :app:`Pyramid`, this file is simply provided as convenience and -example. +This sample ``tests.py`` file has one unit test and one functional test defined +within it. These tests are executed when you run ``py.test myproject/tests.py +-q``. You may add more tests here as you build your application. You are not +required to write tests to use :app:`Pyramid`. This file is simply provided for +convenience and example. See :ref:`testing_chapter` for more information about writing :app:`Pyramid` unit tests. +.. index:: + pair: modifying; package structure + .. _modifying_package_structure: Modifying Package Structure ----------------------------- +--------------------------- It is best practice for your application's code layout to not stray too much -from accepted Pyramid scaffold defaults. If you refrain from changing -things very much, other Pyramid coders will be able to more quickly -understand your application. However, the code layout choices made for you -by a scaffold are in no way magical or required. Despite the choices -made for you by any scaffold, you can decide to lay your code out any -way you see fit. +from accepted Pyramid scaffold defaults. If you refrain from changing things +very much, other Pyramid coders will be able to more quickly understand your +application. However, the code layout choices made for you by a scaffold are +in no way magical or required. Despite the choices made for you by any +scaffold, you can decide to lay your code out any way you see fit. For example, the configuration method named :meth:`~pyramid.config.Configurator.add_view` requires you to pass a :term:`dotted Python name` or a direct object reference as the class or -function to be used as a view. By default, the ``pyramid_starter`` scaffold -would have you add view functions to the ``views.py`` module in your -package. However, you might be more comfortable creating a ``views`` -*directory*, and adding a single file for each view. +function to be used as a view. By default, the ``starter`` scaffold would have +you add view functions to the ``views.py`` module in your package. However, you +might be more comfortable creating a ``views`` *directory*, and adding a single +file for each view. If your project package name was ``myproject`` and you wanted to arrange all your views in a Python subpackage within the ``myproject`` :term:`package` -named ``views`` instead of within a single ``views.py`` file, you might: - -- Create a ``views`` directory inside your ``mypackage`` package directory - (the same directory which holds ``views.py``). - -- *Move* the existing ``views.py`` file to a file inside the new ``views`` - directory named, say, ``blog.py``. - -- Create a file within the new ``views`` directory named ``__init__.py`` (it - can be empty, this just tells Python that the ``views`` directory is a - *package*. - -Then change the __init__.py of your myproject project (*not* the -``__init__.py`` you just created in the ``views`` directory, the one in its -parent directory). For example, from something like: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.my_view', - renderer='myproject:templates/mytemplate.pt') - -To this: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.blog.my_view', - renderer='myproject:templates/mytemplate.pt') - -You can then continue to add files to the ``views`` directory, and refer to -view classes or functions within those files via the dotted name passed as -the first argument to ``add_view``. For example, if you added a file named -``anothermodule.py`` to the ``views`` subdirectory, and added a view callable -named ``my_view`` to it: - -.. code-block:: python - :linenos: - - config.add_view('myproject.views.anothermodule.my_view', - renderer='myproject:templates/anothertemplate.pt') - -This pattern can be used to rearrage code referred to by any Pyramid API -argument which accepts a :term:`dotted Python name` or direct object -reference. - - +named ``views`` instead of within a single ``views.py`` file, you might do the +following. + +- Create a ``views`` directory inside your ``myproject`` package directory (the + same directory which holds ``views.py``). + +- Create a file within the new ``views`` directory named ``__init__.py``. (It + can be empty. This just tells Python that the ``views`` directory is a + *package*.) + +- *Move* the content from the existing ``views.py`` file to a file inside the + new ``views`` directory named, say, ``blog.py``. Because the ``templates`` + directory remains in the ``myproject`` package, the template :term:`asset + specification` values in ``blog.py`` must now be fully qualified with the + project's package name (``myproject:templates/blog.pt``). + +You can then continue to add view callable functions to the ``blog.py`` module, +but you can also add other ``.py`` files which contain view callable functions +to the ``views`` directory. As long as you use the ``@view_config`` directive +to register views in conjunction with ``config.scan()``, they will be picked up +automatically when the application is restarted. + +Using the Interactive Shell +--------------------------- + +It is possible to use the ``pshell`` command to load a Python interpreter +prompt with a similar configuration as would be loaded if you were running your +Pyramid application via ``pserve``. This can be a useful debugging tool. See +:ref:`interactive_shell` for more details. + +.. _what_is_this_pserve_thing: + +What Is This ``pserve`` Thing +----------------------------- + +The code generated by a :app:`Pyramid` scaffold assumes that you will be using +the ``pserve`` command to start your application while you do development. +``pserve`` is a command that reads a :term:`PasteDeploy` ``.ini`` file (e.g., +``development.ini``), and configures a server to serve a :app:`Pyramid` +application based on the data in the file. + +``pserve`` is by no means the only way to start up and serve a :app:`Pyramid` +application. As we saw in :ref:`firstapp_chapter`, ``pserve`` needn't be +invoked at all to run a :app:`Pyramid` application. The use of ``pserve`` to +run a :app:`Pyramid` application is purely conventional based on the output of +its scaffolding. But we strongly recommend using ``pserve`` while developing +your application because many other convenience introspection commands (such as +``pviews``, ``prequest``, ``proutes``, and others) are also implemented in +terms of configuration availability of this ``.ini`` file format. It also +configures Pyramid logging and provides the ``--reload`` switch for convenient +restarting of the server when code changes. + +.. _alternate_wsgi_server: + +Using an Alternate WSGI Server +------------------------------ + +Pyramid scaffolds generate projects which use the :term:`Waitress` WSGI server. +Waitress is a server that is suited for development and light production +usage. It's not the fastest nor the most featureful WSGI server. Instead, its +main feature is that it works on all platforms that Pyramid needs to run on, +making it a good choice as a default server from the perspective of Pyramid's +developers. + +Any WSGI server is capable of running a :app:`Pyramid` application. But we +suggest you stick with the default server for development, and that you wait to +investigate other server options until you're ready to deploy your application +to production. Unless for some reason you need to develop on a non-local +system, investigating alternate server options is usually a distraction until +you're ready to deploy. But we recommend developing using the default +configuration on a local system that you have complete control over; it will +provide the best development experience. + +One popular production alternative to the default Waitress server is +:term:`mod_wsgi`. You can use mod_wsgi to serve your :app:`Pyramid` application +using the Apache web server rather than any "pure-Python" server like Waitress. +It is fast and featureful. See :ref:`modwsgi_tutorial` for details. + +Another good production alternative is :term:`Green Unicorn` (aka +``gunicorn``). It's faster than Waitress and slightly easier to configure than +mod_wsgi, although it depends, in its default configuration, on having a +buffering HTTP proxy in front of it. It does not, as of this writing, work on +Windows. |
