简体   繁体   English

如何对 Chalice 应用程序进行异步 API 调用?

[英]How to make an asynchronous API call to a Chalice app?

I need a user-request from a web app to call an AWS Chalice endpoint which triggers a long-running job.我需要来自 web 应用程序的用户请求来调用触发长时间运行作业的 AWS Chalice 端点。 I can't let the user's browser wait for a response.我不能让用户的浏览器等待响应。

Chalice creates a REST API in API Gateway automatically, so this should be possible as it's not an HTTP API. Chalice 在 API 网关中自动创建了一个 REST API,所以这应该是可能的,因为它不是 HTTP API。

How to implement an endpoint in AWS Chalice which responds to the user immediately before executing the attached Lambda function?如何在执行附加的 Lambda function 之前立即响应用户的 AWS Chalice 端点?

I am aware of the InvocationType: Event header which should allow for this , but this has no effect, the endpoint does not call the Lambda asynchronously (the client gets a response when the job completes 20-30 seconds later).我知道InvocationType: Event header 应该允许这个,但这没有效果,端点不会异步调用 Lambda (当作业在 20-30 秒后完成时,客户端会收到响应)。

Here's what the endpoint in the Chalice app roughly looks like: Chalice 应用程序中的端点大致如下所示:

@app.route('/api-v1/runLongJob', methods=['PUT'])
def run_long_job():

    # do some stuff that takes a long time here

    return {'status_code': 200}

I have also set InvocationType as a header in the Method request section in the API Gateway console:我还在 API 网关控制台的Method request部分中将InvocationType设置为 header:

See this screenshot for what that looks like请参阅此屏幕截图以了解它的外观

An example of how I call this endpoint from Python with the InvocationType header:我如何使用InvocationType header 从 Python 调用此端点的示例:

url = "https://----------.execute-api.xx-xxxx-x.amazonaws.com/api/v1-api/runLongJob"
data = {
    'some parameter': 'some data'
}
headers = {
    'Content-Type': 'application/json',
    'InvocationType': 'Event'
}

r = requests.put(
    url,
    data=json.dumps(data),
    headers=headers
)

How to create an asynchronous endpoint in a Chalice app?如何在 Chalice 应用程序中创建异步端点?

The solution is to use the .lambda_function feature in Chalice along with the invocationType='Event' parameter in the invocation call, like this:解决方案是在调用调用中使用 Chalice 中的.lambda_function功能以及invocationType='Event'参数,如下所示:

import boto3
from chalice import Chalice


lambda_client = boto3.client('lambda')
app = Chalice(app_name='api')
LOG.setLevel(logging.INFO)


@app.route('/v1/lambdaTest')
def test_endpoint():
    LOG.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    _ = lambda_client.invoke(
        FunctionName="api-dev-testFunction",
        InvocationType='Event',
        Payload="{}"
    )
    LOG.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    return {'status_code': 200}


@app.lambda_function(name='testFunction')
def test_lambda_function(event, context):
    LOG.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    time.sleep(20)
    LOG.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

This generates two lambda functions, one for the API and one for the asynchronous task.这会生成两个 lambda 函数,一个用于 API,一个用于异步任务。 When the API is called, the response is immediate, but the task takes 20 seconds to complete.当调用 API 时,响应是立即的,但任务需要 20 秒才能完成。

Note that I had to manually permit the API lambda to invoke the other, in the AWS console.请注意,我必须在 AWS 控制台中手动允许 API lambda 调用另一个。

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

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