从Boto3 Cost Explorer客户端解析AWS Lambda Python函数响应

时间:2019-07-07 23:08:15

标签: python json amazon-web-services aws-lambda serverless-framework

我正在用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)

它根据the docs

给出这样的响应
{
    '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
            }

我试图仅解析从网上论坛中获得的信息,既作为打印后的响应,当我将其代理回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

有什么明显的地方我做错了吗?我是否只能解析体内的特定数组?感谢您的提前帮助!

1 个答案:

答案 0 :(得分:0)

ResultsByTime中的第一项有一个空白的Group。因此,不可能从中获得Keys

相反,使用:

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

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