http - python 在 Content-Disposition 中请求 POST Multipart/form-data 和附加参数

标签 http curl post python-requests

任务是向某个 TTS(文本到语音)端点发送请求,并从响应中获取音频。 端点位于专用网络中,因此我无法与您分享以直接进行测试,但我的问题不是特定于域的,我认为这是一个一般 http 问题

现有的工作curl和python2脚本,如下:

curl -v  -H  "Content-Type:multipart/form-data;boundary=message_boundary_0001" -H "Accept:audio/ogg;codecs=opus;" --data-binary @request.txt ip:port/someother/ -m 10 -o response.txt

请求.txt:

    --message_boundary_0001--
Content-Disposition: form-data; name="RequestData"
Content-Type: application/json; charset=utf-8

{
    jsondata1
}
--message_boundary_0001--
Content-Disposition: form-data; name="TtsParameter"; paramName="TEXT_TO_READ"
Content-Type: application/json; charset=utf-8

{
   jsondata2
}
--message_boundary_0001--

python2脚本主要构造请求内容,然后调用httplib.HTTPConnection..request('POST', uri, some BytesIO(), headers)。如果需要,我可以在此处粘贴代码。

现在我想使用 python 3 请求库重写

我搜索了请求 doc , 和一个现有的 SO question , 并编写了以下代码,但出现 400 错误:

import requests
from requests_toolbelt import MultipartEncoder

headers = {'Accept': 'audio/ogg;codecs=opus;',
           'Connection': 'keep-alive',
           'Content-Type': 'multipart/form-data;boundary=message_boundary_0001',
           }

RequestData = '''{
    jsondata1
}'''

TtsParameter_TEXT_TO_READ = '''{
   jsondata2
}'''

# url_origin = 'https://httpbin.org/post' # for debugging
url = 'http://ip:port/someother/'
resp = requests.post(url, headers=headers,
                     files={'RequestData': (None, RequestData), 'TtsParameter': (None, TtsParameter_TEXT_TO_READ)},
                     timeout=10)
print(resp.status_code)
print(resp.content.decode('utf-8'))

这并不奇怪,因为在我的 curl request.txt 中有一个特殊的 Content-Disposition: Content-Disposition: form-data; name="TtsParameter"; paramName="TEXT_TO_READ",在任何教程中都很少见到。

所以我的问题是如何将 paramName="TEXT_TO_READ"传递给请求?

更新

最新的python代码已经推送到github了。 https://github.com/LeiYangGH/py3requeststts

最佳答案

普通请求无法做到这一点。

使用工具带思想有一种不太理想的方法。

from requests_toolbelt.multipart import encoder


mpe = encoder.MultipartEncoder(fields={'RequestData': (None, RequestData), 'TtsParameter': (None, TtsParameter_TEXT_TO_READ)})
for part in mpe.parts:
   if 'name="TtsParameter"' in part.headers:
       part.headers = part.headers.replace('name="TtsParameter"',
                                           'name="TtsParameter"; paramName="TEXT_TO_READ"')

headers.update({'Content-Type': mpe.content_type})
requests.post(url, headers=headers, data=mpe)

关于http - python 在 Content-Disposition 中请求 POST Multipart/form-data 和附加参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54209711/

相关文章:

android - 在特定时间点在gradle中运行curl命令

ruby-on-rails - 使用 token 对 API 进行身份验证

html - 发出相关请求时从哪里获取 HOST header ?

php - file_get_contents 发出警告

php - 向 php $_POST 发送 cURL 终端命令返回 null

php - 与 openCPU 交互

javascript - windows.location.href 更改导致 POST,期望 GET

http - Meteor HTTP POST 中的新行

ios - Post 方法不在 api 调用中发送我的数据

html - 从网络文件共享提供文件时的浏览器缓存