Как правильно сделать Async Api Requests в Python? - PullRequest
0 голосов
/ 13 июня 2019

Я не эксперт по python, поэтому у меня возникают проблемы при попытке сделать асинхронные запросы API, он выдает «RuntimeError: цикл обработки событий закрыт».

Я делаю много запросов к API, и иногда он возвращает код состояния 429 (слишком много запросов), поэтому я хочу, чтобы, когда это произошло, я хотел продолжать попытки запроса, пока он не вернет код состояния 200, и продолжить процесс.

import requests
import asyncio
import aiohttp

CONCURRENCY = 3
TIMEOUT = 40000

async def fetch(session, sem, obj):
    async with sem:
        async with session.get(obj['url'], headers={}, params={}) as resp:
            #print(await response.json())

            if resp.status == 429: # too many consecutive requests
                print('Too many requests. Waiting some seconds to continue...')
                await sleep(5)

                while True:
                    r = await requests.get(obj['url'], auth=('xxxxx',''))
                    if r.status != 429:
                        break
                    await sleep(6)

                return await r


async def call_api(list_obj):
    try:
        sem = asyncio.Semaphore(CONCURRENCY)
        async with aiohttp.ClientSession(
            auth=aiohttp.BasicAuth(login='xxxxx', password='')) as session:
                responses = await asyncio.gather(*(
                    asyncio.wait_for(fetch(session, sem, i), TIMEOUT)
                    for i in list_obj
        ))

        return responses
    except :
        logger.critical('API request problem: ' + traceback.format_exc())



loop = asyncio.get_event_loop()
future = asyncio.ensure_future(call_api(array))
data = loop.run_until_complete(future)
loop.close()

Выдает «RuntimeError: цикл обработки событий закрыт».

...