我正在用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
有什么明显的地方我做错了吗?我是否只能解析体内的特定数组?感谢您的提前帮助!
答案 0 :(得分:0)
ResultsByTime
中的第一项有一个空白的Group
。因此,不可能从中获得Keys
。
相反,使用:
response['ResultsByTime'][0]['Groups'].get('Keys', '')
如果Keys
不存在,它将返回一个空字符串。