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.

It is recommended you organize your code in a Python project with a
setup.py 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.

This setup.py assumes you also have a myproject subdirectory
in your project directory that is a Python package, i.e. it contains
an __init__.py. 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 main() function in the myproject.main
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 pythonsetup.pydevelop, or pipinstall-e. from within a virtualenv.

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

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 __init__.py.

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

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 main module is also a good place to do other general configuration
for the application, such as setting up a database connection.

If you for some reason get 404NotFound 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 setup.py with an
install_requires that depends 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 pipinstall-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 __init__.py. Modules in the top-level of a
project won’t be scanned as a package

Check whether manually scanning the individual modules or packages
helps. Try writing this code in main instead of autosetup:

Alternatively you can try moving your code into main.py and see
whether it starts working.

If this fixes things, then your Python package seems not to be
properly installed as a Python package; only the main module get
scanned properly. Morepath should be able to pick up everything in
your package if only you organize it correctly.

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 setup.py so we also require
waitress:

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 wsgi.py:

The model.py 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
model.py that just uses plain Python classes:

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.

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 collection.py module. This module,
like model.py also does not have any dependencies on Morepath.

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.