diff options
Diffstat (limited to 'docs/narr/commandline.rst')
| -rw-r--r-- | docs/narr/commandline.rst | 1325 |
1 files changed, 766 insertions, 559 deletions
diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 3cabbd8f4..b571a7d7b 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -3,9 +3,68 @@ Command-Line Pyramid ==================== -Your :app:`Pyramid` application can be controlled and inspected using a -variety of command-line utilities. These utilities are documented in this -chapter. +Your :app:`Pyramid` application can be controlled and inspected using a variety +of command-line utilities. These utilities are documented in this chapter. + +We commonly refer to this collection of utilities as "p-scripts", which is short for "Pyramid console scripts". + +Each p-script's command line usage details is available in the :ref:`pscripts_documentation`. + + +.. index:: + single: running p-scripts + pair: running; p-scripts + +.. _running-pscripts: + +Running p-scripts +----------------- + +All of the Pyramid console scripts may be run either: + +* by its name +* as a Python module + + +.. index:: + single: running p-script by name + triple: p-script; running; name + +.. _running-pscripts-by-name: + +Running by ``p*`` script name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each of Pyramid's console scripts may be run by its name. For example: + +.. code-block:: bash + + $VENV/bin/pserve development.ini --reload + +.. note:: ``$VENV/bin/`` is a convention we use to simplify Pyramid documentation. + It represents the ``bin`` directory in a virtual environment, where ``$VENV`` is an environment variable representing its path. + See :ref:`installing_unix` and :ref:`Why use $VENV/bin/pip instead of source bin/activate, then pip <venv-bin-pip-vs-source-bin-activate>` for more information. + + +.. index:: + single: running p-scripts via Python + triple: p-script; running; Python + +.. _custom-arguments-to-python: + +Using Custom Arguments to Python when Running ``p*`` Scripts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.5 + +Each of Pyramid's console scripts (``pserve``, ``pviews``, etc.) can be run +using ``python3 -m``, allowing custom arguments to be sent to the +Python interpreter at runtime. For example: + +.. code-block:: bash + + python3 -m pyramid.scripts.pserve development.ini --reload + .. index:: pair: matching views; printing @@ -13,141 +72,141 @@ chapter. .. _displaying_matching_views: -Displaying Matching Views for a Given URL ------------------------------------------ +``pviews``: Displaying Matching Views for a Given URL +----------------------------------------------------- + +.. seealso:: See also the output of :ref:`pviews --help <pviews_script>`. For a big application with several views, it can be hard to keep the view -configuration details in your head, even if you defined all the views -yourself. You can use the ``pviews`` command in a terminal window to -print a summary of matching routes and views for a given URL in your -application. The ``pviews`` command accepts two arguments. The first -argument to ``pviews`` is the path to your application's ``.ini`` file and -section name inside the ``.ini`` file which points to your application. This -should be of the format ``config_file#section_name``. The second argument is -the URL to test for matching views. The ``section_name`` may be omitted; if -it is, it's considered to be ``main``. +configuration details in your head, even if you defined all the views yourself. +You can use the ``pviews`` command in a terminal window to print a summary of +matching routes and views for a given URL in your application. The ``pviews`` +command accepts two arguments. The first argument to ``pviews`` is the path to +your application's ``.ini`` file and section name inside the ``.ini`` file +which points to your application. This should be of the format +``config_file#section_name``. The second argument is the URL to test for +matching views. The ``section_name`` may be omitted; if it is, it's considered +to be ``main``. Here is an example for a simple view configuration using :term:`traversal`: -.. code-block:: text - :linenos: +.. code-block:: bash + :linenos: - $ $VENV/bin/pviews development.ini#tutorial /FrontPage + $VENV/bin/pviews development.ini#tutorial /FrontPage - URL = /FrontPage + URL = /FrontPage - context: <tutorial.models.Page object at 0xa12536c> - view name: + context: <tutorial.models.Page object at 0xa12536c> + view name: - View: - ----- - tutorial.views.view_page - required permission = view + View: + ----- + tutorial.views.view_page + required permission = view -The output always has the requested URL at the top and below that all the -views that matched with their view configuration details. In this example -only one view matches, so there is just a single *View* section. For each -matching view, the full code path to the associated view callable is shown, -along with any permissions and predicates that are part of that view -configuration. +The output always has the requested URL at the top and below that all the views +that matched with their view configuration details. In this example only one +view matches, so there is just a single *View* section. For each matching view, +the full code path to the associated view callable is shown, along with any +permissions and predicates that are part of that view configuration. A more complex configuration might generate something like this: -.. code-block:: text - :linenos: - - $ $VENV/bin/pviews development.ini#shootout /about - - URL = /about - - context: <shootout.models.RootFactory object at 0xa56668c> - view name: about - - Route: - ------ - route name: about - route pattern: /about - route path: /about - subpath: - route predicates (request method = GET) - - View: - ----- - shootout.views.about_view - required permission = view - view predicates (request_param testing, header X/header) - - Route: - ------ - route name: about_post - route pattern: /about - route path: /about - subpath: - route predicates (request method = POST) - - View: - ----- - shootout.views.about_view_post - required permission = view - view predicates (request_param test) - - View: - ----- - shootout.views.about_view_post2 - required permission = view - view predicates (request_param test2) +.. code-block:: bash + :linenos: + + $VENV/bin/pviews development.ini#shootout /about + + URL = /about + + context: <shootout.models.RootFactory object at 0xa56668c> + view name: about + + Route: + ------ + route name: about + route pattern: /about + route path: /about + subpath: + route predicates (request method = GET) + + View: + ----- + shootout.views.about_view + required permission = view + view predicates (request_param testing, header X/header) + + Route: + ------ + route name: about_post + route pattern: /about + route path: /about + subpath: + route predicates (request method = POST) + + View: + ----- + shootout.views.about_view_post + required permission = view + view predicates (request_param test) + + View: + ----- + shootout.views.about_view_post2 + required permission = view + view predicates (request_param test2) In this case, we are dealing with a :term:`URL dispatch` application. This specific URL has two matching routes. The matching route information is -displayed first, followed by any views that are associated with that route. -As you can see from the second matching route output, a route can be -associated with more than one view. +displayed first, followed by any views that are associated with that route. As +you can see from the second matching route output, a route can be associated +with more than one view. -For a URL that doesn't match any views, ``pviews`` will simply print out a -*Not found* message. +For a URL that doesn't match any views, ``pviews`` will simply print out a *Not +found* message. .. index:: single: interactive shell - single: IPython single: pshell - single: bpython .. _interactive_shell: -The Interactive Shell ---------------------- +``pshell``: The Interactive Shell +--------------------------------- + +.. seealso:: See also the output of :ref:`pshell --help <pshell_script>`. -Once you've installed your program for development using ``setup.py -develop``, you can use an interactive Python shell to execute expressions in -a Python environment exactly like the one that will be used when your -application runs "for real". To do so, use the ``pshell`` command line -utility. +Once you've installed your program for development using ``pip install -e .``, +you can use an interactive Python shell to execute expressions in a Python +environment exactly like the one that will be used when your application runs +"for real". To do so, use the ``pshell`` command line utility. The argument to ``pshell`` follows the format ``config_file#section_name`` where ``config_file`` is the path to your application's ``.ini`` file and ``section_name`` is the ``app`` section name inside the ``.ini`` file which -points to your application. For example, if your application ``.ini`` file -might have a ``[app:main]`` section that looks like so: +points to your application. For example, your application ``.ini`` file might +have an ``[app:main]`` section that looks like so: .. code-block:: ini - :linenos: + :linenos: - [app:main] - use = egg:MyProject - pyramid.reload_templates = true - pyramid.debug_authorization = false - pyramid.debug_notfound = false - pyramid.debug_templates = true - pyramid.default_locale_name = en + [app:main] + use = egg:MyProject + pyramid.reload_templates = true + pyramid.debug_authorization = false + pyramid.debug_notfound = false + pyramid.debug_templates = true + pyramid.default_locale_name = en -If so, you can use the following command to invoke a debug shell using the -name ``main`` as a section name: +If so, you can use the following command to invoke a debug shell using the name +``main`` as a section name: -.. code-block:: text +.. code-block:: bash - $ $VENV/bin starter/development.ini#main - Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) + $VENV/bin/pshell starter/development.ini#main + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -172,19 +231,19 @@ name ``main`` as a section name: The WSGI application that is loaded will be available in the shell as the ``app`` global. Also, if the application that is loaded is the :app:`Pyramid` -app with no surrounding :term:`middleware`, the ``root`` object returned by -the default :term:`root factory`, ``registry``, and ``request`` will be -available. +app with no surrounding :term:`middleware`, the ``root`` object returned by the +default :term:`root factory`, ``registry``, and ``request`` will be available. You can also simply rely on the ``main`` default section name by omitting any hash after the filename: -.. code-block:: text +.. code-block:: bash - $ $VENV/bin/pshell starter/development.ini + $VENV/bin/pshell starter/development.ini Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). + .. index:: pair: pshell; extending @@ -193,59 +252,69 @@ Press ``Ctrl-D`` to exit the interactive shell (or ``Ctrl-Z`` on Windows). Extending the Shell ~~~~~~~~~~~~~~~~~~~ -It is convenient when using the interactive shell often to have some -variables significant to your application already loaded as globals when -you start the ``pshell``. To facilitate this, ``pshell`` will look for a -special ``[pshell]`` section in your INI file and expose the subsequent -key/value pairs to the shell. Each key is a variable name that will be -global within the pshell session; each value is a :term:`dotted Python name`. -If specified, the special key ``setup`` should be a :term:`dotted Python name` -pointing to a callable that accepts the dictionary of globals that will -be loaded into the shell. This allows for some custom initializing code -to be executed each time the ``pshell`` is run. The ``setup`` callable -can also be specified from the commandline using the ``--setup`` option -which will override the key in the INI file. - -For example, you want to expose your model to the shell, along with the -database session so that you can mutate the model on an actual database. -Here, we'll assume your model is stored in the ``myapp.models`` package. +It is convenient when using the interactive shell often to have some variables +significant to your application already loaded as globals when you start the +``pshell``. To facilitate this, ``pshell`` will look for a special ``[pshell]`` +section in your ``.ini`` file and expose the subsequent key/value pairs to the +shell. Each key is a variable name that will be global within the pshell +session; each value is a :term:`dotted Python name`. If specified, the special +key ``setup`` should be a :term:`dotted Python name` pointing to a callable +that accepts the dictionary of globals that will be loaded into the shell. This +allows for some custom initializing code to be executed each time the +``pshell`` is run. The ``setup`` callable can also be specified from the +commandline using the ``--setup`` option which will override the key in the ``.ini`` +file. + +For example, you want to expose your model to the shell along with the database +session so that you can mutate the model on an actual database. Here, we'll +assume your model is stored in the ``myapp.models`` package and that you're +using ``pyramid_tm`` to configure a transaction manager on the request as +``request.tm``. .. code-block:: ini - :linenos: + :linenos: - [pshell] - setup = myapp.lib.pshell.setup - m = myapp.models - session = myapp.models.DBSession - t = transaction + [pshell] + setup = myapp.lib.pshell.setup + models = myapp.models -By defining the ``setup`` callable, we will create the module -``myapp.lib.pshell`` containing a callable named ``setup`` that will receive -the global environment before it is exposed to the shell. Here we mutate the -environment's request as well as add a new value containing a WebTest version -of the application to which we can easily submit requests. +By defining the ``setup`` callable, we will create the module ``myapp.lib.pshell`` containing a callable named ``setup`` that will receive the global environment before it is exposed to the shell. Here we mutate the environment's request as well as add a new value containing a WebTest version of the application to which we can easily submit requests. The ``setup`` callable can also be a generator which can wrap the entire shell lifecycle, executing code when the shell exits. .. code-block:: python :linenos: # myapp/lib/pshell.py + from contextlib import suppress + from transaction.interfaces import NoTransaction from webtest import TestApp def setup(env): - env['request'].host = 'www.example.com' - env['request'].scheme = 'https' + request = env['request'] + request.host = 'www.example.com' + request.scheme = 'https' + env['testapp'] = TestApp(env['app']) -When this INI file is loaded, the extra variables ``m``, ``session`` and -``t`` will be available for use immediately. Since a ``setup`` callable -was also specified, it is executed and a new variable ``testapp`` is -exposed, and the request is configured to generate urls from the host -``http://www.example.com``. For example: + # start a transaction which can be used in the shell + request.tm.begin() + + # if using the SQLAlchemy backend from our cookiecutter, the dbsession is + # connected to the transaction manager above + env['tm'] = request.tm + env['dbsession'] = request.dbsession + try: + yield -.. code-block:: text + finally: + with suppress(NoTransaction): + request.tm.abort() - $ $VENV/bin/pshell starter/development.ini - Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) +When this ``.ini`` file is loaded, the extra variable ``models`` will be available for use immediately. Since a ``setup`` callable was also specified, it is executed and new variables ``testapp``, ``tm``, and ``dbsession`` are exposed, and the request is configured to generate URLs from the host ``http://www.example.com``. For example: + +.. code-block:: bash + + $VENV/bin/pshell starter/development.ini + Python 2.6.5 (r265:79063, Apr 29 2010, 00:31:32) [GCC 4.4.3] on linux2 Type "help" for more information. @@ -258,35 +327,94 @@ exposed, and the request is configured to generate urls from the host testapp <webtest.TestApp object at ...> Custom Variables: - m myapp.models - session myapp.models.DBSession - t transaction + dbsession + model myapp.models + tm >>> testapp.get('/') <200 OK text/html body='<!DOCTYPE...l>\n'/3337> >>> request.route_url('home') 'https://www.example.com/' + >>> user = dbsession.query(models.User).get(1) + >>> user.name = 'Joe' + >>> tm.commit() + >>> tm.begin() + >>> user = dbsession.query(models.User).get(1) + >>> user.name == 'Joe' + 'Joe' -.. index:: - single: IPython - single: bpython .. _ipython_or_bpython: -IPython or bpython +Alternative Shells ~~~~~~~~~~~~~~~~~~ -If you have `IPython <http://en.wikipedia.org/wiki/IPython>`_ and/or -`bpython <http://bpython-interpreter.org/>`_ in -the interpreter you use to invoke the ``pshell`` command, ``pshell`` will -autodiscover and use the first one found, in this order: -IPython, bpython, standard Python interpreter. However you could -specifically invoke one of your choice with the ``-p choice`` or +The ``pshell`` command can be easily extended with alternate REPLs if the +default python REPL is not satisfactory. Assuming you have a binding +installed such as ``pyramid_ipython`` it will normally be auto-selected and +used. You may also specifically invoke your choice with the ``-p choice`` or ``--python-shell choice`` option. -.. code-block:: text +.. code-block:: bash + + $VENV/bin/pshell -p ipython development.ini#MyProject + +You may use the ``--list-shells`` option to see the available shells. + +.. code-block:: bash + + $VENV/bin/pshell --list-shells + Available shells: + bpython + ipython + python + +If you want to use a shell that isn't supported out of the box, you can +introduce a new shell by registering an entry point in your ``setup.py``: + +.. code-block:: python + + setup( + entry_points={ + 'pyramid.pshell_runner': [ + 'myshell=my_app:ptpython_shell_factory', + ], + }, + ) + +And then your shell factory should return a function that accepts two +arguments, ``env`` and ``help``, which would look like this: + +.. code-block:: python + + from ptpython.repl import embed + + def ptpython_shell_runner(env, help): + print(help) + return embed(locals=env) + +.. versionchanged:: 1.6 + User-defined shells may be registered using entry points. Prior to this + the only supported shells were ``ipython``, ``bpython`` and ``python``. + + ``ipython`` and ``bpython`` have been moved into their respective + packages ``pyramid_ipython`` and ``pyramid_bpython``. + + +Setting a Default Shell +~~~~~~~~~~~~~~~~~~~~~~~ + +You may use the ``default_shell`` option in your ``[pshell]`` ini section to +specify a list of preferred shells. + +.. code-block:: ini + :linenos: + + [pshell] + default_shell = ptpython ipython bpython + +.. versionadded:: 1.6 - $ $VENV/bin/pshell -p ipython | bpython | python development.ini#MyProject .. index:: pair: routes; printing @@ -294,41 +422,82 @@ specifically invoke one of your choice with the ``-p choice`` or .. _displaying_application_routes: -Displaying All Application Routes ---------------------------------- +``proutes``: Displaying All Application Routes +---------------------------------------------- -You can use the ``proutes`` command in a terminal window to print a summary -of routes related to your application. Much like the ``pshell`` -command (see :ref:`interactive_shell`), the ``proutes`` command -accepts one argument with the format ``config_file#section_name``. The -``config_file`` is the path to your application's ``.ini`` file, and -``section_name`` is the ``app`` section name inside the ``.ini`` file which -points to your application. By default, the ``section_name`` is ``main`` and -can be omitted. +.. seealso:: See also the output of :ref:`proutes --help <proutes_script>`. + +You can use the ``proutes`` command in a terminal window to print a summary of +routes related to your application. Much like the ``pshell`` command (see +:ref:`interactive_shell`), the ``proutes`` command accepts one argument with +the format ``config_file#section_name``. The ``config_file`` is the path to +your application's ``.ini`` file, and ``section_name`` is the ``app`` section +name inside the ``.ini`` file which points to your application. By default, +the ``section_name`` is ``main`` and can be omitted. For example: -.. code-block:: text - :linenos: - - $ $VENV/bin/proutes development.ini - Name Pattern View - ---- ------- ---- - home / <function my_view> - home2 / <function my_view> - another /another None - static/ static/*subpath <static_view object> - catchall /*subpath <function static_view> - -``proutes`` generates a table with three columns: *Name*, *Pattern*, -and *View*. The items listed in the -Name column are route names, the items listed in the Pattern column are route -patterns, and the items listed in the View column are representations of the -view callable that will be invoked when a request matches the associated -route pattern. The view column may show ``None`` if no associated view -callable could be found. If no routes are configured within your -application, nothing will be printed to the console when ``proutes`` -is executed. +.. code-block:: bash + :linenos: + + $VENV/bin/proutes development.ini + Name Pattern View Method + ---- ------- ---- ------ + debugtoolbar /_debug_toolbar/*subpath <wsgiapp> * + __static/ /static/*subpath dummy_starter:static/ * + __static2/ /static2/*subpath /var/www/static/ * + __pdt_images/ /pdt_images/*subpath pyramid_debugtoolbar:static/img/ * + a / <unknown> * + no_view_attached / <unknown> * + route_and_view_attached / app1.standard_views.route_and_view_attached * + method_conflicts /conflicts app1.standard_conflicts <route mismatch> + multiview /multiview app1.standard_views.multiview GET,PATCH + not_post /not_post app1.standard_views.multview !POST,* + +``proutes`` generates a table with four columns: *Name*, *Pattern*, *View*, and +*Method*. The items listed in the Name column are route names, the items +listed in the Pattern column are route patterns, the items listed in the View +column are representations of the view callable that will be invoked when a +request matches the associated route pattern, and the items listed in the +Method column are the request methods that are associated with the route name. +The View column may show ``<unknown>`` if no associated view callable could be +found. The Method column, for the route name, may show either ``<route +mismatch>`` if the view callable does not accept any of the route's request +methods, or ``*`` if the view callable will accept any of the route's request +methods. If no routes are configured within your application, nothing will be +printed to the console when ``proutes`` is executed. + +It is convenient when using the ``proutes`` command often to configure which +columns and the order you would like to view them. To facilitate this, +``proutes`` will look for a special ``[proutes]`` section in your ``.ini`` file +and use those as defaults. + +For example you may remove the request method and place the view first: + +.. code-block:: ini + :linenos: + + [proutes] + format = view + name + pattern + +You can also separate the formats with commas or spaces: + +.. code-block:: ini + :linenos: + + [proutes] + format = view name pattern + + [proutes] + format = view, name, pattern + +If you want to temporarily configure the columns and order, there is the +argument ``--format``, which is a comma separated list of columns you want to +include. The current available formats are ``name``, ``pattern``, ``view``, and +``method``. + .. index:: pair: tweens; printing @@ -336,220 +505,238 @@ is executed. .. _displaying_tweens: -Displaying "Tweens" -------------------- +``ptweens``: Displaying "Tweens" +-------------------------------- -A :term:`tween` is a bit of code that sits between the main Pyramid -application request handler and the WSGI application which calls it. A user -can get a representation of both the implicit tween ordering (the ordering -specified by calls to :meth:`pyramid.config.Configurator.add_tween`) and the -explicit tween ordering (specified by the ``pyramid.tweens`` configuration -setting) orderings using the ``ptweens`` command. Tween factories -will show up represented by their standard Python dotted name in the -``ptweens`` output. +.. seealso:: See also the output of :ref:`ptweens --help <ptweens_script>`. -For example, here's the ``ptweens`` command run against a system -configured without any explicit tweens: +A :term:`tween` is a bit of code that sits between the main Pyramid application +request handler and the WSGI application which calls it. A user can get a +representation of both the implicit tween ordering (the ordering specified by +calls to :meth:`pyramid.config.Configurator.add_tween`) and the explicit tween +ordering (specified by the ``pyramid.tweens`` configuration setting) using the +``ptweens`` command. Tween factories will show up represented by their +standard Python dotted name in the ``ptweens`` output. -.. code-block:: text - :linenos: +For example, here's the ``ptweens`` command run against a system configured +without any explicit tweens: - $ $VENV/bin/ptweens development.ini - "pyramid.tweens" config value NOT set (implicitly ordered tweens used) +.. code-block:: bash + :linenos: + + $VENV/bin/ptweens development.ini + "pyramid.tweens" config value NOT set (implicitly ordered tweens used) - Implicit Tween Chain + Implicit Tween Chain - Position Name Alias - -------- ---- ----- - - - INGRESS - 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory pdbt - 1 pyramid.tweens.excview_tween_factory excview - - - MAIN + Position Name Alias + -------- ---- ----- + - - INGRESS + 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory pdbt + 1 pyramid.tweens.excview_tween_factory excview + - - MAIN -Here's the ``ptweens`` command run against a system configured *with* -explicit tweens defined in its ``development.ini`` file: +Here's the ``ptweens`` command run against a system configured *with* explicit +tweens defined in its ``development.ini`` file: -.. code-block:: text - :linenos: +.. code-block:: bash + :linenos: - $ ptweens development.ini - "pyramid.tweens" config value set (explicitly ordered tweens used) + $VENV/bin/ptweens development.ini + "pyramid.tweens" config value set (explicitly ordered tweens used) - Explicit Tween Chain (used) + Explicit Tween Chain (used) - Position Name - -------- ---- - - INGRESS - 0 starter.tween_factory2 - 1 starter.tween_factory1 - 2 pyramid.tweens.excview_tween_factory - - MAIN + Position Name + -------- ---- + - INGRESS + 0 starter.tween_factory2 + 1 starter.tween_factory1 + 2 pyramid.tweens.excview_tween_factory + - MAIN - Implicit Tween Chain (not used) + Implicit Tween Chain (not used) - Position Name - -------- ---- - - INGRESS - 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory - 1 pyramid.tweens.excview_tween_factory - - MAIN + Position Name + -------- ---- + - INGRESS + 0 pyramid_debugtoolbar.toolbar.toolbar_tween_factory + 1 pyramid.tweens.excview_tween_factory + - MAIN -Here's the application configuration section of the ``development.ini`` used -by the above ``ptweens`` command which reports that the explicit tween chain -is used: +Here's the application configuration section of the ``development.ini`` used by +the above ``ptweens`` command which reports that the explicit tween chain is +used: .. code-block:: ini - :linenos: - - [app:main] - use = egg:starter - reload_templates = true - debug_authorization = false - debug_notfound = false - debug_routematch = false - debug_templates = true - default_locale_name = en - pyramid.include = pyramid_debugtoolbar - pyramid.tweens = starter.tween_factory2 - starter.tween_factory1 - pyramid.tweens.excview_tween_factory + :linenos: + + [app:main] + use = egg:starter + reload_templates = true + debug_authorization = false + debug_notfound = false + debug_routematch = false + debug_templates = true + default_locale_name = en + pyramid.include = pyramid_debugtoolbar + pyramid.tweens = starter.tween_factory2 + starter.tween_factory1 + pyramid.tweens.excview_tween_factory See :ref:`registering_tweens` for more information about tweens. + .. index:: single: invoking a request single: prequest .. _invoking_a_request: -Invoking a Request ------------------- +``prequest``: Invoking a Request +-------------------------------- + +.. seealso:: See also the output of :ref:`prequest --help <prequest_script>`. You can use the ``prequest`` command-line utility to send a request to your application and see the response body without starting a server. There are two required arguments to ``prequest``: -- The config file/section: follows the format ``config_file#section_name`` +- The config file/section: follows the format ``config_file#section_name``, where ``config_file`` is the path to your application's ``.ini`` file and ``section_name`` is the ``app`` section name inside the ``.ini`` file. The - ``section_name`` is optional, it defaults to ``main``. For example: + ``section_name`` is optional; it defaults to ``main``. For example: ``development.ini``. -- The path: this should be the non-url-quoted path element of the URL to the +- The path: this should be the non-URL-quoted path element of the URL to the resource you'd like to be rendered on the server. For example, ``/``. -For example:: +For example: + +.. code-block:: bash - $ $VENV/bin/prequest development.ini / + $VENV/bin/prequest development.ini / This will print the body of the response to the console on which it was invoked. -Several options are supported by ``prequest``. These should precede any -config file name or URL. +Several options are supported by ``prequest``. These should precede any config +file name or URL. -``prequest`` has a ``-d`` (aka ``--display-headers``) option which prints the -status and headers returned by the server before the output:: +``prequest`` has a ``-d`` (i.e., ``--display-headers``) option which prints the +status and headers returned by the server before the output: - $ $VENV/bin/prequest -d development.ini / +.. code-block:: bash -This will print the status, then the headers, then the body of the response -to the console. + $VENV/bin/prequest -d development.ini / -You can add request header values by using the ``--header`` option:: +This will print the status, headers, and the body of the response to the +console. - $ $VENV/bin/prequest --header=Host:example.com development.ini / +You can add request header values by using the ``--header`` option: -Headers are added to the WSGI environment by converting them to their -CGI/WSGI equivalents (e.g. ``Host=example.com`` will insert the ``HTTP_HOST`` -header variable as the value ``example.com``). Multiple ``--header`` options -can be supplied. The special header value ``content-type`` sets the -``CONTENT_TYPE`` in the WSGI environment. +.. code-block:: bash -By default, ``prequest`` sends a ``GET`` request. You can change this by -using the ``-m`` (aka ``--method``) option. ``GET``, ``HEAD``, ``POST`` and -``DELETE`` are currently supported. When you use ``POST``, the standard -input of the ``prequest`` process is used as the ``POST`` body:: + $VENV/bin/prequest --header=Host:example.com development.ini / - $ $VENV/bin/prequest -mPOST development.ini / < somefile +Headers are added to the WSGI environment by converting them to their CGI/WSGI +equivalents (e.g., ``Host=example.com`` will insert the ``HTTP_HOST`` header +variable as the value ``example.com``). Multiple ``--header`` options can be +supplied. The special header value ``content-type`` sets the ``CONTENT_TYPE`` +in the WSGI environment. -Using Custom Arguments to Python when Running ``p*`` Scripts ------------------------------------------------------------- +By default, ``prequest`` sends a ``GET`` request. You can change this by using +the ``-m`` (aka ``--method``) option. ``GET``, ``HEAD``, ``POST``, and +``DELETE`` are currently supported. When you use ``POST``, the standard input +of the ``prequest`` process is used as the ``POST`` body: -.. versionadded:: 1.5 +.. code-block:: bash -Each of Pyramid's console scripts (``pserve``, ``pviews``, etc) can be run -directly using ``python -m``, allowing custom arguments to be sent to the -python interpreter at runtime. For example:: + $VENV/bin/prequest -mPOST development.ini / < somefile - python -3 -m pyramid.scripts.pserve development.ini -Showing All Installed Distributions and their Versions ------------------------------------------------------- +.. index:: + single: pdistreport + single: distributions, showing installed + single: showing installed distributions + +.. _showing_distributions: + +``pdistreport``: Showing All Installed Distributions and Their Versions +----------------------------------------------------------------------- .. versionadded:: 1.5 -You can use the ``pdistreport`` command to show the Pyramid version in use, the -Python version in use, and all installed versions of Python distributions in -your Python environment:: +.. seealso:: See also the output of :ref:`pdistreport --help + <pdistreport_script>`. + +You can use the ``pdistreport`` command to show the :app:`Pyramid` version in +use, the Python version in use, and all installed versions of Python +distributions in your Python environment: - $ $VENV/bin/pdistreport - Pyramid version: 1.5dev - Platform Linux-3.2.0-51-generic-x86_64-with-debian-wheezy-sid - Packages: - authapp 0.0 - /home/chrism/projects/foo/src/authapp - beautifulsoup4 4.1.3 - /home/chrism/projects/foo/lib/python2.7/site-packages/beautifulsoup4-4.1.3-py2.7.egg - ... more output ... +.. code-block:: bash + + $VENV/bin/pdistreport + Pyramid version: 1.5dev + Platform Linux-3.2.0-51-generic-x86_64-with-debian-wheezy-sid + Packages: + authapp 0.0 + /home/chrism/projects/foo/src/authapp + beautifulsoup4 4.1.3 + /home/chrism/projects/foo/lib/python2.7/site-packages/beautifulsoup4-4.1.3-py2.7.egg + # ... more output ... ``pdistreport`` takes no options. Its output is useful to paste into a pastebin when you are having problems and need someone with more familiarity with Python packaging and distribution than you have to look at your environment. + .. _writing_a_script: Writing a Script ---------------- All web applications are, at their hearts, systems which accept a request and -return a response. When a request is accepted by a :app:`Pyramid` -application, the system receives state from the request which is later relied -on by your application code. For example, one :term:`view callable` may assume -it's working against a request that has a ``request.matchdict`` of a -particular composition, while another assumes a different composition of the -matchdict. +return a response. When a request is accepted by a :app:`Pyramid` application, +the system receives state from the request which is later relied on by your +application code. For example, one :term:`view callable` may assume it's +working against a request that has a ``request.matchdict`` of a particular +composition, while another assumes a different composition of the matchdict. In the meantime, it's convenient to be able to write a Python script that can -work "in a Pyramid environment", for instance to update database tables used -by your :app:`Pyramid` application. But a "real" Pyramid environment doesn't -have a completely static state independent of a request; your application -(and Pyramid itself) is almost always reliant on being able to obtain -information from a request. When you run a Python script that simply imports -code from your application and tries to run it, there just is no request -data, because there isn't any real web request. Therefore some parts of your -application and some Pyramid APIs will not work. +work "in a Pyramid environment", for instance to update database tables used by +your :app:`Pyramid` application. But a "real" Pyramid environment doesn't have +a completely static state independent of a request; your application (and +Pyramid itself) is almost always reliant on being able to obtain information +from a request. When you run a Python script that simply imports code from +your application and tries to run it, there just is no request data, because +there isn't any real web request. Therefore some parts of your application and +some Pyramid APIs will not work. For this reason, :app:`Pyramid` makes it possible to run a script in an environment much like the environment produced when a particular :term:`request` reaches your :app:`Pyramid` application. This is achieved by -using the :func:`pyramid.paster.bootstrap` command in the body of your -script. +using the :func:`pyramid.paster.bootstrap` command in the body of your script. .. versionadded:: 1.1 :func:`pyramid.paster.bootstrap` +.. versionchanged:: 1.8 + Added the ability for ``bootstrap`` to cleanup automatically via the + ``with`` statement. + In the simplest case, :func:`pyramid.paster.bootstrap` can be used with a single argument, which accepts the :term:`PasteDeploy` ``.ini`` file -representing Pyramid your application configuration as a single argument: +representing your Pyramid application's configuration as a single argument: .. code-block:: python - from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini') - print(env['request'].route_url('home')) + from pyramid.paster import bootstrap + + with bootstrap('/path/to/my/development.ini') as env: + print(env['request'].route_url('home')) :func:`pyramid.paster.bootstrap` returns a dictionary containing framework-related information. This dictionary will always contain a @@ -579,58 +766,59 @@ registry closer - A parameterless callable that can be used to pop an internal - :app:`Pyramid` threadlocal stack (used by - :func:`pyramid.threadlocal.get_current_registry` and - :func:`pyramid.threadlocal.get_current_request`) when your scripting job - is finished. + A parameterless callable that can be used to pop an internal :app:`Pyramid` + threadlocal stack (used by :func:`pyramid.threadlocal.get_current_registry` + and :func:`pyramid.threadlocal.get_current_request`) when your scripting + job is finished. -Let's assume that the ``/path/to/my/development.ini`` file used in the -example above looks like so: +Let's assume that the ``/path/to/my/development.ini`` file used in the example +above looks like so: .. code-block:: ini - [pipeline:main] - pipeline = translogger - another + [pipeline:main] + pipeline = translogger + another - [filter:translogger] - filter_app_factory = egg:Paste#translogger - setup_console_handler = False - logger_name = wsgi + [filter:translogger] + filter_app_factory = egg:Paste#translogger + setup_console_handler = False + logger_name = wsgi - [app:another] - use = egg:MyProject + [app:another] + use = egg:MyProject The configuration loaded by the above bootstrap example will use the -configuration implied by the ``[pipeline:main]`` section of your -configuration file by default. Specifying ``/path/to/my/development.ini`` is -logically equivalent to specifying ``/path/to/my/development.ini#main``. In -this case, we'll be using a configuration that includes an ``app`` object -which is wrapped in the Paste "translogger" :term:`middleware` (which logs -requests to the console). +configuration implied by the ``[pipeline:main]`` section of your configuration +file by default. Specifying ``/path/to/my/development.ini`` is logically +equivalent to specifying ``/path/to/my/development.ini#main``. In this case, +we'll be using a configuration that includes an ``app`` object which is wrapped +in the Paste "translogger" :term:`middleware` (which logs requests to the +console). -You can also specify a particular *section* of the PasteDeploy ``.ini`` file -to load instead of ``main``: +You can also specify a particular *section* of the PasteDeploy ``.ini`` file to +load instead of ``main``: .. code-block:: python - from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini#another') - print(env['request'].route_url('home')) + from pyramid.paster import bootstrap + + with bootstrap('/path/to/my/development.ini#another') as env: + print(env['request'].route_url('home')) The above example specifies the ``another`` ``app``, ``pipeline``, or ``composite`` section of your PasteDeploy configuration file. The ``app`` object present in the ``env`` dictionary returned by :func:`pyramid.paster.bootstrap` will be a :app:`Pyramid` :term:`router`. + Changing the Request ~~~~~~~~~~~~~~~~~~~~ By default, Pyramid will generate a request object in the ``env`` dictionary -for the URL ``http://localhost:80/``. This means that any URLs generated -by Pyramid during the execution of your script will be anchored here. This -is generally not what you want. +for the URL ``http://localhost:80/``. This means that any URLs generated by +Pyramid during the execution of your script will be anchored here. This is +generally not what you want. So how do we make Pyramid generate the correct URLs? @@ -638,46 +826,50 @@ Assuming that you have a route configured in your application like so: .. code-block:: python - config.add_route('verify', '/verify/{code}') + config.add_route('verify', '/verify/{code}') You need to inform the Pyramid environment that the WSGI application is handling requests from a certain base. For example, we want to simulate -mounting our application at `https://example.com/prefix`, to ensure that -the generated URLs are correct for our deployment. This can be done by -either mutating the resulting request object, or more simply by constructing -the desired request and passing it into :func:`~pyramid.paster.bootstrap`: +mounting our application at `https://example.com/prefix`, to ensure that the +generated URLs are correct for our deployment. This can be done by either +mutating the resulting request object, or more simply by constructing the +desired request and passing it into :func:`~pyramid.paster.bootstrap`: .. code-block:: python - from pyramid.paster import bootstrap - from pyramid.request import Request + from pyramid.paster import bootstrap + from pyramid.request import Request - request = Request.blank('/', base_url='https://example.com/prefix') - env = bootstrap('/path/to/my/development.ini#another', request=request) - print(env['request'].application_url) - # will print 'https://example.com/prefix' + request = Request.blank('/', base_url='https://example.com/prefix') + with bootstrap('/path/to/my/development.ini#another', request=request) as env: + print(env['request'].application_url) + # will print 'https://example.com/prefix' Now you can readily use Pyramid's APIs for generating URLs: .. code-block:: python - env['request'].route_url('verify', code='1337') - # will return 'https://example.com/prefix/verify/1337' + env['request'].route_url('verify', code='1337') + # will return 'https://example.com/prefix/verify/1337' + Cleanup ~~~~~~~ -When your scripting logic finishes, it's good manners to call the ``closer`` +If you're using the ``with``-statement variant then there's nothing to +worry about. However if you're using the returned environment directly then +when your scripting logic finishes, it's good manners to call the ``closer`` callback: .. code-block:: python - from pyramid.paster import bootstrap - env = bootstrap('/path/to/my/development.ini') + from pyramid.paster import bootstrap + env = bootstrap('/path/to/my/development.ini') - # .. do stuff ... + # .. do stuff ... + + env['closer']() - env['closer']() Setting Up Logging ~~~~~~~~~~~~~~~~~~ @@ -689,12 +881,13 @@ use the following command: .. code-block:: python - import pyramid.paster - pyramid.paster.setup_logging('/path/to/my/development.ini') + import pyramid.paster + pyramid.paster.setup_logging('/path/to/my/development.ini') See :ref:`logging_chapter` for more information on logging within :app:`Pyramid`. + .. index:: single: console script @@ -703,93 +896,89 @@ See :ref:`logging_chapter` for more information on logging within Making Your Script into a Console Script ---------------------------------------- -A "console script" is :term:`setuptools` terminology for a script that gets -installed into the ``bin`` directory of a Python :term:`virtualenv` (or -"base" Python environment) when a :term:`distribution` which houses that -script is installed. Because it's installed into the ``bin`` directory of a -virtualenv when the distribution is installed, it's a convenient way to -package and distribute functionality that you can call from the command-line. -It's often more convenient to create a console script than it is to create a -``.py`` script and instruct people to call it with the "right" Python -interpreter. A console script generates a file that lives in ``bin``, and when it's -invoked it will always use the "right" Python environment, which means it -will always be invoked in an environment where all the libraries it needs -(such as Pyramid) are available. +A "console script" is :term:`Setuptools` terminology for a script that gets +installed into the ``bin`` directory of a Python :term:`virtual environment` +(or "base" Python environment) when a :term:`distribution` which houses that +script is installed. Because it's installed into the ``bin`` directory of a +virtual environment when the distribution is installed, it's a convenient way +to package and distribute functionality that you can call from the +command-line. It's often more convenient to create a console script than it is +to create a ``.py`` script and instruct people to call it with the "right" +Python interpreter. A console script generates a file that lives in ``bin``, +and when it's invoked it will always use the "right" Python environment, which +means it will always be invoked in an environment where all the libraries it +needs (such as Pyramid) are available. In general, you can make your script into a console script by doing the following: - Use an existing distribution (such as one you've already created via - ``pcreate``) or create a new distribution that possesses at least one - package or module. It should, within any module within the distribution, - house a callable (usually a function) that takes no arguments and which - runs any of the code you wish to run. + ``cookiecutter``) or create a new distribution that possesses at least one package + or module. It should, within any module within the distribution, house a + callable (usually a function) that takes no arguments and which runs any of + the code you wish to run. - Add a ``[console_scripts]`` section to the ``entry_points`` argument of the - distribution which creates a mapping between a script name and a dotted - name representing the callable you added to your distribution. + distribution which creates a mapping between a script name and a dotted name + representing the callable you added to your distribution. -- Run ``setup.py develop``, ``setup.py install``, or ``easy_install`` to get - your distribution reinstalled. When you reinstall your distribution, a - file representing the script that you named in the last step will be in the - ``bin`` directory of the virtualenv in which you installed the - distribution. It will be executable. Invoking it from a terminal will - execute your callable. +- Run ``pip install -e .`` or ``pip install .`` to get your distribution + reinstalled. When you reinstall your distribution, a file representing the + script that you named in the last step will be in the ``bin`` directory of + the virtual environment in which you installed the distribution. It will be + executable. Invoking it from a terminal will execute your callable. As an example, let's create some code that can be invoked by a console script -that prints the deployment settings of a Pyramid application. To do so, -we'll pretend you have a distribution with a package in it named -``myproject``. Within this package, we'll pretend you've added a -``scripts.py`` module which contains the following code: +that prints the deployment settings of a Pyramid application. To do so, we'll +pretend you have a distribution with a package in it named ``myproject``. +Within this package, we'll pretend you've added a ``scripts.py`` module which +contains the following code: .. code-block:: python - :linenos: - - # myproject.scripts module - - import optparse - import sys - import textwrap - - from pyramid.paster import bootstrap - - def settings_show(): - description = """\ - Print the deployment settings for a Pyramid application. Example: - 'show_settings deployment.ini' - """ - usage = "usage: %prog config_uri" - parser = optparse.OptionParser( - usage=usage, - description=textwrap.dedent(description) - ) - parser.add_option( - '-o', '--omit', - dest='omit', - metavar='PREFIX', - type='string', - action='append', - help=("Omit settings which start with PREFIX (you can use this " - "option multiple times)") - ) - - options, args = parser.parse_args(sys.argv[1:]) - if not len(args) >= 1: - print('You must provide at least one argument') - return 2 - config_uri = args[0] - omit = options.omit - if omit is None: - omit = [] - env = bootstrap(config_uri) - settings, closer = env['registry'].settings, env['closer'] - try: - for k, v in settings.items(): - if any([k.startswith(x) for x in omit]): - continue - print('%-40s %-20s' % (k, v)) - finally: - closer() + :linenos: + + # myproject.scripts module + + import optparse + import sys + import textwrap + + from pyramid.paster import bootstrap + + def settings_show(): + description = """\ + Print the deployment settings for a Pyramid application. Example: + 'show_settings deployment.ini' + """ + usage = "usage: %prog config_uri" + parser = optparse.OptionParser( + usage=usage, + description=textwrap.dedent(description) + ) + parser.add_option( + '-o', '--omit', + dest='omit', + metavar='PREFIX', + type='string', + action='append', + help=("Omit settings which start with PREFIX (you can use this " + "option multiple times)") + ) + + options, args = parser.parse_args(sys.argv[1:]) + if not len(args) >= 1: + print('You must provide at least one argument') + return 2 + config_uri = args[0] + omit = options.omit + if omit is None: + omit = [] + with bootstrap(config_uri) as env: + settings = env['registry'].settings + for k, v in settings.items(): + if any([k.startswith(x) for x in omit]): + continue + print('%-40s %-20s' % (k, v)) This script uses the Python ``optparse`` module to allow us to make sense out of extra arguments passed to the script. It uses the @@ -799,131 +988,149 @@ defined in that config file. After adding this script to the package, you'll need to tell your distribution's ``setup.py`` about its existence. Within your distribution's -top-level directory your ``setup.py`` file will look something like this: +top-level directory, your ``setup.py`` file will look something like this: .. code-block:: python - :linenos: - - import os - - from setuptools import setup, find_packages - - here = os.path.abspath(os.path.dirname(__file__)) - with open(os.path.join(here, 'README.txt')) as f: - README = f.read() - with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() - - requires = ['pyramid', 'pyramid_debugtoolbar'] - - setup(name='MyProject', - version='0.0', - description='My project', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="myproject", - entry_points = """\ - [paste.app_factory] - main = myproject:main - """, - ) - -We're going to change the setup.py file to add an ``[console_scripts]`` -section with in the ``entry_points`` string. Within this section, you should -specify a ``scriptname = dotted.path.to:yourfunction`` line. For example:: - - [console_scripts] - show_settings = myproject.scripts:settings_show + :linenos: + + import os + + from setuptools import setup, find_packages + + here = os.path.abspath(os.path.dirname(__file__)) + with open(os.path.join(here, 'README.txt')) as f: + README = f.read() + with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + + requires = ['pyramid', 'pyramid_debugtoolbar'] + + tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', # includes virtualenv + 'pytest-cov', + ] + + setup(name='MyProject', + version='0.0', + description='My project', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + extras_require={ + 'testing': tests_require, + }, + entry_points = """\ + [paste.app_factory] + main = myproject:main + """, + ) + +We're going to change the ``setup.py`` file to add a ``[console_scripts]`` +section within the ``entry_points`` string. Within this section, you should +specify a ``scriptname = dotted.path.to:yourfunction`` line. For example: + +.. code-block:: ini + + [console_scripts] + show_settings = myproject.scripts:settings_show The ``show_settings`` name will be the name of the script that is installed into ``bin``. The colon (``:``) between ``myproject.scripts`` and ``settings_show`` above indicates that ``myproject.scripts`` is a Python -module, and ``settings_show`` is the function in that module which contains -the code you'd like to run as the result of someone invoking the -``show_settings`` script from their command line. +module, and ``settings_show`` is the function in that module which contains the +code you'd like to run as the result of someone invoking the ``show_settings`` +script from their command line. The result will be something like: .. code-block:: python - :linenos: - - import os - - from setuptools import setup, find_packages - - here = os.path.abspath(os.path.dirname(__file__)) - with open(os.path.join(here, 'README.txt')) as f: - README = f.read() - with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() - - requires = ['pyramid', 'pyramid_debugtoolbar'] - - setup(name='MyProject', - version='0.0', - description='My project', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="myproject", - entry_points = """\ - [paste.app_factory] - main = myproject:main - [console_scripts] - show_settings = myproject.scripts:settings_show - """, - ) - -Once you've done this, invoking ``$$VENV/bin/python setup.py -develop`` will install a file named ``show_settings`` into the -``$somevirtualenv/bin`` directory with a small bit of Python code that points -to your entry point. It will be executable. Running it without any -arguments will print an error and exit. Running it with a single argument -that is the path of a config file will print the settings. Running it with -an ``--omit=foo`` argument will omit the settings that have keys that start -with ``foo``. Running it with two "omit" options (e.g. ``--omit=foo ---omit=bar``) will omit all settings that have keys that start with either -``foo`` or ``bar``:: - - $ $VENV/bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar - debug_routematch False - debug_templates True - reload_templates True - mako.directories [] - debug_notfound False - default_locale_name en - reload_resources False - debug_authorization False - reload_assets False - prevent_http_cache False - -Pyramid's ``pserve``, ``pcreate``, ``pshell``, ``prequest``, ``ptweens`` and + :linenos: + :emphasize-lines: 43-44 + + import os + + from setuptools import setup, find_packages + + here = os.path.abspath(os.path.dirname(__file__)) + with open(os.path.join(here, 'README.txt')) as f: + README = f.read() + with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + + requires = ['pyramid', 'pyramid_debugtoolbar'] + + tests_require = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', # includes virtualenv + 'pytest-cov', + ] + + setup(name='MyProject', + version='0.0', + description='My project', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + extras_require={ + 'testing': tests_require, + }, + entry_points = """\ + [paste.app_factory] + main = myproject:main + [console_scripts] + show_settings = myproject.scripts:settings_show + """, + ) + +Once you've done this, invoking ``$VENV/bin/pip install -e .`` will install a +file named ``show_settings`` into the ``$somevenv/bin`` directory with a +small bit of Python code that points to your entry point. It will be +executable. Running it without any arguments will print an error and exit. +Running it with a single argument that is the path of a config file will print +the settings. Running it with an ``--omit=foo`` argument will omit the settings +that have keys that start with ``foo``. Running it with two "omit" options +(e.g., ``--omit=foo --omit=bar``) will omit all settings that have keys that +start with either ``foo`` or ``bar``: + +.. code-block:: bash + + $VENV/bin/show_settings development.ini --omit=pyramid --omit=debugtoolbar + debug_routematch False + debug_templates True + reload_templates True + mako.directories [] + debug_notfound False + default_locale_name en + reload_resources False + debug_authorization False + reload_assets False + prevent_http_cache False + +Pyramid's ``pserve``, ``pshell``, ``prequest``, ``ptweens``, and other ``p*`` scripts are implemented as console scripts. When you invoke one of those, you are using a console script. |
