Search code examples
pythonasynchronouspython-requestspython-asyncioaiohttp

How to add a try until success loop inside aiohttp requests


I have the following code,

import aiohttp
import asyncio

async def get_data(session, x):
    try:
        async with session.get(url=f'https://api.abc.com/{x}') as response:
            data = await response
            if data.status_code == 200:
                data = float(data.json())
                return data
            else:
                continue
    except Exception as e:
        print("Unable to get url {} due to {}.".format(x, e.__class__))
        return None

async def main(datas):
    async with aiohttp.ClientSession() as session:
        ret = await asyncio.gather(*[get_data(session, data) for data in datas])
        return {datas[i]: ret[i] for i in range(len(datas))}  # Return the results as a dictionary

datas = ['x1', 'x2', 'x3', 'x4']
results = asyncio.run(main(datas))

I want to query the api until i get a response == 200 and i am able to get float(data), if the data is text, it will fail. so it should try the float(data) until it succeeds.

If either fail, I want to retry until it succeeds.

Will the code work? I am not used to asych code.


Solution

  • import aiohttp
    import asyncio
    
    async def get_data(session, x):
        while True:
            try:
                async with session.get(url=f'https://api.abc.com/{x}') as response:
                    if response.status == 200:
                        data = await response.json()
                        try:
                            data = float(data)
                            return data
                        except ValueError:
                            print("Data is not a valid float. Retrying...")
                    else:
                        print("Received non-200 status code. Retrying...")
                await asyncio.sleep(1)  # Wait for 1 second before retrying
            except Exception as e:
                print("Unable to get url {} due to {}. Retrying...".format(x, e.__class__))
                await asyncio.sleep(1)  # Wait for 1 second before retrying
    
    async def main(datas):
        async with aiohttp.ClientSession() as session:
            ret = await asyncio.gather(*[get_data(session, data) for data in datas])
            return {datas[i]: ret[i] for i in range(len(datas))}  # Return the results as a dictionary
    
    datas = ['x1', 'x2', 'x3', 'x4']
    results = asyncio.run(main(datas))
    

    In the updated get_data function, we have a while True loop that will keep retrying until the conditions are met. When the API response has a status code of 200, we attempt to convert the data to a float using float(data). If it succeeds, we return the result. If the data is not a valid float (raises a ValueError), we print a message and retry.