如何正确编写与AWS Lambda一起使用的asyncio代码?

17

我写了下面的代码:


import asyncio

loop = asyncio.get_event_loop()

async def get_urls(event):

    return {'msg':'Hello World'}

def lambda_handler(event,context):

    return loop.run_until_complete(get_urls(event))

我想更快地完成以下任务。


def lambda_handler(event, context):
    # TODO implement
    return {'msg':'Hello World'}

在AWS Lambda环境中编写代码的正确方式是什么?


1
你解决了吗? - Juliano
4个回答

21

对我来说可行...你需要选择运行时“Python 3.6”或“Python 3.7”。

import asyncio

loop = asyncio.get_event_loop()

async def get_urls(event):
    return {'msg':'Hello World'}

def lambda_handler(event, context):
    return loop.run_until_complete(get_urls(event))

在这里输入图片描述


1
AWS Lambda最佳实践建议“在函数处理程序之外初始化数据库连接”。 您如何在这样的代码中创建数据库连接?是否可以在函数处理程序之外创建数据库连接? - Matan Givoni
2
@givo 是的。Python在导入时执行任何“外部代码”(位于任何函数或类之外的最左边级别的代码)。 另一个选项是使用全局变量来保存连接,并仅在处理程序函数中初始化它,如果它还没有被初始化的话。 - Messa
谢谢@Messa,你的运行时帮我省了好几个小时的头疼。 - Fucio
1
在处理请求时,积极地预热你需要的东西是AWS Lambda服务器实现的重要优化策略。AWS的建议还不够,你应该为更多的东西这样做,而不仅仅是数据库连接。此外,如果你不在后续请求中重用对象,你的性能将会非常糟糕。记住你创建的东西,并在下次使用时重复利用它们,如果可能的话。 - doug65536

5

异步执行可以同时完成多个任务。你只能做一件事情,无法比做一件事情的时间更快。异步执行允许您同时执行本来需要一个接一个(同步)执行的独立任务,然后返回所有任务的结果。因此,您必须执行多个操作。


8
你说得对,但在 AWS Lambda 中有些情况下你可以从异步中获益。例如,当你的函数需要聚合多个 HTTP 端点的结果时。 - Juan José Brown

5

对于 Python 3.7+,可以使用 asyncio.run() 来执行您的协程:

import asyncio

# The AWS Lambda handler
def handler(event, context):
    asyncio.run(main())

async def main():
    # Here you can await any awaitable
    await asyncio.sleep(1)
    await asyncio.gather([coroutine_1, coroutine_2])

这是一个完整的例子,展示了如何使用asyncio、aiohttp和aiobotocore在AWS Lambda上开发、测试和部署异步Python函数:https://github.com/geeogi/async-python-lambda-template

1
我认为这是错误的,至少如果您在Lambda调用之间重复使用全局资源。当我使用asyncio.run时,后续运行会出现“事件循环关闭”错误。我猜这是因为这些全局资源与先前的事件循环相关联? - mariaines
@mariaines是对的。我刚刚解决了一个由于在AWS Lambda上使用asyncio.run()引起的错误。asyncio.get_event_loop()似乎是正确的方法。 - Johan Levin

0

需要将 aioboto3 安装在本地作为部署 zip 包的一部分。

import asyncio
import aioboto3



async def list_s3_objs (bucket):
    async with aioboto3.client("s3") as s3_client:
        objs = await s3_client.list_objects(Bucket=bucket)
    return objs['Contents']

def lambda_handler(event, context):
    loop = asyncio.get_event_loop()
    loop.run_until_complete(list_s3_objs('bucket_name'))

`


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