Early version of ZooKeeper bindings for Python. All functions are imported as methods into the zookeeper module.

Please do not rely on APIs staying constant in the short term. The handling of exceptions and failure modes is one area that is subject to change. 

DEPENDENCIES:
-------------

This has only been tested against SVN (i.e. 3.2.0 in development) but should work against 3.1.1. 

You will need the Python development headers installed to build the module - on many package-management systems, these can be found in python-devel.

Python >= 2.6 is required. We have tested against 2.6. We have not tested against 3.x. 

BUILD AND INSTALL:
-------------------

To install, make sure that the C client has been built and that the libraries are installed in /usr/local/lib (or change this directory in setup.py). Then run:

ant install

from zookeeper/src/contrib/zkpython/.

To test, run ant test from the same directory. 

You can compile the module without installing by running

ant compile

In order to use the module, zookeeper.so must be in your PYTHONPATH or in one of the directories referenced by sys.path. Running ant install should make sure that this is the case, but if you only run ant compile you probably need to add build/contrib/zkpython/* to PYTHONPATH to find the module. The C client libraries must be in a system library path, or LD_LIBRARY_PATH or DYLD_LIBRARY_PATH (Mac OS) for the module to work correctly, otherwise you will see a library not found error when trying to import the module. 

NAMING CONVENTIONS:
--------------------

All methods that in the C library are zoo_fn_name have been implemented as zookeeper.fn_name. The exception is any function that has a watch function argument is named without the 'w' prefix (for example, zoo_wexists becomes zookeeper.exists). The variants of these functions without the watch argument (i.e. zoo_exists) have not been implemented on the understanding that they are superseded by the zoo_w* API. 

Enums and integer constants that begin ZOO_int_name are named as zookeeper.int_name.

PARAMETER CHANGES:
------------------

Zookeeper handles are represented as integers to avoid marshalling the entire structure for every call. Therefore they are opaque from Python. 

Any parameter that is used to provide arguments to callback methods is not exposed in the API. Python provides better mechanisms for providing a closure to be called in the future.

Every callback gets passed the handle of the ZooKeeper instance used to register the callback.

DATA TYPES:
-----------

ACL_vectors are lists of dictionaries. Stat structures are dictionaries. String_vectors are lists of strings.

EXCEPTIONS AND ERROR HANDLING:
------------------------------

Currently synchronous calls indicate failure by throwing an exception (note that this includes the synchronous calls to set up asynchronous completion callbacks!). Success is returned as an integer. 

Callbacks signify failure by having the integer response code passed in. 

WHAT'S NEW IN 0.4:
------------------

More test coverage. 

Better reference counting, fixing at least two serious bugs.

Out-of-range zhandles are now checked, fixing a potential security hole.

Docstrings! Editing and cleanup required, but most of the text is there.

zookeeper.set_watcher is now implemented correctly.

zookeeper.client_id is now implemented correctly. zookeeper.init now respects the client_id parameter.

get_context and set_context have been removed from the API. The context mechanism is used by PyZK to store the callables that are dispatched by C-side watchers. Messing with this from Python-side causes bugs very quickly. You should wrap all desired context up in a callable and then use zookeeper.set_watcher to attach it to the global watcher. 

Many methods now have optional parameters (usually if you can specify a watch, it's optional). The only time where genuinely optional parameters are still mandatory is when a required parameters comes after it. Currently we still respect the ZK C client parameter ordering. For example, you can simply connect with zookeeper.init("host:port") and ignore the other three parameters.


WHAT'S NEW IN 0.3:
------------------

Some tests in zkpython/test. More to follow!

A variety of bugfixes.

Changed the way methods return results - all responses are integers now, for the client to convert to a string if it needs.

WHAT'S NEW IN 0.2:
------------------

The asynchronous API is now implemented (see zookeeper.a*).

Most enums defined in zookeeper.h are now added as constants to the module.

_set2 and a few other edge API calls have been implemented. The module is now nearly 100% feature complete!

A reference count error was tracked down and killed. More probably lurk in there!

WHAT'S NOT DONE / KNOWN ISSUES / FUTURE WORK:
---------------------------------------------

1. There may well be more memory leaks / reference count issues; however I am more confident that common paths are relatively safe. 
2. There probably needs to be a more Pythonic Python-side wrapper for these functions (e.g. a zookeeper object, the ability to iterate through a tree of zk nodes)
3. Docstrings need a cleanup.
4. The way exceptions and error codes are returned needs looking at. Currently synchronous calls throw exceptions on everything but ZOK return, but asynchronous completions are simply passed the error code. Async. functions should never throw an exception on the C-side as they are practically impossible to catch. For the sync. functions, exceptions seem more reasonable, but some cases are certainly not exceptional. 

Bug reports / comments very welcome!

Henry Robinson henry@cloudera.com
