使用API​​网关尝试AWS Python Lambda函数中的访问参数时出错,

时间:2019-03-25 21:00:36

标签: python python-3.x aws-lambda

我有这个python lambda函数

import json

def lambda_handler(event, context):

    post_user = ""
    post_user = event["user"]
    print(post_user)        

    return {
        "statusCode": 200,
        "headers": {"Content-Type": "application/json"},
        "body": True
        }

当我在lambda IDE中运行测试时,这可以按预期工作。测试配置为通过:

  

{“ user”:“ JOHN”,“ pwd”:“ pwd1”}

但是当我使用API​​网关运行测试时,出现此错误:

  

2019年3月25日星期一20:47:29 UTC:端点响应正文   转换:{“ errorMessage”:“'用户'”,“ errorType”:“ KeyError”,   “ stackTrace”:[“文件\” / var / task / lambda_function.py \“,第6行,在   lambda_handler \ n post_user = event [\“ user \”] \ n“]}星期一3月25   20:47:29 UTC 2019:由于以下原因,Lambda执行失败,状态为200   客户功能错误:“用户”。 Lambda请求ID:   f7955f74-e608-4b10-b216-4e4acf682307 Mon Mar 25 20:47:29 UTC 2019:   方法完成,状态:502

我已经定义了API网关测试,如下所示: enter image description here

3 个答案:

答案 0 :(得分:1)

这是因为当event对象来自API Gateway时,它具有一些额外的信息。它不像您用来从控制台进行测试的JSON一样简单。

您需要先访问body对象,然后再访问JSON对象。

这是来自API网关的事件的样子:

{
    "path": "/test/hello",
    "headers": {
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
      "Accept-Encoding": "gzip, deflate, lzma, sdch, br",
      "Accept-Language": "en-US,en;q=0.8",
      "CloudFront-Forwarded-Proto": "https",
      "CloudFront-Is-Desktop-Viewer": "true",
      "CloudFront-Is-Mobile-Viewer": "false",
      "CloudFront-Is-SmartTV-Viewer": "false",
      "CloudFront-Is-Tablet-Viewer": "false",
      "CloudFront-Viewer-Country": "US",
      "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
      "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
      "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
      "X-Forwarded-For": "192.168.100.1, 192.168.1.1",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https"
    },
    "pathParameters": {
      "proxy": "hello"
    },
    "requestContext": {
      "accountId": "123456789012",
      "resourceId": "us4z18",
      "stage": "test",
      "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
      "identity": {
        "cognitoIdentityPoolId": "",
        "accountId": "",
        "cognitoIdentityId": "",
        "caller": "",
        "apiKey": "",
        "sourceIp": "192.168.100.1",
        "cognitoAuthenticationType": "",
        "cognitoAuthenticationProvider": "",
        "userArn": "",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
        "user": ""
      },
      "resourcePath": "/{proxy+}",
      "httpMethod": "GET",
      "apiId": "wt6mne2s9k"
    },
    "resource": "/{proxy+}",
    "httpMethod": "GET",
    "queryStringParameters": {
      "name": "me"
    },
    "stageVariables": {
      "stageVarName": "stageVarValue"
    },
    "body": "'{\"user\":\"john\",\"pwd\":\"pwd1\"}'"
  }

请记住,API网关中的body总是字符串化的,因此,如果要访问它,首先需要使用json.loads(event["body"])解析此JSON字符串。

请记住,如我们在this answer上所讨论的那样,当返回API网关时,必须对响应的主体进行字符串化处理。

您可以在docs

中查看从API网关发送的事件

答案 1 :(得分:1)

@Thales Minussi使我得到了这个答案,但是我从回答中得到的关键与他的建议不同,但是他的建议对我有所帮助,所以我接受它作为答案

我得到了这个回应。 body键以null的形式出现。但是有queryStringParameters

{
  "resource": "/match_creds",
  "path": "/match_creds",
  "httpMethod": "GET",
  "headers": null,
  "multiValueHeaders": null,
  "queryStringParameters": {
    "pwd": "pwd1",
    "user": "JOHN"
  },
  "multiValueQueryStringParameters": {
    "pwd": [
      "pwd1"
    ],
    "user": [
      "JOHN"
    ]
  },
  "pathParameters": null,
  "stageVariables": null,
  "requestContext": {
    "path": "/match_creds",
    "accountId": "",
    "resourceId": "",
    "stage": "test-invoke-stage",
    "domainPrefix": "testPrefix",
    "requestId": "",
    "identity": {
      "cognitoIdentityPoolId": null,
      "cognitoIdentityId": null,
      "apiKey": "test-invoke-api-key",
      "cognitoAuthenticationType": null,
      "userArn": "",
      "apiKeyId": "test-invoke-api-key-id",
      "userAgent": "",
      "accountId": "",
      "caller": "",
      "sourceIp": "test-invoke-source-ip",
      "accessKey": "",
      "cognitoAuthenticationProvider": null,
      "user": ""
    },
    "domainName": "testPrefix.testDomainName",
    "resourcePath": "/match_creds",
    "httpMethod": "GET",
    "extendedRequestId": "",
    "apiId": ""
  },
  "body": null,
  "isBase64Encoded": false
}

我将功能更改为

import json

    def lambda_handler(event, context):

        json_data = event["queryStringParameters"] 
        user = json_data["user"]

        return {
            "statusCode": 200,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps(user)
            }

答案 2 :(得分:0)

您需要激活“集成请求”下的“使用Lambda代理集成”设置。