Reputation: 3948
I'm designing an API, that I would like to make asynchronous. On the other hand I would still like to keep a simple to use synchronous version of it. Is there a simple way to achieve this?
I imagine something like a decorator that auto generates blocking wrappers for my async def
methods.
Upvotes: 1
Views: 914
Reputation: 17332
Running an async function requires an event loop that takes control over the execution.
Just consider every async function you want to convert as a separate program. What you are asking for is then running an async program.
# async version:
await asyncfunc(arg1, arg2, ...)
# sync version:
asyncio.run(asyncfunc(arg1, arg2, ...))
Writing such decorator should be is easy.
Of course, the overhead is big.
Upvotes: 1
Reputation: 4446
It's possible to make a decorator that just creates an event loop every time you want to run an async function, but that adds a lot of overhead and confusion.
Another common practice is to create a client that can accept a transport, that way you can just choose to make the transport sync or async, for example, this project https://github.com/aio-libs/aioelasticsearch, which takes the sync elasticsearch pkg, but adds an async transport that you can use with it.
Or elasticsearch's official solution to using async with their pkg https://elasticsearch-py.readthedocs.io/en/master/async.html
Anyways, if you ask me I think its better to stick to one thing, if your project benefits from async, just keep the client async.
Upvotes: 1