Monday, July 28, 2008

using libcurl, pycurl on for xml post

I had to do an xml call to get data from a remote server. it had to be a post request.
This is a simple example of using PycURL (pycurl) to access the libcurl library. I had been doing a python popen3() call to '/usr/bin/curl' and passing the params. This was ugly. A co-worker recommended pycurl. So, here it is, the sample code:

c = pycurl.Curl()
c.setopt(pycurl.URL, ncServerURL)
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.HTTPHEADER, ["Content-type: text/xml"])
c.setopt(pycurl.TIMEOUT, ncServerMaxTime)
c.setopt(pycurl.CONNECTTIMEOUT, ncServerMaxTime)
c.setopt(pycurl.NOSIGNAL, 1) # disable signals, curl will be using other means besides signals to timeout.
c.setopt(pycurl.POSTFIELDS, xmlRequest)
import StringIO
b = StringIO.StringIO()
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.perform()
ncServerData = b.getvalue()

This would only work after I installed pycurl. However, I'm running this on Ubuntu Hardy Heron, and Hardy wanted apt-get to install libcurl version 7.18.0. But pycurl wanted version 7.18.2 minimum. So, I had to go back a version on pycurl. Recommendation: hand-install pycurl version 7.16.4 (the one previous to 7.18.1) and it will work.

Enjoy!

2 comments:

Unknown said...

When I try to post xml, file python return "invalid arguments to setopt" to string c.setopt(pycurl.POSTFIELDS, xml). What it can be?

Unknown said...

Thanks for the info. Very helpful.

One suggestion would be to wrap the perform in a try/exception:

try:
curl.perform()
except pycurl.error, e:
print "Error code: ", e[0]
print "Error message: ", e[1]

else:
status = curl.getinfo(pycurl.HTTP_CODE)


curl.close()