Jump to: navigation, search

Python Client Library (Marconi)

Revision as of 01:49, 20 July 2013 by Alejandro Cabrera (talk | contribs) (Queue Handling: queue.stats should return a dictionary, not a controller.)

This document exists to establish the feel of working with the python Marconi client. It serves as both a vision and a direction for implementors. Check out the blueprints for more details.

If you have questions, reach us at freenode.irc.net #openstack-marconi!

Features

  • Certificate verification
  • Reauthentication on token expiration
  • Async operations
  • Full coverage of Marconi API

Classes

Controllers

  • Client: handles account-wide operations - queue retrieval, etc.
  • Queue: gives access to some metadata ops, as well as message handling
  • Message: gives access to properties of message, as well as deletion
  • Claim: Collection of claimed messages - handle querying, updating, and deleting

Core

  • Connection: handles authentication with Keystone, acquires Marconi endpoint, handles requests and networking logic

Utility

  • ErrorBase: the foundation for Marconi client specific errors

API Synopsis

See Marconi/specs/api/v1

Usage

Working With a Connection

    >>> from marconiclient.common.connection import Connection
    >>> conn = Connection('tacocat', apikey='my_awesome_key')
    >>> conn.tenant
    123456
    >>> conn.username
    u'tacocat'
    >>> conn.version
    u'1.0'
    >>> conn.token
    u'1234567654321234543hj2b34j54bj32'
    >>> conn.expires
    datetime.datetime(2013, 7, 10, 13, 29, 54, 702873)
    >>> conn.host
    u'https://marconi.example.com/v1.0'
    >>> conn.headers
    {u'x-auth-token': ..., u'host': ..., u'date': ..., u'accept': ...,
     u'accept-encoding': ..., u'content-length': ..., u'x-project-id': ...}
    # Client ID set at the Client level
    >>> conn.request(Http.GET, headers={u'x-client-id': 100},
                     data=json.dumps({'my': 'message'}),
                     verify=True)
    <Response [200]>
    >>> conn
    <MarconiConnection user:tacocat expires:2013-07-11T03:28:33.834-05:00>

Http.Get is a client-defined Python enumeration. See flufl.enum and PEP 435 for more information on Python enumerations.

Client Operation

    # Implement auth using common lib. Client calls to that.
    >>> client = Client(conn, async=False)
    >>> client.queues(marker=..., limit=10, detailed=False)
    <generator object <genexpr> ar 0x7fd3ef1ed730>
    >>> client.create_queue(name='wot')
    <MarconiQueue [wot]>
    >>> client.home
    <HomeDoc ...>
    # affects all operations for objects acquired from the client
    >>> client.async
    False

Queue Handling

    >>> queue = next(q for q in client.queues if q.name == 'tacocat')
    >>> queue.name
    u'tacocat'
    >>> queue.href
    u'/v1/queues/tacocat'
    >>> queue.stats
    # a dictionary derived from a JSON response
    >>> queue.get_messages(include_claimed=False)
    <generator object <genexpr> ar 0x7fd3ef1ed742>
    >>> queue.get_messages(ids=[50b68a50d6f5b8c8a7c62b01, 50b68a50d6f5b8c8a7c62b02],
                           claim=a28ee94e-6cb4-11e2-b4d5-7703267a7926, limit=1)
    <generator object <genexpr> ar 0x7fd3ef1ed742>
    >>> queue.post_messages(messages=...)
    >>> queue.metadata
    <Metadata ...>  # fetches metadata from API, returns a Metadata controller
    >>> queue.claim(limit=10)
    <Claim size:8 ...>  # size: actual number of messages received
    >>> queue.delete()

Queue Metadata Handling

    >>> meta = queue.metadata
    >>> meta.update({'max_size': 1000})  # communicate with API, replaces
    >>> meta.reload()  # gets most recent attributes from API

Message Handling

    >>> message = next(queue.messages(...))
    >>> message.age
    90
    >>> message.ttl
    120
    >>> message.href
    u'/v1/queues/darn_good_queue/messages/91wqe9bqwsbq98'
    >>> message.body
    {u'action': u'win'}
    >>> message.reload()
    >>> message.delete()
    >>> message.status
    <EnumValue: Message.Free [value=1]>

Claim Management

>>> claim = queue.claim(limit=10)
>>> claim.messages(...)
<generator object <genexpr> ar 0x7fd3ef1ed742>
>>> msg = next(claim.messages(...))
>>> msg.status
<EnumValue: Message.Claimed [value=2]>
>>> claim.href
u'/v1/queues/tacocat/claims/a28ee94e-6cb4-11e2-b4d5-7703267a7926'
>>> claim.ttl
90
>>> claim.grace
30
>>> claim.patch(ttl=..., grace=...)
>>> claim.release()

Error Management

The wiki gives a thorough explanation of Marconi Errors. Error handling at the client-level is a matter of transforming responses returned by Marconi into exceptions that are meaningful to users.

Here's a quick mock up of error usage at the level of the client:

    >> error = marconi.error.ErrorBase()
    >>> error.title
    u'...'
    >>> error.description
    u'...'
    >>> error.code
    1092
    >>> raise error
    ErrorBase (error.code): error.title
    error.description