Imagine we have an original API that returns a generator (it really is a mechanisms that brings pages/chunks of results from a server while the providing a simple generator to the user, and lets him iterate over these results one by one. For simplicity:
# Original sync generator
def get_results():
# fetch from server
yield 1
yield 2
# fetch next page
yield 3
yield 4
# ....
Now there is a need to implement an asyncio version of the API, however we need to keep the old API operational as well. This is where things get complicated, we kind of want to translate an async generator into sync one, but I can't find an elegant way to do that. The best I could make work so far is "fetch all result into a list first, then provide a fake sync generator on that list". Which kind of defeats the purpose:
# Async generator
async def get_results_async():
# await fetch from server
yield 1
yield 2
# await fetch next page
yield 3
yield 4
# ....
# Backward compatible sync generator
def get_results():
async def gather_all_results():
res = []
async for i in get_results_async():
res.append(i)
return res
res = asyncio.run(gather_all_results())
for i in res:
yield i
Is there a better, more elegant way to do that without fetching all the results before returning them?
Thanks