AWS Lambda: 使用boto3调用另一个AWS Lambda函数

7

我有一个简单的Lambda函数,它位于以下端点下:

https://******.execute-api.eu-west-2.amazonaws.com/lambda/add?x=1&y=2

AWS Chalice 用于在这里添加简单的端点。

@app.route('/{exp}', methods=['GET'])
def add(exp):
    app.log.debug("Received GET request...")
    request = app.current_request 
    app.log.debug(app.current_request.json_body)
    x = request.query_params['x']
    y = request.query_params['y']
    if exp == 'add':
        app.log.debug("Received ADD command...")
        result = int(x) + int(y)
        return {'add': result}

基本上,它检查path是否等于add并从query_params中求和两个值。
现在,我正在尝试在另一个lambda中调用此lambda。
我的问题是:
如何使用boto3 lambda客户端将pathquery_params传递给我的原始lambda函数?
到目前为止,我尝试了什么:
我在policy.json文件中添加了两行,允许我调用原始函数。
我在StackOverflow上看到了很多类似的问题,但大多数人将有效负载作为json传递。
@app.route('/')
def index():
    lambda_client = boto3.client('lambda')
    invoke_response = lambda_client.invoke(
        FunctionName="function-name",
        InvocationType="RequestResponse"
    )
    app.log.debug(invoke_response['Payload'].read())

感谢您的提前帮助!

你能否直接向API端点发送POST请求而不是调用它? - Sudharsan Sivasankaran
@SudharsanSivasankaran,可以的。但如果可能的话,我想使用boto3来调用它。我认为以后我想要向我的原始lambda函数添加身份验证机制(例如使用AWS Cognito),这将更容易。 - Kyrylo
1个回答

13

也许你可以将下面的代码添加到你的add函数中,这样它就可以接受有效载荷了:

@app.route('/{exp}', methods=['GET'])
def add(exp, *args, **kwargs):
    if isinstance(exp, dict):
        # exp is event here
        request = exp.get('request', {'x': 0, 'y': 0})
        exp = exp.get('exp', 'add')

我将写一个通用的例子,你可以轻松修改它以匹配你的需求。在你的情况下,数据字典将具有requestexp键,你需要找到你的Lambda函数的arn。

AWS文档:Lambda.invoke

现在假设我们有两个名为“master”和“slave”的Lambda函数。master将调用slave。

目前有3种不同类型的调用方式:

  1. 请求响应(默认):master调用并等待slave响应
  2. 事件:异步,master调用然后忘记
  3. DryRun:运行之前执行一些验证

我将使用#1请求响应:

Slave:

def lambda_handler(event, context):
    result = {}
    result['event'] = event
    result['result'] = "It's ok"
    return result

它的arn类似于arn:aws:lambda:us-east-1:xxxxxxxxxxxxxx:function:slave

在这个例子中,slave只是一个回声函数

现在,主函数需要适当角色的权限来调用它,以及arn或名称。您可以编写类似以下内容的代码:

import boto3
from datetime import datetime
import json

client = boto3.client('lambda')

def lambda_handler(event, context):
    arn = 'arn:aws:lambda:us-east-1:xxxxxxxxxxxxxx:function:slave'
    data = {'my_dict': {'one': 1, 'two': 2}, 'my_list': [1,2,3], 'my_date': datetime.now().isoformat()}

    response = client.invoke(FunctionName=arn,
                             InvocationType='RequestResponse',
                             Payload=json.dumps(data))

    result = json.loads(response.get('Payload').read())
    return result

通常你可以通过像 os.environ.get('slave_arn') 这样的方式获取ARN。

所有从/到Lambda的数据必须是JSON可序列化的。


如果在循环中调用工作/从属 Lambda,以便多个实例同时运行,这是否有效?我能否使用同一客户端异步地多次调用 Lambda,还是需要动态创建 boto3 客户端来执行此操作? - Maile Cupo
1
同时支持异步和同步https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/lambda.html#Lambda.Client.invoke调用 Lambda 函数。您可以同步调用函数(并等待响应),也可以异步调用。要异步调用函数,请将 InvocationType 设置为 Event。 - dadiaar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接