From bfd4b39b3467681ad34b1dda74acd20294e81a86 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 09:10:10 -0500 Subject: - Changed scaffolding machinery around a bit to make it easier for people who want to have extension scaffolds that can work across Pyramid 1.0.X, 1.1.X, 1.2.X and 1.3.X. See the new "Creating Pyramid Scaffolds" chapter in the narrative documentation for more info. - Added an API docs chapter for ``pyramid.scaffolds``. - Added a narrative docs chapter named "Creating Pyramid Scaffolds". - The ``template_renderer`` method of ``pyramid.scaffolds.PyramidScaffold`` was renamed to ``render_template``. If you were overriding it, you're a bad person, because it wasn't an API before now. But we're nice so we're letting you know. --- docs/api.rst | 1 + docs/api/scaffolds.rst | 13 ++++ docs/index.rst | 1 + docs/narr/scaffolding.rst | 171 ++++++++++++++++++++++++++++++++++++++++++++++ docs/whatsnew-1.3.rst | 4 ++ 5 files changed, 190 insertions(+) create mode 100644 docs/api/scaffolds.rst create mode 100644 docs/narr/scaffolding.rst (limited to 'docs') diff --git a/docs/api.rst b/docs/api.rst index 979e8f490..d510c0d27 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -26,6 +26,7 @@ documentation is organized alphabetically by module name. api/renderers api/request api/response + api/scaffolds api/scripting api/security api/session diff --git a/docs/api/scaffolds.rst b/docs/api/scaffolds.rst new file mode 100644 index 000000000..827962e19 --- /dev/null +++ b/docs/api/scaffolds.rst @@ -0,0 +1,13 @@ +.. _scaffolds_module: + +:mod:`pyramid.scaffolds` +------------------------ + +.. automodule:: pyramid.scaffolds + + .. autoclass:: pyramid.scaffolds.Template + :members: + + .. autoclass:: pyramid.scaffolds.PyramidTemplate + :members: + diff --git a/docs/index.rst b/docs/index.rst index df7a422d4..ca5f4aa30 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -93,6 +93,7 @@ Narrative documentation in chapter form explaining how to use narr/extending narr/advconfig narr/extconfig + narr/scaffolding narr/threadlocals narr/zca diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst new file mode 100644 index 000000000..fda0632f8 --- /dev/null +++ b/docs/narr/scaffolding.rst @@ -0,0 +1,171 @@ +.. _scaffolding_chapter: + +Creating Pyramid Scaffolds +========================== + +You can extend Pyramid by creating a :term:`scaffold` template. A scaffold +template is useful if you'd like to distribute a customizable configuration +of Pyramid to other users. Once you've created a scaffold, and someone has +installed the distribution that houses the scaffold, they can use the +``pcreate`` script to create a custom version of your scaffold's template. +Pyramid itself uses scaffolds to allow people to bootstrap new projects. For +example, ``pcreate -s alchemy MyStuff`` causes Pyramid to render the +``alchemy`` scaffold template to the ``MyStuff`` directory. + +Basics +------ + +A scaffold template is just a bunch of source files and directories on disk. +A small definition class points at this directory; it is in turn pointed at +by a :term:`setuptools` "entry point" which registers the scaffold so it can +be found by the ``pcreate`` command. + +To create a scaffold template, create a Python :term:`distribution` to house +the scaffold which includes a ``setup.py`` that relies on the ``setuptools`` +package. See `Creating a Package +`_ for more information +about how to do this. For the sake of example, we'll pretend the +distribution you create is named ``CoolExtension``, and it has a package +directory within it named ``coolextension`` + +Once you've created the distribution put a "scaffolds" directory within your +distribution's package directory, and create a file within that directory +named ``__init__.py`` with something like the following: + +.. code-block:: python + :linenos: + + # CoolExtension/coolextension/scaffolds/__init__.py + + from pyramid.scaffolds import PyramidTemplate + + class CoolExtensionTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool extension' + +Once this is done, within the ``scaffolds`` directory, create a template +directory. Our example used a template directory named +``coolextension_scaffold``. + +As you create files and directories within the template directory, note that: + +- Files which have a name which are suffixed with the value ``_tmpl`` will be + rendered, and replacing any instance of the literal string ``{{var}}`` with + the string value of the variable named ``var`` provided to the scaffold. + +- Files and directories with filenames that contain the string ``+var+`` will + have that string replaced with the value of the ``var`` variable provided + to the scaffold. + +Otherwise, files and directories which live in the template directory will be +copied directly without modification to the ``pcreate`` output location. + +The variables provided by the default ``PyramidTemplate`` include ``project`` +(the project name provided by the user as an argument to ``pcreate``), +``package`` (a lowercasing and normalizing of the project name provided by +the user), ``random_string`` (a long random string), and ``package_logger`` +(the name of the package's logger). + +See Pyramid's "scaffolds" package +(https://github.com/Pylons/pyramid/tree/master/pyramid/scaffolds) for +concrete examples of scaffold directories (``zodb``, ``alchemy``, and +``starter``, for example). + +After you've created the template directory, add the following to the +``entry_points`` value of your distribution's ``setup.py``: + + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + +For example:: + + def setup( + ..., + entry_points = """\ + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + """ + ) + +Run your distribution's ``setup.py develop`` or ``setup.py install`` +command. After that, you should be able to see your scaffolding template +listed when you run ``pcreate -l``. It will be named ``coolextension`` +because that's the name we gave it in the entry point setup. Running +``pcreate -s coolextension MyStuff`` will then render your scaffold to an +output directory named ``MyStuff``. + +See the module documentation for :mod:`pyramid.scaffolds` for information +about the API of the :class:`pyramid.scaffolds.PyramidScaffold` class and +related classes. You can override methods of this class to get special +behavior. + +Supporting Older Pyramid Versions +--------------------------------- + +Because different versions of Pyramid handled scaffolding differently, if you +want to have extension scaffolds that can work across Pyramid 1.0.X, 1.1.X, +1.2.X and 1.3.X, you'll need to use something like this bit of horror while +defining your scaffold template: + +.. code-block:: python + :linenos: + + try: # pyramid 1.0.X + # "pyramid.paster_templates" doesn't exist past 1.0.X + from pyramid.paster_templates import PyramidTemplate + from pyramid.paster_templates import paste_script_template_renderer + except ImportError: + try: # pyramid 1.1.X, 1.2.X + # trying to import "paste_script_template_renderer" fails on 1.3.X + from pyramid.scaffolds import paste_script_template_renderer + from pyramid.scaffolds import PyramidTemplate + except ImportError: # pyramid >=1.3a2 + paste_script_template_renderer = None + from pyramid.scaffolds import PyramidTemplate + + class CoolExtensionTemplateTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool extension' + template_renderer = staticmethod(paste_script_template_renderer) + +And then in the setup.py of the package that contains your scaffold, define +the template as a target of both ``paste.paster_create_template`` (for +``paster create``) and ``pyramid.scaffold`` (for ``pcreate``):: + + [paste.paster_create_template] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + [pyramid.scaffold] + coolextension=coolextension.scaffolds:CoolExtensionTemplate + +Doing this hideousness will allow your scaffold to work as a ``paster +create`` target (under 1.0, 1.1, or 1.2) or as a ``pcreate`` target (under +1.3). If an invoker tries to run ``paster create`` against a scaffold +defined this way under 1.3, an error is raised instructing them to use +``pcreate`` instead. + +If you want only to support Pyramid 1.3 only, it's much cleaner, and the API +is stable: + +.. code-block:: python + :linenos: + + from pyramid.scaffolds import PyramidTemplate + + class CoolExtensionTemplate(PyramidTemplate): + _template_dir = 'coolextension_scaffold' + summary = 'My cool_extension' + +You only need to specify a ``paste.paster_create_template`` entry point +target in your ``setup.py`` if you want your scaffold to be consumable by +users of Pyramid 1.0, 1.1, or 1.2. To support only 1.3, specifying only the +``pyramid.scaffold`` entry point is good enough. If you want to support both +``paster create`` and ``pcreate`` (meaning you want to support Pyramid 1.2 +and some older version), you'll need to define both. + +Examples +-------- + +Existing third-party distributions which house scaffolding are available via +:term:`PyPI`. The ``pyramid_jqm``, ``pyramid_zcml`` and ``pyramid_jinja2`` +packages house scaffolds. You can install and examine these packages to see +how they work in the quest to develop your own scaffolding. diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst index 608db74cd..12132e7fd 100644 --- a/docs/whatsnew-1.3.rst +++ b/docs/whatsnew-1.3.rst @@ -276,6 +276,10 @@ Documentation Enhancements - A narrative documentation chapter named :ref:`using_introspection` was added. It describes how to query the introspection system. +- Added an API docs chapter for :mod:`pyramid.scaffolds`. + +- Added a narrative docs chapter named :ref:`scaffolding_chapter`. + Dependency Changes ------------------ -- cgit v1.2.3 From 9dce50a3bdd30b7c5c9b8efd184bad7cbbb1a030 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 09:23:22 -0500 Subject: prep for 1.3a2 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index f913b2462..79543777d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -80,7 +80,7 @@ copyright = '%s, Agendaless Consulting' % datetime.datetime.now().year # other places throughout the built documents. # # The short X.Y version. -version = '1.3a1' +version = '1.3a2' # The full version, including alpha/beta/rc tags. release = version -- cgit v1.2.3 From 351777c2f870ba4fb3ba2a81e6b413d3bf50da72 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 21:03:36 -0500 Subject: fix for 1.0 --- docs/narr/scaffolding.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index fda0632f8..214ddfdfa 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -112,8 +112,8 @@ defining your scaffold template: try: # pyramid 1.0.X # "pyramid.paster_templates" doesn't exist past 1.0.X - from pyramid.paster_templates import PyramidTemplate - from pyramid.paster_templates import paste_script_template_renderer + from pyramid.paster import PyramidTemplate + from pyramid.paster import paste_script_template_renderer except ImportError: try: # pyramid 1.1.X, 1.2.X # trying to import "paste_script_template_renderer" fails on 1.3.X -- cgit v1.2.3 From 604b812a4361a63ed93f3135be3a800d5592b2a1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 22:22:44 -0500 Subject: avoid warning under 1.2 --- docs/narr/scaffolding.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/narr/scaffolding.rst b/docs/narr/scaffolding.rst index 214ddfdfa..3e7b102fd 100644 --- a/docs/narr/scaffolding.rst +++ b/docs/narr/scaffolding.rst @@ -111,9 +111,9 @@ defining your scaffold template: :linenos: try: # pyramid 1.0.X - # "pyramid.paster_templates" doesn't exist past 1.0.X - from pyramid.paster import PyramidTemplate + # "pyramid.paster.paste_script..." doesn't exist past 1.0.X from pyramid.paster import paste_script_template_renderer + from pyramid.paster import PyramidTemplate except ImportError: try: # pyramid 1.1.X, 1.2.X # trying to import "paste_script_template_renderer" fails on 1.3.X -- cgit v1.2.3 From bc08bb6989f674e9c1c2ecf383bf5d71fc0d5f98 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 14 Dec 2011 22:23:14 -0500 Subject: mention backports and fix incorrect info about being able to use paster create for internal pyramid scaffolds --- docs/whatsnew-1.3.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst index 53ab8e91d..b0afacfe6 100644 --- a/docs/whatsnew-1.3.rst +++ b/docs/whatsnew-1.3.rst @@ -76,8 +76,10 @@ command:: The ``ini`` configuration file format supported by Pyramid has not changed. As a result, Python 2-only users can install PasteScript manually and use -``paster serve`` and ``paster create`` instead if they like. However, using -``pserve`` and ``pcreate`` will work under both Python 2 and Python 3. +``paster serve`` instead if they like. However, using ``pserve`` will work +under both Python 2 and Python 3. ``pcreate`` is required to be used for +internal Pyramid scaffolding; externally distributed scaffolding may allow +for both ``pcreate`` and/or ``paster create``. Analogues of ``paster pshell``, ``paster pviews`` and ``paster ptweens`` also exist under the respective console script names ``pshell``, ``pviews``, and @@ -101,6 +103,10 @@ actually recommended if you rely on proxying from Apache or Nginx to a ``pserve`` -invoked application. **The wsgiref server is not a production quality server.** See :ref:`alternate_wsgi_server` for more information. +New releases in every older major Pyramid series (1.0.2, 1.1.3, 1.2.5) also +have the ``egg:pyramid#wsgiref`` entry point, so scaffold-writers can depend +on it being there even in older major Pyramid versions. + .. warning:: Previously, paste.httpserver "helped" by converting header values that weren't -- cgit v1.2.3 From 4288cbb755941537a02fff35004309fc13c912dc Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 14:59:14 -0500 Subject: we now use wsgiref which prints nothing --- docs/index.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/index.rst b/docs/index.rst index ca5f4aa30..21e587992 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,10 +19,9 @@ When saved to ``helloworld.py``, the above application can be run via: $ easy_install pyramid $ python helloworld.py - serving on 0.0.0.0:8080 view at http://127.0.0.1:8080 -And when you visit ``http://localhost:8080/hello/world`` in a browser, you -will see the text ``Hello, world!``. +When you visit ``http://localhost:8080/hello/world`` in a browser, you will +see the text ``Hello, world!``. See :ref:`firstapp_chapter` for a full explanation of how this application works. Read the :ref:`html_narrative_documentation` to understand how -- cgit v1.2.3 From c8061ee1d797cb666e1d45e19765ede565d21915 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 17:29:01 -0500 Subject: finish prequest feature --- docs/narr/commandline.rst | 65 ++++++++++++++++++++++++++++++++++++++++++++--- docs/whatsnew-1.3.rst | 9 ++++--- 2 files changed, 68 insertions(+), 6 deletions(-) (limited to 'docs') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 66ef46671..b9aa2c8c3 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -121,7 +121,8 @@ The Interactive Shell 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. +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 @@ -311,7 +312,7 @@ For example: .. code-block:: text :linenos: - [chrism@thinko MyProject]$ ../bin/proutes development.ini#MyProject + [chrism@thinko MyProject]$ ../bin/proutes development.ini Name Pattern View ---- ------- ---- home / @@ -354,7 +355,7 @@ configured without any explicit tweens: .. code-block:: text :linenos: - [chrism@thinko pyramid]$ ptweens development.ini + [chrism@thinko pyramid]$ myenv/bin/ptweens development.ini "pyramid.tweens" config value NOT set (implicitly ordered tweens used) Implicit Tween Chain @@ -416,6 +417,64 @@ is used: See :ref:`registering_tweens` for more information about tweens. +.. index:: + single: invoking a request + single: prequest + +.. _invoking_a_request: + +Invoking a Request +------------------ + +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`` + 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: + ``development.ini``. + +- 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:: + + $ 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. + +``prequest`` has a ``-d`` (aka ``--display-headers``) option which prints the +status and headers returned by the server before the output:: + + $ bin/prequest -d development.ini / + +This will print the status, then the headers, then the body of the response +to the console. + +You can add request header values by using the ``--header`` option:: + + $ bin/prequest --header=Host=example.com development.ini / + +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. + +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:: + + $ bin/prequest -mPOST development.ini / < somefile + .. _writing_a_script: Writing a Script diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst index b0afacfe6..a69efd268 100644 --- a/docs/whatsnew-1.3.rst +++ b/docs/whatsnew-1.3.rst @@ -81,9 +81,9 @@ under both Python 2 and Python 3. ``pcreate`` is required to be used for internal Pyramid scaffolding; externally distributed scaffolding may allow for both ``pcreate`` and/or ``paster create``. -Analogues of ``paster pshell``, ``paster pviews`` and ``paster ptweens`` also -exist under the respective console script names ``pshell``, ``pviews``, and -``ptweens``. +Analogues of ``paster pshell``, ``paster pviews``, ``paster request`` and +``paster ptweens`` also exist under the respective console script names +``pshell``, ``pviews``, ``prequest`` and ``ptweens``. We've replaced use of the Paste ``httpserver`` with the ``wsgiref`` server in the scaffolds, so once you create a project from a scaffold, its @@ -296,6 +296,9 @@ Documentation Enhancements - Added a narrative docs chapter named :ref:`scaffolding_chapter`. +- Added a description of the ``prequest`` command-line script at + :ref:`invoking_a_request`. + Dependency Changes ------------------ -- cgit v1.2.3 From 02d7451d4e6a3fafdda8ebbb65e19d4333bb9c33 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 21:25:43 -0500 Subject: fix import --- docs/narr/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 3c6799afb..a1ed6c7ff 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -119,7 +119,7 @@ Here's some sample code that implements a minimal forbidden view: .. code-block:: python :linenos: - from pyramid.views import view_config + from pyramid.view import view_config from pyramid.response import Response def forbidden_view(request): -- cgit v1.2.3 From 61838b76639d6dcf9facd549841a2ed0d07ea012 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 15 Dec 2011 21:35:23 -0500 Subject: - Added a section named "Making Your Script into a Console Script" in the "Command-Line Pyramid" chapter. --- docs/narr/commandline.rst | 231 ++++++++++++++++++++++++++++++++++++++++++++++ docs/whatsnew-1.3.rst | 3 + 2 files changed, 234 insertions(+) (limited to 'docs') diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index b9aa2c8c3..dc3cff8ac 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -654,3 +654,234 @@ use the following command: import logging.config logging.config.fileConfig('/path/to/my/development.ini') + +.. index:: + single: console script + +.. _making_a_console_script: + +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": because it generates a file that lives in ``bin``, 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. + +- 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. + +- 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. + +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: + +.. 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: + 'psettings 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() + +This script uses the Python ``optparse`` module to allow us to make sense out +of extra arguments passed to the script. It uses the +:func:`pyramid.paster.bootstrap` function to get information about the the +application defined by a config file, and prints the deployment settings +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: + +.. code-block:: python + :linenos: + + import os + + from setuptools import setup, find_packages + + here = os.path.abspath(os.path.dirname(__file__)) + README = open(os.path.join(here, 'README.txt')).read() + CHANGES = open(os.path.join(here, 'CHANGES.txt')).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="wiggystatic", + entry_points = """\ + [paste.app_factory] + main = wiggystatic: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 + +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. + +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__)) + README = open(os.path.join(here, 'README.txt')).read() + CHANGES = open(os.path.join(here, 'CHANGES.txt')).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="wiggystatic", + entry_points = """\ + [paste.app_factory] + main = wiggystatic:main + [console_scripts] + show_settings = myproject.scripts:settings_show + """, + ) + +Once you've done this, invoking ``$somevirtualenv/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``:: + + [chrism@thinko somevenv]$ 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 +other ``p*`` scripts are implemented as console scripts. When you invoke one +of those, you are using a console script. diff --git a/docs/whatsnew-1.3.rst b/docs/whatsnew-1.3.rst index a69efd268..8dd3c3cdb 100644 --- a/docs/whatsnew-1.3.rst +++ b/docs/whatsnew-1.3.rst @@ -299,6 +299,9 @@ Documentation Enhancements - Added a description of the ``prequest`` command-line script at :ref:`invoking_a_request`. +- Added a section to the "Command-Line Pyramid" chapter named + :ref:`making_a_console_script`. + Dependency Changes ------------------ -- cgit v1.2.3