Basics of a Python Web Stack

When it comes to web development, you could fill warehouses with the stuff I don’t know. Five years ago, I knew a certain amount less than I do now — but there was also dramatically less to know. Reading this post (hn) today helped me to realize that if I do not take action, I may at some point look back at this point as the zenith of my knowledge, relative to what it takes to get a web application up and running.

As such, I’ve spent the last hour or two getting reacquainted with heroku (which, holy damn, heroku is so easy to use). I’ve followed their python tutorial and installed flask and whatnot, and realized that I’m very fortunate to already grok virtualenv, pip, flask, and gunicorn. The heroku docs do an excellent job of explaining how to set things up, if not what precisely they are. So, I decided to do some gap filling — here’s a brief overview of what these things are and why someone would use them:

virtualenv

Virtual Environments are used to create a python environment which is isolated from the rest of the machine. You can install packages into it and easily pack it up to move elsewhere, or duplicate it if needed. I can think of 5 things virtualenv makes it easy to do:

  1. Run multiple versions of python on one computer
  2. Avoid ongoing dependency conflicts between your own projects*
  3. Test/play with new libraries without messing other projects up*
  4. Identify requirements when packaging your code up to deploy
  5. Manage installed packages without being root or configuring by hand

* okay, these are the same problem, but they can come up independently of each other.

For ruby folks: think of virtualenv in the same vein as rvm, but with different philosophies. Some folks on hackernews suggested that an even better analog is rbenv, which I’ve never used — but it sure sounds right!

Typical usage is:

$ ls
$ virtualenv env
$ source env/bin/activate
(env)$ easy_install cool_module
(env)$ vim app.py
(env)$ cat app.py
import cool_module

# code which uses cool_module
...
(env)$ python app.py
# runs successfully
(env)$ deactivate
$ python app.py
# cool_module fails to import

Note the following:

  • On windows, ‘source env/bin/activate’ is ‘env\Scripts\activate.bat’
  • in bash, ‘source’ can be replaced by ‘.’ — it’s common to see ‘. env/bin/activate’ used
  • ‘env’ is just a common name; you can name an environment whatever you’d like
  • there are useful virtualenv switches which can be found by just running ‘virtualenv’, particularly ‘–distribute’, which adds pip by default.
  • ‘deactivate’ is added to your path by virtualenv; it is not a separate program.
  • virtualenv is a program that needs to be installed, either manually, via easy_install, pip, or a package manager. It will be part of future versions of python, but your computer does not have it by default because you have python.
  • there are many different setups of “where you put code” vs “where your env lives”, this is just one.
  • two advantages of not putting your code anywhere inside of your env/ folder are that you can put ‘env’ in your .gitignore, and that if things get messed up somehow, you can have a clean slate python-wise by rm -rf’ing your env directory.

Using virtualenv is very easy to do, and it will quickly become part of the mental model of your working environment. There is some streamlining left to do — ‘. env/bin/activate’ is cumbersome — but it’s a great tool.

pip

I can’t write anything much about pip that hasn’t been written. People have discussed python package management systems very thoroughly! A quick sum-up, then:

Pip is a nice package manager for python. It tracks dependencies, can install/uninstall modules, and can distill a list of requirements (‘pip freeze’), which is both human and machine-readable. Pip can even read from one of its requirements-lists and duplicate an environment. There are apparently things about pip that aren’t great, but I encourage you to go google about them if you care to.

Common usages are: ‘pip install cool_module’, ‘pip uninstall cool_module’, ‘pip freeze’, ‘pip install -r requirements.txt’

Flask

Flask is a web application framework, like Bottle or Sinatra, and to a lesser extent like Django, Rails, or Symfony. It actually started off as a joke! It has a fairly small code footprint and nice documentation. It uses the Jinja templating engine by default and Werkzeug for routing (if you know those things that’s meaningful), and is a very common choice for writing api servers at the moment. It’s pretty darn easy to get started with.

Because it has such a small codebase, it’s pretty easy to hack up and extend if you need to do that kind of thing (you probably don’t), and it’s got a lot of features to allow for modular code. It’s also got a lot of extension stuff available that can fill most of the gaps you might be looking for. If you’re coming from Django, it’s like starting with the minimum and building up to what you need instead of starting with the maximum and wishing you could shed a few pounds.

Rather than outright duplicate the fine documentation work that’s been done, I suggest you take a look at the Flask docs themselves for an introduction to how to use it.

Warnings: Advanced practices are not very well covered by the documentation, and there are some weird practices around importing and using flask extensions due to a funky design decision they made when Flask was young and are still safely backing out of. Occasionally you’ll find extensions written for an “old style” of Flask extension import. The “new style” of extension importing is intended to support both new and old Flask extensions, but it still occasionally breaks. It’s beyond me when it does — I had this happen attempting to use Flask’s OAuth extension.

gunicorn

Ah, now we’re almost completely outside of my sphere of knowledge. Gunicorn stands for “green unicorn”, and it’s a web server. It’s better than the one that comes with flask, and is quite popular. Alternatives are things like Tornado, nginx, or apache.

Before you think “oh, I have apache installed! I’ll just go do that then instead”, be warned: mod_wsgi can be a pretty major pain to set up and diagnose problems for. I’ve heard that mod_passenger is a better way to go, but I haven’t tried it myself. If you can avoid putting python on apache, it’s probably a good idea.

More things

I don’t know anything about front end frameworks like jQuery, Backbone, or Bootstrap, and I haven’t ever written coffeescript. They’re what I’m going to mess around with a bit this weekend — Backbone is just too new for me to have played with yet (or, I feel like it is!), while jQuery’s anonymous callbacks-with-params mess with my head when I try to build a mental model of how information flows through a program. I feel like I’m supposed to “just trust” that information is there, and that’s weird. We’ll see how I feel in a few days!

(Also, so long and thanks for a super towel day)

Leave a Reply

Your email address will not be published.