问题描述
我刚刚了解了由队列存储事件处理程序触发的 Azure 函数。在这种情况下,队列存储正在处理事件网格消息。
问题:如何使用 Python 访问嵌套在下面 "body"
中的各种值?
- 比如
body/data/blobUrl
的值
队列存储消息如下所示(缩进以便于阅读):
-
"body"
是嵌套的 EventGrid 消息
{
"id": "<big-long-guid>","body": "{
\"topic\":\"/subscriptions/<big-long-guid>/resourceGroups/azureStorage/providers/Microsoft.Storage/storageAccounts/stgcool\",\"subject\":\"/blobServices/default/containers/cont-pics/blobs/profile_pic.jpg\",\"eventType\":\"Microsoft.Storage.BlobCreated\",\"id\":\"<big-long-guid>\",\"data\":{
\"api\":\"PutBlob\",\"clientRequestId\":\"<big-long-guid>\",\"requestId\":\"<big-long-guid>\",\"eTag\":\"0x8D94CE0B2F5CD71\",\"contentType\":\"image/jpeg\",\"contentLength\":35799,\"blobType\":\"BlockBlob\",\"blobUrl\":\"https://stgcool.blob.core.windows.net/cont-pics/profile_pic.jpg\",\"url\":\"https://stgcool.blob.core.windows.net/cont-pics/profile_pic.jpg\",\"sequencer\":\"00000000000000000000000000003730000000000000312a\",\"storageDiagnostics\":{
\"batchId\":\"<big-long-guid>\"
}
},\"dataVersion\":\"\",\"MetadataVersion\":\"1\",\"eventTime\":\"2021-07-22T07:17:00.8479184Z\"
}","expiration_time": "2021-07-30T05:10:37+00:00","insertion_time": "2021-07-23T05:10:37+00:00","time_next_visible": "2021-07-23T05:20:37+00:00","pop_receipt": "cOQ8m5lN2QgBAAAA","dequeue_count": 1
}
import logging
import json
import azure.functions as func
def main(msg: func.QueueMessage):
logging.info('Python queue trigger function processed a queue item.')
result = json.dumps({
'id': msg.id,'body': msg.get_body().decode('utf-8'),'expiration_time': (msg.expiration_time.isoformat()
if msg.expiration_time else None),'insertion_time': (msg.insertion_time.isoformat()
if msg.insertion_time else None),'time_next_visible': (msg.time_next_visible.isoformat()
if msg.time_next_visible else None),'pop_receipt': msg.pop_receipt,'dequeue_count': msg.dequeue_count
})
logging.info(result)
尝试过:
- 在
msg.get_body()
和get_json()
的不同迭代中包装json.dumps()
,但收到错误。
编辑 1:
-
将
'body': msg.get_body().decode('utf-8'),
更改为'body': json.loads(msg.get_body().decode('utf-8')),
会将正文转换为实际的 JSON,这很好。 -
但是我如何访问
['body']['data']['blobUrl'] in
result`? -
type(result)
是str
解决方法
我写这篇文章的目的是理解您正在尝试更新您为 result
提供 logging
的方式。如果您真正想做的是从构造不佳的 Queue Storage
消息中解析它,请告诉我。
以你给出的字典为例:
d = {
"id": "<big-long-guid>","body": "{
\"topic\":\"/subscriptions/<big-long-guid>/resourceGroups/azureStorage/providers/Microsoft.Storage/storageAccounts/stgcool\",\"subject\":\"/blobServices/default/containers/cont-pics/blobs/profile_pic.jpg\",\"eventType\":\"Microsoft.Storage.BlobCreated\",\"id\":\"<big-long-guid>\",\"data\":{
\"api\":\"PutBlob\",\"clientRequestId\":\"<big-long-guid>\",\"requestId\":\"<big-long-guid>\",\"eTag\":\"0x8D94CE0B2F5CD71\",\"contentType\":\"image/jpeg\",\"contentLength\":35799,\"blobType\":\"BlockBlob\",\"blobUrl\":\"https://stgcool.blob.core.windows.net/cont-pics/profile_pic.jpg\",\"url\":\"https://stgcool.blob.core.windows.net/cont-pics/profile_pic.jpg\",\"sequencer\":\"00000000000000000000000000003730000000000000312a\",\"storageDiagnostics\":{
\"batchId\":\"<big-long-guid>\"
}
}",\"dataVersion\":\"\",\"metadataVersion\":\"1\",\"eventTime\":\"2021-07-22T07:17:00.8479184Z\"
}","expiration_time": "2021-07-30T05:10:37+00:00","insertion_time": "2021-07-23T05:10:37+00:00","time_next_visible": "2021-07-23T05:20:37+00:00","pop_receipt": "cOQ8m5lN2QgBAAAA","dequeue_count": 1
}
我们可以这样查看 "body"
中的值:
d['body']['data']['api']
PutBlob
不幸的是,如果您尝试这样做,您会因为尝试使用 TypeError
尝试访问另一个 string
中的索引而向您抛出 string
。我们使用 string
对象作为 dict
的键,而不是 string
的索引。您被抛出此类错误的原因是 "body"
"dict
" 实际上是 str
,而不是 dict
(注意 "
花括号的两边)。
通过更新 json.dumps
的 'body'
来解决此问题:
result = json.dumps({
'id': msg.id,'body': json.loads(msg.get_body().decode('utf-8')),...
编辑:
重新阅读您的问题,似乎我在您的示例中称为 dict
的内容在您得到它时可能仍然是一个字符串。在这种情况下,您可能会因为 "body"
的格式不正确而遇到更多问题。
如果是这种情况,您可以通过运行以下命令清除 "
值周围那些讨厌的 "body"
标记:
message = message.replace('"{','{').replace('}"','}')
在阅读之前:
d = json.loads(message)