【问题标题】:Requests returns 400 with JSON in payload, string in payload returns 200请求返回 400,负载中带有 JSON,负载中的字符串返回 200
【发布时间】:2020-08-17 20:10:07
【问题描述】:

使用在 POST 请求后返回嵌套 JSON 数据集的 API。 它期望有效载荷是:

payload = '{"metrics":[ {"name":"Jobs.2019"}, {"name", "Jobs.2018"], "constraints": ["dimensionName": "Area", "map": {"Adams, OH":["39001"],"Allen, OH":["39003"]} }, {"dimensionName": "Industry", "map": {"Crop Production":["111000"]} } ] }'

{"Adams, OH":["391001"]} 在 FIPS 代码 391001 上放置标签以供查找。 问题是俄亥俄州有 88 个县,而美国每个州的县都更多。

我想我可以将县放入为counties.json

{
   "Adams, OH":[
      "39001"
   ],
   "Allen, OH":[
      "39003"
   ]
}

并在我的脚本中设置变量

with open('data.json', 'r') as json_file:
    counties = json.load(json_file)

然后调用我的请求

metrics = '[{"name": "Jobs.2019" }, {"name": "Jobs.2018"}, {"name": "Jobs.2017"}, {"name": "Jobs.2016"}, {"name": "Jobs.2015"}, {"name": "Jobs.2020"}, {"name": "Estab.2019" }, {"name": "Estab.2018"}, {"name": "Estab.2017"}, {"name": "Estab.2016"}, {"name": "Estab.2015"}, {"name": "Estab.2014"}, {"name": "EPW.2019"}, {"name": "EPW.2018"}, {"name": "EPW.2017"}, {"name": "EPW.2016"}, {"name": "EPW.2015"}, {"name": "EPW.2014"}]'

payload = f'{{"metrics": {metrics},  "constraints": [{{"dimensionName": "Area", "map": {counties} }}, {{"dimensionName": "Industry", "map": {{"Crop Production":["111000"]}}  ]}}'

result = requests.request("POST", url, headers=headers, data=payload)

但是这会返回一个 错误请求,我的有效负载看起来像:

{"metrics": [{"name": "Jobs.2019" }, {"name": "Jobs.2018"}, {"name": "Jobs.2017"}, {"name": "Jobs.2016"}, {"name": "Jobs.2015"}, {"name": "Jobs.2020"}, {"name": "Estab.2019" }, {"name": "Estab.2018"}, {"name": "Estab.2017"}, {"name": "Estab.2016"}, {"name": "Estab.2015"}, {"name": "Estab.2014"}, {"name": "EPW.2019"}, {"name": "EPW.2018"}, {"name": "EPW.2017"}, {"name": "EPW.2016"}, {"name": "EPW.2015"}, {"name": "EPW.2014"}],  "constraints": [{"dimensionName": "Area", "map": {'Adams, OH': ['39001'], 'Allen, OH': ['39003']} }, {"dimensionName": "Industry", "map": {"Crop Production":["111000"]}  ]}

但是,当我这样称呼时:

metrics = '[{"name": "Jobs.2019" }, {"name": "Jobs.2018"}, {"name": "Jobs.2017"}, {"name": "Jobs.2016"}, {"name": "Jobs.2015"}, {"name": "Jobs.2020"}, {"name": "Estab.2019" }, {"name": "Estab.2018"}, {"name": "Estab.2017"}, {"name": "Estab.2016"}, {"name": "Estab.2015"}, {"name": "Estab.2014"}, {"name": "EPW.2019"}, {"name": "EPW.2018"}, {"name": "EPW.2017"}, {"name": "EPW.2016"}, {"name": "EPW.2015"}, {"name": "EPW.2014"}]'

payload = '{"metrics":' + metrics + ',"constraints": [{"dimensionName": "Area", "map": {"Adams, OH":["39001"],"Allen, OH":["39003"]} }, {"dimensionName": "Industry", "map": {"Crop Production":["111000"]} } ] }'

result = requests.request("POST", url, headers=headers, data=payload)

我收到一个 ,其有效负载如下所示:

{"metrics":[{"name": "Jobs.2019" }, {"name": "Jobs.2018"}, {"name": "Jobs.2017"}, {"name": "Jobs.2016"}, {"name": "Jobs.2015"}, {"name": "Jobs.2020"}, {"name": "Estab.2019" }, {"name": "Estab.2018"}, {"name": "Estab.2017"}, {"name": "Estab.2016"}, {"name": "Estab.2015"}, {"name": "Estab.2014"}, {"name": "EPW.2019"}, {"name": "EPW.2018"}, {"name": "EPW.2017"}, {"name": "EPW.2016"}, {"name": "EPW.2015"}, {"name": "EPW.2014"}],"constraints": [{"dimensionName": "Area", "map": {"Adams, OH":["39001"],"Allen, OH":["39003"]} }, {"dimensionName": "Industry", "map": {"Crop Production":["111000"]} } ] }

据我所见,一切都完全相同,解释器将 JSON 吐出为单引号 (') 而不是双引号 ("),但据我回忆,请求模块接收相同的有效负载。

我觉得我错过了一些明显的愚蠢和明显的东西,但我已经尝试了我工具带中的每一个技巧。

【问题讨论】:

    标签: python json python-3.x python-requests


    【解决方案1】:

    问题在于,当您读取 JSON 文件时,json.load 正在返回 Python dict。然后,当您将其用作f-string 的输入时,您只是获得了该dict 的Python 表示,而不是一个有效的JSON 对象——正如您所注意到的,它显示为单引号,而不是在 JSON 中有效 - JSON 对单引号和双引号很挑剔。

    您可以使用json.dumps(counties) 代替counties

    但是,我建议您做一些不同的事情。与其操作字符串来创建 JSON 对象,不如在 Python 中完成这项工作,然后根据需要转换为 JSON。这就是 json 库可以帮助您解决的问题!

    例如您可以执行以下操作,这比较简单:

    metrics = json.loads('[{"name": "Jobs.2019" }, {"name": "Jobs.2018"}, {"name": "Jobs.2017"}, {"name": "Jobs.2016"}, {"name": "Jobs.2015"}, {"name": "Jobs.2020"}, {"name": "Estab.2019" }, {"name": "Estab.2018"}, {"name": "Estab.2017"}, {"name": "Estab.2016"}, {"name": "Estab.2015"}, {"name": "Estab.2014"}, {"name": "EPW.2019"}, {"name": "EPW.2018"}, {"name": "EPW.2017"}, {"name": "EPW.2016"}, {"name": "EPW.2015"}, {"name": "EPW.2014"}]')
    
    payload = {"metrics": metrics,
               "constraints": [{"dimensionName": "Area",
                                "map": counties},
                               {"dimensionName": "Industry",
                                "map": {"Crop Production": ["111000"]}}]}
    
    result = requests.post(url, headers=headers, json=payload)
    

    【讨论】:

      猜你喜欢
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-19
      • 2018-12-15
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      相关资源
      最近更新 更多