terricain / aioboto3

Wrapper to use boto3 resources with the aiobotocore async backend

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SQS issue with aioboto3.session.client('SQS')

Dz0n1Pr0 opened this issue · comments

Hello, I have been working on a function that will log my responses asynchronously to SQS, but I am having trouble creating an SQS client that is open and not closed like how it is shown in the "with aioboto3.session.client("sqs") as sqs" example.

I tried following the ideas in this issue:
https://github.com/terrycain/aioboto3/issues/233

I created a function

app.session = aioboto3.Session()
app.sqs = None

async def get_sqs():
if app.sqs is None:
app.sqs = await app.session.client("sqs")
return app.sqs

but when I call the function I get an error TypeError: object ClientCreatorContext can't be used in 'await' expression on line app.sqs = await app.session.client("sqs")

Can you possibly assist me in resolving this issue?

I am using Quart for developing this API.

I think this is mentioned in the README.

The .client and .resource functions must now be used as async context managers.

Looks like you just need to use a context manager like in the README examples.

The issue is that each time I want to send logs to SQS it takes too long for every request (and we have hundreds per hour) to open a new SQS client connection.
Also, I think we can agree that it is not practical to open It every time if there is a way for me to keep this one connection to SQS open as long as my API is available.

Based on the ticket I linked in my first comment I thought this approach was viable.

Yeah you definitely dont want to be creating a new client for every message.

You should be able to do something like this: (untested and probably not syntactically correct)

import contextlib
import asyncio
import aioboto3

async def main():
    stack = contextlib.AsyncExitStack()
    session = aioboto3.Session()
    sqs = await stack.enter_async_context(session.client("sqs"))
    #... pass sqs object around, into other async functions etc..

    # before you exit, clean up
    await stack.aclose()


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

That or you could just do something like

import asyncio
import aioboto3

SQS = None

async def main():
    global SQS
    session = aioboto3.Session()
    SQS = session.client("sqs").__aenter__()
    #... pass sqs object around, into other async functions etc..

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

If you really dont care about cleaning up.

I managed to make it work with the second solution, where I awaited the SQS object that I got through the aenter() function as it was a corutine. Thank you for the assistance :)