Connecting Python To Apache On My MacBook Pro Using A VirtualHost

Posted August 9, 2010 at 8:59 AM by Ben Nadel

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:

127.0.0.1 python.bennadel.com

Once this entry was added to my hosts file, all browsers requests made for "python.bennadel.com" would evaluate to 127.0.0.1.

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

  • <VirtualHost *:80>
  •  
  • # Hook virtual host domain name into physical location.
  • ServerName python.bennadel.com
  • DocumentRoot "/Sites/bennadel.com/testing/python"
  •  
  • # Log errors to a custom log file.
  • ErrorLog /private/etc/apache2/logs/python.bennadel.com.log
  •  
  • # 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/bennadel.com/testing/python">
  •  
  • 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

Aug 9, 2010 at 9:18 AM // reply »
1 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!


Aug 9, 2010 at 9:34 AM // reply »
92 Comments

Ben...

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:
http://www.webmonkey.com/2010/02/get_started_with_python/

and this

http://code.google.com/edu/languages/google-python-class/

and @wizputer uses Python at Mahalo.

and I just bought this book:
http://www.amazon.com/Learning-Python-Powerful-Object-Oriented-Programming/dp/0596158068/ref=sr_1_1?ie=UTF8&s=books&qid=1281360849&sr=8-1


Aug 9, 2010 at 9:54 AM // reply »
5 Comments

Thanks for the timely post, Ben. It just so happens that I've been starting to tinker with Python, too!


Aug 9, 2010 at 10:02 AM // reply »
44 Comments

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.


Aug 9, 2010 at 10:06 AM // reply »
92 Comments

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".


Aug 9, 2010 at 10:16 AM // reply »
11,241 Comments

@Jeff,

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.

@Andy,

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.


Aug 9, 2010 at 10:17 AM // reply »
11,241 Comments

@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.


Aug 9, 2010 at 10:33 AM // reply »
92 Comments

Ben...

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.


Aug 9, 2010 at 10:40 AM // reply »
11,241 Comments

@Andy,

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.


Aug 9, 2010 at 11:09 AM // reply »
92 Comments

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.


Aug 9, 2010 at 7:48 PM // reply »
113 Comments

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.


Aug 9, 2010 at 10:40 PM // reply »
11,241 Comments

@Justice,

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:

http://www.bennadel.com/blog/1979-Connecting-Ruby-To-Apache-On-My-MacBook-Pro-Using-A-VirtualHost.htm

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).


Aug 10, 2010 at 8:16 AM // reply »
74 Comments

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


Aug 10, 2010 at 10:38 AM // reply »
24 Comments

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!


Aug 10, 2010 at 10:53 AM // reply »
11,241 Comments

@Tony,

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.


Aug 10, 2010 at 11:10 AM // reply »
92 Comments

I discovered TextWrangler recently and I'm liking it. It's no EditPlus but it seems solid and does most of what I need.


Aug 10, 2010 at 1:29 PM // reply »
74 Comments

@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


Aug 10, 2010 at 2:05 PM // reply »
11,241 Comments

@Wendy,

No worries - moving this comment would require me to actually go into the database - way too much effort.


Aug 10, 2010 at 3:18 PM // reply »
74 Comments

Okay, no worries then. If it doesn't bug you, it doesn't bug me. Just listen to the album. :)


ym
Apr 8, 2012 at 8:27 AM // reply »
1 Comments

hi. i read ur post,i succeeded: http://as3.brite.biz/test.py,but how to integrate apache and python app?i installed an python app here: http://as3.brite.biz:8000/


Sep 14, 2012 at 11:37 AM // reply »
1 Comments

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



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 22, 2013 at 11:47 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dana, Awesome - so it looks like this bug was fixed in ColdFusion 10. Thanks so much for double-checking that. ... read »
May 22, 2013 at 11:37 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
When I c&p and run on cf10, I get: Selected User IDs: 1,4 User 1 selected: YES - YES User 2 selected: NO - NO User 3 selected: NO - NO User 4 selected: YES - YES User 5 selected: NO - ... read »
May 22, 2013 at 11:27 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Tom, Good thought, but no dice. Both of these still exhibit the same behavior: users.id[ users.currentRow ] users[ "id" ][ users.currentRow ] It's just something whacky happening with ... read »
May 22, 2013 at 11:07 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
Could your problem be that "users.id" is actually an ARRAY, not a single value? Perhaps try it again with "users.id[1]" (I only have CF8 here at work). ... read »
May 22, 2013 at 7:52 AM
Nested Views, Routing, And Deep Linking With AngularJS
Hi, Just a quick thank you. As it happens, for my own purposes, the pending ui-router work being done in native angular is likely the one I'll adopt, but your exploration, code and documentation of ... read »
May 22, 2013 at 4:43 AM
How Do You Use The ColdFusion CFParam Tag?
'<cfparam>' or 'isDefined()and <cfset>' performs the same task.Is there any difference? ... read »
May 21, 2013 at 7:46 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
No luck. At least I have uncovered the cause, URLScan 3.1. Here is what I see in the IIS log when a file is over 30mb. 2013-05-21 23:29:05 10.105.45.128 GET /plupload/assets/jquery/jquery-1.8. ... read »
May 21, 2013 at 6:12 PM
Using Plupload For Drag & Drop File Uploads In ColdFusion
Ben, I did not see you after Pete Freitag's Lockdown session at cfObjective but he said that IIS sets file size limits at 30MB by default which just happened to be the threshold for file size when ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools