Python 使用代理集成通过API网关触发AWS Lambda

Python 使用代理集成通过API网关触发AWS Lambda,python,amazon-web-services,aws-lambda,aws-api-gateway,Python,Amazon Web Services,Aws Lambda,Aws Api Gateway,我刚刚开始学习AWS,并在AWS Lambda中制作了一个基本计算器,如下所示: import json def lambda_handler(event, context): op1 = event.get('op1',0) op2 = event.get('op2',0) operator = event.get('op', None) if op1 == 0 or op2 == 0 or operator == None: result = 'Please enter valid

我刚刚开始学习AWS,并在AWS Lambda中制作了一个基本计算器,如下所示:

import json

def lambda_handler(event, context):
op1 = event.get('op1',0)
op2 = event.get('op2',0)
operator = event.get('op', None)
if op1 == 0 or op2 == 0 or operator == None:
    result = 'Please enter valid input data'
    ret_code = 219
else:
    if operator in {'add', 'plus', '+'}:
        result = op1 + op2
        ret_code = 278
    elif operator in {'subtract', 'minus', '-'}:
        result = op1 - op2
        ret_code = 278
    elif operator in {'multiply', '*'}:
        result = op1 * op2
        ret_code = 278
    elif operator in {'divide', '/'}:
        result = op1 / op2
        ret_code = 278
    else:
        result = 'Please enter valid operator'
        ret_code = 219
return {
    'isBase64Encoded': False,
    'statusCode': ret_code,
    'headers': {'Content-Type': 'application/json'},
    'body': json.dumps(result)
}
当我使用以下方法测试Lambda时,此函数工作正常

{
"op1": 7,
"op2": 9,
"op": "divide"
}
然后,我在AmazonAPI网关中创建了一个API,并将其配置为使用Lambda代理集成,如中所示

但是,现在,当我尝试通过与之前相同的输入数据通过PUT或POST触发AWS Lambda时,我得到了一个219错误,这意味着数据没有传递到Lambda事件中,而是Lambda使用默认的零,给出了错误。我从API网关得到的响应如下:

Execution log for request test-request
Tue Nov 21 12:19:34 UTC 2017 : Starting execution for request: test-invoke-request
Tue Nov 21 12:19:34 UTC 2017 : HTTP Method: PUT, Resource Path: /
Tue Nov 21 12:19:34 UTC 2017 : Method request path: {}
Tue Nov 21 12:19:34 UTC 2017 : Method request query string: {}
Tue Nov 21 12:19:34 UTC 2017 : Method request headers: {}
Tue Nov 21 12:19:34 UTC 2017 : Method request body before transformations: {
"op1": 7,
"op2": 9,
"op": "divide"
}
Tue Nov 21 12:19:34 UTC 2017 : Endpoint request URI: https://lambda.eu-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-2:*:function:newCalc/invocations
Tue Nov 21 12:19:34 UTC 2017 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=*, X-Amz-Date=20171121T121934Z, x-amzn-apigateway-api-id=*, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-2:*:wrsio8dvp3/null/PUT/{proxy+}, Accept=application/json, User-Agent=AmazonAPIGateway_*, X-Amz-Security-Token=*
Tue Nov 21 12:19:34 UTC 2017 : Endpoint request body after transformations: {"resource":"/{proxy+}","path":"/","httpMethod":"PUT","headers":null,"queryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":{"path":"/{proxy+}","accountId":"*","resourceId":"fsamcn","stage":"test-invoke-stage","requestId":"test-invoke-request","identity":{"cognitoIdentityPoolId":null,"accountId":"*","cognitoIdentityId":null,"caller":"*","apiKey":"test-invoke-api-key","sourceIp":"test-invoke-source-ip","accessKey":"*","cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":"arn:aws:iam::*:user/*","userAgent":"Apache-HttpClient/4.5.x (Java/1.8.0_144)","user":"*"},"resourcePath":"/{proxy+}","httpMethod":"PUT","apiId":"wrsio8dvp3"},"body":"{\n  \"op1\": 7,\n  \"op2\": 9,\n  \"op\": \"divide\"\n}","isBase64Encoded":false}
Tue Nov 21 12:19:34 UTC 2017 : Sending request to https://lambda.eu-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-2:*:function:newCalc/invocations
Tue Nov 21 12:19:34 UTC 2017 : Received response. Integration latency: 287 ms
Tue Nov 21 12:19:34 UTC 2017 : Endpoint response body before transformations: {"isBase64Encoded": false, "statusCode": 219, "headers": {"Content-Type": "application/json"}, "body": "\"Please enter valid input data\""}
Tue Nov 21 12:19:34 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, Connection=keep-alive, x-amzn-RequestId=3befcbd6-ceb6-11e7-a4dd-c3db02aba4a2, Content-Length=139, Date=Tue, 21 Nov 2017 12:19:34 GMT, X-Amzn-Trace-Id=root=1-5a1419d6-106413cfbf4bf985d840894f;sampled=0, Content-Type=application/json}
Tue Nov 21 12:19:34 UTC 2017 : Method response body after transformations: "Please enter valid input data"
Tue Nov 21 12:19:34 UTC 2017 : Method response headers: {X-Amzn-Trace-Id=sampled=0;root=1-5a1419d6-106413cfbf4bf985d840894f, Content-Type=application/json}
Tue Nov 21 12:19:34 UTC 2017 : Successfully completed execution
Tue Nov 21 12:19:34 UTC 2017 : Method completed with status: 219

因此,请您帮助我找出我做错了什么,以及如何正确设置请求正文的格式以触发Lambda函数。

您面临的问题来自api网关的代理集成。如果您选中此项,则提供给lambda的输入结构不再是提供给PUT操作的普通有效负载

事件参数实际上由以下结构组成(在日志中,转换后的行
端点请求正文


因此,要访问原始事件,您必须解码
event.body
元素。

使用
payload=json.loads(event.get('body'))
然后通过
op1=payload['op1']读取单个元素,更新代码以首先将event.body作为dict读取。
{
    "resource": "/{proxy+}",
    "path": "/",
    "httpMethod": "PUT",
    "headers": null,
    "queryStringParameters": null,
    "pathParameters": null,
    ....
    "body": "{\n  \"op1\": 7,\n  \"op2\": 9,\n  \"op\": \"divide\"\n}",
    "isBase64Encoded": false
}