AGH_TORN
AGH_TORN

Reputation: 833

How to approach returning an async function recursively

I've got a function that recursively attempts to retrieve information from a URL. If it receives a response other than 200, it tries again 3 times, ultimately returning None if nothing could be returned. My problem though is that when I run this through an event loop, instead of running again as a normal recursive function would, the function simply returns the coroutine and not the JSON response or None as expected.

async def make_request(session, url, attempt=0):
    async with session.get(url) as response:
        if response.status == 200:
            return await response.json()
        elif attempt < 3:
            return await make_request(session, url, attempt + 1) 
            # When it gets to this line, instead of returning the result of this function, 
            # it returns the coroutine object itself.
        return None

Should I be running something beforehand to ensure that this runs properly?

Upvotes: 3

Views: 4561

Answers (1)

Mikhail Gerasimov
Mikhail Gerasimov

Reputation: 39546

Can't reproduce your error without full code example. Anyway here's code that works:

import asyncio
import aiohttp


async def make_request(session, url, attempt=0):
    async with session.get(url) as response:
        if response.status == 200:
            return await response.json()
        elif attempt < 3:
            print(f'failed #{attempt}')  # to debug, remove later
            return await make_request(session, url, attempt + 1)
        return None


async def main():
    async with aiohttp.ClientSession() as session:
        res = await make_request(session, 'http://httpbin.org/status/404')
        print(res)

        res = await make_request(session, 'http://httpbin.org/json')
        print(res)


asyncio.run(main())

Btw, instead of trying to write your own retry stuff you may be interested in using other people's solutions, for example:

https://github.com/inyutin/aiohttp_retry

https://github.com/hellysmile/async_retrying

Upvotes: 4

Related Questions