In an effort to maintain some mental stimulation while we go through our post-migration shake-down (i.e. Bugzilla and feature request wrangling), I’ve decided to learn Python in the off-hours. I also figured while I was at it, I might as well get some useful code out of it.
I started out experimenting with Django, because I’m interested in cool web platforms – you never know what will drive a better OPAC. By doing this, I got to see how other people write Python code and I got to write some myself. So far, the coolest thing about Django is the built-in admin interface. Basically, you write some Python classes modeling a set of database tables, and it gives you a nice interface for managing the data. This is nothing new, of course (nor is this a Django advertisement), but they do a good job of modeling the DB relations in a user-friendly manner. As a result, I’ve developed a new admin interface to sit on top of several of the ILS database tables. These are essentially configuration tables that contain data like the library info, circulation rules, etc., that are under the direct control of the ILS administrator. Normally, I would link to the interface here, but it’s sitting on top of our development DB, so it’s firewalled off. It’s pretty cool, though. I promise.
After the warm-up I moved on to the main event. If anyone is ever going to communicate with the ILS directly via Jabber (not Apache, anyone can talk HTTP ;)), we need a Python OpenSRF client library. This adventure was a little more challenging, because it required some updates to the core OpenSRF JSON code. Basically, we had to modify our wire protocol to play nicer with existing JSON parsers. This change will make it much easier to develop client libraries.
After that was completed, I moved on to the fun stuff. Fortunatly, Python has a healthy array of contributed modules. I started out with pyxmpp and simplejson for the core network communication, and libxml2 for the config file and IDL parsing (since pyxmpp already uses libxml2). There’s a smattering of other modules throughout, but those are the big ones and they do all of the heavy lifting. All I really had to do was implement the OpenSRF network stack and session handling, which is a lot easier than writing a Jabber client or a JSON parser (especially in C, oh my..).
What we have now is a functioning Python OpenSRF + OpenILS client. In the example below, I connect to the OpenSRF network, then fetch the user object with ID 1 and print the object’s username:
————————————————————–
#!/usr/bin/python
import sys
from oils.oils_sys import oilsConnect
from osrf.osrf_ses import osrfClientSession
oilsConnect(sys.argv[1])
ses = osrfClientSession(‘open-ils.cstore’)
req = ses.request(‘open-ils.cstore.direct.actor.user.retrieve’, 1)
resp = req.recv(timeout=10)
user = resp.content()
req.cleanup()
ses.cleanup()
print ‘username = ‘ + user.usrname()
————————————————————-
If you don’t need the more advanced OpenSRF features (streaming method responses, connected sessions, etc.), the above can be accomplished in a more concise manner with the osrfAtomicRequest() method:
————————————————————–
#!/usr/bin/python
import sys
from oils.oils_sys import oilsConnect
from osrf.osrf_ses import osrfClientSession, osrfAtomicRequest
oilsConnect(sys.argv[1])
user = osrfAtomicRequest( 'open-ils.cstore',
'open-ils.cstore.direct.actor.user.retrieve', 1 )
print 'username = ' + user.usrname()
--------------------------------------------------------------
Nice and easy - nice and fun. After I shake out a few more bugs I'll be comitting all this new code to HEAD in our CVS repository.