您可以在 Lambda Python 3.6 中使用异步处理程序吗?

Can you have an async handler in Lambda Python 3.6?

我以前制作过 Lambda 函数,但 Python 中没有。我在 Javascript 中知道 Lambda 支持异步处理函数,但如果我在 Python.

中尝试它,我会收到错误消息

这是我要测试的代码:

async def handler(event, context):
    print(str(event))
    return { 
        'message' : 'OK'
    }

这是我得到的错误:

An error occurred during JSON serialization of response: <coroutine object handler at 0x7f63a2d20308> is not JSON serializable
Traceback (most recent call last):
  File "/var/lang/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/var/lang/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/var/lang/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/var/runtime/awslambda/bootstrap.py", line 149, in decimal_serializer
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <coroutine object handler at 0x7f63a2d20308> is not JSON serializable

/var/runtime/awslambda/bootstrap.py:312: RuntimeWarning: coroutine 'handler' was never awaited
  errortype, result, fatal = report_fault(invokeid, e)

编辑 2021

由于这个问题似乎越来越受欢迎,我假设人们来这里是为了弄清楚如何让 async 像我一样使用 AWS Lambda。坏消息是,即使在一年多之后的现在,AWS 仍然不支持在基于 Python 的 Lambda 函数中使用异步处理程序。 (我不知道为什么,因为基于 NodeJS 的 Lambda 函数可以完美地处理它。)

好消息是,从 Python 3.7 开始,有一个简单的解决方法 asyncio.run:

import asyncio

def lambda_handler(event, context):
    # Use asyncio.run to synchronously "await" an async function
    result = asyncio.run(async_handler(event, context))
    
    return {
        'statusCode': 200,
        'body': result
    }

async def async_handler(event, context):
    # Put your asynchronous code here
    await asyncio.sleep(1)
    
    return 'Success'

完全没有。 AWS Lambda 不支持异步 Python 处理程序

如果您需要在您的 AWS Lambda 中使用 async/await 功能,您必须在您的代码中定义一个异步函数(在 Lambda 文件或 Lambda 层中)并调用 asyncio.get_event_loop().run_until_complete(your_async_handler()) 在您的同步处理程序中。

请注意 asyncio.run (introduced in Python 3.7) is not a proper way to call an async handler in AWS Lambda execution environment since Lambda tries to reuse the execution context for subsequent invocations. The problem here is that asyncio.run creates a new EventLoop and closes the previous one. If you have opened any resources or created coroutines attached to the closed EventLoop from previous Lambda invocation you will get «Event loop closed» error. asyncio.get_event_loop().run_until_complete allows you to reuse the same loop. See related Whosebug .

AWS Lambda 文档通过引入同步和异步 调用 稍微误导了读者。不要将它与 sync/async Python 函数混淆。 Synchronous refers to invoking AWS Lambda with further waiting for the result (blocking operation). The function is called immediately and you get the response as soon as possible. Whereas using an asynchronous 调用您要求 Lambda 安排函数执行并且根本不等待响应 。到时候,Lambda 仍然会同步.

调用处理函数