17

Edit: I had the wrong version of the pika package installed on my device. It works fine after I updated from pip.

I just started learning the usage of RabbitMQ (using Python) by following their tutorial. The send.py code works works fine but when I try to run receive.py, I see this error:

Traceback (most recent call last):
  File "receive.py", line 15, in <module>
    no_ack=True)
TypeError: basic_consume() got multiple values for keyword argument 'queue'

Here's the code inside receive.py:

#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()


channel.queue_declare(queue='hello')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

Any idea what I am doing wrong?

sudhanva
  • 699
  • 1
  • 7
  • 28

6 Answers6

31

You probably don't need it anymore, but I had exactly the same problem as You and this is what I figured out.

For me it turned out that RabbitMQ documentation must've been using a different version of pika. I found out that in pika 1.0.0 basic_consume function has different order of arguments. This is how it looks on my machine:

    def basic_consume(self,
                  queue,
                  on_message_callback,
                  auto_ack=False,
                  exclusive=False,
                  consumer_tag=None,
                  arguments=None):

Once I changed the order of arguments passed, or added keyword 'on_message_callback=callback' it all worked. I hope it helps!

Piotr Wieleba
  • 409
  • 4
  • 9
21

just change

channel.basic_consume(callback, queue='hello', no_ack=True)

to

channel.basic_consume('hello', callback, auto_ack=True)
Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
maschzh
  • 211
  • 2
  • 2
  • they simply swapped the args between Pika 0.9.x and 1.0.x also naming all args works: `channel.basic_consume(on_message_callback=callback, queue='hello', no_ack=True)` – user1708042 Oct 28 '19 at 16:15
  • To get the same behaviour as `no_ack=True`, I think you need `auto_ack=False`. – laker93 Jan 19 '21 at 10:11
5

I can't reproduce your error, but I want to be as concise as possible, when trying to.

At first I set up a rabbitmq server as docker container on my computer, not to pollute my system:

$ docker run -d --hostname localhost --name some-rabbit rabbitmq:3

Then I use inspect to find about the IPAddress my rabbitmq container is running actually:

$ docker inspect some-rabbit --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
172.17.0.2

Next I use pipenv to create a virtual environment in python3 that contains at least pika and dependencies to follow the example:

$ mkdir example && cd example && pipenv --three install pika
Creating a virtualenv for this project…
Using /usr/bin/python3 (3.6.5) to create virtualenv…

Note, that you can also use python 2.7 here if you say pipenv --two when installing pika.

Then jump into the environment using pipenv shell:

~/example$ pipenv shell
Spawning environment shell (/bin/bash). Use 'exit' to leave.

There I create the two files send.py and receive.py as proposed by the example documentation of pika, but I'll replace the localhost by the docker containers IP from above:

$ cat send.py 
#!/usr/bin/env python 
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='172.17.0.2'))
channel = connection.channel()


channel.queue_declare(queue='hello')

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

And receive.py:

$ cat receive.py
#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='172.17.0.2'))
channel = connection.channel()


channel.queue_declare(queue='hello')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

channel.basic_consume(callback,
                      queue='hello',
                      no_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

Having receive.py running in one terminal and running send.py in another works as expected:

 $ python receive.py 
 [*] Waiting for messages. To exit press CTRL+C

 $ python send.py
 [x] Sent 'Hello World!'

 $ python receive.py 
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received b'Hello World!

HTH, f3rdy

Dodge
  • 3,219
  • 3
  • 19
  • 38
ferdy
  • 7,366
  • 3
  • 35
  • 46
1

I got the same issue on Ubuntu 18.04 with the in-stock python-pika package version 0.11.0-1, after I remove the in-stock version and installed a newer version pika (1.0.1) by pip, this issue disappeared.

Shengyao Xue
  • 111
  • 2
0

just change

channel.basic_consume(callback, queue='hello', no_ack=True)

to

channel.basic_consume(queue='hello', callback, no_ack=True)

because i found the code in lib is.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
  • def basic_consume(self, queue, on_message_callback, auto_ack=False, exclusive=False, consumer_tag=None, arguments=None): – jiangbo liu Jan 08 '19 at 09:12
  • 1
    This doesn't work. The second like should be without `queue=` and `no_ack` should be `auto_ack`, thus, the correct line is: `channel.basic_consume('hello', callback, auto_ack=True)` – Avión May 24 '19 at 14:54
0

This code might help:

channel.basic_consume(on_message_callback=callback, queue='hello')

or

channel.basic_consume(on_message_callback=callback, queue='hello', auto_ack=True)
Reza Rahemtola
  • 1,182
  • 7
  • 16
  • 30
okoksal
  • 41
  • 1
  • 3