请求返回400,有效负载中包含JSON,有效负载中的字符串返回200

时间:2020-08-17 20:10:07

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

使用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)

但是对于错误的请求,它会返回<400>,而我的有效负载如下:

{"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)

我收到一个<200>的有效载荷,如下所示:

{"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喷出为单引号(')而不是双引号(“),但从我回忆起,请求模块收到了相同的有效载荷。

我觉得我缺少明显的愚蠢和明显的东西,但是我已经尝试了工具带中的所有技巧。

1 个答案:

答案 0 :(得分:1)

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

您可以使用counties来代替json.dumps(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)