Posts Tagged ‘Python’

Playing with RDF

Friday, May 15th, 2009

I’ve been playing with the master branch of tracker and i’m loving it – it looks like its finally reached the stage where I won’t just turn it straight off after a fresh install.

It now brings GNOME an RDF store with a SPARQL interface. Powerful joo-joo, but kinda scary if you haven’t seen it before. Most conversations about it lead to words like graphs, triples, ontologies… My eyes start to gloss over.. I need to learn by doing. So i’ve been playing with writing some python wrappers to hide tracker and just provide a familiar pythonic interface.

Any object type that tracker knows about will be available in python via the wonders of introspection. All properties of the class are available, with docstrings explaining the intent of the property and its type. Obviously you can get, set and delete and do simple queries. And behind the scenes are SPARQL queries in all their glory. Theres a lot still to do, but enough done that I can synchronise my address book to Tracker with Conduit (see my tracker branch).

So far it looks something like this (but its subject to very rapid change):

import tralchemy
from tralchemy.nco import Contact

# add a contact
c = Contact.create()
c.fullname = "John Carr"
c.firstname = "John"
c.nickname = "Jc2k"
c.commit()

# find all the people called John
for c in Contact.get(firstname="John"):
  print c.uri, c.fullname

# subscribe to any contact changes
def callback(subjects):
  print subjects
Contact.notifications.connect("SubjectsAdded", callback)

# Will probably be just:
Contact.added.connect(callback)

While get() is a nice way to do simple queries, what if you wanted to do something a little more complicated. It always feels messy when you have SQL or SPARQL nested in other code. Existing SQL ORM tools are a great place to start at avoiding this, but i quite like the LINQ style generator-to-SPARQL. Something like:


q = Query(Contact.firstname for Contact in Store if Contact.nickname == 'Jc2k')

or


q = Query(c.firstname for c in Store if c is Contact and c.nickname == 'Jc2k')

Hmm decisions. Hope to implement similar abstractions in JavaScript, C# (via LINQ) and Vala (via Magic). Anyone wanna share their cloning tech?

A new XmlObject

Sunday, April 15th, 2007

I’ve become somewhat addicted to the SqlObject stuff in TurboGears. After reading and reading my book (and finishing my first skim through) I was left with an appetite to put it to good use. Obviously theres Conduit.net. But I ended up thinking about the state of the data types in conduit. I remember implementing the contact datatype, and it’s always been in a pretty sorry state. Your best hope for working with the data was to directly work with self.vObject, which I have zero-understanding of. On top of that, we want to use the OpenSync XML schemas in Conduit to aid interoperability with it, SynCE and to help with any networking layers we add (Conduit-web, Avahi/Twisted).

Could there possibly be an SqlObject equivalent for Xml? At first glance, yes and no. XMLObject would seem to be dead? You have to craft a parser, and there seems to be a compilation step. Another XMLObject seems better. It doesn’t seem to have the magic glue that SQLObject does, and you don’t seem to be able to create your own “model objects”. EaseXML is the closest to what I want, but it too seems dead?

Anyway, at the moment I am hacking away on my own implementation as bit of a learning tool. I’ve implemented the latest OpenSync Note schema in my objects and have something that looks like this:

class Note(xmlobject.XmlObject):
Body = MultiText(maxOccurs=1, minOccurs=1)
Categories = Categories(maxOccurs=1, minOccurs=0)
Class = Class()
DateCreated = DateTimeContent()
LastModified = DateTimeContent()
Summary = MultiText()
XIrmcLuid = StringContent()

And am able to produce some dummy output using Note().get_xml()

<Note>
<Body Language="Language" AlternativeTextRep="AlternativeTextRep">
<Content>Content</Content>
</Body>
<LastModified TimezoneID="TimezoneID" DateValue="DateValue">
<Content>Content</Content>
</LastModified>
<Summary Language="Language" AlternativeTextRep="AlternativeTextRep">
<Content>Content</Content>
</Summary>
<XIrmcLuid>
<Content>Content</Content>
</XIrmcLuid>
<DateCreated TimezoneID="TimezoneID" DateValue="DateValue">
<Content>Content</Content>
</DateCreated>
<Class>
<ClassValue>ClassValue</ClassValue>
</Class>
<Categories>
<Category>Category</Category>
</Categories>
</Note>

It’s all pretty dirty and basic right now. But it’s going pretty well.

Isn’t today meant to be unlucky?

Friday, April 13th, 2007

Despite it being Friday 13th I got my TurboGears book and my free OpenSolaris starter kit through the post today.

The book really impressed me. I’ve read the first few chapters and am on to building a Bookmark Web App. I’m considering starting with that for “Conduit Web” – some kind of online way of accessing data like my contacts, calendar, bookmarks, etc. As part of some kind of general “sync server”. Unfortunately i’m having trouble getting it going on Feisty :(

I tried Nexenta, one of the distros in the OpenSolaris starter kit, and it scared me. At first I thought it had crashed (didn’t seem to background DHCP, so was dog slow to boot). My lappy is 17″ widescreen but it seemed to get run at 320×240 or something silly. The sound worked though. Late-ish at night and the gnome login sound kicks in on what would seem to be FULL. The sub woofer did not sound pleased… So I’m staying with Fesity/Gutsy for the time being! Still interested in tracking OpenSolaris progress though, and I hope Conduit will work great on there too.