DjangoKit help?

I spent a little time last night trying to assemble an application
using DjangoKit without much success.

I’m running Python 2.5 on a PowerBook with Mac OS 10.4. I downloaded
and installed PyObjC from source so it would compile (I thought) against
the right version of Python, then installed DjangoKit using
python setup.py install. Everything seemed to be working, and I was
able to build an application. But when I ran that app, it produced an
error about the version of the SQLite libraries being used (2 instead of
3) and missing libraries.

I gave up on Python 2.5, re-installed PyObjC and DjangoKit for 2.4 and
tried again. Same error.

Just for grins, I copied the app over to my wife’s laptop (she has a
MacBook Pro). The result was, of course, a new error about the platform.
No universal binaries? Really?

I’m sure there are options, or something, that I’m leaving out when I
build the app. This was mostly an experiment, and I was in a hurry, so I
gave up easily and just installed the django code I wanted on an
existing (Linux) web server and let her use that instead of messing with
a desktop application.

Has anyone else had more success building portable Python apps, esp.
with django, on Mac OS X?

Updated

Of course I knew better than to post in frustration when I posted this
originally. In my haste, I didn’t post sample code, the error message,
or much of the rest of the information I would have wanted if I was the
DjangoKit author trying to help someone out. Nonetheless, Tom did some
digging anyway and offered suggestions. Others did as well. Thanks! I
finally found time to follow up, and am coming closer to an answer.

Here are the full details

The application is very, very simple. The model just contains 2
classes for creating an index of a pile of Cook’s Illustrated magazine
we have laying around the house. There is no front-end, since the admin
views already provide the functionality she wanted. I thought I would be
cute and bundle it as a desktop app for Ms. PyMOTW, instead of setting
the app up on my web server. I have packaged the sample code and placed
it on my server.

I have included 2 separate setup.py files (setup.py and
djangokit_setup.py). I couldn’t package the source using the DjangoKit
version of setup:

$ python djangokit_setup.py sdist --force-manifest
Loading 'initial_data' fixtures...
No fixtures found.
running sdist
warning: sdist: missing required meta-data: name, url
warning: sdist: manifest template 'MANIFEST.in' does not exist (using default file list)
error: dist/Cook's Illustrated Index.app/Contents/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5/Frameworks/Python.framework/Versions/2.5: File name too long

I only seem to get the error if my dist directory includes the
application, too. Otherwise I get a minimal package with the name
‘UNKNOWN’. So, the tarball was packaged with a regular distutils
setup.py. That’s not a big problem, since it is easy to use separate
files.

When I ran python djangokit_setup.py py2app, the first time it
reported this error:

*** creating application bundle: Cook's Illustrated Index ***
error: can't copy 'media': doesn't exist or not a regular file

I eventually figured out (guessed) that even though I don’t have any
external media, I need a media directory at the same level in the
directory tree as the setup file. Creating the directory let me create
the app. Running that app gives me this traceback:

Traceback (most recent call last):
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/__boot__.py", line 31, in
    _run('app.py')
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/__boot__.py", line 28, in _run
    execfile(path, globals(), globals())
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/app.py", line 9, in
    from pysqlite2 import dbapi2 as sqlite
ImportError: No module named pysqlite2

That brings the error reporting up to date, without trying any of the
suggestions in the comments, yet. As I mentioned, the code itself works
if I run django outside of the packaged application (from the command
line, etc.). So I’m confident that my own imports are valid, etc.

Based on a hint from Tom (in the comments, he suggests that I install
pysqlite2), I tried editing the app.py file created inside the
application to import from sqlite3 instead of sqlite2. Editing the file
directly didn’t do it. Editing the copy already in my application
changed the error message to:

Traceback (most recent call last):
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/__boot__.py", line 31, in
    _run('app.py')
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/__boot__.py", line 28, in _run
    execfile(path, globals(), globals())
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/app.py", line 10, in
    from sqlite3 import dbapi2 as sqlite
ImportError: No module named sqlite3

Next I tried editing the version of app.py in
/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/djangokit.
After removing the application and rebuilding, I see the same error.

So I finally broke down and installed the pysqlte2 package Tom
pointed out for me. The package seems to imply that it is for Python
2.4, and I’m running 2.5, but I installed it anyway.

The application Packaged with python 2.5 gave me “No module named
pysqlite2” when I ran it. Repackaged using “python2.4
djangokit_setup.py py2app”, I got the app to run but it does not seem
to actually work. The console log shows this:

2007-06-23 15:07:28.403 Cook's Illustrated Index[14739] creating support folder /Users/dhellmann/Library/Application Support/DjangoKit/CooksIndex
2007-06-23 15:07:28.405 Cook's Illustrated Index[14739] installing default database
Starting web server on port 10557
Unhandled exception in thread started by
Traceback (most recent call last):
  File "/Users/dhellmann/Devel/personal/CooksIndex/trunk/dist/Cook's Illustrated Index.app/Contents/Resources/app.py", line 81, in startWebServer
    handler = AdminMediaHandler(WSGIHandler(), path)
TypeError: __init__() takes exactly 2 arguments (3 given)

So, I am a lot closer but not quite where I would like to be. I don’t
really care whether I package under 2.4 or 2.5, so long as the result
runs on my wife’s laptop, which doesn’t have any development packages
installed.

PyAtl Presentations

Last night’s Atlanta Python Meetup included several interesting
presentations. Living so far outside of Atlanta, it isn’t easy to make
it down for as many of the meetings as I would like, but it was
definitely worth the effort last night. We had a larger than usual
crowd, due to the fact that Google was sponsoring pizza and providing
speakers, all apparently part of their current recruiting drive.

Cary Hull of Google talked about twisted. I hadn’t ever really
looked at twisted closely, so the overview and examples he provided were
new material for me. It seems to be very informative and something worth
looking into, particularly since we are looking at redoing the
architecture of part of our system at work, and we will want to handle a
lot of sub-processes which might block on I/O from a number of sources.
We already know we want to use processes to take advantage of
multi-processor systems, but twisted seems to offer some nice tools for
managing those processes.

Sandwiched between Cary and the final presenter, Luis Caamano gave a
presentation on DynaCenter, our use of Pyro, and the event manager we
have built with it. Luis’ talk was our first “public” technical
presentation from Racemi, and it seemed to be well received.

After Luis, Dan Morrill of Google spoke on cross-site scripting
vulnerabilities. Lots of food for thought there, especially regarding
the trustworthiness of data coming from your own database. Dan is on the
web toolkit team at Google. He has obviously given similar presentations
before, and it was clear that he knew what he was talking about. Due to
a miscommunication about network access, the live demo he had planned
wasn’t possible. He wasn’t phased a bit, and proceeded to work up sample
code on the fly in front of the audience.

Noah also announced the formation of the PyAtl Book Club,
membership in which comes with a discount code for O’Reilly books. I’m
looking forward to participating, since it will be something I can do
without making that 90 minute drive. :-) If you are interested, even if
you aren’t in the Atlanta area, join our Google group.

S(a|i)mple Python Programs

Via Jesse Noller, I came across Steve Howell’s SimplePrograms
page in the Python wiki. What an excellent idea!

It’s a perfectly concise reference for program structure and common
usage patterns. It isn’t anywhere close to as exhaustive as the Python
Quick Reference
(can anything 59 pages long qualify as a “quick”
reference?) or the Python Phrasebook (another recent discovery, I
need to pick up a copy) – but that’s the point. It is a lot more
challenging to write concise examples than an exhaustive reference.
Thanks to Steve for a getting the ball rolling.

I do not see an example of raising exceptions. I’ll have to spend some
time thinking of the simplest program that would benefit from using
exceptions.

Dialing down email distractions

I have been experimenting with various productivity hacks lately. I
feel like I’m already fairly productive, based on tracking the amount of
work I accomplish week-to-week. So instead of trying to do more, I’m
trying to maintain the same level of output with less effort (and
hopefully time).

One of the top tips I have seen repeatedly is to reduce the amount of
time spent checking email, and only check it a couple of times per day.
I’m not sure I’m ready go go that hard-core, yet. Our team is spread out
and relies heavily on email for communication. Most of the messages are
important, and there aren’t too many that I feel like I have trouble
keeping up. The biggest issue is that they can be very time-sensitive.
Our code-review process is triggered via email messages generated when a
ticket is given a specific status in trac. If one of us does not notice
the change, the author of the change might be blocked for some period of
time from doing dependent work, until the code review can be completed.
Since we want to encourage code reviews, we don’t want those blockages
to last too long. So, I can’t turn email off entirely. But I can dial it
down fairly far.

Besides cutting down on email during the week, I also want to break
myself of the habit of checking work email over the weekend. Working for
a startup, it is too easy (for me) to get sucked into giving up weekend
after weekend. This is draining, so I’m not as fresh during the week as
I would be if I avoided the work mail. But, I don’t want to give up my
personal email at the same time.

image0So, the question is, how do I strike that balance?

The first step was to decide what my new mail schedule would be. I
tend to get up fairly early in the mornings, and enjoy breakfast on the
patio when the weather is nice enough (it rained last night, finally).
This is relaxing time, but not especially conducive to the long
stretches of deep thought needed for development or debugging. So,
mornings are a good time to do a lot of email, instant messaging with
the rest of the team, review code or documentation, and the other sorts
of tasks that don’t take hours at a stretch to complete. Afternoons are
too warm to sit outside and think anyway, so I move inside to work on
coding projects then. That gives me a schedule: I am willing to have
more interactions (and interruptions) in the morning than the afternoon
and I want to “reclaim” weekends. The next step is to tell Mail the
news.

image1I use the same email client (OS X’s Mail.app) to access all
of my mail accounts. Even though I use IMAP, this lets me read and
search old messages when I don’t have access to the network. The
brute-force way would be to manually change the preference “Check for
new mail” to the appropriate schedule. I hate doing things like this
manually, though.

I’ve done some work with AppleScript and Mail in the past. This
week (I’m not sure why it took me so long to figure out this approach) I
realized I could use AppleScript to control how often Mail checks for
new messages, and which accounts are checked.

Now that I have a general schedule identified, I can configure some
events in iCal using AppleScripts to control Mail. I began by composing
a few AppleScripts in Script Editor.

To check mail frequently in the morning:

image2

To check mail infrequently, for the afternoons:

image3

To turn of automatic checking entirely in the evening:

image4

To disable my work account for the weekend:

image5

To enable my work account on Monday mornings:

image6

With the scripts in place, I configured events in iCal to run the
scripts to adjust my settings at appropriate times.

image7Every week day morning, I turn up the frequency to every 5
minutes. This ensures that by the time I am up and ready to look at
email, the mailbox is up to date.

image8Around lunch time, I turn the frequency back down to once
per hour. I find I don’t even notice the change, and when I come back
from lunch I am ready to settle in and concentrate. I don’t make it
through the afternoon without checking email, but stretching out the
time between checks does help.

image9And in the evenings, I turn email off entirely. Note that
this script only runs Monday-Thursday. On Friday, I leave Mail set to
check messages once per hour, since I do receive personal messages over
the weekend and I want to see those.

image10To avoid being sucked back into work, I disable that
account entirely. Of course, on Monday morning, I have a similar job
scheduled to run the MailCheckWorkEnable script to re-enable the account
for the week.

Disabling the account entirely seemed like a drastic step, but is very
effective. When Monday comes around, I am refreshed and ready to work
again. I do not miss any personal mail, and have not been tempted to
“just look at this one thing” from my work messages.

PyMOTW: os

The os module provides a wrapper for platform specific modules such as
posix, nt, and mac. The API for functions available on all
platform should be the same, so using the os module offers some
measure of portability. Not all functions are available on all
platforms, however. Many of the process management functions
described in this summary are not available for Windows.

Read more at pymotw.com: os

PyMOTW: locale

The locale module is part of Python’s internationalization and
localization support library. It provides a standard way to handle
operations that may depend on the language or location of your users.
For example, formatting numbers as currency, comparing strings for
sorting, and working with dates. It does not cover translation (see the
gettext module) or Unicode encoding.

Read more at pymotw.com: locale

Telecommuting

I recently came across a few articles by Esther Schindler on
telecommuting which struck a chord with me.

The first, “Getting Clueful: Seven Things the CIO Should Know About
Telecommuting
”, is directed at managers of telecommuters. It covers
the benefits to the company of having telecommuters (cost savings,
productivity, etc.), potential pitfalls (not everyone can manage
themselves well enough to work remotely, ), and how to cope with them.
She places a heavy emphasis on building trust in the manager/employee
relationship, especially through communication.

The second article is directed at the telecommuting employee. In
Telecommuters Need to Develop Special Skills”, Schindler goes a
bit beyond the basic advice normally found in articles like this.
Unsurprisingly, most of that advice centers around communication issues
such as status reporting and “visibility”. One key item regards
conference calls and telling people sitting around a speaker phone to
speak up – we have that problem frequently at my company.

Both articles include specific advice from experienced managers and
telecommuters. I’m happy to say that my company gets most of this right.
We are based in Atlanta, and unless you live in the same building as
your company there is no easy commute in Atlanta. From the very
beginning, my manager told all of us he would rather have us working
than sitting in traffic and we have been expected to figure out how to
do as much of our work from home as possible. This went beyond the
grudging acceptance of telecommuting at my previous employer to active
encouragement. He saw the immediate cost benefit in office space and
productivity benefit in gaining as much as 2 hours per day of extra
work.

As far as remote communication goes, we follow the technology chart
laid out by Schindler pretty closely. We don’t have formalized rules; it
just seemed to work out that way naturally. One category of tools she
does not mention for status/discussion are online collaboration tools
such as wikis and issue tracking systems. We rely on both, with the
ticket tracking system used for asynchronous design discussions and the
wiki for historical documentation, how-tos, etc.

After an initial settling in period (2-3 months) where I got to know
my new co-workers and learned about the development environment, I have
been working at home as much as possible. These days that usually means
4 of 5 days in a week, sometimes 9 of 10 over 2 weeks. There have been
stretches where I didn’t go to the office for a few months at a time,
but those are rare. One day in the office per week works out well, since
most of the developers seem to talk better with a whiteboard in front of
us. I’ve looked into online whiteboard tools in the past, but haven’t
found anything to replace the nuance of the in-person meeting. Perhaps
if we installed some web cams…

We’re a small group, so we try to keep everyone informed of all design
issues. The code is usually implemented by just one or two developers,
but everyone has an opportunity to be involved in signing off on design
and implementation before anything goes into the svn trunk. We’ve been
doing this for 5-6 years now, so we’ve settled into a pattern. For small
designs, an individual developer may do the work and write up the
“approach”, explaining the design and tricky implementation details. The
approach (a wiki page in trac) is then submitted for review along with
the completed changeset. This works well for small changes or bug fixes,
but for larger projects we usually have some sort of conversation before
development begins. It might be a simple sanity check by one other
developer via IM, phone, or email. If a more formal review is needed, we
typically write a preliminary approach, without any code, and submit it
for comments. If we can’t agree on the approach it is time to schedule a
meeting, either as a conference call or in person.

Of course, we also make heavy use of instant messaging on our own
Jabber server. Most of our quick communication has moved off of email to
IM, and we use IM for “presence” notification. If I step away from my
desk to take care of something around the house, run an errand, or get
lunch, I use the IM status message to tell people when I expect to come
back. Email tends to be reserved for progress updates, issues that don’t
need immediate resolution, and sometimes scheduling times for more
direct means of communication.

A drawback to working remotely so often is that I frequently end up
the last to know about things like schedule or priority changes. If an
informal discussion in the hall results in a major decision, an email
still might not go out right away or the eventual message might assume
more knowledge of details than I have. This is a group communication
problem, and we’re working on it, but it can be frustrating at times.

Schindler does not offer tips for handling physical space for
telecommuters in the office. She mentions the opportunity to save office
space, but doesn’t get into what to do when all of those remote workers
do show up at the office. For a couple of years I had my own cube,
even though I was hardly ever there. We’ve recently grown big enough
that my desk was needed by someone who is in the office more frequently
than I am, so I gave it up. When I cleaned out the drawers, the only
things I kept were a handful of business cards and a couple of pocket
reference books. There wasn’t anything else in the drawers that belonged
to me!

Now I sit in the “hotel” room when I’m in the office for meetings;
that’s typically the only reason I go in, any more. Even if I don’t plan
specific meetings, I usually end up spending the day in informal
discussions rather than writing code. We converted a small conference
room by replacing the central table with folding tables along the walls
to serve as desks and by adding a few chairs. There are internet
connections (or wireless), a phone, and the old whiteboard from when the
room was actually a conference room. I used to spend most of my time at
the office in a conference room anyway, so this works out fine. :-)

And of course when I’m at home, I work at my desk here most of the
time. I do try to mix it up a bit, though. On nice days, I start on the
patio after breakfast. I catch up on email, read news, listen to
podcasts, etc. If it is cold or wet, I usually start out at the dining
room table, or on the sofa with a cat in my lap. When I am ready to do
some coding, I move to my home office, where I have a door to close and
space on the desk to spread out notes or reference manuals. I also have
a second monitor for my laptop there, which turns out to be a lot more
useful than I ever expected. Occasionally I take some reading or
documentation work to a local coffee shop, but their chairs tend to be
less comfortable and the people traffic can be distracting, so I don’t
usually do any coding while I’m there.

Our application runs on Linux, and my desktop is a PowerBook, so I
rely heavily on remote access tools such as ssh and VNC. I have a
development box at home, because the lag time to the office is
intolerable sometimes. Most of the collaboration tools we, such as trac
and Jabber, use can be tunneled, so my ssh configuration includes a lot
of port-forwarding. The end result is that I can access any of my work
systems or tools remotely, even from the coffee shop if need be.

I’ve been working remotely for several years now, and I have a hard
time imagining going back to the office every day. I do like being in
the office, but the commute is killer. If the job were closer, or we
lived somewhere else, it might not be as big of a concern. But this is a
good situation for me now, and I’ve had no trouble getting used to it.