Today I wanted to set up a quick web script; just something that ran on the Apache server I already had set up, took some query parameters and spat out a basic page in response. My usual go-to for this kind of thing would typically be PHP, because it's so quick to throw together and deploy. But this time, I wanted to see what the Python equivalent would be. Is it possible to write a quick Python script, drop it on a server and have it just work? Well, yes, it turns out it is. Or very close, at least. Here's how...

Step 1: Get Apache

For the purposes of this tutorial, we're going to use Apache because if you're running PHP, you most likely already have it set up - they're a popular combination. If it isn't already installed, you'll find it in your package repository or there'll be an installer on the website. In Debian-based flavours of Linux, it's a one-liner:

$ sudo apt-get install apache2

To check that Apache is set up, you'll want to visit localhost in your browser (perhaps localhost:8080, depending on the default config), and make sure you're greeted with the "it works!" page, or whatever.

Step 2: Get Python

You'll need the Python interpreter to execute Python scripts. Again, your package manager will almost certainly list it, or else you can find an installer on the Python website. For Debian, it's just:

$ sudo apt-get install python

Step 3: Mod-WSGI

There are a bunch of different ways of using Python for the web, but if you're interested in having your script be compatible with a wide number of different environments, the WSGI standard is the way to go. Short for Web Standard Gateway Interface, this is a spec that was drawn up in 2003 as a standard way for web servers to interface with the Python application running on it. It's been widely adopted by many Python web frameworks, as it allows you to develop a web application that can run on many different web servers.

Mod-WSGI lets us serve WSGI-compatible scripts via Apache, in the same way that Mod-PHP serves PHP scripts. It is likely to be present in your package manager on Linux, but otherwise you will need to follow the installation guide. In Debian, using Python 2, it's:

$ sudo apt-get install libapache2-mod-wsgi

Or for Python 3, make sure you use:

$ sudo apt-get install libapache2-mod-wsgi-py3

Step 4: Write a Script

Writing a WSGI-compatible Python script is as simple as implementing a single function. Here's the basic "Hello World" script that responds with some text:


def application( environment, start_response ):
    start_response( '200 OK', [( 'Content-Type', 'text/plain' )] )
    return [ 'Hello World' ]

We implement a function called application, and this takes 2 parameters. The first parameter is a dictionary of values from the web server. This contains things like the query parameters, the path of the document root, and so on.

The second parameter is a function which we can call to start outputting the response. The first parameter to this function is the HTTP status code, which will be "200 OK" for a successful request. The second parameter is a list of headers to include in the response. In the example above, we just output a single "Content-Type" header to tell the browser to treat the content as plain text.

The return value of this application function must be an iterable containing the response body. The reason for an iterable is simply to make it convenient to build up the response in stages. It allows us to, for example, use a generator instead to yield bits of the response as we go along.

Step 5: Create a Home For Your Web Scripts

Now we need to create a directory to put our web scripts in, so that Apache can find them. Note, this should not be Apache's document root, because if we put a script there Apache will serve up the source code instead of running it.

We'll create the example directory suggested in Mod-WSGI's documentation, but this could be whatever you like:

$ sudo mkdir -p /usr/local/www/wsgi-scripts

You should put your test WSGI script in this directory.

Step 6: Configure Apache

Finally we need to tell Apache how to serve up the WSGI script. Locate your Apache config file. On my Linux setup this was /etc/apache2/apache2.conf, but it can also be typically found at /etc/httpd/httpd.conf. At the bottom of the file, we'll add the following directive. This ensures that Apache can access our scripts directory:

<Directory /usr/local/www/wsgi-scripts>
Order allow,deny
Allow from all
</Directory>

And below this, we must add a directive to tell Apache what URL to map our script to. The first parameter to WSGIScriptAlias is the URL path the application will reside under. The second parameter is the file system path to the script file itself:

WSGIScriptAlias /test /usr/local/www/wsgi-scripts/myscript.wsgi

Depending on your version of Apache, you may need to use Require all granted instead of the Order and Allow lines.

We'll need to restart Apache to make these changes take effect:

$ sudo service apache2 restart

Now, when you visit http://localhost/test you should see the output from the Python script, "Hello World".

Errors

If there is an error in the Python script, Apache will instead report "500: Internal Server Error". The reason for the error can be found in the Apache error log. On my setup this was at /var/log/apache/error.log.

Conclusion

This makes for a fairly straightforward setup that gets you from Python to browser in a minimal number of steps, and in a way that allows you to progress to one of the many WSGI-compatible web frameworks if your script grows in complexity.

It's still not quite as easy to deploy as PHP, as each new script will require a new WSGIScriptAlias directive and a restart of Apache, but it's not bad.

Have fun writing quick web scripts in Python!