Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at the New York ColdFusion User Group (Jan. 2009) with: Ray Camden
Ben Nadel at the New York ColdFusion User Group (Jan. 2009) with: Ray Camden@cfjedimaster )

Connecting Python To Apache On My MacBook Pro Using A VirtualHost

By Ben Nadel on
Tags: Python

I've never programmed anything in Python before; but, seeing as I have just recently switched from a PC over to a MacBook Pro, I figured I would try out as many of the computer's available features as possible. As I was looking through some of the core directories, I noticed that there were a few programming languages already installed; Python was one of these. As such, I wanted to connect it to my default Apache installation and see if I could get it running.

The first thing I had to do was add a mapping to my hosts file (/etc/hosts) that would direct a special "python" url to my local host address:

Once this entry was added to my hosts file, all browsers requests made for "" would evaluate to

Then, I had to add a VirtualHost entry in my Apache configuration that would map local requests for "" to a physical directory on my computer:

  • <VirtualHost *:80>
  • # Hook virtual host domain name into physical location.
  • ServerName
  • DocumentRoot "/Sites/"
  • # Log errors to a custom log file.
  • ErrorLog /private/etc/apache2/logs/
  • # Add python file extensions as CGI script handlers.
  • AddHandler cgi-script .py
  • # Be sure to add ** ExecCGI ** as an option in the document
  • # directory so Apache has permissions to run CGI scripts.
  • <Directory "/Sites/">
  • Options Indexes FollowSymLinks MultiViews ExecCGI
  • AllowOverride None
  • Order allow,deny
  • Allow from all
  • </Directory>
  • </VirtualHost>

In addition to mapping the python domain name to a directory on my machine, this VirtualHost entry is also telling Apache how to process Python (.py) code files. Python is a scripting language that understands the CGI (Common Gateway Interface) standard. As such, all we need to do is tell Apache to start using ".py" file extensions as a hook into the CGI script interpreter:

AddHandler cgi-script .py

In addition to doing this, we also need to provide Apache with permissions to execute CGI scripts in our mapped directory:

Options Indexes FollowSymLinks MultiViews ExecCGI

Here, the "ExecCGI" option tells Apache that it is OK to execute CGI scripts in the given directory.

Once this has been configured, we are now ready to execute our Python script files. I created a very simple "hello world" type example to see if everything was setup properly:

  • #! /usr/bin/python
  • # The preceeding line (starting with the shebang) is required to
  • # tell Apache where to find the Python interpreter for the
  • # following Python script. As far as I can tell, this has to be the
  • # first line in the file (even before any line breaks otherwise it
  • # will throw a "Premature end of script headers" error.
  • # ------------------------------------------------------------ #
  • # ------------------------------------------------------------ #
  • # Define our collection of girls. With brackets, we can create
  • # lists in Python - these are dynamically-sized arrays.
  • girls = [ "Tricia", "Sarah", "Joanna" ];
  • # ------------------------------------------------------------ #
  • # ------------------------------------------------------------ #
  • # Output the mime-type in the header.
  • print "Content-type: text/html\n\n";
  • # Output the page content. The triple quote allow us to create
  • # multi-line string values.
  • print """
  • <html>
  • <head>
  • <title>My First Python Script Running On Mac</title>
  • </head>
  • <body>
  • <h1>
  • My First Python Script Running On Mac
  • </h1>
  • <p>
  • Check out these groovy ladies:
  • </p>
  • <ul>
  • <li>""" + girls[ 0 ] + """</li>
  • <li>""" + girls[ 1 ] + """</li>
  • <li>""" + girls[ 2 ] + """</li>
  • </ul>
  • </body>
  • </html>
  • """;
  • # End print.

In the above code, the first line is absolutely crucial:

#! /usr/bin/python

Sometimes referred to as a "pound-bang" or a "shebang", this line of code tells the server where to find the Python interpreter. The server needs this binary in order to execute the rest of the code contained within the file.

It is also necessary that this directive appear as the very first line of code in the file. If you put so much as a line break before it, Apache will not know how to process the file and will result in a 500 Internal Server Error:

Premature end of script headers

NOTE: If you are getting a 401 Unauthorized error, you probably need to run a chmod command on the python script file to grant "everyone" read/write/execute permissions.

Once you have your hosts file updated, your Apache VirtualHost in place, and you have a Python file that starts out with a shebang, your Python code should execute successfully (assuming no coding errors exist). When I run the code above, I get the following page output:

My First Python Script Running On Mac

Check out these groovy ladies:
* Tricia
* Sarah
* Joanna

This is the first Python script that I have ever written, so I won't even try to explain how it is working, though I think it is fairly self-evident. Mostly, I just wanted to see if I could get Python to work on my Mac, period. And don't worry, I'm not about to stop programming in ColdFusion any time soon!

Reader Comments

Dude, you are on your way! Actually, the best thing about Python is that it doesn't have to be used for web development. You can learn to use it for general scripting on your Mac. If you want to get into it more, look into PIP and VirtualEnv. PIP is a Python packager which makes it real easy to install packages written by others. VirtualEnv allows you to create "virtual" Python environments so that you can have multiple Python environments that don't step on each other.

You will find that Python is a wonderful, powerful development tool, even if you never want to use it on the web. But if you do, Django is the way to go and its easy to get installed: "pip install django".

Maybe we'll see you at next year's PyCon!


I'm actually learning Python right now. You could change the lines containing the LI tags to something called a list comprehension. It looks like this:

['<li>%s</li> % g for g in girls]

And that would give you the same result. The %s is sort of like doing <li>#variable#</li> in ColdFusion, but %s indicates a string that follows the expression, %d is for numbers.

Python is bad to the bone. Gotta read through this:

and this

and @wizputer uses Python at Mahalo.

and I just bought this book:

All this talk about people trying out Python is incredibly eerie. I decided to start learning it on a total whim about two weeks ago. I'll have to keep an eye out for future Python posts.

Give me a few weeks to get a better grasp on Python and I'm planning on starting a short series on "Learning Python for ColdFusion developers".


I didn't really understand most of what you said :) But, I only just used Python for the first time. It never even occurred to me that you could use it for anything but web development, though I guess that is pretty much true for all programming languages.


Ahh, that's how it is done. When I was looking up some "intro" type articles on Python (to get even this far), I did see them reference things like this:

"....." % map

... where the string was executed in the context of the dictionary (ie. struct), "map." I had tried to do this in my example, but couldn't figure out how to get it to work with anything but static variables.

Thanks for tip! I'll be sure to check out the articles you posted.

@Jose, @Tony,

I recently pre-ordered a Pragmatic Programmers book, "Seven Languages in Seven Weeks." It does a high-level review of why some of the most popular languages are "most popular." It will be fun to start exploring some other concepts to see what is out there... and what kind of juicy goodness I can pull back into the ColdFusion world.


Jeff was talking about the fact that Python can actually be used to build "real" desktop-style software. It compiles at run time and generates a .pyc file, much like ColdFusion generates class files.

As far as PIP goes, while I've never heard of it, it sounds much like gem or rpm. You can install software packages through the Terminal window by issuing a simple shell command. "pip install django" actually goes out to the net, grabs the most recent version of django and installs it on your machine.


Sounds very interesting. I vaguely understand the concept of gems in Ruby and I've seen people just install them via the command line. I guess I've been on the web for so long, non-web concepts don't quite gel all that quickly.

I know exactly what you mean Ben. Believe it or not, the command line is one of the main reasons I've stayed away from looking into Ruby on Rails for so long. I'm decent with the command line, but I don't like being forced to use it just to install some directories.

The command line, command-based editors (Vim), and command-operated programs are indeed scary, have a long learning curve, and are many times more efficient than their graphical counterparts once learned. But there's not strictly any need to use them. You can certainly use the folder viewer and Eclipse to do Ruby+Rails/Sinatra/etc or Python+Django/Pylons/etc development and rarely touch the command line.


For the most part, I have stayed away from the command line. Certain actions, however, seem to require it. For example, it seems no matter what I do, I have to edit the "hosts" file from the command line, typically with:

nano hosts

(I can't remember offhand if I had to run "sudo" permissions for it). If I try to edit this file in TextEdit or Builder, it always fails to save. Even changing the access permissions in Finder seems to not do anything (unless I was simply messing something up).

Also, since you mentioned Ruby, I was able to get that configured as well via Apache:

I guess since both Ruby and Python are both adhering to the CGI standard, the setup for both is pretty much identical (this of course has nothing to do with Ruby On Rails).

If it *doesn't* make you cry, Ben, you gots no heart. Most soulful album I own. ;) (Vivian Green is often compared to Nina Simone, fyi :)Off to work out...

If you want to edit your hosts file outside the command line, you can do it with TextMate (well worth the 39 EUR., IMO). Then you can just type:

mate /etc/hosts

And your host file will open in the TextMate editor. When you save it will prompt you for your admin password and you're good to go!


I'll take a look into it. I've downloaded TextWrangler and have been somewhat enjoying it. I've heard great things about TextMate as well.

@Ben- Somehow I managed to post my comment about the Vivian Green album/song on this thread rather than on the right one- sorry! That's what I get for trying to post from my iPod in the middle of the night. Please feel free to delete it (I don't even understand the comments! :), or move it to the right thread. And listen to the album

Thanks Ben I was bit confused how to get apache playing nicely with python. Hard enough working out a new language without the setup :)