How can I POST parameters with a file object to a URL using httplib in python web services.
Am using the following scripts:
import httplib
import urllib
params = urllib.urlencode({"@str1":"string1", "@str2":"string2", "@file":"/local/path/to/file/in/client/machine", "@action":"action.php" })
headers = {"Content-type":"application/pdf , text/*" }
conn = httplib.HTTPConnection("192.168.2.17")
conn.request("POST", "/SomeName/action.php", params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
data
conn.close()
And I have the following output:
200
OK
<html>.....some html code </html>
I wrote some php code for save those string and the file in DB
My problem is that, Am only getting the file path as a sting but not my file.
May be I have to send the file object like,
file_obj = open("filename.txt","r")
conn.request("POST", "/SomeName/action.php", file_obj, headers)
But I want to send both strings and file. Any suggestions to solve this?
EDIT
I change my code as follows:
When i send a pdf file, by directly using httplib, to my server the file saves as BIN file.
def document_management_service(self,str_loc_file_path,*args):
locfile = open(str_loc_file_path,'rb').read()
host = "some.hostname.com"
selector = "/api/?task=create"
fields = [('docName','INVOICE'),('docNumber','DOC/3'),('cusName','name'),('cusNumber','C124'),('category','INVOICE'),('data','TIJO MRS,SOME/DATA/CONTENT,Blahblah,2584.00,blahblah'),('action','create')]
files = [('strfile','File.pdf',locfile)]
response = self.post_multipart(host, selector, fields, files)
print response
pass
def post_multipart(self,host, selector, fields, files):
content_type, body = self.encode_multipart_formdata(fields, files)
h = httplib.HTTP(host)
h.set_debuglevel(1)
h.putrequest('POST', selector)
h.putheader('content-type', content_type)
h.putheader('content-length', str(len(body)))
h.putheader('Host', host)
h.endheaders()
h.send(body)
errcode, errmsg, headers= h.getreply()
return h.file.read()
def encode_multipart_formdata(self, 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' % self.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, body
def get_content_type(self, filename):
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
I have debug the request which shows as:
[('content-length', '4191'), ('accept-ranges', 'bytes'), ('server', 'Apache/2.2.12 (Ubuntu)'), ('last-modified', 'Tue, 23 Oct 2012 04:46:36 GMT'), ('etag', 'W/"567dd-105f-4ccb2a7a9a500"'), ('date', 'Tue, 23 Oct 2012 04:46:36 GMT'), ('content-type', 'application/pdf')]
multipart/form-data; boundary=----------lImIt_of_THE_fIle_eW_$
And I didn’t try requests,Coz I would like to solve this with httplib(without any external lib)
To post parameters and a file in a body you could use
multipart/form-datacontent type:requests.postsends to the server something like-this:To reproduce it with
httplibsee POST form-data with Python example.A simpler solution if your parameters do not contain much data is to pass them in the url query part and leave the body to contain only the file:
It corresponds to the following HTTP request:
It should be easier to translate to
httplibif you need it.