We are currently triggering Jenkins jobs from a Python script with the help of PycURL. We would like, however, to get rid of the PycURL dependency, but have had little success so far. What makes our scenario more complicated is that we need to post a file as a parameter. Our current PycURL logic for posting the request looks as follows:
url = "https://myjenkins/job/myjob/build"
with contextlib.closing(pycurl.Curl()) as curl:
curl.setopt(pycurl.URL, url)
curl.setopt(pycurl.USERPWD, "myuser:mypassword")
curl.setopt(pycurl.SSL_VERIFYPEER, False)
curl.setopt(pycurl.SSL_VERIFYHOST, False)
curl.setopt(pycurl.FAILONERROR, True)
data = [
("name", "integration.xml"),
("file0", (pycurl.FORM_FILE, "integration.xml")),
("json", "{'parameter': [{'name': 'integration.xml', 'file': 'file0'}]}"),
("Submit", "Build"),
]
curl.setopt(pycurl.HTTPPOST, data)
try:
curl.perform()
except pycurl.error, err:
raise JenkinsTriggerError(curl.errstr())
How can we replace this with facilities from the standard Python library?
We've tried before, but had to give up as we could not see how to upload files successfully, as you can see from my question on that issue.
I found a solution, using the requests and urllib3 libraries. Not entirely standard, but more lightweight than the PycURL dependency. It should be possible to do this directly with requests (avoiding the urllib3 part), but I ran into a bug.
import urllib3, requests, json
url = "https://myjenkins.com/job/myjob"
params = {"parameter": [
{"name": "integration.xml", "file": "file0"},
]}
with open("integration.xml", "rb") as f:
file_data = f.read()
data, content_type = urllib3.encode_multipart_formdata([
("file0", (f.name, file_data)),
("json", json.dumps(params)),
("Submit", "Build"),
])
resp = requests.post(url, auth=("myuser", "mypassword"), data=data,
headers={"content-type": content_type}, verify=False)
resp.raise_for_status()