Получите ответ на запрос aiohttp в обратном вызове с бесконечной l oop асинхронной задачей - PullRequest
0 голосов
/ 03 марта 2020

Что я делаю - я пытаюсь сделать несколько запросов на публикацию (к одному и тому же URL с разными параметрами) за бесконечное время l oop, используя asyncio и aiohttp.

def callback(response):
    print(response) 

async def make_request(session, payload, sema):
        async with sema, session.post(url=URL, headers=HEADERS, data=json.dumps(payload)) \
                as response:
            return await response.json()


async def generate_requests(payloads):
    tasks = []
    sema = asyncio.BoundedSemaphore(value=100)
    async with aiohttp.ClientSession() as session:
        for payload in payloads:
            tasks.append(make_request(session, payload, sema))
        results = await asyncio.gather(*tasks, return_exceptions=True)
        print(results)


def run_asyncio_requests():
    loop = asyncio.get_event_loop()
    while True:
        for country in countries:
            cities = country.cities
            loop.run_until_complete(generate_requests(cities))


if __name__ == '__main__':
    run_asyncio_requests()

Проблема: run_asyncio_requests Функция генерирует и делает несколько запросов (городов против страны), а затем ожидает всех ответов на запросы одной страны, затем выполняет следующую запросы страны.

Что я хочу: Запросы всех стран должны выполняться одновременно, а функция обратного вызова (своего рода связанная функция с каждым запросом) должна обрабатывать каждый ответ, поскольку время ответа после запроса для каждого запроса это отличается. Не следует ждать, чтобы собрать все ответы. Запросы должны генерироваться в каждом цикле (infinite-l oop), а функция обратного вызова в фоновом режиме должна быть связана с каждым ответом. Я знаю, что использую asyncio.gather , чтобы получать все ответы до завершения запросов. Но я понятия не имею, как это сделать.

1 Ответ

0 голосов
/ 03 марта 2020

Вы можете применить ту же технику при вызове generate_requests, что и при вызове make_request:

async def generate_all_countries():
    tasks = [generate_requests(country.cities) for country in countries]
    results = await asyncio.gather(*tasks)
    print(results)

if __name__ == '__main__':
    asyncio.run(generate_all_countries())

Обратите внимание, что вам не нужно run_asyncio_requests в качестве отдельной функции syn c , вы можете просто вызвать асинхронную функцию c, используя asyncio.run() и продолжить оттуда.

...