python - 解析来自 Boto3 Cost Explorer 客户端的 AWS Lambda Python 函数响应
问题描述
我正在 Python 3.6 中编写一个 Lambda 函数来从 Cost Explorer API 中查询特定条件,它最终将由 API Gateway 调用,因此我希望能够发送回一个缩减的响应,以及获取相同的响应和将其保存到 S3 中。
我的整体功能正常工作,我希望能够快速解析并抓取响应,但这不适用于 Glue 和 Athena。基本功能代码如下:
import boto3
import json
def handler(event,context):
client = boto3.client('ce')
s3 = boto3.resource('s3')
object = s3.Object('s3-bucket', 'path/object.json')
response = client.get_cost_and_usage(
TimePeriod={
'Start': '2019-01-01',
'End': '2019-07-01'
},
Granularity='MONTHLY',
Metrics=[
'UnblendedCost',
],
GroupBy=[
{
'Type': 'DIMENSION',
'Key': 'SERVICE'
},
],
)
object.put(Body=json.dumps(response).encode())
return str (response)
{
'NextPageToken': 'string',
'GroupDefinitions': [
{
'Type': 'DIMENSION'|'TAG',
'Key': 'string'
},
],
'ResultsByTime': [
{
'TimePeriod': {
'Start': 'string',
'End': 'string'
},
'Total': {
'string': {
'Amount': 'string',
'Unit': 'string'
}
},
'Groups': [
{
'Keys': [
'string',
],
'Metrics': {
'string': {
'Amount': 'string',
'Unit': 'string'
}
}
},
],
'Estimated': True|False
},
]
}
当我运行我的函数时,它看起来像这样(VS Code 做了这个间距):
{
"GroupDefinitions": [
{
"Type": "DIMENSION",
"Key": "SERVICE"
}
],
"ResultsByTime": [
{
"TimePeriod": {
"Start": "2019-01-01",
"End": "2019-02-01"
},
"Total": {
"UnblendedCost": {
"Amount": "0",
"Unit": "USD"
}
},
"Groups": [],
"Estimated": true
},
{
"TimePeriod": {
"Start": "2019-02-01",
"End": "2019-03-01"
},
"Total": {
"UnblendedCost": {
"Amount": "0",
"Unit": "USD"
}
},
"Groups": [],
"Estimated": true
},
{
"TimePeriod": {
"Start": "2019-03-01",
"End": "2019-04-01"
},
"Total": {
"UnblendedCost": {
"Amount": "0",
"Unit": "USD"
}
},
"Groups": [],
"Estimated": false
},
{
"TimePeriod": {
"Start": "2019-04-01",
"End": "2019-05-01"
},
"Total": {},
"Groups": [
{
"Keys": [
"AWS CloudTrail"
],
"Metrics": {
"UnblendedCost": {
"Amount": "0.032953",
"Unit": "USD"
}
}
},
{
"Keys": [
"AWS CodeCommit"
],
"Metrics": {
"UnblendedCost": {
"Amount": "0",
"Unit": "USD"
}
}
},
{
"Keys": [
"AWS Config"
],
"Metrics": {
"UnblendedCost": {
"Amount": "10.148",
"Unit": "USD"
}
}
},
{
"Keys": [
"AWS Elemental MediaStore"
],
"Metrics": {
"UnblendedCost": {
"Amount": "0",
"Unit": "USD"
}
}
}
],
"ResponseMetadata": {
"RequestId": "1d149b43-3b7b-46cb-973a-6b0e9adfbe14",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "1d149b43-3b7b-46cb-973a-6b0e9adfbe14",
"content-type": "application/x-amz-json-1.1",
"content-length": "9310",
"date": "Sun, 07 Jul 2019 00:00:00 GMT"
},
"RetryAttempts": 0
}
我试图仅解析从 Groups 获得的信息,作为我将其代理回 API Gateway 时的打印响应以及当我将其持久保存到 S3(或 Dynamo)以保存报告并最终添加一些分析分层时. 我将函数代码的末尾修改为:
...Lambda Code...
object.put(Body=json.dumps(response['ResultsByTime'][0]['Groups']['Keys']).encode())
return str (response['ResultsByTime'][0]['Groups']['Keys'])
那不起作用,现在我在 CloudWatch Logs 中收到此错误
list indices must be integers or slices, not str: TypeError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 25, in handler
print(response['ResultsByTime'][0]['Groups']['Keys'])
TypeError: list indices must be integers or slices, not str
有什么明显的我做错了吗?我是否不允许仅解析正文中的特定数组?提前感谢您的帮助!
解决方案
中的第一个条目ResultsByTime
是空的Group
。因此,不可能从中得到Keys
。
相反,使用:
response['ResultsByTime'][0]['Groups'].get('Keys', '')
Keys
如果不存在,这将返回一个空字符串。
推荐阅读
- keras - 如何计算 Conv2D 和 Conv2DTranspose 的输出
- ios - 等价于 Flutter 中的 viewWillAppear()
- c - 在 C 函数中读取文件并将参数传递给结构数组
- azure-devops - 部署过程中何时使用 ARM 模板?
- node.js - Hyperledger Fabric 智能合约的函数类型
- python - 为什么从 C 和 Python 使用 OpenSSL API 时会得到不同的签名?
- reactjs - React - 如何在 React 应用程序中进行动态路由
- java - Java中使用原子变量的线程安全
- c# - 菜单项一直出现在左侧,而不是右侧。我怎样才能解决这个问题?
- python - 如何在另一个函数中使用一个函数并在 Python 中对其进行操作?