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
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!