Python client for Consul.io¶
Documentation¶
Status¶
Example¶
import consul
c = consul.Consul()
# poll a key for updates
index = None
while True:
index, data = c.kv.get('foo', index=index)
print data['Value']
# in another process
c.kv.put('foo', 'bar')
Installation¶
pip install python-consul
Status¶
There’s a few API endpoints still to go to expose all features available in Consul v0.5.0. If you need an endpoint that’s not in the documentation, just open an issue and I’ll try and add it straight away.
Clients¶
This library is designed to be easily adapted for a number of clients. Particularly asynchronous clients. The following clients are currently supported.
Standard¶
This is a standard blocking python client. It isn’t particularly useful for creating server components - but it does serve as a base. It makes use of the requests library for http requests.
>>> import consul
>>> c = consul.Consul()
>>> c.kv.put('foo', 'bar')
True
>>> index, data = c.kv.get('foo')
>>> data['Value']
'bar'
# this will block until there's an update or a timeout
>>> index, data = c.kv.get('foo', index=index)
Vanilla¶
An asynchronous Vanilla plugin based on this library is available at: https://github.com/cablehead/vanilla.consul
gevent¶
The terribly awful thing about gevent is that anything that uses the socket library from the python standard lib, including the requests library can be made non-blocking via monkey patching. This means the standard python-consul client will just work asynchronously with gevent.
Tornado¶
There is a Tornado client which makes use of gen.coroutine. The API for this client is identical to the standard python-consul client except that you need to yield the result of each API call. This client is available in consul.tornado.
import consul.tornado
class Config(object):
def __init__(self):
self.foo = None
loop.add_callback(self.watch)
@tornado.gen.coroutine
def watch(self):
c = consul.tornado.Consul()
# asynchronously poll for updates
index = None
while True:
index, data = yield c.kv.get('foo', index=index)
self.foo = data['Value']
asyncio¶
There is a asyncio (using aiohttp) client which works with Python3.4 and
makes use of asyncio.coroutine. The API for this client is identical to
the standard python-consul client except that you need to yield from
the
result of each API call. This client is available in consul.aio.
import asyncio
import consul.aio
loop = asyncio.get_event_loop()
@asyncio.coroutine
def go():
# always better to pass ``loop`` explicitly, but this
# is not mandatory, you can relay on global event loop
c = consul.aio.Consul(port=consul_port, loop=loop)
# set value, same as default api but with ``yield from``
response = yield from c.kv.put(b'foo', b'bar')
assert response is True
# get value
index, data = yield from c.kv.get(b'foo')
assert data['Value'] == b'bar'
# delete value
response = yield from c.kv.delete(b'foo2')
assert response is True
loop.run_until_complete(go())
Wanted¶
Adaptors for Twisted and a thread pool based adaptor.
Tools¶
Handy tools built on python-consul.
Example Uses¶
ACLs¶
import consul
# master_token is a *management* token, for example the *acl_master_token*
# you started the Consul server with
master = consul.Consul(token=master_token)
master.kv.put('foo', 'bar')
master.kv.put('private/foo', 'bar')
rules = """
key "" {
policy = "read"
}
key "private/" {
policy = "deny"
}
"""
token = master.acl.create(rules=rules)
client = consul.Consul(token=token)
client.kv.get('foo') # OK
client.kv.put('foo', 'bar2') # raises ACLPermissionDenied
client.kv.get('private/foo') # returns None, as though the key doesn't
# exist - slightly unintuitive
client.kv.put('private/foo', 'bar2') # raises ACLPermissionDenied