首页 > 解决方案 > 解析来自 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

有什么明显的我做错了吗?我是否不允许仅解析正文中的特定数组?提前感谢您的帮助!

标签: pythonjsonamazon-web-servicesaws-lambdaserverless-framework

解决方案


中的第一个条目ResultsByTime是空的Group。因此,不可能从中得到Keys

相反,使用:

response['ResultsByTime'][0]['Groups'].get('Keys', '')

Keys如果不存在,这将返回一个空字符串。


推荐阅读