AWS Lambda函数是否在python中错误解释事件字典?

时间:2018-01-22 16:09:24

标签: python json amazon-web-services aws-lambda aws-api-gateway

我正在尝试将Google日历api部署到AWS Lambda。由于我在从事件字典中提取值时遇到问题(由POST请求的JSON有效负载中的lambda创建),我创建了一个玩具函数来测试

def handler(event,context):
    a=event.get("type")

    if a=='create':
        return {
                "statusCode": 200,
                "headers": { "Content-Type": "text/plain"},
                #"body": "Event_id"+ str(event_identifier) + " Event Link: " +str(links)
                "body" : str(a)
            }
    else:
        return {
                "statusCode": 200,
                "headers": { "Content-Type": "text/plain"},
                #"body": "Event_id"+ str(event_identifier) + " Event Link: " +str(links)
                "body" : "nope"
            }

使用以下JSON在Lambda控制台上进行测试时,我得到了正确的响应。

测试有效负载:     {       “start_time”:“2018-01-24T09:00:00”,       “end_time”:“2018-01-24T13:00:00”,       “type”:“创造”,       “event_identifier”:“pvno”,       “摘要”:“公司”,       “booking-email”:“abc@example.com”     }

响应:

{
  "body": "create",
  "headers": {
    "Content-Type": "text/plain"
  },
  "statusCode": 200
}

当我从postman(二进制或主体POST)发送相同的有效负载(或在API网关控制台上测试)时,当我从event.get(“type”)返回值时,我得到“None”。

进一步解释,如果我尝试获取event.get('body')并将其全部作为字符串返回,我得到以下内容,根据lambda事件应该如何工作,这是不正确的:

{
  "start_time" : "2018-01-24T09:00:00",
  "end_time" : "2018-01-24T13:00:00",
  "type": "create",
  "event_identifier": "pvnoc",
  "summary": "Company",
  "booking-email": "abc@example.com"
}

我的问题:

  • 我做错了什么?
  • 如何从事件字典中获取正确的值?

4 个答案:

答案 0 :(得分:8)

当您在本地或通过Lambda控制台调用lambda时,您直接调用该lambda,因此您的lambda将完全接收您正在发送的内容。

当您通过API网关调用它时,API Gateway会根据您的HTTP请求为您创建event对象。它添加了HTTP标头,路径,查询字符串,有效负载等。

以下是您从API网关调用中获得event的内容摘要:

{
    "resource": "Resource path",
    "path": "Path parameter",
    "httpMethod": "Incoming request's method name"
    "headers": {Incoming request headers}
    "queryStringParameters": {query string parameters }
    "pathParameters":  {path parameters}
    "stageVariables": {Applicable stage variables}
    "requestContext": {Request context, including authorizer-returned key-value pairs}
    "body": "A JSON string of the request payload."
    "isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encode"
}

参考:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-simple-proxy-for-lambda-input-format

如您所见,body将作为string发送给您,您可以使用json.loads()进行解析。

答案 1 :(得分:1)

经过一整天的努力来解决这个问题后,意识到以下几点:

  • 该请求实际上是完全打包的,并在'正文中作为单个字符串发送。事件的关键词。
  • 此行为与测试控制台或从CLI调用只有事件dict中的有效负载意味着event.get(' type')直接工作。

我找到的解决方案如下(假设您要访问&#34的值;键入"有效负载中的键),但希望找到更清晰的解决方案:

import json
def lambda_handler(event, context):    
    a=(json.loads(event['body'])).get('type')

希望这有助于某人!

答案 2 :(得分:0)

我有一个更好的测试建议。
 只需返回您在 lambda_handler 中收到的事件

答案 3 :(得分:0)

AWS在内部测试Lamda,这导致了一个解决方案:您需要在AWS收到它时使用整个帖子,您不能像curl一样发送一些数据json。

因此,如果有疑问,您可以在Lambda收到事件时使用来获取事件

import json

def lambda_handler(event, context):

    return { "statusCode": 200, "body": json.dumps(event, indent=2) }

保存后,此lambda将返回您需要粘贴到AWS Lmbda页面上的测试事件中的json。