{"id":10302,"library":"tooz","title":"Tooz Coordination Library","description":"Tooz is a Python library designed to provide distributed systems primitives such as group membership, leader election, distributed locking, and distributed messaging. It offers a unified API over various backend drivers like Redis, ZooKeeper, and Etcd. Currently at version 8.1.0, it is actively maintained as part of the OpenStack ecosystem with regular updates.","status":"active","version":"8.1.0","language":"en","source_language":"en","source_url":"https://github.com/openstack/tooz","tags":["distributed systems","coordination","locks","leader election","group membership","messaging","concurrency"],"install":[{"cmd":"pip install tooz","lang":"bash","label":"Base installation"},{"cmd":"pip install tooz[redis]","lang":"bash","label":"Installation with Redis driver"},{"cmd":"pip install tooz[zookeeper]","lang":"bash","label":"Installation with Zookeeper driver"}],"dependencies":[{"reason":"Required for the Redis driver. Install with 'pip install tooz[redis]'.","package":"redis","optional":true},{"reason":"Required for the Zookeeper driver. Install with 'pip install tooz[zookeeper]'.","package":"kazoo","optional":true},{"reason":"Required for the Etcd driver. Install with 'pip install tooz[etcd3]'.","package":"python-etcd3","optional":true}],"imports":[{"symbol":"DriverFactory","correct":"from tooz.drivers import DriverFactory"},{"note":"Locks are commonly obtained via `driver.get_lock()` but the class can be imported directly for type hinting or advanced usage.","symbol":"Lock","correct":"from tooz.locking import Lock"},{"note":"The `CoordinationDriver` class moved to `tooz.coordination`. `DriverFactory` is the recommended entrypoint for instantiating drivers.","wrong":"from tooz import CoordinationDriver","symbol":"CoordinationDriver","correct":"from tooz.coordination import CoordinationDriver"}],"quickstart":{"code":"import os\nimport time\nfrom tooz.drivers import DriverFactory\n\n# Use a file-based driver for local testing or set an environment variable for a real backend\n# e.g., export TOOZ_BACKEND=\"redis://localhost:6379/0\" (for Redis DB 0)\n# e.g., export TOOZ_BACKEND=\"zookeeper://localhost:2181\"\nconnection_string = os.environ.get(\"TOOZ_BACKEND\", \"file:///tmp/tooz_locks_example\")\n\n# Group ID for coordination primitives, must be bytes\ngroup_id = b\"my_application_group\"\n\ndriver = None\ntry:\n    # Initialize the driver factory. This will select the appropriate driver\n    # based on the connection string prefix (e.g., 'redis://', 'file://').\n    driver = DriverFactory(connection_string, group_id)\n    print(f\"Connected to tooz backend: {connection_string}\")\n\n    # Example: Acquire a distributed lock\n    lock_name = b\"my_critical_section\"\n    \n    # `timeout` specifies how long to wait to acquire the lock.\n    # `heartbeat_timeout` specifies how often to renew the lock if acquired.\n    lock = driver.get_lock(lock_name, timeout=5, heartbeat_timeout=1)\n\n    print(f\"Attempting to acquire lock '{lock_name.decode()}'...\")\n    if lock.acquire():\n        print(\"Lock acquired successfully! Performing critical work...\")\n        # Simulate some work\n        time.sleep(2)\n        print(\"Work done, releasing lock.\")\n        # Lock is automatically released by the 'finally' block when driver disconnects\n        # or can be explicitly released with lock.release()\n    else:\n        print(\"Could not acquire lock within timeout.\")\n\nfinally:\n    if driver:\n        # Ensure the driver is disconnected to release resources and locks.\n        driver.disconnect()\n        print(\"Disconnected from tooz backend.\")\n","lang":"python","description":"This quickstart demonstrates how to initialize a `tooz` driver using `DriverFactory` and acquire a distributed lock. It uses a file-based driver by default for easy local testing, but can be configured with a `TOOZ_BACKEND` environment variable for real backends like Redis or Zookeeper. The example shows how to acquire a lock with a timeout and ensures proper cleanup."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or later, or use an older `tooz` version (e.g., `tooz<8`) if you must stay on Python 3.9 or earlier.","message":"Tooz versions 8.0.0 and above require Python 3.10 or newer. Older Python versions are no longer supported.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Install `tooz` with the desired backend extra, for example: `pip install tooz[redis]`, `pip install tooz[zookeeper]`, or `pip install tooz[etcd3]`.","message":"Tooz drivers for specific backends (e.g., Redis, Zookeeper) are optional dependencies and must be installed separately using 'extras'. Installing just `pip install tooz` will only provide the core library and file/memory drivers.","severity":"gotcha","affected_versions":"all"},{"fix":"Use `from tooz.drivers import DriverFactory` and initialize your driver with `driver = DriverFactory(connection_string, group_id)`.","message":"While `tooz.coordination.CoordinationDriver` is still available, `tooz.drivers.DriverFactory` is the recommended and more robust entry point for initializing drivers since `tooz` v7.0.0. Direct instantiation of specific drivers (e.g., `tooz.drivers.redis.RedisDriver`) is also less portable.","severity":"deprecated","affected_versions":">=7.0.0"},{"fix":"Always wrap your `tooz` driver usage, especially lock acquisition, in `try...finally` blocks to ensure `driver.disconnect()` is called. Consider using `with driver.get_lock(...) as lock:` if supported for the specific primitive and driver.","message":"Distributed locks obtained via `tooz` are not automatically released if the process crashes or loses connectivity without properly calling `driver.disconnect()` or `lock.release()`. Use `try...finally` blocks to ensure cleanup.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Ensure the necessary driver extra is installed (e.g., `pip install tooz[redis]`). Verify the connection string format is correct for your chosen backend.","cause":"The required backend driver package (e.g., 'redis') is not installed, or the connection string prefix does not match any available driver.","error":"tooz.drivers.NoDriverFound: No driver could be found for connection string 'redis://localhost:6379'."},{"fix":"Import `CoordinationDriver` from `tooz.coordination` (e.g., `from tooz.coordination import CoordinationDriver`). For new code, prefer `tooz.drivers.DriverFactory` as the main entry point.","cause":"`CoordinationDriver` and other core classes are not directly exposed under the top-level `tooz` package for newer versions. This import path might have worked in very old versions.","error":"ImportError: cannot import name 'CoordinationDriver' from 'tooz' (or similar for other classes)"},{"fix":"Ensure the backend service is running and configured to accept connections from your application. Double-check the host, port, and any authentication details in your `tooz` connection string.","cause":"The backend service (e.g., Redis server, Zookeeper ensemble, Etcd cluster) specified in the connection string is not running or is not accessible at the given host and port from your application's environment.","error":"redis.exceptions.ConnectionError: Error connecting to server: [Errno 111] Connection refused."}]}