A Walkthrough of a Complex Flask App

August 1st, 2017


Flask is my favorite server framework, due to its clarity and flexibility. However, getting Flask beyond “Hello, World” always feels iffy, with most popular online tutorials being several years old and having been built by educators instead of veterans.

Sentry’s founder David Cramer recently started a new open source project called Zeus, which uses both my favorite tools (Flask, SQLAlchemy, Celery), and a few tools I’ve wanted to learn to use (Alembic, Redux). In typical Cramer fashion, the code base has blossomed to over 15,000 LOC and within weeks, is nearly a fully functional product. Even Armin himself has contributed a few hundred lines. As I work with Cramer and Armin, it’s a rare opportunity to understand, as the “ground level”, how large Flask applications are built.

README

The README itself is well structured—not just talking about what the app does, but how the directories and data models are structured: a definite rarity. The setup instructions have a make step, which executes the develop command within the Makefile. Of that various bits that executes, Zeus’ own setup.py is the most interesting.

## setup.py

This does a few things—install requirements, but also add the entrypoint is the main function within zeus/cli/__init__. This isn’t usually needed for small Flask apps, but it’s not uncommon for most open source tools to need cli commands.

entry_points={
    'console_scripts': ['zeus=zeus.cli:main'],
},

Now, when you run zeus init, it runs the init function within zeus/cli/init.py and when you run zeus devserver, it runs the devserver function within zeus/cli/devserver.py. devserver in turn, triggers the main server (zeus run) along with the background webpack and workers. FLASK_APP has been set to zeus.app earlier, to let’s follow that.

zeus/app.py

Basically, create_app, which is in config.py

zeus/config.py

All of the various configs go in here. There’s a treasure trove, like SQLALCHEMY_COMMIT_ON_TEARDOWN, but like the cave of wonders, we need to keep going. The core of it all is the Flask server object, instatiated at the beginning of create_all.