Python3

【Python】HTTP(POST)でメッセージボディ含めたファイル送信をpycurl又はrequestsで実現する

More than 1 year has passed since last update.

curlで書くと以下となる機能を、Pythonのpycurl又はrequestsそれぞれで実現するコードを記載する。

curl -x xxx.proxy.address.xxx:8080 -k -X POST "https://address.to.post.com/upload?locale=ja_JP" -H "X-Access-Token: 9b6ff625-cf28" -H "X-Service-Code: 000003-00001" -H "Content-Type: multipart/form-data" -F "file=@test.mp3;type=audio/mp3"

上記の -F "file=@test.mp3;type=audio/mp3" をどう表現するかでハマったのでメモ。正解は以下。

pycurl_test.py
import pycurl
import sys
#import certifi

url = 'https://address.to.post.com/upload?locale=ja_JP'

curl = pycurl.Curl()
#curl.setopt(pycurl.CAINFO,certifi.where())
#curl.setopt(pycurl.VERBOSE, True)
curl.setopt(pycurl.URL,url)
curl.setopt(pycurl.CUSTOMREQUEST,'POST')
curl.setopt(pycurl.PROXY,'xxx.proxy.address.xxx:8080')
curl.setopt(pycurl.HTTPHEADER,['X-Access-Token:9b6ff625-cf28', 'X-Service-Code:000003-00001', 'Content-Type:multipart/form-data'])
curl.setopt(pycurl.HTTPPOST, [('file', (pycurl.FORM_FILE,"test.mp3", pycurl.FORM_CONTENTTYPE,"audio/mp3"))])

curl.perform()
curl.close()

pycurlの pycurl.HTTPPOST[(A, B)] におけるAとBは1対1なので、Bにアップロードファイル指定とCONTENTTYPE指定の2つを含めたいなら、 pycurl.HTTPPOST[(A, (B1, B2))] の形にするのがミソ。

requests_test.py
import sys
import requests

proxies = {
  'http': 'xxx.proxy.address.xxx:8080',
  'https': 'xxx.proxy.address.xxx:8080',
}
headers2 = {
    "X-Access-Token": "9b6ff625-cf28",
    "X-Service-Code": "000003-00001",
}
payload2 = {
    'locale': 'ja_JP',
}
files = {
    'file': ('test.mp3', open('test.mp3', 'rb'), 'audio/mp3'),
}
q = requests.post('https://address.to.post.com/upload', proxies=proxies, headers=headers2, params=payload2, files=files)
print(q.json())

requestsの方が美しいよね。