02: Python Packages for Pyramid Applications

Most modern Python development is done using Python packages, an approach Pyramid puts to good use. In this step we redo "Hello World" as a minimum Python package inside a minimum Python project.

Background

Python developers can organize a collection of modules and files into a namespaced unit called a package. If a directory is on sys.path and has a special file named __init__.py, it is treated as a Python package.

Packages can be bundled up, made available for installation, and installed through a (muddled, but improving) toolchain oriented around a setup.py file for a setuptools project. Explaining it all in this tutorial will induce madness. For this tutorial, this is all you need to know:

  • We will have a directory for each tutorial step as a setuptools project
  • This project will contain a setup.py which injects the features of the setuptool's project machinery into the directory
  • In this project we will make a tutorial subdirectory into a Python package using an __init__.py Python module file
  • We will run python setup.py develop to install our project in development mode

In summary:

  • You'll do your development in a Python package
  • That package will be part of a setuptools project

Objectives

  • Make a Python "package" directory with an __init__.py
  • Get a minimum Python "project" in place by making a setup.py
  • Install our tutorial project in development mode

Steps

  1. Make an area for this tutorial step:

    $ cd ..; mkdir package; cd package
    
  2. In package/setup.py, enter the following:

    from setuptools import setup
    
    requires = [
        'pyramid',
    ]
    
    setup(name='tutorial',
          install_requires=requires,
    )
    
  3. Make the new project installed for development then make a directory for the actual code:

    $ $VENV/bin/python setup.py develop
    $ mkdir tutorial
    
  4. Enter the following into package/tutorial/__init__.py:

    # package
    
  5. Enter the following into package/tutorial/app.py:

    from wsgiref.simple_server import make_server
    from pyramid.config import Configurator
    from pyramid.response import Response
    
    
    def hello_world(request):
        print ('Incoming request')
        return Response('<body><h1>Hello World!</h1></body>')
    
    
    if __name__ == '__main__':
        config = Configurator()
        config.add_route('hello', '/')
        config.add_view(hello_world, route_name='hello')
        app = config.make_wsgi_app()
        server = make_server('0.0.0.0', 6543, app)
        server.serve_forever()
    
  6. Run the WSGI application with:

    $ $VENV/bin/python tutorial/app.py
    
  7. Open http://localhost:6543/ in your browser.

Analysis

Python packages give us an organized unit of project development. Python projects, via setup.py, gives us special features when our package is installed (in this case, in local development mode.)

In this step we have a Python package called tutorial. We use the same name in each step of the tutorial, to avoid unnecessary retyping.

Above this tutorial directory we have the files that handle the packaging of this project. At the moment, all we need is a bare-bones setup.py.

Everything else is the same about our application. We simply made a Python package with a setup.py and installed it in development mode.

Note that the way we're running the app (python tutorial/app.py) is a bit of an odd duck. We would never do this unless we were writing a tutorial that tries to capture how this stuff works a step at a time. It's generally a bad idea to run a Python module inside a package directly as a script.