你能在 Lambda Python 3.6 中有一个异步处理程序吗?

Abi*_*n47 9 python amazon-web-services async-await aws-lambda python-3.6

我以前做过 Lambda 函数,但没有在 Python 中做过。我知道在 Javascript 中 Lambda 支持异步处理函数,但是如果我在 Python 中尝试它,我会得到一个错误。

这是我要测试的代码:

async def handler(event, context):
    print(str(event))
    return { 
        'message' : 'OK'
    }
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误:

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)
Run Code Online (Sandbox Code Playgroud)

编辑 2021 年

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

好消息是,自 Python 3.7 以来,有一种简单的解决方法,形式为asyncio.run

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)
Run Code Online (Sandbox Code Playgroud)

Ant*_*lov 16

一点也不。AWS Lambda不支持异步 Python 处理程序。

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

请注意,asyncio.run在 Python 3.7 中引入不是在 AWS Lambda 执行环境中调用异步处理程序的正确方法,因为 Lambda尝试为后续调用重用执行上下文。这里的问题是asyncio.run创建一个新的EventLoop并关闭前一个。如果您打开了任何资源或创建了附加到EventLoop从之前的 Lambda 调用中关闭的协程,您将收到“事件循环关闭”错误。asyncio.get_event_loop().run_until_complete允许您重复使用相同的循环。请参阅相关的 StackOverflow问题

AWS Lambda 文档通过引入同步和异步调用来误导读者。不要将它与同步/异步 Python 函数混淆。同步是指调用 AWS Lambda 并进一步等待结果(阻塞操作)。该函数会立即被调用,您会尽快得到响应。而使用异步调用你问LAMBDA调度功能的执行,不等待响应所有。到时候,Lambda 还是会同步调用处理函数。

  • @Yusuf 异步代码执行不仅允许并行处理多个 Lambda 请求,还可以并行化 Lambda 内部 IO 绑定活动,例如对 AWS 服务的调用(例如,在单个 Lambda 调用中并行写入多个 S3 对象)。因此,问题不在于通过单个 Lambda 函数并行处理请求,而在于在 Lambda 执行环境中使用 Python 的异步功能。 (2认同)