Steve Piercy
2018-08-21 4b84f6e97b321309544513b0697e8b378a57bafc
Synch Hello World app with canonical version on trypyramid.com and elsewhere
10 files modified
118 ■■■■■ changed files
README.rst 6 ●●●● patch | view | raw | blame | history
docs/designdefense.rst 7 ●●●●● patch | view | raw | blame | history
docs/index.rst 4 ●●●● patch | view | raw | blame | history
docs/narr/configuration.rst 27 ●●●●● patch | view | raw | blame | history
docs/narr/firstapp.rst 30 ●●●● patch | view | raw | blame | history
docs/narr/hellotraversal.py 15 ●●●●● patch | view | raw | blame | history
docs/narr/hellotraversal.rst 16 ●●●● patch | view | raw | blame | history
docs/narr/helloworld.py 7 ●●●●● patch | view | raw | blame | history
docs/quick_tour.rst 4 ●●●● patch | view | raw | blame | history
docs/quick_tour/hello_world/app.py 2 ●●● patch | view | raw | blame | history
README.rst
@@ -24,14 +24,14 @@
    from pyramid.response import Response
    def hello_world(request):
        return Response('Hello %(name)s!' % request.matchdict)
        return Response('Hello World!')
    if __name__ == '__main__':
        with Configurator() as config:
            config.add_route('hello', '/hello/{name}')
            config.add_route('hello', '/')
            config.add_view(hello_world, route_name='hello')
            app = config.make_wsgi_app()
        server = make_server('0.0.0.0', 8080, app)
        server = make_server('0.0.0.0', 6543, app)
        server.serve_forever()
Pyramid is a project of the `Pylons Project <https://pylonsproject.org>`_.
docs/designdefense.rst
@@ -1644,13 +1644,14 @@
    from pyramid.response import Response
    def hello_world(request):
        return Response('Hello world!')
        return Response('Hello World!')
    if __name__ == '__main__':
        with Configurator() as config:
            config.add_view(hello_world)
            config.add_route('hello', '/')
            config.add_view(hello_world, route_name='hello')
            app = config.make_wsgi_app()
        server = make_server('0.0.0.0', 8080, app)
        server = make_server('0.0.0.0', 6543, app)
        server.serve_forever()
Pyramid has over 1200 pages of documentation (printed), covering topics from
docs/index.rst
@@ -13,8 +13,8 @@
.. literalinclude:: narr/helloworld.py
After you install :app:`Pyramid` and run this application, 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
`<http://localhost:6543/>`_ in a browser, you will see the text
``Hello World!`` See :ref:`firstapp_chapter` for a full explanation of how
this application works.
docs/narr/configuration.rst
@@ -48,9 +48,10 @@
    if __name__ == '__main__':
        with Configurator() as config:
            config.add_route('hello', '/')
            config.add_view(hello_world)
            app = config.make_wsgi_app()
        server = make_server('0.0.0.0', 8080, app)
        server = make_server('0.0.0.0', 6543, app)
        server.serve_forever()
We won't talk much about what this application does yet.  Just note that the
@@ -81,13 +82,14 @@
.. code-block:: python
    :linenos:
    :emphasize-lines: 2-4
    from pyramid.response import Response
    from pyramid.view import view_config
    @view_config(name='hello', request_method='GET')
    def hello(request):
        return Response('Hello')
    @view_config(route_name='hello', request_method='GET')
    def hello_world(request):
        return Response('Hello World!')
The mere existence of configuration decoration doesn't cause any configuration
registration to be performed.  Before it has any effect on the configuration of
@@ -95,7 +97,7 @@
code must be found through a process known as a :term:`scan`.
For example, the :class:`pyramid.view.view_config` decorator in the code
example above adds an attribute to the ``hello`` function, making it available
example above adds an attribute to the ``hello_world`` function, making it available
for a :term:`scan` to find it later.
A :term:`scan` of a :term:`module` or a :term:`package` and its subpackages for
@@ -105,21 +107,25 @@
.. code-block:: python
    :linenos:
    :emphasize-lines: 15
    from wsgiref.simple_server import make_server
    from pyramid.config import Configurator
    from pyramid.response import Response
    from pyramid.view import view_config
    @view_config()
    def hello(request):
        return Response('Hello')
    @view_config(route_name='hello', request_method='GET')
    def hello_world(request):
        return Response('Hello World!')
    if __name__ == '__main__':
        with Configurator() as config:
            config.add_route('hello', '/')
            config.scan()
            app = config.make_wsgi_app()
        server = make_server('0.0.0.0', 8080, app)
        server = make_server('0.0.0.0', 6543, app)
        server.serve_forever()
The scanning machinery imports each module and subpackage in a package or
@@ -143,7 +149,8 @@
.. code-block:: python
    config.add_view(hello)
    config.add_view(hello_world, route_name='hello',
                    request_method='GET')
Summary
-------
docs/narr/firstapp.rst
@@ -23,7 +23,7 @@
When this code is inserted into a Python script named ``helloworld.py`` and
executed by a Python interpreter which has the :app:`Pyramid` software
installed, an HTTP server is started on TCP port 8080.
installed, an HTTP server is started on TCP port 6543.
On Unix:
@@ -38,9 +38,9 @@
    %VENV%\Scripts\python helloworld.py
This command will not return and nothing will be printed to the console. When
port 8080 is visited by a browser on the URL ``/hello/world``, the server will
port 6543 is visited by a browser on the URL ``/hello/world``, the server will
simply serve up the text "Hello world!".  If your application is running on
your local system, using `<http://localhost:8080/hello/world>`_ in a browser
your local system, using `<http://localhost:6543/hello/world>`_ in a browser
will show this result.
Each time you visit a URL served by the application in a browser, a logging
@@ -63,15 +63,15 @@
   :lineno-match:
   :lines: 1-3
The script imports the :class:`~pyramid.config.Configurator` class from the
:mod:`pyramid.config` module.  An instance of the
:class:`~pyramid.config.Configurator` class is later used to configure your
:app:`Pyramid` application.
Like many other Python web frameworks, :app:`Pyramid` uses the :term:`WSGI`
protocol to connect an application and a web server together.  The
:mod:`wsgiref` server is used in this example as a WSGI server for convenience,
as it is shipped within the Python standard library.
The script imports the :class:`~pyramid.config.Configurator` class from the
:mod:`pyramid.config` module.  An instance of the
:class:`~pyramid.config.Configurator` class is later used to configure your
:app:`Pyramid` application.
The script also imports the :class:`pyramid.response.Response` class for later
use.  An instance of this class will be used to create a web response.
@@ -126,7 +126,7 @@
.. literalinclude:: helloworld.py
   :lineno-match:
   :lines: 9-15
   :lines: 10-16
Let's break this down piece by piece.
@@ -135,7 +135,7 @@
.. literalinclude:: helloworld.py
   :lineno-match:
   :lines: 9-10
   :lines: 10-11
The ``if __name__ == '__main__':`` line in the code sample above represents a
Python idiom: the code inside this if clause is not invoked unless the script
@@ -167,7 +167,7 @@
.. literalinclude:: helloworld.py
   :lineno-match:
   :lines: 11-12
   :lines: 12-13
The first line above calls the :meth:`pyramid.config.Configurator.add_route`
method, which registers a :term:`route` to match any URL path that begins with
@@ -186,7 +186,7 @@
.. literalinclude:: helloworld.py
   :lineno-match:
   :lines: 13
   :lines: 14
After configuring views and ending configuration, the script creates a WSGI
*application* via the :meth:`pyramid.config.Configurator.make_wsgi_app` method.
@@ -213,7 +213,7 @@
.. literalinclude:: helloworld.py
   :lineno-match:
   :lines: 14-15
   :lines: 15-16
Finally, we actually serve the application to requestors by starting up a WSGI
server.  We happen to use the :mod:`wsgiref` ``make_server`` server maker for
@@ -221,14 +221,14 @@
"listen on all TCP interfaces".  By default, the HTTP server listens only on
the ``127.0.0.1`` interface, which is problematic if you're running the server
on a remote system and you wish to access it with a web browser from a local
system.  We also specify a TCP port number to listen on, which is 8080, passing
system.  We also specify a TCP port number to listen on, which is 6543, passing
it as the second argument.  The final argument is the ``app`` object (a
:term:`router`), which is the application we wish to serve.  Finally, we call
the server's ``serve_forever`` method, which starts the main loop in which it
will wait for requests from the outside world.
When this line is invoked, it causes the server to start listening on TCP port
8080.  The server will serve requests forever, or at least until we stop it by
6543.  The server will serve requests forever, or at least until we stop it by
killing the process which runs it (usually by pressing ``Ctrl-C`` or
``Ctrl-Break`` in the terminal we used to start it).
docs/narr/hellotraversal.py
@@ -2,21 +2,24 @@
from pyramid.config import Configurator
from pyramid.response import Response
class Resource(dict):
    pass
def get_root(request):
    return Resource({'a': Resource({'b': Resource({'c': Resource()})})})
def hello_world_of_resources(context, request):
    output = "Here's a resource and its children: %s" % context
    return Response(output)
if __name__ == '__main__':
    config = Configurator(root_factory=get_root)
    config.add_view(hello_world_of_resources, context=Resource)
    app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 8080, app)
    with Configurator() as config:
        config.set_root_factory(get_root)
        config.add_view(hello_world_of_resources, context=Resource)
        app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 6543, app)
    server.serve_forever()
docs/narr/hellotraversal.rst
@@ -18,16 +18,16 @@
You may notice that this application is intentionally very similar to the
"hello world" application from :doc:`firstapp`.
On lines 5-6, we create a trivial :term:`resource` class that's just a
On lines 6-7, we create a trivial :term:`resource` class that's just a
dictionary subclass.
On lines 8-9, we hard-code a :term:`resource tree` in our :term:`root factory`
On lines 10-11, we hard-code a :term:`resource tree` in our :term:`root factory`
function.
On lines 11-13, we define a single :term:`view callable` that can display a
On lines 14-15, we define a single :term:`view callable` that can display a
single instance of our ``Resource`` class, passed as the ``context`` argument.
The rest of the file sets up and serves our :app:`Pyramid` WSGI app.  Line 18
The rest of the file sets up and serves our :app:`Pyramid` WSGI app.  Line 22
is where our view gets configured for use whenever the traversal ends with an
instance of our ``Resource`` class.
@@ -37,19 +37,19 @@
Example requests
----------------
If this example is running on http://localhost:8080, and the user browses to
http://localhost:8080/a/b, Pyramid will call ``get_root(request)`` to get the
If this example is running on http://localhost:6543, and the user browses to
http://localhost:6543/a/b, Pyramid will call ``get_root(request)`` to get the
root resource, then traverse the tree from there by key; starting from the
root, it will find the child with key ``"a"``, then its child with key ``"b"``;
then use that as the ``context`` argument for calling
``hello_world_of_resources``.
Or, if the user browses to http://localhost:8080/, Pyramid will stop at the
Or, if the user browses to http://localhost:6543/, Pyramid will stop at the
root—the outermost ``Resource`` instance, in this case—and use that as the
``context`` argument to the same view.
Or, if the user browses to a key that doesn't exist in this resource tree, like
http://localhost:8080/xyz or http://localhost:8080/a/b/c/d, the traversal will
http://localhost:6543/xyz or http://localhost:6543/a/b/c/d, the traversal will
end by raising a KeyError, and Pyramid will turn that into a 404 HTTP response.
A more complicated application could have many types of resources, with
docs/narr/helloworld.py
@@ -4,12 +4,13 @@
def hello_world(request):
    return Response('Hello %(name)s!' % request.matchdict)
    return Response('Hello World!')
if __name__ == '__main__':
    with Configurator() as config:
        config.add_route('hello', '/hello/{name}')
        config.add_route('hello', '/')
        config.add_view(hello_world, route_name='hello')
        app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 8080, app)
    server = make_server('0.0.0.0', 6543, app)
    server.serve_forever()
docs/quick_tour.rst
@@ -87,13 +87,13 @@
New to Python web programming? If so, some lines in the module merit
explanation:
#. *Lines 6-7*. Implement the view code that generates the :term:`response`.
#. *Line 10*. ``if __name__ == '__main__':`` is Python's way of saying "Start
   here when running from the command line".
#. *Lines 11-13*. Use Pyramid's :term:`configurator` in a :term:`context manager` to connect :term:`view`
   code to a particular URL :term:`route`.
#. *Lines 6-7*. Implement the view code that generates the :term:`response`.
#. *Lines 14-16*. Publish a :term:`WSGI` app using an HTTP server.
docs/quick_tour/hello_world/app.py
@@ -4,7 +4,7 @@
def hello_world(request):
    return Response('<h1>Hello World!</h1>')
    return Response('Hello World!')
if __name__ == '__main__':