Saturday, 20 December 2008

CouchDB Notification in Python

I’m playing with trying to get reference updates in CouchDB and as part of this I had to get notifications working.. Just to save anybody else the same pain here are the steps I took so far.

Here is the local.ini file

; CouchDB Configuration Settings

; Custom settings should be made in this file. They will override settings
; in default.ini, but unlike changes made to default.ini, this file won't be
; overwritten on server upgrade.

[couchdb]
;max_document_size = 4294967296 ; bytes

[httpd]
;port = 5984
bind_address = 0.0.0.0

[log]
;level = info

[update_notification]
unique notifier name=/home/tim/git/couchish/couchish/notifier.py

The notifier gets called when couchdb starts and then couchdb streams updates to it line by line.

Here is the notifier script.. It has a few lines to check that things are ‘OK’.. you should make sure it’s executable by couchdb (it’s worth su’ing to couchdb and checking you can run the script and what happens if you <code>echo ‘foo’ | python {notifier script}</code>

#!/usr/bin/env python

import sys, time

import logging as log
log.basicConfig(level=log.INFO, filename='/tmp/couch-updater.log')


def notifications():
    simplejson_imported = False
    while True:
        line = sys.stdin.readline()
        log.info('read %s'%line)
        if not line:
            raise StopIteration()
        if not simplejson_imported:
            try:
                import simplejson
                simplejson_imported = True
            except ImportError:
                yield 'Bad Import'
        try:
            yield simplejson.loads(line)
        except Exception, e:
            yield 'Failed to Parse line : "%s"'%line

def main(args):
    for notification in notifications():
        log.info("notification: %r" % (notification,))
if __name__ == '__main__':
    try:
        args = sys.argv[1:]
        log.info("Started with args: %r"%(args,))
        main(args)
        log.info("Shutdown normally")
    except KeyboardInterrupt:
        log.info("Shutdown with Ctrl+C")
    except Exception, e:
        log.info("Shutdown by exception: %r"%(e,))

My next step is to get the script to remember the last seq no and to parse the list of individual updates to apply an referential referencing.

2 comments:

Norm said...

great, thanks. The more examples the better, this explained to me how notifications can be configured. Works on linux, but broken on windows :-(.

Tim Parkin said...

Hi Norm,

Unfortunately I don't have a windows machine :-( [ or fortunately depending on your point of view!]

Post a Comment