繁体   English   中英

AWS Lambda 函数在 python 中误解了事件字典?

[英]AWS Lambda Function is misinterpreting event dictionary in python?

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

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": "create", "event_identifier": "pvno ", "summary": "Company", "booking-email": "abc@example.com" }

回应:

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

当我从邮递员(二进制或正文 POST)(或在 API 网关控制台上测试)发送相同的有效负载时,当我从 event.get("type") 返回值时,我得到“无”。

为了进一步解释,如果我尝试获取 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"
}

我的问题:

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

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

当您通过 API Gateway 调用它时,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()解析该string

  • 请求被完全打包并作为event字典的'body'键中的单个字符串发送。
  • 此行为不同于测试控制台或从 CLI 调用,后者在event字典中只有有效负载,这意味着event.get('type')直接工作。

显示如何访问有效负载中"type"键值的示例代码:

import json

def lambda_handler(event, context):
    body_str = event.get("body", "{}")
    body_str = body_str if body_str else "{}"
    body_obj = json.loads(body_str)
    a = body_obj.get("type", "")

我有一个更好的建议来测试。
只是返回您在lambda_handler接收事件

如前所述,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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM