A Flask Mega-Tutorial: Part II

In Part I, we set up a virtual environment and installed a few too many modules in it. In this part, we’ll look over the directory hierarchy and start creating an application that can load configuration.

Remember to navigate to that ppppp.git repository of ours, and source venv/bin/activate.

A Directory Structure

The following is a suggested directory structure for the application. While I’m fairly certain this works, I’m open to suggestions on whether it is the best possible layout. Note that in my own application, I’ve not yet started using Blueprints nor Views yet, but may end up doing so, and I will definitely have an API exposed (possibly RESTful), that is also not included here.

In summary, this includes:

docs/

This directory will hold the Sphinx documentation for your project. Another part of this mega-tutorial may be dedicated to just that.

ppppp/

The application root directory for your application. This is where Flask will search for templates, static contents, themes, translations, and anything you’ll want to address with from ppppp.module import foo.

migrations/

Database migration scripts.

tests/

Your unit and functional tests, as well as your fixtures for those tests.

You will serve and use all of this from a file in the root of the GIT repository, named manage.py. Let’s get started!

Hello World!

For a first application, we’re going to spit out the infamous “Hello World!” phrase. Note that the shebang is important, and allows the virtual environment to be used as opposed to the system-wide Python installation.

Save this off, make it executable, commit it to GIT and run it with ./manage.py. Then visit http://127.0.0.1:5000 (or wherever it says it runs on the console). You should see your message appear.

Note that syntax errors and other such errors notwithstanding, the application should automatically reload (and do so successfully) when you change any of the already loaded files, as it monitors the filesystem underneath the application for changed files.

Loading Configuration

Now, we’re going to want to load this application with some configuration. We can do this with the app.config object already available. Create a empty file ppppp/__init__.py and another one ppppp/default_settings.py containing the following:

On a general note, I tend to use single quotes for strings of which I do not make up the value willy nilly, and double quotes for those that I do.

Note that none of these settings have any effect as of yet.

Now, you can modify manage.py such that it loads this configuration file:

(...)
app = Flask('ppppp')

# Load default configuration
app.config.from_object('ppppp.default_settings')
(...)

This should allow you to substitute your return “Hello World!” for any of those configured items, such as:

(...)
@app.route('/')
def root():
    return app.config.get('THEMES_PATH', None)
(...)

Your manage.py should now look as follows:

We can now make this a multi-faceted, white-label site by also loading configuration from a file contained in an environment variable:

(...)
app.config.from_object('ppppp.default_settings')

import os
if os.environ.has_key('PPPPP_SETTINGS'):
    if os.path.isfile(os.environ['PPPPP_SETTINGS']):
        app.config.from_envvar('PPPPP_SETTINGS')
(...)

Making manage.py look as follows:

This is the end of Part II, I mean to address the following topics in future parts:

  • testing, testing, testing
  • rendering pages from templates
  • creating the base layout and extend it
  • error handling
  • the database model
  • rendering pages from themed templates
  • base and themed asset management
  • localization
  • localization of the database contents
  • language and theme selection

UPDATE: When I said I had not yet even drafted Part III on testing, I could not resist to get started. In writing it though, I discovered some typos. Yey for testing! The typos have obviously been corrected.

Advertisements