Skip to content

Latest commit

 

History

History
317 lines (221 loc) · 6.76 KB

File metadata and controls

317 lines (221 loc) · 6.76 KB

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.

from tornado.ioloop import IOLoop
from tornado.gen import coroutine
from consul.base import Timeout
from consul.tornado import Consul


class Config(object):
    def __init__(self, loop):
        self.foo = None
        loop.add_callback(self.watch)

    @coroutine
    def watch(self):
        c = Consul()

        # asynchronously poll for updates
        index = None
        while True:
            try:
                index, data = yield c.kv.get('foo', index=index)
                if data is not None:
                    self.foo = data['Value']
            except Timeout:
                # gracefully handle request timeout
                pass

if __name__ == '__main__':
    loop = IOLoop.instance()
    _ = Config(loop)
    loop.start()

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.

ianitor is a doorkeeper for your services discovered using consul. It can automatically register new services through consul API and manage TTL health checks.

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

API Documentation

Check

.. autoclass:: consul.Check

Check.docker

.. automethod:: consul.Check.docker

Check.script

.. automethod:: consul.Check.script

Check.http

.. automethod:: consul.Check.http

Check.tcp

.. automethod:: consul.Check.tcp

Check.ttl

.. automethod:: consul.Check.ttl


Consul

.. autoclass:: consul.Consul

Consul.acl

.. autoclass:: consul.base::Consul.ACL()
   :members:
   :undoc-members:

Consul.agent

.. autoclass:: consul.base::Consul.Agent()
   :members:
   :exclude-members: Service

.. autoclass:: consul.base::Consul.Agent.Service()
   :members:

.. autoclass:: consul.base::Consul.Agent.Check()
   :members:

Consul.catalog

.. autoclass:: consul.base::Consul.Catalog()
   :members:
   :undoc-members:

Consul.event

.. autoclass:: consul.base::Consul.Event()
   :members:
   :undoc-members:

Consul.coordinate

.. autoclass:: consul.base::Consul.Coordinate()
   :members:
   :undoc-members:

Consul.health

.. autoclass:: consul.base::Consul.Health()
   :members:
   :undoc-members:
   :exclude-members: Check

Consul.kv

.. autoclass:: consul.base::Consul.KV()
   :members:
   :undoc-members:

Consul.query

.. autoclass:: consul.base::Consul.Query()
   :members:
   :undoc-members:

Consul.session

.. autoclass:: consul.base::Consul.Session()
   :members:
   :undoc-members:

Consul.status

.. autoclass:: consul.base::Consul.Status()
   :members:
   :undoc-members:

Consul.txn

.. autoclass:: consul.base::Consul.Txn()
   :members:
   :undoc-members: