python - 你能在 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
(在 Python 3.7 中引入)不是在 AWS Lambda 执行环境中调用异步处理程序的正确方法,因为 Lambda尝试将执行上下文重用于后续调用。这里的问题是asyncio.run
创建一个新的EventLoop
并关闭前一个。如果您打开了任何资源或创建了附加到EventLoop
先前 Lambda 调用关闭的协程,您将收到 «Event loop closed» 错误。asyncio.get_event_loop().run_until_complete
允许您重用相同的循环。请参阅相关的 StackOverflow问题。
AWS Lambda 文档通过引入同步和异步调用稍微误导了读者。不要将它与同步/异步 Python 函数混淆。同步是指调用 AWS Lambda 并进一步等待结果(阻塞操作)。该函数会立即被调用,您会尽快得到响应。而使用异步调用,您要求 Lambda 安排函数执行并且根本不等待响应。到时候,Lambda 还是会同步调用 handler 函数。
推荐阅读
- java - 将项目从一个表视图添加到另一个从选择(JAVAFX)
- google-data-studio - Datas Studio 社区连接器:getData 被调用两次,并且 fields list = null
- javascript - 在反应导航中,如何防止 AppBar 固定在顶部?我希望它在滚动时消失
- java - Sonar 要求“使用 try-with-resources 或在“finally”子句中关闭此“连接”。
- javascript - 我现有项目中的 Google 图表 HTML 页面集成不起作用
- c++ - 在 ARM 上进行 GCC 矢量化后的错误计算
- c++ - 在 C++ 中为 Linux 平台动态加载 DLL
- php - 如何检查电视流是否通过 PHP 工作
- ios - 如何在 swift 中创建可以通过 cocoapods 安装的 pod
- c# - 使用客户端证书时,大型 POST 请求会导致 Asp.Net Web API 超时