API呼び出しを行って、ファイルの詳細を含むJSON文字列とともにファイルをアップロードする必要があります。
python要求libを使用してこれを実行しようとしています:
import requests
info = {
'var1' : 'this',
'var2' : 'that',
}
data = json.dumps({
'token' : auth_token,
'info' : info,
})
headers = {'Content-type': 'multipart/form-data'}
files = {'document': open('file_name.pdf', 'rb')}
r = requests.post(url, files=files, data=data, headers=headers)
これにより、次のエラーがスローされます。
raise ValueError("Data must not be a string.")
ValueError: Data must not be a string
リクエストから「ファイル」を削除すると、機能します。
リクエストから「データ」を削除すると、機能します。
JSONとしてデータをエンコードしない場合、動作します。
このため、エラーはJSONデータとファイルを同じリクエストで送信することに関係していると思います。
これを機能させる方法についてのアイデアはありますか?
Jsonを使用してエンコードしないでください。
import requests
info = {
'var1' : 'this',
'var2' : 'that',
}
data = {
'token' : auth_token,
'info' : info,
}
headers = {'Content-type': 'multipart/form-data'}
files = {'document': open('file_name.pdf', 'rb')}
r = requests.post(url, files=files, data=data, headers=headers)
これは別のフォームデータセクションになるため、必ずしも必要なものではないことに注意してください。
このスレッドを参照してください マルチパートPOSTリクエストの一部としてJSONを送信する方法
自分でContent-typeヘッダーを設定しないで、生成するpyrequestsにそのままにしてください
def send_request():
payload = {"param_1": "value_1", "param_2": "value_2"}
files = {
'json': (None, json.dumps(payload), 'application/json'),
'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
}
r = requests.post(url, files=files)
print(r.content)
マルチパートでエンコードされたファイルでデータとファイルの両方を送信できるとは思わないので、データも「ファイル」にする必要があります。
files = {
'data' : data,
'document': open('file_name.pdf', 'rb')
}
r = requests.post(url, files=files, headers=headers)
Facebook Messenger APIを送信するために、すべてのペイロードディクショナリ値を文字列に変更しました。その後、ペイロードをdata
パラメーターとして渡すことができます。
import requests
ACCESS_TOKEN = ''
url = 'https://graph.facebook.com/v2.6/me/messages'
payload = {
'access_token' : ACCESS_TOKEN,
'messaging_type' : "UPDATE",
'recipient' : '{"id":"1111111111111"}',
'message' : '{"attachment":{"type":"image", "payload":{"is_reusable":true}}}',
}
files = {'filedata': (file, open(file, 'rb'), 'image/png')}
r = requests.post(url, files=files, data=payload)
さらに何ですか:
files = {
'document': open('file_name.pdf', 'rb')
}
ファイルがスクリプトと同じディレクトリにある場合にのみ機能します。
別のディレクトリからファイルを追加する場合は、次を実行する必要があります。
files = {
'document': open(os.path.join(dir_path, 'file_name.pdf'), 'rb')
}
dir_pathは'file_name.pdf'ファイルがあるディレクトリです。
しかし、複数のPDFを送信したい場合はどうでしょうか?
必要なファイルのリストを返すためのカスタム関数を作成するだけです(この場合、拡張子は。pdfのファイルのみです)。これには、サブディレクトリ内のファイルも含まれます(ファイルを再帰的に検索します)。
def prepare_pdfs():
return sorted([os.path.join(root, filename) for root, dirnames, filenames in os.walk(dir_path) for filename in filenames if filename.endswith('.pdf')])
それからあなたはそれを呼び出すことができます:
my_data = prepare_pdfs()
そして、単純なループで:
for file in my_data:
pdf = open(file, 'rb')
files = {
'document': pdf
}
r = requests.post(url, files=files, ...)