title: Python POST binary data
body: <p>I am writing some code to interface with redmine and I need to upload some files as part of the process, but I am not sure how to do a POST request from python containing a binary file.</p>
  
  <p>I am trying to mimic the commands <a href="http://www.redmine.org/projects/redmine/wiki/Rest_api_with_curl">here</a>:</p>
  
  <pre><code>curl --data-binary "@image.png" -H "Content-Type: application/octet-stream" -X POST -u login:password http://redmine/uploads.xml
  </code></pre>
  
  <p>In python (below), but it does not seem to work. I am not sure if the problem is somehow related to encoding the file or if something is wrong with the headers.</p>
  
  <pre><code>import urllib2, os
  
  FilePath = "C:\somefolder\somefile.7z"
  FileData = open(FilePath, "rb")
  length = os.path.getsize(FilePath)
  
  password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
  password_manager.add_password(None, 'http://redmine/', 'admin', 'admin')
  auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
  opener = urllib2.build_opener(auth_handler)
  urllib2.install_opener(opener)
  request = urllib2.Request( r'http://redmine/uploads.xml', FileData)
  request.add_header('Content-Length', '%d' % length)
  request.add_header('Content-Type', 'application/octet-stream')
  try:
      response = urllib2.urlopen( request)
      print response.read()
  except urllib2.HTTPError as e:
      error_message = e.read()
      print error_message
  </code></pre>
  
  <p>I have access to the server and it looks like a encoding error:</p>
  
  <pre><code>...
  invalid byte sequence in UTF-8
  Line: 1
  Position: 624
  Last 80 unconsumed characters:
  7z¼¯'ÅÐÐ·2^Ôøë4g¸R&lt;süðí6kÄ¤ª¶!»=}jcdjSPúá-º#»ÄAtD»H7Ê!æ½]j):
  
  (further down)
  
  Started POST "/uploads.xml" for 192.168.0.117 at 2013-01-16 09:57:49 -0800
  Processing by AttachmentsController#upload as XML
  WARNING: Can't verify CSRF token authenticity
    Current user: anonymous
  Filter chain halted as :authorize_global rendered or redirected
  Completed 401 Unauthorized in 13ms (ActiveRecord: 3.1ms)
  </code></pre>