{"id":3248,"library":"python-consul","title":"Python Consul Client","description":"Python-consul is a client library for interacting with the Consul HTTP API. It provides a comprehensive set of features for service discovery, key-value storage, health checking, and session management. The library is currently at version 1.1.0 and is actively maintained with a moderate release cadence.","status":"active","version":"1.1.0","language":"en","source_language":"en","source_url":"https://github.com/cablehead/python-consul","tags":["consul","service discovery","key-value store","devops","microservices"],"install":[{"cmd":"pip install python-consul","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used for making HTTP requests to the Consul API.","package":"requests"}],"imports":[{"symbol":"Consul","correct":"from consul import Consul"}],"quickstart":{"code":"import consul\nimport os\n\n# Configure Consul connection details\nconsul_host = os.environ.get('CONSUL_HOST', '127.0.0.1')\nconsul_port = int(os.environ.get('CONSUL_PORT', '8500'))\nconsul_scheme = os.environ.get('CONSUL_SCHEME', 'http')\nconsul_token = os.environ.get('CONSUL_TOKEN', None) # For ACLs\n\ntry:\n    # Initialize Consul client\n    c = consul.Consul(\n        host=consul_host,\n        port=consul_port,\n        scheme=consul_scheme,\n        token=consul_token\n    )\n\n    # Example: Key-Value store operations\n    key = \"my_app/config/setting1\"\n    value = \"hello_consul_world\"\n\n    # Put a value\n    if c.kv.put(key, value):\n        print(f\"Successfully set key '{key}' to '{value}'\")\n    else:\n        print(f\"Failed to set key '{key}'\")\n\n    # Get a value\n    index, data = c.kv.get(key)\n    if data:\n        retrieved_value = data['Value'].decode('utf-8')\n        print(f\"Retrieved key '{key}': '{retrieved_value}' (index: {index})\")\n    else:\n        print(f\"Key '{key}' not found.\")\n\n    # Example: Register a service (minimal)\n    service_name = \"my-test-service\"\n    service_id = \"my-test-service-1\"\n    if c.agent.service.register(name=service_name, service_id=service_id, port=8000, tags=['python']):\n        print(f\"Service '{service_name}' registered successfully.\")\n    else:\n        print(f\"Failed to register service '{service_name}'.\")\n\n    # You can deregister later with:\n    # c.agent.service.deregister(service_id)\n    # print(f\"Service '{service_name}' deregistered.\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n    print(\"Please ensure a Consul agent is running and accessible at \"\n          f\"{consul_scheme}://{consul_host}:{consul_port}\")","lang":"python","description":"Initializes a Consul client, sets and retrieves a key-value pair, and registers a simple service. It demonstrates configuring the connection using environment variables and basic error handling."},"warnings":[{"fix":"Access data via the `data` tuple element returned by the API call, which directly contains the parsed JSON. For example, `index, data = c.kv.get('foo')` where `data` is the dictionary payload.","message":"The `ConsulResponse` object (returned by blocking queries) no longer has `.json()` or `.text` methods. These were removed in version 1.0.0 due to issues with blocking queries.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Update call sites to expect a string return from `acl.create`. Refactor any usage of `acl.clone` to use `acl.create` with the desired parameters.","message":"The `acl.create` method now returns the ACL ID directly (as a string) instead of a dictionary containing the ID. Also, the `acl.clone` method was removed.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Convert integer `ttl` values to their string representations (e.g., `30` becomes `'30s'`).","message":"Many `ttl` arguments (e.g., in health check definitions or session creation) now expect a string (e.g., '10s') instead of an integer representing seconds.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always capture the `index` value (e.g., `index, data = c.kv.get('foo')`) and pass it as the `index` argument for subsequent blocking calls (`index, new_data = c.kv.get('foo', index=index)`).","message":"When performing blocking queries, it's crucial to pass the `index` returned from a previous call to subsequent calls. Failing to do so will result in immediate (non-blocking) queries, leading to busy-waiting or inefficient polling.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure `token` is passed either during `consul.Consul()` initialization or as an argument to specific API calls that require it.","message":"If your Consul server has Access Control Lists (ACLs) enabled, you must provide a valid `token` to relevant client methods (e.g., `c.kv.put('key', 'value', token='your-token')`) or during client initialization.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}