保存来自 POST 请求的字典列表的值

Save values from POST request of a list of dicts

我试图公开一个 API(如果这是正确的说法)。我正在使用 Quart,一个由 Flask 制作的 python 库,我的代码如下所示:

async def capture_post_request(request_json):
    for item in request_json:
        callbackidd = item['callbackid']
        print(callbackidd)

@app.route('/start_work/', methods=['POST'])
async def start_work():
    content_type = request.headers.get('content-type')
    if (content_type == 'application/json'):
        request_json = await request.get_json()
        loop = asyncio.get_event_loop()
        loop.create_task(capture_post_request(request_json)) 
        body = "Async Job Started"
        return body
    else:
        return 'Content-Type not supported!'

我的架构如下所示:

[
    {
        "callbackid": "dd",
        "itemid": "234r",
        "input": [
            {
                "type": "thistype",
                "uri": "www.uri.com"
            }
        ],
        "destination": {
            "type": "thattype",
            "uri": "www.urino2.com"
        }
    },
    {
        "statusCode": "202"
    }
]

到目前为止我得到的是这个错误:

line 11, in capture_post_request
    callbackidd = item['callbackid']
KeyError: 'callbackid'

我已经尝试了很多 Whosebug 帖子来了解如何遍历我的字典列表,但没有任何效果。在我的 start_work 函数中的某个时刻,我使用了 get_data(as_text=True) 方法但仍然没有结果。事实上,使用最后一种方法(或 attr)我得到了:

TypeError: string indices must be integers

非常感谢任何有关如何访问这些值的帮助。干杯。

您的架构表明 两个 项在 request_json 中。第一个确实有callbackid,第二个只有statusCode.

调试应该很容易:

async def capture_post_request(request_json):
    for item in request_json:
        print(item)
        callbackidd = item.get('callbackid')
        print(callbackidd) # will be None in case of the 2nd 'item'

这将打印两个命令:

{
    "callbackid": "dd",
    "itemid": "234r",
    "input": [
        {
            "type": "thistype",
            "uri": "www.uri.com"
        }
    ],
    "destination": {
        "type": "thattype",
        "uri": "www.urino2.com"
    }
}

第二个,你的KeyError的原因:

{
    "statusCode": "202"
}

我已经包含了各种 'fix':

callbackidd = item.get('callbackid')

如果键不在字典中,这将默认为 None

希望这能让你更进一步!

编辑

如何只使用包含您的密钥的字典?有两种选择。

首先,使用filter。像这样:

def has_callbackid(dict_to_test):
    return 'callbackid' in dict_to_test

list_with_only_list_callbackid_items = list(filter(has_callbackid, request_json))
# Still a list at this point! With dicts which have the `callbackid` key

过滤器接受一些参数:

  1. 调用以确定是否应过滤掉正在测试的值的函数。
  2. 您要过滤的可迭代对象

也可以用'lambda function',不过有点邪恶。但同样有用:

list_with_only_list_callbackid_items = list(filter(lambda x: 'callbackid' in x, request_json))
# Still a list at this point! With dict(s) which have the `callbackid` key

选项 2,简单地循环结果,只抓取你想要使用的那个。

found_item = None # default
for item in request_json:
    if 'callbackid' in item:
        found_item = item
        break # found what we're looking for, stop now
# Do stuff with the found_item from this point.