Python请求:一部分为json的多部分

2024-06-16 05:10:52 发布

您现在位置:Python中文网/ 问答频道 /正文

Netflix的Genie API要么采用JSON,要么采用multipart,在application/json中有一部分request,在application/octet-stream中有任意数量的attachment部分。你知道吗

请求使得简单的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移到filesdict中,但它似乎没有作为JSON处理,现在我需要使用包来编码它?你知道吗

我这样问是因为requests在参数和响应对象中处理json时,我怀疑它也会在某个地方处理多部分形式的json,否则我只会为json.dumps(...)引入json

另外:

  1. 似乎没有一种方法可以发送多个名为attachment的部分,如果您需要多个附加文件,api将允许/期望这些部分。[在我的评论中,这可以通过将files更改为列表名到文件对的列表来完成]。你知道吗
  2. 示例请求显示部分头的名称没有引号,例如Content-Disposition: form-data; name=requestContent-Disposition: form-data; name=attachment,而请求包似乎生成了Content-Disposition: form-data; name="attachment"。你知道吗

Tags: testbuildcomtraviswebjsonhomeattachment
1条回答
网友
1楼 · 发布于 2024-06-16 05:10:52

“我可以将JSON dict移到文件dict中,但它似乎不能作为JSON处理”

  1. You can dump the dict to JSON files on disk.

tempfile.TemporaryFile can of use. Dump, request, clean and repeat

“否则我带来的json只是为了json.dumps文件(…)”

  1. It is okay to do this if you need to keep the dict around and the request built during run (ignore 1 for this use-case). However, remember to convert the dumps to io.BytesIO objects so that requests can compute the content-length header.

Also, remember to pass the content type for the files as "application/octet-stream" and not "plain/text"

“示例请求显示部件头的名称没有引号”

I don't think that it should matter. RFC 2183 documents that parameter values of length < 78 but containing tspecials should be represented as quoted-string.

While the value for the name parameter doesn't include tspecials, this is more robust handling for short values IMO.

相关问题 更多 >