Using MultipartPostHandler to POST form-data with Python Using MultipartPostHandler to POST form-data with Python python python

Using MultipartPostHandler to POST form-data with Python


It seems that the easiest and most compatible way to get around this problem is to use the 'poster' module.

# test_client.pyfrom poster.encode import multipart_encodefrom poster.streaminghttp import register_openersimport urllib2# Register the streaming http handlers with urllib2register_openers()# Start the multipart/form-data encoding of the file "DSC0001.jpg"# "image1" is the name of the parameter, which is normally set# via the "name" parameter of the HTML <input> tag.# headers contains the necessary Content-Type and Content-Length# datagen is a generator object that yields the encoded parametersdatagen, headers = multipart_encode({"image1": open("DSC0001.jpg")})# Create the Request objectrequest = urllib2.Request("http://localhost:5000/upload_image", datagen, headers)# Actually do the request, and get the responseprint urllib2.urlopen(request).read()

This worked perfect and I didn't have to muck with httplib. The module is available here:http://atlee.ca/software/poster/index.html


Found this recipe to post multipart using httplib directly (no external libraries involved)

import httplibimport mimetypesdef post_multipart(host, selector, fields, files):    content_type, body = encode_multipart_formdata(fields, files)    h = httplib.HTTP(host)    h.putrequest('POST', selector)    h.putheader('content-type', content_type)    h.putheader('content-length', str(len(body)))    h.endheaders()    h.send(body)    errcode, errmsg, headers = h.getreply()    return h.file.read()def encode_multipart_formdata(fields, files):    LIMIT = '----------lImIt_of_THE_fIle_eW_$'    CRLF = '\r\n'    L = []    for (key, value) in fields:        L.append('--' + LIMIT)        L.append('Content-Disposition: form-data; name="%s"' % key)        L.append('')        L.append(value)    for (key, filename, value) in files:        L.append('--' + LIMIT)        L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))        L.append('Content-Type: %s' % get_content_type(filename))        L.append('')        L.append(value)    L.append('--' + LIMIT + '--')    L.append('')    body = CRLF.join(L)    content_type = 'multipart/form-data; boundary=%s' % LIMIT    return content_type, bodydef get_content_type(filename):    return mimetypes.guess_type(filename)[0] or 'application/octet-stream'


Just use python-requests, it will set proper headers and do upload for you:

import requests files = {"form_input_field_name": open("filename", "rb")}requests.post("http://httpbin.org/post", files=files)