Organizing your Project


Morepath does not put any requirements on how your Python code is organized. You can organize your Python project as you see fit and put app classes, paths, views, etc, anywhere you like. A single Python package (or even module) may define a single Morepath app, but could also define multiple apps. In this Morepath is like Python itself; the Python language does not restrict you in how you organize functions and classes.

While this leaves you free to organize your code as you see fit, that doesn’t mean that your code shouldn’t be organized. Here are some guidelines on how you may want to organize things in your own project. But remember: these are guidelines to break when you see the need.

Python project

It is recommended you organize your code in a Python project with a where you declare the dependency on Morepath. If you’re unfamiliar with how this works, you can check out this tutorial.

Doing this is good Python practice and makes it easy for you to install and distribute your project using common tools like pip, buildout and PyPI. In addition Morepath itself can also load its code more easily.

Project layout

Here’s a quick overview of the files and directories of Morepath project that follows the guidelines in this document:


Project setup

Here is an example of your project’s with only those things relevant to Morepath shown and everything else cut out:

from setuptools import setup, find_packages

         'console_scripts': [
          'myproject-start ='

This assumes you also have a myproject subdirectory in your project directory that is a Python package, i.e. it contains an This is the directory where you put your code. The find_packages() call finds it for you.

The install_requires section declares the dependency on Morepath. Doing this makes everybody who installs your project automatically also pull in a release of Morepath and its own dependencies. In addition, it lets this package be found and configured when you use morepath.autosetup().

Finally there is an entry_points section that declares a console script (something you can run on the command-prompt of your operating system). When you install this project, a myproject-start script is automatically generated that you can use to start up the web server. It calls the run() function in the module. Let’s create this next.

You now need to install this project. If you want to install this project for development purposes you can use python develop, or pip install -e . from within a virtualenv.

See also the setuptools documentation.

Project naming

Its possible to name your project differently than you name your Python package; you could for instance have the name ThisProject in, and then have your Python package be still called myproject. We recommend naming the project the same as the Python package to avoid confusion.

Namespace packages

Sometimes you have projects that are grouped in some way: they are all created by the same organization or they are part of the same larger project. In that case you can use Python namespace packages to make this relationship clear. Let’s say you have a larger project called myproject. The namespace package itself may not contain any code, so unlike the example everywhere else in this document the myproject directory is always empty but for a

Different sub-projects could then be called myproject.core,, etc. Let’s examine the files and directories of myproject.core:


The change is the namespace package directory myproject that contains a single file,, that contains the following code to declare it is a namespace package:


Inside is the normal package called core. is modified too to include a declaration in namespace_packages, and we’ve changed the entry point:

         'console_scripts': [
          'myproject.core-start ='

See also the namespace packages documentation.

App Module

The module is where we define our Morepath app. Here’s a sketch of

import morepath

class App(morepath.App):

Run Module

In the module we define how our application should be served. We take the App class defined in, then have a run() function that is going to be called by the myproject-start entry point we defined in

from .app import App

def run():

This run function does two things:

  • Use morepath.autosetup() to set up Morepath, including any of your code.
  • start a WSGI server for the App instance on port localhost, port 5000. This uses the standard library wsgiref WSGI server. Note that this should only used for testing purposes, not production! For production, use an external WSGI server.

The run module is also a good place to do other general configuration for the application, such as setting up a database connection.

Debugging scanning problems

If you for some reason get 404 Not Found errors where you expect some content, something may have gone wrong with scanning the configuration of your project. Here’s a checklist:

  • Check whether your project has a with an install_requires that depends on morepath (possibly indirectly through another dependency). You need to declare your code as a project so that autosetup can find it.

  • Check whether your project is installed in a virtualenv using pip install -e . or in a buildout. Morepath needs to be able to find your project in order to scan it.

  • Be sure that you have your modules in an actual sub-directory to the project with its own Modules in the top-level of a project won’t be scanned as a package

  • Try manually scanning a package and see whether it works then:

    import mysterious_package

    If this fixes things, the package is somehow not being picked up for automatic scanning. Check the package’s

  • Try manually importing the modules before doing a morepath.autosetup() and see whether it works then:

    import mysterious_module

    If this fixes things, then your own package is not being picked up as a Morepath package for some reason.

  • Try moving Morepath directives into the module that also runs the application. If this works, your own package is not recognized as a proper Morepath package.

Variation: automatic restart

During development it can be very helpful to have the WSGI server restart the Morepath app whenever a file is changed.

Morepath’s built in development server does not offer this feature, but you can accomplish it with Werkzeug’s server.

First install the Werkzeug package into your project. Then modify your run module to look like this:

import morepath
from werkzeug.serving import run_simple
from .app import App

def run():
    run_simple('localhost', 8080, App(), use_reloader=True)

Using this runner changes to Python code in your package trigger a restart of the WSGI server.

Variation: no or multiple entry points

Not all packages have an entry point to start it up: a framework app that isn’t intended to be run directly may not define one. Some packages may define multiple apps and multiple entry points.

Variation: waitress

Instead of using Morepath’s simple built-in WSGI server you can use another WSGI server. The built-in WSGI server is only meant for testing, so we strongly recommend doing so in production. Here’s how you’d use Waitress. First we adjust so we also require waitress:


Then we modify to use waitress:

import waitress


def run():

Variation: command-line WSGI servers

You could also do away with the entry point and instead use waitress-serve on the command line directly. For this we need to first create a factory function that returns the fully configured WSGI app:

def wsgi_factory():
   return App()

$ waitress-serve --call

This uses waitress’s --call functionality to invoke a WSGI factory instead of a WSGI function. If you want to use a WSGI function directly we have to create one using the wsgi_factory function we just defined. To avoid circular dependencies you should do it in a separate module that is only used for this purpose, say

prepared_app = wsgi_factory()

You can then do:

$ waitress-serve myproject.wsgi:prepared_app

You can also use gunicorn this way:

$ gunicorn -w 4 myproject.wsgi:prepared_app

Model module

The module is where we define the models relevant to the web application. They may integrate with some kind of database system, for instance the SQLAlchemy ORM. Note that your model code is completely independent from Morepath and there is no reason to import anything Morepath related into this module. Here is an example that just uses plain Python classes:

class Document(object):
    def __init__(self, id, title, content): = id
        self.title = title
        self.content = content

Variation: models elsewhere

Sometimes you don’t want to include model definitions in the same codebase that also implements a web application, as you would like to reuse them outside of the web context without any dependencies on Morepath. Your model classes are independent from Morepath, so this is easy to do: just put them in a separate project and depend on it from your web project.

You can also have a project that reuses models defined by another Morepath project. Each Morepath app is isolated from the others by default, so you could remix its models into a whole new web application.

Variation: collection module

An application tends to contain two kinds of models:

  • content object models, i.e. a Document. If you use an ORM like SQLAlchemy these would typically be backed by a table.
  • collection models, i.e. a collection of documents. This typically let you browse content models, search/filter for them, and let you add or remove them.

Since collection models tend to not be backed by a database directly but are often application-specific classes, it can make sense to maintain them in a separate module. This module, like also does not have any dependencies on Morepath.

Path module

Now that we have models, we need to publish them on the web. First we need to define their paths. We do this in a module:

from .app import App
from . import model

@App.path(model=model.Document, path='documents/{id}')
def get_document(id):
   if id != 'foo':
      return None # not found
   return Document('foo', 'Foo document', 'FOO!')

In the functions decorated by App.path() we do whatever query is necessary to retrieve the model instance from a database, or return None if the model cannot be found.

Morepath allows you to scatter @App.path decorators throughout your codebase, but by putting them all together in a single module it becomes really easy to inspect and adjust the URL structure of your application, and to see exactly what is done to query or construct the model instances. Once it becomes really big you can always split a single path module into multiple ones, though at that point you may want to consider splitting off a separate project with its own application instead.

View module

We have models and they’re published on a path. Now we need to represent them as actual web resources. We do this in the module:

from .app import App
from . import model

def document_default(self, request):
    return {'id':, 'title': self.title, 'content': self.content }

Here we use App.view(), App.json() and App.html() directives to declare views.

By putting them all in a view module it becomes easy to inspect and adjust how models are represented, but of course if this becomes large it’s easy to split it into multiple modules.

Directive debugging

Morepath’s directive issue log messages that can help you debug your application: see Logging for more information.