python - Python 请求:多部分,其中一部分为 json
问题描述
Netflix 的 Genie API 采用JSON或multipart,其中一个部分request
在.application/json
attachment
application/octet-stream
Requests 让一个普通的 JSON POST 变得非常简单:
requests.post(
url=self.host + self.endpoint,
json={
"version" : "1.0",
"user" : "genie",
"name" : "List * ... Directories bash job",
"description" : "Genie 3 Test Job",
"configs" : [ "/home/travis/build/Netflix/genie/genie-web/build/resources/test/com/netflix/genie/web/controllers/JobRestControllerIntegrationTests/job/config1" ],
"dependencies" : [ "/home/travis/build/Netflix/genie/genie-web/build/resources/test/com/netflix/genie/web/controllers/JobRestControllerIntegrationTests/job/dep1" ],
"setupFile" : "/home/travis/build/Netflix/genie/genie-web/build/resources/test/com/netflix/genie/web/controllers/JobRestControllerIntegrationTests/job/jobsetupfile",
"commandArgs" : "-c 'echo hello world'",
"clusterCriterias" : [ {
"tags" : [ "localhost" ]
} ],
"commandCriteria" : [ "bash" ],
},
)
命令是有限的,所以如果你有一个大的命令(查询)要发送,你最好使用附件。
对于请求,请求多部分也不难:
requests.post(
url=self.host + self.endpoint,
json={
"version" : "1.0",
"user" : "genie",
"name" : "List * ... Directories bash job",
"description" : "Genie 3 Test Job",
"configs" : [ "/home/travis/build/Netflix/genie/genie-web/build/resources/test/com/netflix/genie/web/controllers/JobRestControllerIntegrationTests/job/config1" ],
"dependencies" : [ "/home/travis/build/Netflix/genie/genie-web/build/resources/test/com/netflix/genie/web/controllers/JobRestControllerIntegrationTests/job/dep1" ],
"setupFile" : "/home/travis/build/Netflix/genie/genie-web/build/resources/test/com/netflix/genie/web/controllers/JobRestControllerIntegrationTests/job/jobsetupfile",
"commandArgs" : "-c 'cat query.sql'",
"clusterCriterias" : [ {
"tags" : [ "localhost" ]
} ],
"commandCriteria" : [ "bash" ],
},
files={
"attachment": (
'query.sql',
'select count(1) from small_table;',
'application/octet-stream'
),
},
)
除非,如果files
存在,它将忽略json
如果我更改json
为data
它将是一种形式。我可以将 JSON dict 移动到files
dict 中,但它似乎没有作为 JSON 处理,现在我需要使用包对其进行编码吗?
我问是因为requests
在参数和响应对象中处理 json 我怀疑它也会在多部分表单的某个地方处理它,否则我json
只是为了json.dumps(...)
此外:
attachment
如果您需要多个附件,似乎没有一种方法可以发送多个名为 API 允许/期望的部分。[正如我的评论,这可以通过更改files
为列表名称到文件对的列表来完成]。- 示例请求显示部分标头具有未引用的名称,
Content-Disposition: form-data; name=request
而Content-Disposition: form-data; name=attachment
请求包似乎是生成的Content-Disposition: form-data; name="attachment"
。
解决方案
“我可以将 JSON 字典移动到文件字典中,但它似乎没有作为 JSON 处理”
- 您可以将 dict 转储到磁盘上的 JSON 文件。
tempfile.TemporaryFile
可以使用。转储、请求、清理和重复
“否则我只为 json.dumps(...) 引入 json”
- 如果您需要保留 dict 并在运行期间构建请求(此用例忽略 1),则可以这样做。但是,请记住将转储转换为 io.BytesIO 对象,以便请求可以计算内容长度标头。
另外,请记住将文件的内容类型传递为“application/octet-stream”而不是“plain/text”
“示例请求显示部分标题的名称未加引号”
我不认为这应该重要。RFC 2183记录了长度 < 78 但包含 tspecials 的参数值应表示为带引号的字符串。
虽然 name 参数的值不包括 tspecials,但对于短值 IMO,这是更可靠的处理。
推荐阅读
- r - 当未绘制二次项中的变量时,如何将 lm() 与 poly() 和 ggeffect() 一起使用来绘制模型效果
- javascript - 如何将东西存储在异步存储中?
- c - Cython 中的方法如何在 C 中实现?
- docker - Docker Desktop 无法切换到 Windows 容器
- java - 带有自定义 HTTP 错误响应的自定义 ConstraintValidator 消息
- javascript - 如何使用 Node.js 随机化 JavaScript 对象中的单个值
- javascript - 如何在 DataTable().row.add() 之后继续自定义 dataTable?
- python - 在字典中自动增加相同的值
- flutter - Flutter中的组件卸载(相当于React componentWillUnmount) - Flutter web
- c++ - 在访问私有元素时重载 << 运算符(朋友)