views:

577

answers:

2

I'm familiar with CURL in PHP but am using it for the first time in Python with pycurl.

I keep getting the error:

Exception Type:     error
Exception Value:    (2, '')

I have no idea what this could mean. Here is my code:

data = {'cmd': '_notify-synch',
        'tx': str(request.GET.get('tx')),
        'at': paypal_pdt_test
        }

post = urllib.urlencode(data)

b = StringIO.StringIO()

ch = pycurl.Curl()
ch.setopt(pycurl.URL, 'https://www.sandbox.paypal.com/cgi-bin/webscr')
ch.setopt(pycurl.POST, 1)
ch.setopt(pycurl.POSTFIELDS, post)
ch.setopt(pycurl.WRITEFUNCTION, b.write)
ch.perform()
ch.close()

The error is referring to the line ch.setopt(pycurl.POSTFIELDS, post)

+1  A: 

It would appear that your pycurl installation (or curl library) is damaged somehow. From the curl error codes documentation:

CURLE_FAILED_INIT (2)
Very early initialization code failed. This is likely to be an internal error or problem.

You will possibly need to re-install or recompile curl or pycurl.

However, to do a simple POST request like you're doing, you can actually use python's "urllib" instead of CURL:

import urllib

postdata = urllib.urlencode(data)

resp = urllib.urlopen('https://www.sandbox.paypal.com/cgi-bin/webscr', data=postdata)

# resp is a file-like object, which means you can iterate it,
# or read the whole thing into a string
output = resp.read()

# resp.code returns the HTTP response code
print resp.code # 200

# resp has other useful data, .info() returns a httplib.HTTPMessage
http_message = resp.info()
print http_message['content-length']  # '1536' or the like
print http_message.type  # 'text/html' or the like
print http_message.typeheader # 'text/html; charset=UTF-8' or the like


# Make sure to close
resp.close()

to open an https:// URL, you may need to install PyOpenSSL: http://pypi.python.org/pypi/pyOpenSSL

Some distibutions include this, others provide it as an extra package right through your favorite package manager.


Edit: Have you called pycurl.global_init() yet? I still recommend urllib/urllib2 where possible, as your script will be more easily moved to other systems.

Crast
I also had trouble with it on my local machine getting an error about TLS handshake error. I'll not use pycurl. Does using urllib offer any advantage over this (which is working for me): cmd = "curl --url 'https://www.sandbox.paypal.com/cgi-bin/webscr' --data '" + post + "'" \ return os.system(cmd)
Matt McCormick
The advantage of urllib is that you do not have to fork an external command, which, especially in the case of a web application, is a good amount of performance increase. In addition, the `os.system()` call varies on what it returns based on the OS; if you moved to Linux it might not give the same return value. `urllib`/`urllib2` also lets you read the response from the website easier. And finally, if you wanted to upload your application to a host that did not have curl (or one like Goog le appengine which does not support any external processes) you would need to use `urllib` or similar.
Crast
A: 

I do like that:

post_params = [
    ('ASYNCPOST',True),
    ('PREVIOUSPAGE','yahoo.com'),
    ('EVENTID',5),
]
resp_data = urllib.urlencode(post_params)
mycurl.setopt(pycurl.POSTFIELDS, resp_data)
mycurl.setopt(pycurl.POST, 1)
...
mycurl.perform()
mapcuk