在aiobotocore中重用create_client以获得更好的性能

问题描述 投票:0回答:1

我正在实现一个异步 Python 代码,它使用 aiobotocore 将对象放入 S3 中。

代码是这样的 -

class Foo:
    def __init__(self):
        self._aiobotocore_session = get_session()

    def a():
        async with self.s3_client as self._aiobotocore_session.create_client('s3'):
            await s3_client.put_object(...)

        .... some logic ...

        async with self.s3_client as self._aiobotocore_session.create_client('s3'):
            await s3_client.put_object(...)

    def b():
        .... some logic ...

        async with self.s3_client as self._aiobotocore_session.create_client('s3'):
            await s3_client.put_object(...)

在官方文档中,看起来这是正确的方法。 然而,我不明白为什么我要一遍又一遍地调用

self._aiobotocore_session.create_client('s3')
,从源代码来看,这看起来像是一个昂贵的操作......

我有什么遗漏的吗?

如果我是正确的,缓存创建的客户端的最佳方法是什么? 现在看来我需要重新实现 ClientCreatorContext,以便它将保留客户端初始化

boto3 python-asyncio botocore aiobotocore
1个回答
0
投票

是的,如此处所述:

是的,可以做到,https://docs.python.org/3/library/contextlib.html#contextlib.AsyncExitStack也应该使用,我今晚会考虑制作一个aiohttp示例

并且this是他所指的aiohttp示例。

以下是我设法使其可重复使用的唯一方法

import aiohttp
import asyncio
import aioboto3
import contextlib


class Downloader:
    def __init__(self, s3_client) -> None:
        self.s3_client = s3_client

    async def download(self, bucket_name, object_key, destination_path) -> str:
        return await self.s3_client.meta.client.download_file(bucket_name, object_key, destination_path)

    async def close(self) -> None:
        await self.s3_client.close()


async def main() -> None:
    context_stack = contextlib.AsyncExitStack()
    session = aioboto3.Session()
    s3_client = await context_stack.enter_async_context(session.resource('s3'))
    d = Downloader(s3_client)
    await d.download("bucket", "my/key1", "/tmp/key1")
    await d.download("bucket", "my/key2", "/tmp/key2")
    await d.close()

if __name__ == "__main__":
    asyncio.run(main())


© www.soinside.com 2019 - 2024. All rights reserved.