This is a quick and dirty demonstration of how Python and Clojure can communicate with one another using rabbitmq.
The use case for me is that I'm writing a webapp in Clojure, and I want it to be backed by some machine learning, and of course Python has the best libraries for that kind of stuff. So, when I want to fit a model, I'm just going to send the data to python and let it send the result back to Clojure when it's done.
To run on your machine:
-
Clone this repo.
-
Install dependencies. For python, you'll need pika,
pip install pika
. You'll also need rabbitmq.brew install rabbitmq
or the apt-get/whev equivalent. If you install via homebrew on mac, be aware that it lands in a place that isn't automatically on PATH for some silly reason. -
Fire up rabbitmq with
/usr/local/sbin/rabbitmq-server
-
Open up a new terminal window and fire up the python script with
python talktoclojure.py
-
Open up a third terminal window and
lein run
.
You should see Clojure send a message to Python which will print on the Python terminal, and then see Python send a reply to Clojure which will print on the Clojure terminal.
- To cleanly shut down, control-c out of the python terminal, and run
/usr/local/sbin/rabbitmqctl stop
to get rabbitmq to shut down --- keyboard interrupts won't do the trick for the last one. Clojure will shut itself down.
You can also just use the shell script talk.sh that will handle the details for you.
If you want to see how clj and python can exchange actual data in JSON format, that's in here too. Just use lein run json
or ./talk.sh json
If you want to try out a version that wires the Clojure-side up with core.async, give it the commandline argument async
instead of json
.
Created using the basic leiningen app template, mostly following this tutorial on the Clojure-side and this tutorial on the Python-side, so, like, almost none of the code is actually mine, but any residual rights that I may have in, I dunno, the act of putting the two tutorials together or something, is hereby committed to the public domain.
Other useful info: this github issue explains why the default needs to be changed on the clojure-side to :auto-delete false
. And this is a very nice general explainer for how rabbitmq works. I also looked at this, though didn't get too much from it.