web-dev-qa-db-ja.com

Python POSTバイナリデータ

私はredmineとインターフェースするためのコードを書いており、プロセスの一部としていくつかのファイルをアップロードする必要がありますが、POST request from pythonバイナリファイルが含まれています。

私はコマンドを模倣しようとしています here

curl --data-binary "@image.png" -H "Content-Type: application/octet-stream" -X POST -u login:password http://redmine/uploads.xml

In python(下記)ですが、うまくいかないようです。問題がファイルのエンコードに何らかの関係があるのか​​、ヘッダーに問題があるのか​​はわかりません。

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

サーバーにアクセスできますが、エンコードエラーのようです。

...
invalid byte sequence in UTF-8
Line: 1
Position: 624
Last 80 unconsumed characters:
7z¼¯'ÅÐз2^Ôøë4g¸R<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)
40
Mac

これは、不正な形式のアップロードとは関係ありません。 HTTPエラーは401不正を明確に示しており、CSRFトークンが無効であることを示しています。アップロードで有効なCSRFトークンを送信してみてください。

Csrfトークンの詳細はこちら:

CSRFトークンとは?その重要性とその機能は?

2
Josh Liptzin

nirest を使用できます。リクエストを投稿する簡単な方法を提供します。 `

import unirest

def callback(response):
 print "code:"+ str(response.code)
 print "******************"
 print "headers:"+ str(response.headers)
 print "******************"
 print "body:"+ str(response.body)
 print "******************"
 print "raw_body:"+ str(response.raw_body)

# consume async post request
def consumePOSTRequestASync():
 params = {'test1':'param1','test2':'param2'}

 # we need to pass a dummy variable which is open method
 # actually unirest does not provide variable to shift between
 # application-x-www-form-urlencoded and
 # multipart/form-data

 params['dummy'] = open('dummy.txt', 'r')
 url = 'http://httpbin.org/post'
 headers = {"Accept": "application/json"}
 # call get service with headers and params
 unirest.post(url, headers = headers,params = params, callback = callback)


# post async request multipart/form-data
consumePOSTRequestASync()

`

完全な例は http://stackandqueue.com/?p=57 で確認できます

0
gvir

次のようにContent-Dispositionヘッダーを追加する必要があります(ここではmod-pythonを使用しましたが、原則は同じである必要があります)。

request.headers_out['Content-Disposition'] = 'attachment; filename=%s' % myfname
0
mrkafk