Adding feeds for the buzz

February 10th, 2010

Found this today via jlapenna’s buzz on how to add more feeds to your buzz:

http://www.google.com/buzz/bradfitz/PPjHXDhANAC/Want-to-connect-your-blog-or-some-other-feed-to

Very useful.

Bit by ModelForms

January 26th, 2010

Put all the callable defaults you want into a Model, the ModelForms aren’t evaluating them properly in Django 1.0.4. Luckily there is a patch: http://code.djangoproject.com/ticket/11940

Getting started with virtualenv

January 14th, 2010

I’m working on a few django sites all at the same time, and keeping the PYTHONPATH environment variable set correctly was getting to be a pain, and virtualenv seemed like it took a lot to set up – or that’s the way it looked from all the other blog posts out there.

So I took the plunge, and I’m happy to say it didn’t take all that much effort to go from a homebrew environment hack to using virtualenv.

Install Virtualenv

This works for me, but note, I have to use python2.5 (because of Google AppEngine) and I’m on OSX or ubuntu all day long.

sudo easy_install-2.5 virtualenv

That’s it.  A lot simpler than I originally thought with all those other articles mentioning pip and zc.buildout.

Use virtualenv

It turns out using virtualenv is a lot easier than I thought also.  A lot of the articles talk about using pip to install dependencies, etc.  I’m sure pip is great and once I start rolling it out I’ll probably never look back.  But for now I have a relatively small set of teams to manage, and everyone uses their own setup that works for them.

There’s only two setup steps and then you can use virtualenv.  You don’t have to change your source control unless you really want to.

First, set up the new environment:

virtualenv --no-site-packages --python=python2.5 my_env_name

Then you activate the new environment:

source my_env_name/bin/activate

Now you are running with an empty environment.  You need to perform your dev environment setup in this python virtual environment.   But you only have to do that once.

Switching environments just means sourcing the right activate script.  After a couple of alias changes in bash I’m all set.

Using Google Analytics Event Tracking

December 31st, 2009

When you are a startup, every minute counts.  It makes complete sense to want analytic analysis of your website, however,  it does not make sense to spend a lot of time building analytic databases/engines/reporting into your website.  These things already exist, and are often free or very low cost.

I often recommend chartbeat.com for real time analysis.  It tells you a lot of great stuff about how many people are on your site now, how they got there, and what they’re saying on twitter.

Google Analytics is great.  Sometimes you want to know a little more than just url – like what are people searching on if you a custom search implemented in your site.  This is easily added using the Event Tracking feature.  With just a couple of javascript calls, you have a lot more data at very little cost.  Best part, you don’t have to build any of it into your database or chew up database cycles reporting it.

If you want to see what people are searching on in your site use the Event Tracker from google analtyics like this:

pageTracker._trackEvent(“Search”, “HeaderSearch”, “{{search}}” );

Then simply slice and dice to your heart’s extent in analytics.  No extra data stored in your database.

The walled garden

October 14th, 2009

Sometimes, not all the times, but sometimes it is better to just allow traffic from certain countries you know are legitimate. MaxMind’s mod_geoip2 makes it easy: http://www.maxmind.com/app/mod_geoip

Optimize your get_or_create blocks

September 15th, 2009

Was going through a code review, and saw something like this:

def some_function(user_id, bobj_id):
    user = User.objects.get(id=user_id)
    bobj=Bobj.objects.get(id=bobj_id
    item, created = MyObject.objects.get_or_create(user=user, bobj=bobj)
    return item

But that is two hits to the database we don’t need since the id’s are passed in. Remember, if you have id’s then you can shortcut pulling the object from the ORM like this:

item, created = MyObject.objects.get_or_create(user__id=user_id, bobj__id=bobj_id)

That will do the

.get()

just fine, but fails when it tries to

.create()

with this error:

psycopg2.IntegrityError: null value in column “user_id” violates not-null constraint

You got the error because

get_or_create

does not automatically use the query spec for the default. There’s probably an enhancement filed for that. Remember to send in the defaults explicitly:

item, created = MyObject.objects.get_or_create(user__id=user_id, bobj__id=bobj_id,
                    defaults={'user_id':user_id, 'bobj_id':bobj_id})

Be sure you look for that in your api calls where you have mainly ids coming in and not object references.

Inserting ads into a video stream

September 10th, 2009
ads

Currently, if you want to insert ads into a video stream, you are going to write a flash video player which periodically stops the video stream and displays an ad stream. Adobe could make this a whole lot easier if they would let you insert the stream at the flash media server instead of the client.

Why don’t they do that?

AuthType allow one file

September 4th, 2009

There is no way to turn off AuthType Basic on a file or directory once it is on, but you can exclude it using regular expressions.

For example, we had use this:

<Location "/">
AuthType Basic
....

but wanted to allow /somefile/ to be accessed without auth.  To do so you want to do this:

<LocationMatch "^(?!/somefile/)">
AuthType Basic
...

django unit testing api logs

August 13th, 2009

The last several years I’ve designed a few APIs.  Designing them is fun, implementing them is fun, testing them is not as fun.  Partly this is because it’s hard to guess how someone is going to misinterpret what you want them to do.

I hit upon a better way to do testing and debugging that hadn’t occurred to me until recently.  First, you have to log all the calls to your API.   This also helps when you want to do performance analysis of your api later, because you can have the traffic come in according to the timestamps at the correct latencies.  When you record the call to your database, make sure to record all the parameters, so you can recreate the call later.

Second, make sure you record whether the call was successful or not.  Some of you may only want to record failures, because you’re not interested in successful calls.  You’ll then want to create a django fixture of the calls you want to test.

Create a django unittest which loads the fixture, runs the tests, and voila you can find and fix your errors.  You don’t have to spend a lot of time with artificial testing, because you are using real data.

Sample code in a few days…

Amazon steps up to AppEngine

May 28th, 2009

Google’s AppEngine was quite promising from the start.  Automatic scaling and load balancing without having to think about the administrative side is extremely nice.

But that’s about it.  There’s a couple of things which make AppEngine a bit cumbersome to recommend for a new application, all of which are well served by Amazon EC2+ELB+ES:

  1. Lack of SSL for your custom domain
  2. Can’t use many django pluggables out of the box because of RDMS dependencies
  3. Some would say naked domains, but ELB can’t do naked domains either, so this is a wash.
  4. Can’t use other off the shelf software, like wordpress, etc.

Don’t get me wrong, I really like AppEngine, and for small apps I’m going to stick with it because of:

  1. Cost – the free instance can’t be beat.  You’re at an automatic $100/month with EC2.
  2. Little to no infrastructure admin needed – mainly just some DNS.
  3. You can run Django 1.0 with either app-engine-patch, or the django-helper.