Running External Django Scripts

Django is pretty good at creating a database driven website. The documentation is clear and the tutorials show how to use the framework to create web based applications. But one part that I wish was a bit more straight forward is running scripts outside the web server. The issue is that Django code expects to have a certain environment configured and setup for the framework. With this in place, you can preform tasks like polling an IMAP server for incoming email messages or monitoring a directory for new files or whatever else needs to be done. There are several posts online to help you get the environment setup here, here and here. But some of them seem not to work correctly because of the changes to Django for the 1.0 release or other reasons.

I have a fairly straight forward example of how to setup the Django environment and allow the rest of your code to access the Django framework for your web application. Its remarkably simple and straight forward.

Suppose that I’ve created a Django project in my tmp directory called demo_scripts and within that project, I create an app called someapp.

peter@fog:~/tmp> startproject demo_scripts
peter@fog:~/tmp> cd demo_scripts/
peter@fog:~/tmp/demo_scripts> startapp someapp

I create a model in someapp that looks like:

from django.db import models
class Foo(models.Model):
    name = models.CharField(max_length=21,
                            help_text="Name of the foo.")
    def __unicode__(self):
    class Meta:
        ordering = ('name',)

Next step is to sync the database:

peter@fog:~/tmp/demo_scripts> ./ syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table someapp_foo
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'peter'):
E-mail address:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model

And add some initial data to the database:

peter@fog:~/tmp/demo_scripts> ./ shell
Python 2.5.4 (r254:67916, May  1 2009, 17:14:50)
[GCC 4.0.1 (Apple Inc. build 5490)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from someapp.models import Foo
>>> Foo(name='A Foo').save()
>>> Foo(name='Another Foo').save()

Now we can write a standalone script to do something with the data model. For simplicity’s sake, I’ll just print out all the Foo objects. The script is going to live in a new directory called scripts. Here’s the source:

#! /usr/bin/env python
import sys
import os
import datetime
sys.path.insert(0, os.path.expanduser('~/tmp/demo_scripts'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from someapp.models import *
print Foo.objects.all()

When I run the script, it prints the array of the two Foo objects that I previously created:

peter@fog:~/tmp/demo_scripts> ./scripts/
[<Foo: A Foo>, <Foo: Another Foo>]

Lines 8 and 9 are the critical lines in the script code. The first adds the project directory to the Python system path so that the settings module can be found. The second tells the Django code which module to import to determine the project settings.

Tags : ,

Django Google Apps Authentication

Django has an excellent user management and authentication system built into the framework. With it you can easily create users that can be authenticated against the website. But there are times when you just need to authenticate against a different system. In the case of an app I recently developed, I originally wanted to authenticate against an OS X Server. The OpenDirectory service on OS X Server is an LDAP server, under the hood you’ll find slapd from OpenLDAP running. So should be pretty straight forward to create an authentication module that uses Python’s LDAP module. And this article from the Carthage WebDev site shows you how to do it.

After I got the module working on my site, I realized the site would be better served if the authentication happened against Google Apps. Since Google Apps is currently being used by the organization for email, calendaring and sharing documents, everyone already has an account there. And with the module from Carthage Webdev, I thought it would be pretty simple to provide a module.

To get started, I had to install gdata. The installation instructions found on the Google Apps APIs page were pretty easy to follow. Specifically, I had to install the Provisioning API.

On a side note, I’m using Python 2.5 as installed via MacPorts. Before I could use the gdata APIs, I had to install py25-socket-ssl.

The APIs are pretty well documented via the examples from the Python Developer’s Guide. Here’s how I’m authenticating a Django project with users on Google Apps.

To start, there are three configuration variables that I added to the Django project’s module:

# Google Apps Settings
GAPPS_USERNAME = 'name_of_an_admin_user'
GAPPS_PASSWORD = 'admin_users_password'

These will allow the module to authenticate against Google Apps and ask for specific details about the user.

Here’s the code for

import logging
from django.contrib.auth.models import User
from django.conf import settings
from gdata.apps.service import AppsService, AppsForYourDomainException
from import DocsService
from gdata.service import BadAuthentication
class GoogleAppsBackend:
    """ Authenticate against Google Apps """
     def authenticate(self, username=None, password=None):
         logging.debug('GoogleAppsBackend.authenticate: %s - %s' % (username, '*' * len(password)))
         admin_email = '%s@%s' % (settings.GAPPS_USERNAME, settings.GAPPS_DOMAIN)
         email = '%s@%s' % (username, settings.GAPPS_DOMAIN)
             # Check user's password
             logging.debug('GoogleAppsBackend.authenticate: gdocs')
             gdocs = DocsService()
    = email
             gdocs.password = password
             # Get the user object
             logging.debug('GoogleAppsBackend.authenticate: gapps')
             gapps = AppsService(email=admin_email,
             guser = gapps.RetrieveUser(username)
             logging.debug('GoogleAppsBackend.authenticate: user - %s' % username)
             user, created = User.objects.get_or_create(username=username)
             if created:
                 logging.debug('GoogleAppsBackend.authenticate: created')
        = email
                 user.last_name =
                 user.first_name =
                 user.is_active = not guser.login.suspended == 'true'
                 user.is_superuser = guser.login.admin == 'true'
                 user.is_staff = True
         except BadAuthentication:
             logging.debug('GoogleAppsBackend.authenticate: BadAuthentication')
             return None
         except AppsForYourDomainException:
             logging.debug('GoogleAppsBackend.authenticate: AppsForYourDomainException')
             return None
         return user
     def get_user(self, user_id):
         user = None
             user = User.objects.get(pk=user_id)
         except User.DoesNotExist:
             logging.debug('GoogleAppsBackend.get_user - DoesNotExist')
             return None
         return user

It was pretty easy to write and debug this code using the module as a working example.

One downside to this code is that any newly created users in the Django auth database don’t have any rights. So if the Django project is expecting to be able to dynamically change the contents based on the rights that the user has, the account will have to manually modified via the Django admin interface. Not too bad, but annoying.

Tags : , ,

SSH and OS X

This has been driving me nuts for the past several months but I hadn’t made the time to figure out the problem. Basically, the only account that could be used to ssh into our OS X server was the admin account. The admin account lives in the traditional Unix /etc/passwd database. Any account that was created via Workgroup Manager, like mine, (that is one that lives in Open Directory, OS X’s LDAP authentication database) wouldn’t work. As I said, this has been driving me nuts and I finally spent some time digging through the man pages, configuration files and log files to figure out what was going on.

It seems that a previous sysadmin had added the AllowUsers keywords to the sshd configuration file in /etc/sshd_config. On the AllowUsers line were listed the users who were able to connect via ssh. And wouldn’t you know, my account wasn’t listed.

I got to this point by reading through the /var/log/secure.log file to see what OS X was recording as the problem with connecting. There was one line in particular that stood out:

Jan 18 15:13:09 xyzzy sshd[4656]: User peter from not allowed because not listed in AllowUsers

AllowUsers? That’s strange. I don’t remember anywhere in OS X that would use a convention like this to control the environment. But a quick search on Google shows that this was a keyword used in the sshd configuration file. Adding my account name to the list and I was able to ssh in without any problem. Oh yeah, life is good!

One cool side note, sshd didn’t have to be restarted. It’s smart enough to know the configuration file has changed. Makes it very easy to test configuration changes.

But modifying the /etc/sshd_config file every time I need to allow ssh access to someone isn’t an easy way to manage account priveleges on OS X. Looking a bit more at the sshd_config man page shows that there’s also a AllowGroup option. So I removed the AllowUsers line and replaced it with:

AllowGroup ssh

Then using the standard Workgroup Manager, I added a new group called ssh and put the various accounts that need ssh access into the group. Now any accounts that needs ssh access can easily be added (or removed) from the ssh group and sshd will automatically give them access.


Tags :

Arduino and LEDs

I’m a software developer by training and one aspect of the software that I’ve always developed is that it just lives inside a computer or network. It doesn’t interact with the real world. That’s been well and good for the last 20 years but of late I’ve been wanting to break out and have software that I develop effect some change in the physical world.

There have been fits and starts where I’ve tried writing code for some embedded system or chip but the mountain of basic knowledge thats needed to get started has always been overwhelming. I would read some book (like Embedded System Design on a Shoestring ) and while the books make it seem easy to get going, the projects would always die a quick and quiet death. There’s nothing wrong with Embedded System Design on a Shoestring or any of the other books I tried, many people have used them quite successfully. Unfortunately it just never clicked for me.

But that’s all changed.

I recently discovered the Arduino platform. The system provides a small microprocessor, a bunch of I/O pins, a USB connection and a very easy to use IDE. The basic features of the platform allow for most any type of interaction with the physical world that I can currently envision. I’m sure there will be some scenario that it won’t support but for right now, I’m very happy with the capabilities.

One of the problems that I encountered in the past was connecting an embedded system to a host platform. It may have involved a vendor specific hardware or something else that wasn’t supported on my systems. The Arduino uses a USB port. After installing the needed drivers on my OS X system, I was able to connect the Arduino without any problems. Seems way easier than other solutions.

The place that I see the Arduino really shining is with the IDE. It’s different that any other IDE that I’ve used but the interface is really straight forward and very easy to use. I was able to quickly try out one of the sample C programs that turns an LED on and off again. The thing that really got me was that it compiled, loaded and ran on the first try. This was just brilliant. Easy to use and works the first time. Outstanding.

When a friend asked for help with a project he was doing and told me that he’d like to have 3 LEDs turning on and off in a random fashion, I knew that an Arduino would be the perfect tool to use. I was able to rework the sample code for turning an LED on and off to work on this project.

The idea behind the project is to have an LED inside of a wax pumpkin where the LED would turn on and off like the light on a firefly. There would be three pumpkins on a small platform, hence the three LEDs.

Here’s the code for the project:

* firefly multibutt illumination
* Copyright (c) 2008 Peter Kropf. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
// all times are in milliseconds
#define SPIN_DELAY 10
#define ILLUMINATION_MAX       255
#define ILLUMINATION_MIN       0
#define MAX_DARK_TIME 10000
#define MIN_DARK_TIME 2000
#define LED_COUNT    6
#define LED_OFF      1
#define LED_ON       2
#define LED_SPINUP   3
#define LED_SPINDOWN 4
int led_pin[LED_COUNT]   = {3, 5, 6, 9, 10, 11};
int led_spin[LED_COUNT]  = {0, 0, 0, 0, 0, 0};
int led_level[LED_COUNT] = {0, 0, 0, 0, 0, 0};
void setup()
void loop()
    for (int led = 0; led < LED_COUNT; led++) {
        switch (led_state[led]) {
        case LED_OFF:
            if (led_spin[led] > SPIN_DELAY) {
                led_spin[led] -= SPIN_DELAY;
            } else {
                led_state[led] = LED_SPINUP;
        case LED_ON:
            if (led_spin[led] > SPIN_DELAY) {
                led_spin[led] -= SPIN_DELAY;
            } else {
                led_state[led] = LED_SPINDOWN;
        case LED_SPINUP:
            if (led_level[led] < ILLUMINATION_MAX) {
                led_level[led] += ILLUMINATION_INCRIMENT;
            } else {
                led_level[led] = ILLUMINATION_MAX;
                led_state[led] = LED_ON;
                led_spin[led]  = random(MIN_ILLUMINATION_TIME, MAX_ILLUMINATION_TIME);
        case LED_SPINDOWN:
            if (led_level[led] > ILLUMINATION_MIN) {
                led_level[led] -= ILLUMINATION_INCRIMENT;
            } else {
                led_level[led] = ILLUMINATION_MIN;
                led_state[led] = LED_OFF;
                led_spin[led]  = random(MIN_DARK_TIME, MAX_DARK_TIME);
        analogWrite(led_pin[led], led_level[led]);

The code is pretty straight forward. Each of the LEDs has a particular state that it’s in: off, on, spinning up or spinning down. That’s tracked in the led_state array. The led_level array holds the current level of illumination for each of the LEDs and the led_spin array holds the random amount of time that the LED will remain on or off. The rest of the code manages the arrays, sets the current level of the LEDs and waits for a small delay before doing it all over again.

Note that the code is currently setup to illuminate up to 6 LEDs since that’s the number of digital I/O lines on the Arduino that supports pulse width modulation, PWM. PWM is how the Arduino is able to vary the light level produced by the LEDs.

Here’s a short video I took while working on the LED timing. It shows only one LED instead of the three that were used in the finished project.

With this project successfully completed, I’m looking forward to my next project: having a flashing light turned on when a specific voicemail box on a Asterisk based phone system has messages waiting. This’ll involve connecting an Arduino to ethernet and controlling a 120v circuit. I can’t wait.

Tags : ,


There are times that I think I’m turning into an old curmudgeon. Complaining about the kids riding up and down the street on their two-stroke gas powered scooters or bemoaning some new technology like twitter. It seems that as we get older, there’s a mindset that’s easy to adopt where things that are different or new are somehow bad. And when I realize that I’m there, I don’t like it.