Package: aiormq
aiormq is a pure python AMQP client library.Table of contentsStatusFeaturesTutorialIntroductionSimple consumerSimple publisherWork QueuesCreate new taskSimple workerPublish SubscribePublisherSubscriberRoutingDirect consumerEmitterTopicsPublisherConsumerRemote procedure call (RPC)RPC serverRPC clientStatus3.x.x branch - Production/Stable4.x.x branch - Unstable (Experimental)5.x.x and greater is only Production/Stable releases.FeaturesConnecting by URLamqp example:amqp://user:password@server.host/vhostsecure amqp example:amqps://user:password@server.host/vhost?cafile=ca.pem&keyfile=key.pem&certfile=cert.pem&no_verify_ssl=0Buffered queue for received framesOnlyPLAINauth mechanism supportPublisher confirmssupportTransactionssupportChannel based asynchronous locksNoteAMQP 0.9.1 requires serialize sending for some frame types
on the channel. e.g. Content body must be following after
content header. But frames might be sent asynchronously
on another channels.Tracking unroutable messages
(Useconnection.channel(on_return_raises=False)for disabling)Full SSL/TLS support, using your choice of:amqps://url query parameters:cafile=- string contains path to ca certificate filecapath=- string contains path to ca certificatescadata=- base64 encoded ca certificate datakeyfile=- string contains path to key filecertfile=- string contains path to certificate fileno_verify_ssl- boolean disables certificates validationcontext=SSLContextkeyword argument toconnect().Pythontype hintsUsespamqpas an AMQP 0.9.1 frame encoder/decoderTutorialIntroductionSimple consumerimportasyncioimportaiormqasyncdefon_message(message):"""
    on_message doesn't necessarily have to be defined as async.
    Here it is to show that it's possible.
    """print(f" [x] Received message{message!r}")print(f"Message body is:{message.body!r}")print("Before sleep!")awaitasyncio.sleep(5)# Represents async I/O operationsprint("After sleep!")asyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()# Declaring queuedeclare_ok=awaitchannel.queue_declare('helo')consume_ok=awaitchannel.basic_consume(declare_ok.queue,on_message,no_ack=True)loop=asyncio.get_event_loop()loop.run_until_complete(main())loop.run_forever()Simple publisherimportasynciofromtypingimportOptionalimportaiormqfromaiormq.abcimportDeliveredMessageMESSAGE:Optional[DeliveredMessage]=Noneasyncdefmain():globalMESSAGEbody=b'Hello World!'# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost//")# Creating a channelchannel=awaitconnection.channel()declare_ok=awaitchannel.queue_declare("hello",auto_delete=True)# Sending the messageawaitchannel.basic_publish(body,routing_key='hello')print(f" [x] Sent{body}")MESSAGE=awaitchannel.basic_get(declare_ok.queue)print(f" [x] Received message from{declare_ok.queue!r}")loop=asyncio.get_event_loop()loop.run_until_complete(main())assertMESSAGEisnotNoneassertMESSAGE.routing_key=="hello"assertMESSAGE.body==b'Hello World!'Work QueuesCreate new taskimportsysimportasyncioimportaiormqasyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()body=b' '.join(sys.argv[1:])orb"Hello World!"# Sending the messageawaitchannel.basic_publish(body,routing_key='task_queue',properties=aiormq.spec.Basic.Properties(delivery_mode=1,))print(f" [x] Sent{body!r}")awaitconnection.close()loop=asyncio.get_event_loop()loop.run_until_complete(main())Simple workerimportasyncioimportaiormqimportaiormq.abcasyncdefon_message(message:aiormq.abc.DeliveredMessage):print(f" [x] Received message{message!r}")print(f"     Message body is:{message.body!r}")asyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()awaitchannel.basic_qos(prefetch_count=1)# Declaring queuedeclare_ok=awaitchannel.queue_declare('task_queue',durable=True)# Start listening the queue with name 'task_queue'awaitchannel.basic_consume(declare_ok.queue,on_message,no_ack=True)loop=asyncio.get_event_loop()loop.run_until_complete(main())# we enter a never-ending loop that waits for data and runs# callbacks whenever necessary.print(" [*] Waiting for messages. To exit press CTRL+C")loop.run_forever()Publish SubscribePublisherimportsysimportasyncioimportaiormqasyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()awaitchannel.exchange_declare(exchange='logs',exchange_type='fanout')body=b' '.join(sys.argv[1:])orb"Hello World!"# Sending the messageawaitchannel.basic_publish(body,routing_key='info',exchange='logs')print(f" [x] Sent{body!r}")awaitconnection.close()loop=asyncio.get_event_loop()loop.run_until_complete(main())Subscriberimportasyncioimportaiormqimportaiormq.abcasyncdefon_message(message:aiormq.abc.DeliveredMessage):print(f"[x]{message.body!r}")awaitmessage.channel.basic_ack(message.delivery.delivery_tag)asyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()awaitchannel.basic_qos(prefetch_count=1)awaitchannel.exchange_declare(exchange='logs',exchange_type='fanout')# Declaring queuedeclare_ok=awaitchannel.queue_declare(exclusive=True)# Binding the queue to the exchangeawaitchannel.queue_bind(declare_ok.queue,'logs')# Start listening the queue with name 'task_queue'awaitchannel.basic_consume(declare_ok.queue,on_message)loop=asyncio.get_event_loop()loop.create_task(main())# we enter a never-ending loop that waits for data# and runs callbacks whenever necessary.print(' [*] Waiting for logs. To exit press CTRL+C')loop.run_forever()RoutingDirect consumerimportsysimportasyncioimportaiormqimportaiormq.abcasyncdefon_message(message:aiormq.abc.DeliveredMessage):print(f" [x]{message.delivery.routing_key!r}:{message.body!r}"awaitmessage.channel.basic_ack(message.delivery.delivery_tag)asyncdefmain():# Perform connectionconnection=aiormq.Connection("amqp://guest:guest@localhost/")awaitconnection.connect()# Creating a channelchannel=awaitconnection.channel()awaitchannel.basic_qos(prefetch_count=1)severities=sys.argv[1:]ifnotseverities:sys.stderr.write(f"Usage:{sys.argv[0]}[info] [warning] [error]\n")sys.exit(1)# Declare an exchangeawaitchannel.exchange_declare(exchange='logs',exchange_type='direct')# Declaring random queuedeclare_ok=awaitchannel.queue_declare(durable=True,auto_delete=True)forseverityinseverities:awaitchannel.queue_bind(declare_ok.queue,'logs',routing_key=severity)# Start listening the random queueawaitchannel.basic_consume(declare_ok.queue,on_message)loop=asyncio.get_event_loop()loop.run_until_complete(main())# we enter a never-ending loop that waits for data# and runs callbacks whenever necessary.print(" [*] Waiting for messages. To exit press CTRL+C")loop.run_forever()Emitterimportsysimportasyncioimportaiormqasyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()awaitchannel.exchange_declare(exchange='logs',exchange_type='direct')body=(b' '.join(arg.encode()forarginsys.argv[2:])orb"Hello World!")# Sending the messagerouting_key=sys.argv[1]iflen(sys.argv)>2else'info'awaitchannel.basic_publish(body,exchange='logs',routing_key=routing_key,properties=aiormq.spec.Basic.Properties(delivery_mode=1))print(f" [x] Sent{body!r}")awaitconnection.close()loop=asyncio.get_event_loop()loop.run_until_complete(main())TopicsPublisherimportsysimportasyncioimportaiormqasyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()awaitchannel.exchange_declare('topic_logs',exchange_type='topic')routing_key=(sys.argv[1]iflen(sys.argv)>2else'anonymous.info')body=(b' '.join(arg.encode()forarginsys.argv[2:])orb"Hello World!")# Sending the messageawaitchannel.basic_publish(body,exchange='topic_logs',routing_key=routing_key,properties=aiormq.spec.Basic.Properties(delivery_mode=1))print(f" [x] Sent{body!r}")awaitconnection.close()loop=asyncio.get_event_loop()loop.run_until_complete(main())Consumerimportasyncioimportsysimportaiormqimportaiormq.abcasyncdefon_message(message:aiormq.abc.DeliveredMessage):print(f" [x]{message.delivery.routing_key!r}:{message.body!r}")awaitmessage.channel.basic_ack(message.delivery.delivery_tag)asyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/",loop=loop)# Creating a channelchannel=awaitconnection.channel()awaitchannel.basic_qos(prefetch_count=1)# Declare an exchangeawaitchannel.exchange_declare('topic_logs',exchange_type='topic')# Declaring queuedeclare_ok=awaitchannel.queue_declare('task_queue',durable=True)binding_keys=sys.argv[1:]ifnotbinding_keys:sys.stderr.write(f"Usage:{sys.argv[0]}[binding_key]...\n")sys.exit(1)forbinding_keyinbinding_keys:awaitchannel.queue_bind(declare_ok.queue,'topic_logs',routing_key=binding_key)# Start listening the queue with name 'task_queue'awaitchannel.basic_consume(declare_ok.queue,on_message)loop=asyncio.get_event_loop()loop.create_task(main())# we enter a never-ending loop that waits for# data and runs callbacks whenever necessary.print(" [*] Waiting for messages. To exit press CTRL+C")loop.run_forever()Remote procedure call (RPC)RPC serverimportasyncioimportaiormqimportaiormq.abcdeffib(n):ifn==0:return0elifn==1:return1else:returnfib(n-1)+fib(n-2)asyncdefon_message(message:aiormq.abc.DeliveredMessage):n=int(message.body.decode())print(f" [.] fib({n})")response=str(fib(n)).encode()awaitmessage.channel.basic_publish(response,routing_key=message.header.properties.reply_to,properties=aiormq.spec.Basic.Properties(correlation_id=message.header.properties.correlation_id),)awaitmessage.channel.basic_ack(message.delivery.delivery_tag)print('Request complete')asyncdefmain():# Perform connectionconnection=awaitaiormq.connect("amqp://guest:guest@localhost/")# Creating a channelchannel=awaitconnection.channel()# Declaring queuedeclare_ok=awaitchannel.queue_declare('rpc_queue')# Start listening the queue with name 'hello'awaitchannel.basic_consume(declare_ok.queue,on_message)loop=asyncio.get_event_loop()loop.create_task(main())# we enter a never-ending loop that waits for data# and runs callbacks whenever necessary.print(" [x] Awaiting RPC requests")loop.run_forever()RPC clientimportasyncioimportuuidimportaiormqimportaiormq.abcclassFibonacciRpcClient:def__init__(self):self.connection=None# type: aiormq.Connectionself.channel=None# type: aiormq.Channelself.callback_queue=''self.futures={}self.loop=loopasyncdefconnect(self):self.connection=awaitaiormq.connect("amqp://guest:guest@localhost/")self.channel=awaitself.connection.channel()declare_ok=awaitself.channel.queue_declare(exclusive=True,auto_delete=True)awaitself.channel.basic_consume(declare_ok.queue,self.on_response)self.callback_queue=declare_ok.queuereturnselfasyncdefon_response(self,message:aiormq.abc.DeliveredMessage):future=self.futures.pop(message.header.properties.correlation_id)future.set_result(message.body)asyncdefcall(self,n):correlation_id=str(uuid.uuid4())future=loop.create_future()self.futures[correlation_id]=futureawaitself.channel.basic_publish(str(n).encode(),routing_key='rpc_queue',properties=aiormq.spec.Basic.Properties(content_type='text/plain',correlation_id=correlation_id,reply_to=self.callback_queue,))returnint(awaitfuture)asyncdefmain():fibonacci_rpc=awaitFibonacciRpcClient().connect()print(" [x] Requesting fib(30)")response=awaitfibonacci_rpc.call(30)print(r" [.] Got{response!r}")loop=asyncio.get_event_loop()loop.run_until_complete(main())