Асинхронное ожидание Python с циклом синхронизации

#python #loops #async-await

#python #циклы #асинхронное ожидание

Вопрос:

У меня есть программа на Python, которая запрашивает данные из нескольких API, а затем выполняет некоторое машинное обучение по данным с высокой производительностью. Я пытаюсь найти способ поддерживать цикл, чтобы он выполнялся последовательно каждые 5 минут, а функции сбора API запускались асинхронно, в то время как машинное обучение по этим данным запускается после того, как все вызовы API вернули данные.

Итак, у меня есть кое-что, что в основном выглядит так:

     while(True):
      try:
        api_data_one = loadFromAPIOne()
        api_data_two = loadFromAPITwo()
    
        results = calculateResults(api_data_one, api_data_two)
        
      except Exception as e:
        print('Exception raised - Uable to complete this iteration', e)
    
      time.sleep(300)
  

Теперь, поскольку машинное обучение занимает около минуты или дольше, для перезапуска итераций требуется больше времени, чем 5 минут. И вызовы API сами по себе занимают некоторое время, поэтому их одновременное выполнение было бы идеальным.

Не имея большого опыта, async и await я изо всех сил пытаюсь найти, с чего начать. Не могли бы вы посоветовать мне, с чего начать?

Комментарии:

1. Почему вы хотите сделать это с async / await в первую очередь? Параллелизм того, что вы описываете, составляет не более 3, что идеально соответствует тому, что могут обрабатывать потоки. Особенно, если ваши функции блокируются (как в настоящее время API и calculate), даже async цикл событий будет запускать их в потоках в любом случае.

2. Я даже не рассматривал возможность использования потоков. Они кажутся отличным вариантом. Спасибо, попробую.

Ответ №1:

Чтобы использовать async / await , для большинства языков вам нужно определить асинхронную функцию (которую вы хотите дождаться), а затем использовать await , чтобы подчеркнуть использование вновь созданной асинхронной функции. Когда вы определяете асинхронную функцию в Python (используя библиотеку asyncio), она определяется как объект сопрограммы, который поддерживает различные операции из библиотеки asyncio. Я не тестировал следующие шаги, поэтому я не совсем уверен, но вы можете начать с,

  • определение loadFromAPIOne() и loadFromAPITwo как асинхронной функции, например :
 async def loadFromAPIOne(): 
    # diverse operations like adding elements to an array 
    # or multiplying the array and so on 
  
  • То же самое для loadFromAPITwo() и calculateResults()
  • Затем вы создаете другую асинхронную функцию, которая будет выполняться asyncio, вы можете скопировать, например, следующее:
 async def loopCalculus(): # eventually the parameters you need for the load function 
    while True: 
        try:
            api_data_one_task = asyncio.create_task(loadFromAPIOne())
            api_data_two_task = asyncio.create_task(loadFromAPITwo())
            
            api_data_one = await api_data_one_task
            api_data_two = await api_data_two_task

            results_task = asyncio.create_task(calculateResults(api_data_one, api_data_two))
            results = await results_task
            # and returning the results 
            return results
    
        except Exception as e:
            print('Exception raised - Uable to complete this iteration', e)


# and do not forget to run the async function by :
asyncio.run(loopCalculus())

# or easier creating an async main 
async def main():
    res = await loopCalculus()

  

Вы также можете ознакомиться с полной документацией: docs async await python
Хорошего дня