Django, mod_wsgi, Apache and OS X — do it.

July 24th, 2009 § 25 comments § permalink

whut_2.jpgSo, I’m one of those peo­ple where I don’t like run­ning things “too far” from what a pro­duc­tion setup might look like (I code on OS/X, deploy to Linux). This is why I jump(ed) through var­i­ous hoops on my OS X sys­tem to get Apache/Django/mod_wsgi/etc all up and run­ning and happy (not for serv­ing the site; just developing).

Since I like simple/succinct guides, I thought I’d post what I did so oth­ers can fol­low in my stead.

Note: These instruc­tions work with the python 2.5 ver­sion which ships with Leop­ard, or a self-compiled ver­sion of 2.6 (which is what I pre­fer) — see the Instal­la­tionOn­Ma­cOSX mod_wsgi page. Addi­tion­ally, see the “Miss­ing Code For Archi­tec­ture” sec­tion for pos­si­ble work-arounds if you find your­self need­ing 32 bit exe­cu­tion of Apache; I think the “Forc­ing 32 Bit Exe­cu­tion” are pre­ferred over the “thin­ning” of the Apache binary.

First, down­load and install mod_wsgi on leop­ard, this is as easy as (on Leopard):

curl -o mod_wsgi.tgz http://modwsgi.googlecode.com/files/mod_wsgi-2.5.tar.gz
tar -xzf mod_wsgi.tgz
cd mod_wsgi-2.5
./configure
make
sudo make install

Now, edit (via sudo) /etc/apache2/httpd.conf and add the line:

LoadModule wsgi_module libexec/apache2/mod_wsgi.so

After the rest of the Load­Mod­ule lines. Cool.

Invari­ably all of my direc­tions play with virtualenv/virtualenvwrapper and pip:

mkvirtualenv django
cdvirtualenv
easy_install pip
pip install http://media.djangoproject.com/releases/1.1/Django-1.1-rc-1.tar.gz
django-admin.py startproject mysite
django-admin.py startapp myapp
cd mysite
mkdir apache
mkdir media

Now, that just sets up the skele­ton — the meat of the wsgi con­fig­u­ra­tion goes in apache/ in the mysite/apache direc­tory. The first file is named mysite.wsgi:

?View Code PYTHON
1
2
3
4
5
6
7
8
9
10
11
import os, sys
 
#Calculate the path based on the location of the WSGI script.
apache_configuration = os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
 
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

This does the needed wsgi project magic for the Django appli­ca­tion — don’t worry about the inter­preter path; we’ll do that next.

Next up is a file named apache_django_wsgi.conf, this looks like this:

# mod_wsgi configuration directives - I like having stdout access, the other two
# options run mod_wsgi in daemon mode - more on this in a minute.
WSGIPythonHome /<path to virtualenv>
WSGIRestrictStdout Off
WSGIDaemonProcess django
WSGIProcessGroup django

#
# This should be the path of the /mysite/media directory
# for example "/Users/jesse/mysite/media/"
#
Alias /site_media/ "<PATH TO>/mysite/media/"
<Directory "<PATH TO>/mysite/media">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>

#
# Directory path to the admin media, for example:
#

Alias /media/ "<PATH TO>/virtualenv/site-packages/django/contrib/admin/media/"
<Directory "<PATH TO>/virtualenv/site-packages/django/contrib/admin/media">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>

#
# Path to the mysite.wsgi file, for example:
# "/Users/jesse/mysite/apache/mysite.wsgi"
#

WSGIScriptAlias / "<PATH TO>/mysite/apache/mysite.wsgi"

<Directory "<PATH TO>/mysite/apache">
Allow from all
</Directory>

The apache_django_wsgi.conf file is the meat-and-potatoes here. This sets up all the paths/permissions, and is in Apache httpd.conf for­mat. You can pretty much log­jam any apache con­fig­u­ra­tion direc­tive here that you like.

Your final step is to once again edit (via sudo) /etc/apache2/httpd.conf and add a line like this at the ver­rrrry bottom:

Include "/path to/mysite/apache/apache_django_wsgi.conf"

And then run “sudo apachectl restart”

You should now be able to hit http://127.0.0.1/ and see the friendly and invit­ing django wel­come page. Note, that if you are using sqlite as your data­base, you should chmod a+rw the file, so that processes which are not you can mess with it.

There’s a final piece to this though. Nor­mally, if you run mod_wsgi in embed­ded mode, you’re going to need to restart apache every sin­gle time you make a change to your django app.

Ah! But we’re run­ning in dae­mon mode. This means all you need to do when you change a file is:

touch mysite/apache/mysite.wsgi

This will trig­ger a reload and magic hap­pens. Me being as lazy as I am (ask my wife) ended up snag­ging Bruno Bord’s tdae­mon script, and hack­ing it up a bit. The tdae­mon script will watch a direc­tory and run tests. Well, I wanted it to watch a direc­tory (and let me fil­ter sub direc­to­ries) and then run that touch com­mand. So I reused my watcher.py (here) — I used this to mon­i­tor my sphinx tree and run builds as well (and other stuff). Here’s how I’d use this:

workon django
cdvirtualenv
cd mysite
python ~/.slash/bin/watcher.py --command "touch apache/mysite.wsgi" -f media

This will auto-fire the touch com­mand when­ever it detects a file change (includ­ing svn updates).

You can also do this another way
In my rush to reuse a tool I use a bit (watcher) I skipped past the mod_wsgi doc­u­ment sec­tion on code reload­ing that shows how to setup a mon­i­tor which will watch .py file changes and kill the wsgi dae­mon, here. If you scroll down a bit, you’ll see the “Mon­i­tor­ing For Code Changes” sec­tion. All you need to do here is copy the code from the wiki into a mod­ule on your PYTHONPATH — in my case, I wrote it to mysite/apache/wsgi_monitor.py (just for this exam­ple! you should put it some­place else!) and then changed the mysite.wsgi file to import it, and set it up:

?View Code PYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import os, sys
 
#Calculate the path based on the location of the WSGI script.
apache_configuration = os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
 
sys.path.append(apache_configuration) # you probably shouldn't do this.
import wsgi_monitor
wsgi_monitor.start(interval=1.0)
 
os.environ['DJANGO_SETTINGS_MODULE'] = 'ui.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

This method — once you reload apache — will watch the project for changes and then kill the wsgi dae­mon (forces a reload). So there you go — two ways of doing it.

The nice thing about this setup is that I can make pro­duc­tion ver­sion of the wsgi scripts and check them in, but keep local “my copies” (ala local_settings.py) addi­tion­ally, I don’t have to jump through hoops to get sta­tic media and con­tent served up via the django devel­op­ment server.

Addi­tional reading:

Evernote invites.

April 30th, 2008 § 28 comments § permalink

Just a quick note — I’ve got 10 Ever­note invites — if you don’t know what Ever­note is, check out the Ars review here. Post in the com­ments if you’d like to test drive it. I’m going to need an email address.

So far, I’m lov­ing it — but I’m also some­one with about 500+ book­marks in Safari, a ton of “to read” stuff saved on my hard drive, and over 100 RSS feeds in Net­NewsWire. So some­thing to help me archive/save/search every­thing is key.

Now I just want PDF index­ing support.

Ok, I have 10 more left!

Per Ars: Sun is talking about porting Java to the iPhone (and an idea for python)

March 8th, 2008 § 4 comments § permalink

coffee poster.pngOk. So Sun has come out stat­ing they’re start­ing work based on the SDK released by Apple for the iPhone ear­lier this week to port the JDK over to the iPhone.

Quot­ing the sun rep:

Now, the iPhone is open” as a tar­get plat­form, Klein said. The free JVM would be made avail­able via Apple’s App­Store mar­ket­place for third-party applications.

Now, as com­ments there and else­where have pointed out — there’s a clause in the Agree­ment that comes with the SDK for­bid­ding appli­ca­tions from being placed on the App­Store that can execute/interpret “other appli­ca­tions” — to whit:

3.3.2) An Appli­ca­tion may not itself install or launch other exe­cutable code by any means, includ­ing with­out lim­i­ta­tion through the use of a plug-in archi­tec­ture, call­ing other frame­works, other APIs or oth­er­wise. No inter­preted code may be down­loaded and used in an Appli­ca­tion except for code that is inter­preted and run by Apple’s Pub­lished APIs and builtin interpreter(s).

So — unless Sun plans on mak­ing a JDK that a) doesn’t run any­thing or b) can be com­piled into an appli­ca­tion that is to be sold on the App­Store (pro­vid­ing the run­time for the app, like a self-standing .jar/.war) then I can’t see this hap­pen­ing, and option a is about as use­ful as a toi­let bowl filled with taco meat.theoffice.jpg

On the other hand, option b: Mak­ing a run­time they release out­side of the app store for appli­ca­tion devel­op­ers to use to write an appli­ca­tion in Java and then have it compile-down to an Objective-C runtime/bytecode binary — then it could work, but those would be some *fat* bina­ries with­out a lot of magic.

Now — could the same thing be done with Python? Per­haps. Right now we have the pyObjC bridge that ships with Leop­ard that allows you mostly unfet­tered access into the Objective-C/OSX pro­gram­ming envi­ron­ment. This means you can build “native” appli­ca­tions in Python.

I doubt these bind­ings will work/exist on the iPhone, which means you want some util­ity to take Python code and “inter­pret” it down into an Objective-C binary, i.e.: an embed-able envi­ron­ment ala what Sun may end up hav­ing to do where you write an app in pyObjC/Python and the app+runtime is com­piled down into Objective-C.

Again, with­out a lot of trick­ery, these would be fatass bina­ries — prob­a­bly fat­ter than the notion of the uni­ver­sal bina­ries most peo­ple ship nowa­days for OS/X.

It’s a thought — now I should get back to pok­ing at Objective-C and other pre-pycon hack­ery. This is some­thing peo­ple more versed in com­pil­ers, run­times and with more free time than me will prob­a­bly explore.

For those of you looking to brush up/get into objective-c…

March 8th, 2008 § 4 comments § permalink

Because you, like me, are inter­ested in writ­ing some iPhone apps (and apple is only allow­ing objective-C stuff right now :sad:) — here is a free eBook I kept in my pocket for when I wanted to finally dive in.

It’s call “BecomeAnX­coder” from CocoaLab

Brent Simmons on NetNewsWire 3.1’s Release as Freeware

January 11th, 2008 § 0 comments § permalink

Net­NewWire, my favorite feed reader ever has gone totally free: Brent Sim­mons on Net­NewsWire 3.1’s Release as Free­ware. I highly rec­om­mend Net­NewWire for feed man­age­ment on OS/X espe­cially for the clipping/blogging fea­tures. I’ve never quite been able to “get into” online read­ers (much like my con­tin­ued need to use an offline mail clients) but NNW also syncs with NewGator’s online sys­tems — which means you can browse your feeds with their online apps as well.

The cross-synchronization and the iPhone opti­mized ver­sion of the online client is what keeps me hooked (also the cold fact that with­out it, I’d have to prune my list of 117 feeds (includ­ing 6 plan­ets and reddit/dzone)).

Yeah, it hap­pened a few days ago, I’m still wad­ing through a back­log of posts.

PyObjC: Run in Python automator action.

December 15th, 2007 § 0 comments § permalink

This is an excel­lent post from yes­ter­day — the author out­lines how, using 10.5 PyObjC bind­ings and the Leop­ard Automa­tor, you can add a “run python script” automa­tor action.

I par­tic­u­larly like his fol­lowup post on where he out­lines how to use the new ‘run in python’ action to ship files off to Amazon’s S3 storage.

The lat­ter of the two posts actu­ally hooked me up with the “boto” python mod­ule — which looks like an excel­lent mod­ule for inter­act­ing with Amazon’s web ser­vices, some­thing I’ve been exam­in­ing recently for a side-project.

PyObjc 2: Leopard, Python 2.5.1 and You.

December 14th, 2007 § 11 comments § permalink

So, most every­one know that Apple released OS/X Leop­ard a bit ago — I was on the early adopter train, and have not had any prob­lems (except for the occa­sional spaces crash because I mash but­tons fast).

One of the cooler things that came out with Leop­ard was a com­pletely over­hauled PyObjC built-in. Includ­ing Webkit bind­ings, and many other things (see here and here for more details), a built-in ver­sion of twisted and many other things.

How­ever, I was a moron. I was knee-deep in debug­ging a prob­lem and com­pul­sively replaced my came-with-leopard ver­sion of Python with the python.org python 2.5.1 build. (Any­one with tips on how to undo this, please let me know).

Once I dropped in the 2.5.1 ver­sion: poof. I man­aged to wipe out all of the deli­cious stuff built into my shiny new OS, which made me a sad panda. Once the PyObjC 2.0 stuff hit the PyObjC SVN tree (here) though, I was filled with hope that I could at least restore the PyObjC stuff.

Alas! It was not to be. Come to find out, there’s a hard coded string in the macpython make­file which causes the pyobjc build to use the wrong SDK and puke and die. After much wail­ing and gnash­ing of teeth, I gave up not real­iz­ing what the prob­lem was. You should see a prob­lem like this:

C compiler: gcc -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -fno-strict-aliasing -Wno-long-double -no-cpp-precomp -mno-fused-madd -fno-common -dynamic -DNDEBUG -g -O3

com­pile options: ‘-I/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5 –c’
gcc: Modules/_Foundation_nscoder.m
Modules/_Foundation_nscoder.m: In func­tion ‘imp_NSCoder_encodeArrayOfObjCType_count_at_’:
Modules/_Foundation_nscoder.m:220: error: ‘NSUIn­te­ger’ unde­clared (first use in this func­tion)
Modules/_Foundation_nscoder.m:220: error: (Each unde­clared iden­ti­fier is reported only once
Modules/_Foundation_nscoder.m:220: error: for each func­tion it appears in.)
Modules/_Foundation_nscoder.m:220: error: syn­tax error before ‘count’
Modules/_Foundation_nscoder.m:228: error: syn­tax error before ‘i’
Modules/_Foundation_nscoder.m:249: error: ‘count’ unde­clared (first use in this func­tion)
Modules/_Foundation_nscoder.m:256: error: ‘i’ unde­clared (first use in this func­tion)

How­ever, last night I was snowed-in at work and in between bug fixes for work, I man­aged to dig up a post (with fix) on the issue I was hav­ing (thanks Barry).

The short answer is sync the tree from sub­ver­sion, and then edit the fol­low­ing file:

/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/config/Makefile

And remove the “-isys­root /Developer/SDKs/MacOSX10.4u.sdk” chunk of text. Drop into the sync’ed svn tree and run the 02-develop-all.sh script. Now I can hap­pily import WebKit:

Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import WebKit
>>>

Posting from iPhone send food

July 1st, 2007 § 1 comment § permalink

After much wait­ing my iphone is all setup and con­fig­ured i am going to have to get used to typ­ing on it though. I have fat thumbs.

And yes — it is as good as you’ve heard.

TextMate 1.5

January 6th, 2006 § 0 comments § permalink

Text­Mate 1.5 is released!

I’ll tell you this much — ever since I watched this screen cast by a guy using it for Python, I’ve spent a lot more time work­ing on the more inter­est­ing lan­guage features.

I’ve added a lot of stuff per­ti­nent to my work in the snip­pets, tab trig­gers, etc. I really have not been this happy with an edi­tor in some time.

Really, you should check it out.

AlmostVPN — Trac

November 4th, 2005 § 0 comments § permalink

Ran across this app via ver­sion tracker: AlmostVPN — Trac

It’s inter­est­ing — it’s an SSH tun­nel­ing man­ager that sits in the Pref. Pane in OS/X instead of being a stand­alone appli­ca­tion. For those of us who have to VPN a lot, but despise things like the offi­cial Cisco VPN client (on any damned plat­form) this might be use­ful (if you have ssh access into the cor­po­rate network).

Where Am I?

You are currently browsing the Apple category at jessenoller.com.