2012-02-18

Django Settings: Three Things Conflated

If you work on a large Django project, there's a good chance that you would describe your settings file as "a mess" (or perhaps you use harsher language). You may even have broken your settings out into a whole package with multiple files to try and keep things organized. We're highly skilled and organized developers, how does this happen to us?

I believe part of the problem is that the "settings" bucket holds three different kinds of things without differentiating between them. If you make a clear distinction between these things in your own mind (and in your code), dealing with settings will become easier, if not easy.

Project composition

The first class of settings comprises those used for project composition. One of the killer features of Django is that projects are composed of independent modules (apps). The most important settings in your project's settings file define what apps make up the project and how they interact with each other. In other frameworks this would be done with code (well, technically settings are Python code), but in Django this is treated as configuration. Things like INSTALLED_APPS, MIDDLEWARE_CLASSES, and TEMPLATE_CONTEXT_PROCESSORS define how the components of your project are combined to achieve the desired functionality.

Settings whose values are (possibly a list of) Python modules normally fall into this category.

External resources

The second class of settings comprises those used for connecting to external resources. This is the area most broadly recognized as configuration. Settings like DATABASES and CACHES fall into this category. These are the things that The Twelve Factor App says should be provided by environment variables, and in fact it's not that difficult to pull these values into your settings from the environment.

In addition to the obvious dictionaries defining pluggable back-ends, any setting whose value is a file system path or a URL likely falls into this category.

Tunable parameters

The final class of settings comprises tunable parameters, things that are mostly constants or variables that are abstracted out because 1) hard-coded values are bad, and 2) you (or users of the code) might want to change the values from the defaults. Things like CACHE_MIDDLEWARE_SECONDS, DEBUG flags,  DATE_FORMAT, and so on are examples of tunable parameters.

This is the area of greatest multiplication. Virtually every app you pull into your project is going to have some tunable parameters.

Conclusion

Armed with the understanding of the three kinds of values in your settings, you may now be able to devise a superior method of organizing them. You might start by sorting your settings.py file into three sections. Or you might decide to break them out into separate files in a package. Maybe you'll start using different tools to manage the three types of settings differently. I don't know, I don't have the solution to this problem right now, just this one nugget of insight.

What successful methods have you used to organize settings in large projects?

2012-02-11

Heroku and the Twelve Factor App: Architecting for High Velocity Web Operations

A while back I wrote that infrastructure should be delivered as code along with every web application, because web applications are not run by users, they are operated on behalf of users, and are therefore incomplete without the infrastructure needed to operate them. In that article, I mentioned Heroku, a platform-as-a-service company that makes a living operating other people's web applications. Inspired by their experience in web operations, some of those folks recently wrote a guide to creating web applications that can be operated easily. They call it The Twelve Factor App.

There is a great deal to be learned from this 12 Factor guide and the platform Heroku has designed. Their business depends on consistent, repeatable, and successful deployment and operation of web applications, and they have this stuff precision-cut and well oiled. The guide, and the Heroku platform, make a clear distinction between what is part of the platform, and what is part of the application. Even if you are heeding my earlier advice and delivering infrastructure with your applications, you will benefit from understanding the points of separation 12 Factor recommends between your application and the platform on which it runs.

I had been planning to summarize each factor here, but the descriptions at the web site are sufficiently concise that summary seems redundant. Just click through the links for each factor and read, it will only take you a few minutes, and it will be well worth your time.

1. One codebase tracked in revision control, many deploys.
2. Explicitly declare and isolate dependencies.
3. Store config in the environment.
4. Treat backing services as attached resources.
5. Strictly separate build and run stages.
6. Execute the app as one or more stateless processes.
7. Export services via port binding.
8. Scale out via the process model.
9. Maximize robustness with fast startup and graceful shutdown.
10. Keep development, staging, and production as similar as possible.
11. Treat logs as event streams.
12. Run admin/management tasks as one-off processes (see 6 above).