You are on page 1of 4

Notes on using Python amqplib For more detailed descriptions of AMQP concepts, visit https://jira.amqp.

org/confluence/display/AMQP/Download This doc just covers some example usages of the Python library. +---------------------------------------------------------------| | IMPORTANT!! - Connections are NOT thread-safe. A multithreaded | Python program can only use amqplib as long as | each thread has its own Connection object, and | does not try to share amqplib objects such as | Connections or Channels with other threads. | +---------------------------------------------------------------Importing the client -------------------This library currently supports the AMQP 0-8 spec, importing a module geared towards that spec can be done with something like: import amqplib.client_0_8 as amqp Connections ---------A connection object represents a network connection to the server. Some examples for creating a Connection object: conn conn conn conn conn conn conn = = = = = = = amqp.Connection() amqp.Connection('1.2.3.4') amqp.Connection('::1') # IPv6 amqp.Connection('[1234::1]:5671') # IPv6 amqp.Connection('foobar.edu:5671') # could be IPv4 or IPv6 amqp.Connection(host='1.2.3.4:5671', ssl=True) amqp.Connection(userid='foo', password='bar')

Fancier SSL options are available with Python >= 2.6 by specifying a dictionary of options as the "ssl" parameter (see the standard Python library ssl.wrap_socket() function documentation) import ssl conn = amqp.Connection(host='1.2.3.4:5671', ssl={ 'ca_certs': '/path/to/cacert.pem', 'keyfile' : '/path/to/key.pem', 'certfile': '/path/to/cert.pem', 'cert_reqs': ssl.CERT_REQUIRED, }) Connections are closed with the close() method conn.close() Channels ---------Once a Connection is open, one or more Channel objects may be

channel(1) # create and open channel with a specific numeric id ch2 = conn. just # return another reference to that. write=True.opened.access_request('/data'. active=True. it needs an access ticket. auto_delete=True) .exchange_declare('myfan'. read=True) ch. A simpler version of the above code is: ch. and used as a default value for other methods that require tickets. ch2. auto_delete=True.channel_id ch3 = conn.channel(1) # since channel 1 is already created and open. 'fanout'. blah. and the actions it wants to perform on that realm.exchange_declare('myfan'. ticket=tkt) The most recently requested ticket is saved in the Channel object..4') as conn: with conn. # ch. blah) # When this point is reached. | +---------------------------------------------------------------Connections and Channels will close automatically when used as context managers in 'with' statements (available in Python 2. the Connection will have been # closed for you. 'fanout'.basic_publish(blah. the Channel will have been # closed for you. # When this point is reached.channel() as ch: # # Do some stuff. instead of potentially being lost. For example: with Connection('1. which doesn't affect other channels ch2. Channels have a close() method too. Channels are where most of the action is. active=True.close() +---------------------------------------------------------------| | IMPORTANT!! . write=True.be sure to close your channels or connection | if you've been calling async methods like | basic_publish() . Access Tickets -------------Before a channel can do much else. tkt = ch.access_request('/data'. specifying a 'realm'.channel() # let amqplib assign a channel number print 'my channel is'..to ensure your messages are | actually flushed out the TCP socket before the | program ends. So it's not necessary to manually keep and pass it around.5 or higher). read=True) ch. ch = conn. acting as virtual connections between peers.2.3.

which then distribute them to queues. which deliver them to receivers. Polling with basic_get() immediately returns either a Message object. content_encoding='UTF8') Messages may have an 'application_headers' dictionary (another 0-10ism. 0-8 just calls the property 'headers').topic'.basic_publish(msg. 'bar': 'baz'}) Exchanges & Queues ------------------In the AMQP model. messages can be received either by polling or by waiting on the channel. 'amq. and bind it to an exchange: ch. type='fanout') ch.fanout') To declare your own exchange and send it a message: ch.datetime.encode('utf-8'). AMQP defines some default exchanges such as.fanout' . consisting of string keys and values that are strings.queue_bind(qname.direct'. To send to one of these default exchanges: ch. 'amq. or .Message('hello world') Unicode bodies are converted to UTF-8 and the 'content_encoding' property is automatically set to 'UTF-8'. 'amq.basic_publish(msg. A Message can be created as simply as msg = amqp. 'amq.Message(u'Unicode hello') msg2 = amqp.exchange_declare('myfan'. publishers send messages to exchanges. qname. _.queue_declare('myqueue') ch.fanout') If the queue name is omitted from the queue_declare() method. so these two Messages are equivalent msg1 = amqp.queue_bind('myqueue'. a unique one is generated by the server and returned (along with message_count and consumer_count values which we don't care about in this case).queue_declare() ch.Message('fancy'. although the class was named 'Message' based on what's coming in the 0-10 spec.fanout') Receiving Messages -----------------Once a queue is bound to an exchange. integers. and other dictionaries containing those same types. datetime. 'myfan') To receive messages. a program must declare a queue. 'amq. Decimal (a bit shaky). _ = ch.Messages --------This library only supports the Basic Content type. 'amq.Message(u'Unicode hello'.which can be used right away. application_headers={'foo': 7. msg = amqp.

tag = ch. use basic_cancel() with a consumer_tag. The AMQP server will deliver messages to the channel as they're placed into the queue. callback=mycallback.. The demo/demo_send.basic_cancel(msg.basic_consume('myqueue'. msg. A consumer_tag is a string that's either specified when you call basic_consume() ch. ch. To block and wait for messages. msg.. and then wait() on the channel.None if no messages are available: msg = ch. def mycallback(msg): print 'received'.basic_consume('myqueue'.basic_cancel('mytag') or uniquely generated by the server. ### EOF ### .basic_cancel(tag) The consumer_tag is also included as a property in any Message objects delivered through a callback. no_ack=True) while True: ch.basic_get('myqueue') if msg is not None: # do something ch.basic_ack(msg. callback=mycallback. consumer_tag='mytag') .channel_id ch.channel. callback=mycallback) . 'from channel #'. use basic_consume() with a callback function.channel.delivery_tag) Received messages are acknowledged with the Channel. ch. msg.basic_ack() method unless we called basic_get() with a no_ack=True parameter.basic_consume('myqueue'..py script uses this to allow for breaking out of a waiting loop cleanly.consumer_tag) A Channel object has a 'callbacks' property that can be checked to see if there are any outstanding basic_consume() operations registered. To cancel the 'consume'.body.wait() The above example will loop forever..