title: Python - multipart form post data
body: <p>This is my first question in this forum. I want to POST(using PUT Method) the data using multipart form data. I found the code for Multipart Post Form Data code in doughellmann.com.It works fine for post data. I ant to add my parameters in PUT Method and i tried it. it does not return back .... Could you please help on this guys....</p>
  
  <p>Code</p>
  
  <pre><code># This Script is used for upload API Calls
  # This script would be inherited under Device API
  # 
  
  import itertools
  import mimetools
  import mimetypes
  from cStringIO import StringIO
  import urllib
  import urllib2
  
  class MultiPartForm(object):
      """Accumulate the data to be used when posting a form."""
  
      def __init__(self):
          self.form_fields = []
          self.files = []
          self.boundary = mimetools.choose_boundary()
          return
  
      def get_content_type(self):
          return 'multipart/form-data; boundary=%s' % self.boundary
  
      def add_field(self, name, value):
          """Add a simple field to the form data."""
          self.form_fields.append((name, value))
          return
  
      def add_file(self, fieldname, filename, fileHandle, mimetype=None):
          """Add a file to be uploaded."""
          body = fileHandle.read()
          if mimetype is None:
              mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
          self.files.append((fieldname, filename, mimetype, body))
          return
  
      def __str__(self):
          """Return a string representing the form data, including attached files."""
          # Build a list of lists, each containing "lines" of the
          # request.  Each part is separated by a boundary string.
          # Once the list is built, return a string where each
          # line is separated by '\r\n'.  
          parts = []
          part_boundary = '--' + self.boundary
  
          # Add the form fields
          parts.extend(
              [ part_boundary,
                'Content-Disposition: form-data; name="%s"' % name,
                '',
                value,
              ]
              for name, value in self.form_fields
              )
  
          # Add the files to upload
          parts.extend(
              [ part_boundary,
                'Content-Disposition: file; name="%s"; filename="%s"' % \
                   (field_name, filename),
                'Content-Type: %s' % content_type,
                '',
                body,
              ]
              for field_name, filename, content_type, body in self.files
              )
  
          # Flatten the list and add closing boundary marker,
          # then return CR+LF separated data
          flattened = list(itertools.chain(*parts))
          flattened.append('--' + self.boundary + '--')
          flattened.append('')
          return '\r\n'.join(flattened)
  
  if __name__ == '__main__':
      # Create the form with simple fields
      form = MultiPartForm()
      form.add_field('firstname', 'Doug')
      form.add_field('lastname', 'Hellmann')
  
      # Add a fake file
      form.add_file('biography', 'bio.txt', 
                    fileHandle=StringIO('Python developer and blogger.'))
  
      # Build the request
      request = urllib2.Request('http://192.1681.2/1.0/api/filecontents')
      request.add_header('User-agent', 'PyMOTW (http://www.doughellmann.com/PyMOTW/)')
      body = str(form)
      request.add_header('Content-type', form.get_content_type())
      request.add_header('Content-length', len(body))
      request.add_data(body)
      regparams={'restMethod' : 'PUT' ,'HTTP_RANGE' :'10-20' }
      print
      print 'OUTGOING DATA:'
      print request.get_data()
      params = urllib.urlencode(regparams)
      print
      print 'SERVER RESPONSE:'
      print urllib2.urlopen(request,params).read()
  </code></pre>