3

I want to post a file to a server via python, for this I need to name this file as "xmlfile" so that server recognizes the input.

import urllib2
url = "http://somedomain"
to_send = open('test.xml').read()
data = {}
data['xmlfile'] = to_send
f = urllib2.urlopen(url, data)

This doesn't work, in addition, how can I retrieve the response and save someplace ?

In other words, I want to do the action as I do with Curl:

curl.exe http://somedomain -F [email protected] -o response.html
asked Feb 4, 2011 at 9:20
1

2 Answers 2

1

I just read the question nimrodm referred to. One answer mentions the poster module. This module can do the multipart/form-data encoding, so if adding another dependency to your project is not a problem I would go with the poster module.


This is not as simple as it should be. There is a code snippet floating around the net which I used for my code and it does the trick. You will probably have to adapt it for your needs.

class RequestWithMethod(urllib2.Request):
 def __init__(self, method, *args, **kwargs):
 self._method = method
 urllib2.Request.__init__(self, *args, **kwargs)
 def get_method(self):
 return self._method
class RestRequest(object):
 def __init__(self, base_url):
 self.base_url = base_url
 def request(self, url, method, headers={"Accept" : "application/json"}, data=None, json_response=True):
 request = RequestWithMethod(url='{0}{1}{2}'.format(self.base_url, root_url(), url),
 method=method,
 headers=headers)
 if data != None:
 data = urllib.urlencode(data)
 response = urllib2.urlopen(request, data=data).read()
 if json_response:
 return from_json(response)
 else:
 return response
 def GET(self, url, **kwargs):
 return self.request(url, 'GET', **kwargs)
 def POST(self, url, **kwargs):
 return self.request(url, 'POST', **kwargs)
 def POST_FILE(self, url, file, headers={"Accept" : "application/json"}, data={}, **kwargs):
 content_type, body = encode_multipart_formdata(data, file)
 headers['Content-type'] = content_type
 headers['Content-length'] = str(len(body))
 request = RequestWithMethod(url='{0}{1}{2}'.format(self.base_url, root_url(), url),
 data=body,
 method='POST',
 headers=headers)
 return from_json(urllib2.urlopen(request).read())
 def PUT(self, url, **kwargs):
 return self.request(url, 'PUT', **kwargs)
 def DELETE(self, url, **kwargs):
 return self.request(url, 'DELETE', **kwargs)
def encode_multipart_formdata(data, file):
 boundary = '----------ThIs_Is_tHe_bouNdaRY_$'
 L = []
 for key, value in data.items():
 L.append('--' + boundary)
 L.append('Content-Disposition: form-data; name="{0}"'.format(key))
 L.append('')
 L.append(value)
 key, filename, value = file
 L.append('--' + boundary)
 L.append('Content-Disposition: form-data; name="{0}"; filename="{1}"'.format(key, filename))
 content_type = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
 L.append('Content-Type: {0}'.format(content_type))
 L.append('')
 L.append(value)
 L.append('--' + boundary + '--')
 L.append('')
 body = '\r\n'.join(L)
 content_type = 'multipart/form-data; boundary={0}'.format(boundary)
 return content_type, body
answered Feb 4, 2011 at 9:58
Sign up to request clarification or add additional context in comments.

Comments

0

Look at this stackoverflow question or directly at the code it references.

urllib normally sends data using application/x-www-form-urlencoded content-type and while you need multipart/form-data. The referenced library encodes the data as required.

answered Feb 4, 2011 at 9:58

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.