4

I am currently using PycURL to trigger a build in Jenkins, by posting to a certain URL. The relevant code looks as follows:

curl = pycurl.Curl()
curl.setopt(pycurl.URL, url)
# These are the form fields expected by Jenkins
data = [
        ("name", "CI_VERSION"),
        ("value", str(version)),
        ("name", "integration.xml"),
        ("file0", (pycurl.FORM_FILE, metadata_fpath)),
        ("json", "{{'parameter': [{{'name': 'CI_VERSION', 'value':"
            "'{0}'}}, {{'name': 'integration.xml', 'file': 'file0'}}]}}".
                format(version,)),
        ("Submit", "Build"),
        ]
curl.setopt(pycurl.HTTPPOST, data)
curl.perform()

As you can see, one of the post parameters ('file0') is a file, as indicated by the parameter type pycurl.FORM_FILE.

How can I replace my usage of PycURL with the standard Python library?

aknuds1
  • 65,625
  • 67
  • 195
  • 317
  • Is pure Python package ok or do you really want to use standard library alone? – Piotr Dobrogost Nov 22 '12 at 21:22
  • @PiotrDobrogost Well, the question is really about the standard library, but I figure you could post a pure Python solution for reference. I was able to solve the problem myself with the [requests](http://python-requests.org) library. – aknuds1 Nov 22 '12 at 22:03
  • That's what I wanted to recommend. See [Send file using POST from a Python script](http://stackoverflow.com/q/68477/95735) – Piotr Dobrogost Nov 22 '12 at 23:33

2 Answers2

1
u = urllib.urlopen(url, data=urllib.urlencode(
                             {'name': 'CI_VERSION', 
                              'value': str(version),
                              'file0': open(metadata_fpath).read(),
                               etc. 
                               etc.})) 

You can do this with urllib / urllib2. Above is a minimal example of sending a POST request.

agf
  • 171,228
  • 44
  • 289
  • 238
  • This doesn't deal with the problem of posting files though, does it? Posting straight string parameters should be simple enough with urllib*. – aknuds1 Aug 15 '11 at 12:46
  • I think this works fine for posting files. Just use `open(metadata_fpath).read()` as a value attacked to the key `file0`. I'll add this to the answer. – agf Aug 15 '11 at 12:49
  • How does this correspond to what seriyPS is saying in his answer though (that multipart/form-data is required to POST files)? See also this bug, http://bugs.python.org/issue3244, which basically says that the stdlib must be extended to support file uploads via POST. It even includes a patch to implement such support. – aknuds1 Aug 15 '11 at 13:54
  • I believe I've used this method before. However, maybe it has limitations -- if the file is below a certain size, or text? I've previously heard good things about both `poster` and `urllib3` (both linked in that report), so you could give them a try if the raw post data method fails. – agf Aug 15 '11 at 13:57
1

Standard python library has no support of multipart/form-data that required for post files through POST requests.

There is some recipes eg http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/

seriyPS
  • 6,817
  • 2
  • 25
  • 16
  • I'm trying to POST a file to Jenkins using this method, but it fails. See my question on this particular issue: http://stackoverflow.com/questions/7078561/posting-file-to-jenkins-fails. – aknuds1 Aug 16 '11 at 13:40