Анализ ответа лямбда-Python-функции AWS от клиента обозревателя стоимости Boto3 - PullRequest
0 голосов
/ 08 июля 2019

Я пишу лямбда-функцию в Python 3.6 для запроса конкретных условий из API проводника затрат, в конечном итоге она будет вызываться API-шлюзом, поэтому я хочу иметь возможность отправить обратно урезанный ответ, а также принять его тот же ответ и сохранить его в 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
            }

Я пытаюсь проанализировать только информацию, которую я получаю от групп, как в виде распечатанного ответа, когда я возвращаю его обратно в 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 голосов
/ 08 июля 2019

Первая запись в ResultsByTime содержит пустой Group.Следовательно, невозможно получить Keys из него.

Вместо этого используйте:

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

Это вернет пустую строку, если Keys не существует.

...