How do I wait for a method in a loop?
I have the following method that generates data for me:
async def generate_url(self, video_id):
data = await self.s3.generate_presigned_url(...video_id...)
return data
def convert_to_json(self, urls):
ids = [self.generate_url(url) for url in urls]
...
What is the correct way to wait generate_url
in convert_to_json
?
+3
user6611764
source
to share
3 answers
You can use a wait
wrapper around the task list:
async def convert_to_json(self, urls):
tasks = [self.generate_url(url) for url in urls]
await asyncio.wait(tasks)
Or, if you cannot mark the convert_to_json
method as async
, wait synchronously:
import asyncio
def convert_to_json(self, urls):
loop = asyncio.get_event_loop()
tasks = [self.generate_url(url) for url in urls]
loop.run_until_complete(asyncio.wait(tasks))
Also you can try to implement an iteratorasync
and use it with syntax async for
like this:
class Loader:
def __init__(self, urls):
self._urls = iter(urls)
async def generate_url(self, video_id):
data = await self.s3.generate_presigned_url(...video_id...)
return data
def __aiter__(self):
return self
async def __anext__(self):
try:
url = next(self._urls)
except StopIteration:
raise StopAsyncIteration
data = await self.generate_url(url)
return data
async for id in Loader(urls):
print(id)
+5
source to share
For me it worked something like this:
import asyncio
class A:
def __init__(self):
pass
async def generate_url(self, video_id):
data = await self.s3.generate_presigned_url(...video_id...)
return data
def add_to_ids(self, id):
ids.append(id.result())
def convert_to_json(self, urls):
loop = asyncio.get_event_loop()
ids = []
tasks = []
for url in urls:
task = asyncio.ensure_future(self.generate_url(url))
task.add_done_callback(self.add_to_ids)
tasks.append(task)
tasks = asyncio.gather(*tasks)
loop.run_until_complete(tasks)
loop.close()
a = A()
a.convert_to_json([1, 2, 3])
Enjoy!
0
source to share