Search code examples
pythonfaye

Emulating a cURL command with Python


I've got a cURL command that does what I need, and I'm trying to translate it into python. Here's the cURL:

curl http://example.com:1234/faye -d 'message={"channel":"/test","data":"hello world"}'

This talks to a Faye server and publishes a message to the channel /test. This works. I'm trying to do that same publishing from within Python. I've looked at this and this, and neither of them helped me; I get a 400 error with both of those methods. Here's some of the stuff I've tried from within the Python shell:

import urllib2, json, requests
addr = 'http://example.com:1234/faye'
data = {'message': {'channel': '/test', 'data': 'hello from python'}}
data_as_json = json.dumps(data)
requests.post(addr, data=data)
requests.post(addr, params=data)
requests.post(addr, data=data_as_json)
requests.post(addr, params=data_as_json)
req = urllib2.Request(addr, data)
urllib2.urlopen(req)
req = urllib2.Request(addr, data_as_json)
urllib2.urlopen(req)
# All these things give 400 errors

Unfortunately I can't wireshark the connection since it's over an SSH tunnel (so everything's encrypted and on the wrong ports). Using the --trace option from cURL I can see that it's not url-encoding the data, so I know I don't need to do that. I also really don't want to Popen cURL itself.


Solution

  • message in this case is the name of a POST variable, and shouldn't be included in the JSON.

    Thus, what you actually want to do is this:

    data = urllib.urlencode({'message': json.dumps({'channel': '/test', 'data': 'hello from python'}))
    conn = urllib2.urlopen('http://example.com:1234/faye', data=data)
    print conn.read()