Stefane Fermigier

Posts for category: Python

A sample Python library for the Nuxeo Content Automation JSON-RPC API

| Comments

I have created a sample Python library to illustrate the use of the Content Automation JSON-RPC API (described here:

The project, which is only illustrative and not officially supported by Nuxeo, lives here:

Here are the functions that have been implemented so far:

def create(self, ref, type, name=None, properties=None):
def update(self, ref, properties=None):
def setProperty(self, ref, xpath, value):
def delete(self, ref):
def getChildren(self, ref):
def getParent(self, ref):
def lock(self, ref):
def unlock(self, ref):
def move(self, ref, target, name=None):
def copy(self, ref, target, name=None):
def fetch(self, ref):
def query(self, query, language=None):
def getBlob(self, ref):
def attachBlob(self, ref, blob):

And here is a sample interactive session to illustrate its use:

% python
Python 2.6.5 (r265:79063, Jul 18 2010, 11:41:34)
[GCC 4.2.1 (Apple Inc. build 5659)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> URL = "http://localhost:8080/nuxeo/site/automation/"
>>> LOGIN = 'Administrator'
>>> PASSWD = 'Administrator'
>>> from nuxeoautomation import Client
>>> from pprint import pprint
>>> c = Client(URL)
>>> s = c.getSession(LOGIN, PASSWD)
>>> pprint(s.getChildren("/"))
{u'entity-type': u'documents',
 u'entries': [{u'entity-type': u'document',
               u'lastModified': u'2010-08-10T13:19:26Z',
               u'path': u'/default-domain',
               u'state': u'project',
               u'title': u'Default domain',
               u'type': u'Domain',
               u'uid': u'20a4bea1-e71a-47b6-86fd-c59e0a63d84d'}]}
>>> pprint(s.getChildren("/default-domain"))
{u'entity-type': u'documents',
 u'entries': [{u'entity-type': u'document',
               u'lastModified': u'2010-08-10T13:19:26Z',
               u'path': u'/default-domain/workspaces',
               u'state': u'project',
               u'title': u'Workspaces',
               u'type': u'WorkspaceRoot',
               u'uid': u'bc56455a-5345-440d-aa4e-31eed166e949'},
              {u'entity-type': u'document',
               u'lastModified': u'2010-08-10T13:19:26Z',
               u'path': u'/default-domain/sections',
               u'state': u'project',
               u'title': u'Sections',
               u'type': u'SectionRoot',
               u'uid': u'f8f7c052-cbb5-407b-8d19-3f2ec9e43efd'},
              {u'entity-type': u'document',
               u'lastModified': u'2010-08-10T13:19:26Z',
               u'path': u'/default-domain/templates',
               u'state': u'project',
               u'title': u'Templates',
               u'type': u'TemplateRoot',
               u'uid': u'cf1edd5a-2781-4b6b-aae7-310954da15f0'}]}
>>> pprint(s.create("/", "File", "First Doc"))
{u'entity-type': u'document',
 u'lastModified': u'2010-08-10T13:20:25Z',
 u'path': u'/First Doc',
 u'state': u'project',
 u'title': u'First Doc',
 u'type': u'File',
 u'uid': u'dafbf9c7-b870-4f39-830c-892469890072'}
>>> pprint(s.delete("dafbf9c7-b870-4f39-830c-892469890072"))

Slides for my "Python best practices" talk at RMLL available

| Comments

The slides for my "Python best practices" talk at the "libre software meeting" in Dijon 10 days ago are now online after some minor polishing.

Unfortunately for non-french speakers, they are in french (but with a faire dose of english quotes and technical lingo ;) ) but I hope you will enjoy them anyway.

I don't consider the talk to be finished, there are many more things I'd like to add over time. You're very welcome to send me your comments by email (sf at nuxeo dot com).

I thank Stefan Holek whose talk on "choosing good names" at EuroPython 2005 was an inspiration for this talk.

And, BTW, it's official now:

Pythonic is better than unpythonic ;)

Laptop stats at the Zope sprint in Europython

| Comments

Here are some stats about the laptops used by the Zope sprinters in Europython:

  • 13 Apple notebooks (all of them 15'' Titanium btw)
  • 5 Dell notebooks
  • 1 IBM X40 subnotebook
  • 1 ASUS S5 subnotebook (mine :) )
  • 2 no-name notebooks (MITAC)

All the non-Apple notebooks seem to be running some variant of Linux (no Windows in sight).

Some of the titanium seem brand new, and all their owners seem to be proud of using the "world's most advanced obsolete computer" :)

JSR 170 (Java Content Repository) and Zope 3 ECM

| Comments

I'm at the Z3ECM sprint in EuroPython 2005 and I've spent yesterday trying to play with the JCR (Java Content Repository aka JSR-170) trying to understand

  1. how easy it would be to how a Zope content management system into a JCR (short answer: not easy - despite of claims of interoperability, JCR is a 100% Java technology).
  2. if there are useful ideas in the JCR that could be put into the design of the repository for Z3ECM (short answer: probably, yes)

Hooking Zope into a JCR

After installing Jackrabbit (an open source implementation of the JCR made by the Apache project) and testing it with some Java examples, I've trying calling it from Python using the JPype Java<->Python bridge.

Installing Jackrabbit is not that hard, it took me about one hour though since I haven't done any Java development since 1996 and didn't have all the right tools (including Maven and a dozen of libraries like xalan, xerces, log4j, etc.) from the Apache Java project installed. Not a big deal anyway.

Unfortunately, JPype is pretty much a work in progress, that would benefit from more users and developers. There are, seemingly, limitations that prevented me from login in the JCR so this experiment didn't succeed and my knowledge of Java is much to light to keep on the experiment.

If we succeed in hooking Python/Zope into a JCR (which is, overall, just a question of Java/JNI knowledge and grunt work), I think the most important question is how the to make Zope and Java transactions systems work well together (transactions are an optional JSR-170 feature, but I don't see how a repository without transactions would be useful at all).

Ideas from the JCR specs

A JCR is a repository of nodes stored in whatever you want (flat files, SQL DB, object DB, XML DB...). Nodes are just collections of properties, so it's a very data-centric model that doesn't impose a programming model, and would work very well outside of Java. In practice, Nodes are the documents you're managing with you application. Nodes can be accessed from a path (hierarchical navigation, something Zope developers are very familiar with), or by UUID (unique identifiers). More interesting are:

  1. Querying nodes, which is based on a simplified XPath query language, or, optionally, a variant of SQL
  2. XML import/export, which would provide interoperability between repositories at list in the sense that you can import data from one repository to another (no vendor lock-in)
  3. Versionning
  4. Events

Overall, nothing very different from what we are already doing with the CPS Repository (from CPSCore), but it's interesting to try to dig a bit further in the specs and to keep then in our minds when designing the Z3ECM model for the repository, querying, and versionning.

Related standards

The WebDAV/DeltaV standard for versionning and its JCP interpretation (JSR-147) are related to these specifications.