Easy way to get Apache and MOD_WSGI working on OS X

I’ve fooled around with some Python Web-frameworks lately, and maybe someone would care to know that you don’t have to install MAMP or XXAMP or whatever they are called, because as you probably already know, OS X does have Apache 2 Server already installed, just waiting to be configured to your needs.
Off course, it is very easy and convenient in many cases to just push a button and have it all working, but I always like to have total control over the environment when I do stuff like this, so…
I don’t know if these packages support mod_wsgi anyway, so I’ll explain how to get things going the hard way! Similarly you could enable PHP, but that is a nother story.

This is about getting Python web hosting locally, so you can set up frameworks like Django, py2web and the likes.

I’m using OS X 10.7 (Lion), but I think this will work just as fine with older versions, but then you’ll get the module linked to an older release of Python by default.

Here is some information on mod_wsgi:

The aim of mod_wsgi is to implement a simple to use Apache module which can host any Python application which supports the Python WSGI interface. The module would be suitable for use in hosting high performance production web sites, as well as your average self managed personal sites running on web hosting services.
The mod_wsgi module is written in C code directly against the internal Apache and Python application programming interfaces. As such, for hosting WSGI applications in conjunction with Apache it has a lower memory overhead and performs better than existing WSGI adapters for mod_python or alternative FASTCGI/SCGI/CGI or proxy based solutions.

As mod_wsgi supports the WSGI interface specification, any Python web framework or application which is compatible with the WSGI interface specification should be able to be hosted on top of mod_wsgi.

Major Python web frameworks and toolkits which are known to work include CherryPy, Django, Pylons, TurboGears, Pyramid, web.py, Werkzeug, Web2Py and Zope. Major Python web applications which are known to work include MoinMoin, PyBlosxom and Trac.

How to set it up using the internal Apache web server on OS X:

Download the latest version of mod_wsgi from:

Unpack the sources, and do the usual:

sudo make install

(if you have an older version of OS X, and would like to link to a newer Python version you have installed, use the

–with-python=/path/to/your_python with ./configure command)

Then, you have to edit the Apache configuration to load the newly installed module:

sudo vi /private/etc/apache2/httpd.conf

After the list of default modules to load type in:

#Load mod_wsgi module:
LoadModule wsgi_module libexec/apache2/mod_wsgi.so
WSGIScriptAlias / /Library/WebServer/Documents/

Now you should be ready to serve Python content on the local Apache server that comes with OS X.

To try out your new configuration, create the following .py file, and save it to your document root folder /Library/WebServer/Documents/testpy.py:

def application(environ, start_response):
status = ‘200 OK’
output = ‘Hello World!’

response_headers = [(‘Content-type’, ‘text/plain’),
(‘Content-Length’, str(len(output)))]
start_response(status, response_headers)

return [output]

Start the web server via System Preferences -> Sharing -> Web Sharing
or via the
sudo /usr/sbin/apachectl start
Terminal command

Visit http://localhost/testpy.py
You should be greeted with the notorious “Hello World!” message, indicating that you now serve Python locally via Apache and mod_wsgi!


10 thoughts on “Easy way to get Apache and MOD_WSGI working on OS X

  1. Hello! Great post, really helped me!

    I was wondering if there would be a way to enable users to run their own python wsgi scripts from their own ~/Sites/cgi-bin directory and how would that be configured.

    I’m trying:

    #WSGIScriptAlias /scripts /Library/WebServer/CGI-Executables
    WSGIScriptAliasMatch ^/~([^/]*)/cgi-bin/(.*) /Users/$1/Sites/cgi-bin/$2

    AllowOverride None
    Options None
    Order allow,deny
    Allow from all

    But it doesn’t seem to work, it just outputs the contents of the file.
    The file has exec perms and the same script works when I run the script from the default /Library/WebServer/CGI-Executables directory.

    Any clues?


  2. Great post, thanks. Just two very minor issues with the test.py code:
    1) Some of the single-quote characters are weird and need to be replaced by ‘ so the code compiles.
    2) Obviously if copy-pasting the code, need to indent all but the first line, as it’s a single function def.

  3. I really love your site.. Very nice colors & theme. Did you create this web site yourself?

    Please reply back as I’m wanting to create my own personal website and would like to learn where you got this from or what the theme is named. Many thanks!

  4. Very useful post — thanks a bunch; it really helped get me off the ground! One thing I’d add, though (note: I’m running OS X 10.6):

    If you define WSGIScriptAlias using just the format shown above ( WSGIScriptAlias / /Library/WebServer/Documents/), I believe you’re essentially telling the service that everything at your document root is be interpreted as a wsgi script. This breaks the document root for anything that’s _not_ a wsgi application, for example, http://localhost will result in the dreaded “Error 403 Forbidden” response. Should that be the case for your configuration, a check of the apache error log at /var/log/apache2/error_log will confirm, as it’ll contain the message “Attempt to invoke directory as WSGI application: /Library/WebServer/Documents/”

    A better and, thankfully, simple solution is to define a subdirectory (or tree) just for wsgi scripts, e.g., WSGIScriptAlias /wsgi /Library/WebServer/Documents/wsgi, into which you’ll place testpy.py.

    With this configuration, you can run the wsgi test using http://localhost/wsgi/testpy.py, while still being able to access the system test page at http://localhost without error.

  5. I did what Greg suggeested:
    WSGIScriptAlias /wsgi /Library/WebServer/Documents/wsgi

    Now going to http://localhost/wsgi/testpy.py just gives me a page with the following text.:
    This text is displayed by a Python script, executed via the webapp.plist(8) mechanism.
    Python version 2.7.5 running mod_wsgi.

    The same text is displayed at http://localhost/wsgi/ 😦

    What I want to see is ‘Hello World’ as ouput by the testpy.py script. Any ideas as to why I’m not seeing this?

  6. Ok I have figured it out as frequently happens after I post a question somewhere!

    I am using Mavericks and it appears that its file structure is different than previous versions of OS X. The webserver’s httpd.conf file is in /Library/Server/Web/Config/apache2/ instead of /private/etc/apache2/.

Comments are closed.