Обработка плохих запросов в aiohttp - PullRequest
2 голосов
/ 14 мая 2019

Я пытаюсь найти способ обработки неверных запросов от API в асинхронной функции с помощью aiohttp. Вот что я получил для тестирования:

async def fetch(session):
    url = 'http://httpbin.org/status/404'
    async with session.request('GET', url) as response:
        if response.status == 200:
            try:
                r = await response.json()
                return r
            except ValueError:
                return
        else:
            return None

async def fetch_all(project_list):
    output = []
    async with ClientSession() as session:
        tasks = [asyncio.ensure_future(fetch(session, project)) for project in project_list]
        for future in await asyncio.gather(*tasks):
            output += future
    return output

def get_data(project_list):
    loop = asyncio.get_event_loop()
    futures = asyncio.ensure_future(fetch_all(project_list))
    output = loop.run_until_complete(futures)
    return output

В этом примере project_list это просто список целых чисел.

В этом случае fetch() не должен возвращать ничего, поскольку ответ, несомненно, будет 404. Проблема возникает в fetch_all(), где я сообщаю его += в будущем. Я получаю TypeError: 'coroutine' object is not iterable. По сути, я бы хотел, чтобы это ничего не возвращало, а в этом случае += ничего к этому списку. В идеальном мире я получал бы правильный ответ json каждый раз, но я бы хотел учесть случайный случай, когда я получаю неверный ответ от сервера.

Из того, что я прочитал, @asyncio.coroutine вернет None, но значения async должны быть awaited, если я правильно понимаю.

1 Ответ

0 голосов
/ 14 мая 2019

Я не совсем уверен, что это лучший способ сделать это, но я собрал это, и это сработало. Если кто-то может исправить меня, пожалуйста.

async def fetch_all(project_list):
    output = []
    async with ClientSession() as session:
        tasks = [asyncio.ensure_future(fetch(session, project)) for project in project_list]
        for future in await asyncio.gather(*tasks):
            if future is not None: #Check if the future is None before adding it
                output += future
    return output
...