Python-zarafa: high-level Python bindings for Zarafa

June 2, 2014 by Mark Dufour  

, , ,

As mentioned in my previous blog post New search using Xapian and Python, we are using Python more and more at Zarafa. For example, ZWS, the new Xapian-based search prototype, our internal testing framework and many custom system administration scripts are written in Python. The main advantage of Python over especially C++ is that productivity is greatly increased. There is no compilation step, so building software becomes faster and (remote) debugging becomes easier. Automatic memory management further greatly improves stability (perhaps the biggest selling point of Java :-)). And last but not least, because of the high-level nature, Python programs are easier to understand, maintain and extend. It is no wonder that Python is one of the most popular high-level languages within the wider open source community.

Unfortunately, our current Python bindings are closely coupled to MAPI (hence the name "python-mapi"), which in many cases does not correspond to the abstraction level of the problems one is trying to solve. For example, suppose we want to scan the contents of attachments (which we clearly do in search). Using python-mapi, this would involve poking at a variety of MAPI properties, tables and streams and dealing with MAPI errors. But it can get even more complex when there are so called "named properties" involved. The bottom line is that MAPI is low-level and complicated as it has organically grown to suit new needs. While some helper functions have been added to python-mapi (such as a "GetUsers" function), we would really like to be able to use a fully object-oriented, more high-level, let's say "pythonic" layer above python-mapi which keeps simple things simple, while at the same time of course still allows one to dive into MAPI as needed.

Enter python-zarafa. While developing the new Xapian-based prototype replacement for search (see my previous blog post), we made sure to abstract as much MAPI-specific code to a separate, object-oriented library as possible. All the while paying much attention to reusability by other (future) programs. In fact there is little MAPI-specific code left in our prototype, only where needed (it is needed as search indexes individual MAPI properties). While there are many other things one can already do with this new library, the following (full!) sample program illustrates the most important aspects.

import zarafa


# connect to server, as specified on command-line (possibly including SSL info) or via defaults

s = zarafa.Server()


# loop over users on this server, with 'parse' checking the command-line for specific user names

for user in s.users(parse=True):


    # some basic user info



    # print an indented overview of all folders in the user's default store

    for folder in

        print folder.depth*'    '


    # print an overview of attachments in inbox

    for item in

        print item.subject

        for attachment in item.attachments():

            print attachment.filename, len(


    # dive into MAPI if needed


As can be seen from the comments, through some underwater Python magic, the program automatically acquires several common command-line options. For example one can add '-c /etc/zarafa/admin.cfg' or '--user username' (or --help to see all common options), and the program will act accordingly. In recent versions of python-zarafa, it is even possible to setup a complete Zarafa 'service', so the program automatically gains a '-F' option, and logging is performed automatically as specified in the right configuration file. Error handling is also improved, as Python comes out-of-the-box with advanced exception handling and traceback functionality, and as we replace MAPI error codes with more readable error messages. It probably won't come as a surprise that the new search prototype is only a few hundred lines of code. Of course this is also due to the fact that we use an off-the-shelf search engine as well as Python itself.

As for the future, we hope to steadily improve and stabilize these bindings. Being quite a large (but fun!) job, it may take many months for it to become more or less feature-complete. Although in the meantime it is already quite useful. We just can't make a guarantee for the foreseeable future that the API will not change in major ways. Obviously one can always bundle a version of python-zarafa with a script, so it will not break, but ultimately our goal is to provide a stable 'python-zarafa' package. For the time being the bindings are also "read-only" for the most part, but in many situations of course we are not actually changing anything. The current version of the code, including some other examples, can already be found on github in any case, and we very much welcome your early feedback:


In upcoming blog posts, we plan to describe some new programs and scripts that have already been written on top of python-zarafa, such as an alternative to MAPISpy/MFCMAPI called "zarafa-inspector". We will also provide further updates on the development of python-zarafa, so stay tuned!


For more information about the advantages of using Python, see the following interview: