Issue
I'm having an issue with a recursive function not properly being called within an event loop. I have the following:
async def get_response(session, url, attempt=0):
async with session.get(url) as response:
if response.status == 200:
return await response.json()
elif attempt < 3:
# This never gets called, a coroutine is returned
return get_response(session, url, attempt + 1)
else:
return None
async def main(loop):
output = []
urls = ["https://httpbin.org/json"]
async with aiohttp.ClientSession(loop=loop) as session:
tasks = []
for url in urls:
tasks.append(asyncio.ensure_future(get_response(session, url)))
for future in await asyncio.gather(*tasks):
output.append(future)
return output
if __name__ == '__main__':
loop = asyncio.get_event_loop()
output = loop.run_until_complete(main(loop))
The problem arises in get_response
where if attempt < 3
it won't actually run the function again. The above code will work just fine since https://httpbin.org/json
will return a 200 code. Correct me if I'm wrong (because I probably am) but I'm thinking that since that iteration of the function isn't in the list of tasks in main
then it won't actually run? What I get in return when I debug is an actual coroutine object rather than None
as I had intended.
What is the proper way to ensure a recursive function within a future
will be called again if necessary?
Solution
As get_response
is async, you need to await it when calling it, even when doing so from itself. So, you need to change:
return get_response(session, url, attempt + 1)
to:
return await get_response(session, url, attempt + 1)
Answered By - user4815162342
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.