Python 3.9 - 调度具有不同参数的异步函数的定期调用

Python 3.9 - Scheduling periodic calls of async function with different parameters

python3.9如何实现定时调用不同参数的异步函数的功能?该功能应该适用于任何 OS (Linux, Windows, Mac)

我有一个函数 fetchOHLCV 从交易所下载市场数据。该函数有两个输入参数 - 货币对、时间范围。 根据货币对和时间范围值,函数从交易所下载数据并将它们存储在数据库中。

目标 - 在不同的时期用不同的参数调用这个函数。

1) fetchOHLCV(pair ='EUR/USD', timeframe="1m") - each minute
2) fetchOHLCV(pair ='EUR/USD', timeframe="1h") - each new hour.
3) fetchOHLCV(pair ='EUR/USD', timeframe="1d") - each new day 
4) fetchOHLCV(pair ='EUR/USD', timeframe="1w") - each new week

目前我没有在 python 中使用调度的经验,我不知道哪些库最适合我的任务,我对实现类似任务的最佳实践很感兴趣。

在这里你使用 apschedulersAsyncIOScheduler,它自然地与异步函数一起工作

scheduler = AsyncIOScheduler()
scheduler.add_job(fetchOHLCV, trigger=tr)
scheduler.start()

tr 是触发器对象。您可以使用 IntervalTriggerCronTrigger 来安排它。建议在程序结束后对调度程序对象执行 shutdown()

或者

您可以使用run_coroutine_threadsafe将协程调度到事件循环

asyncio.run_coroutine_threadsafe(async_function(), bot.loop)

asyncioPython3.9

上的工作示例
import asyncio

async def periodic():
    while True:
        print('periodic')
        await asyncio.sleep(1) #you can put 900 seconds = 15mins

def stop():
    task.cancel()

loop = asyncio.get_event_loop()
loop.call_later(5, stop) #increase end time as per your requirement
task = loop.create_task(periodic())

try:
    loop.run_until_complete(task)
except asyncio.CancelledError:
    pass

正如您所见,异步函数是在 1second 的调度中调用的,stop 函数是在 5th second 调用的。尝试实现它并可能解决您的问题

作为即用型解决方案,您可以使用aiocron library. If you are not familiar with cron expression syntax, you can use this在线编辑器进行检查。

示例(这适用于任何 OS):

import asyncio
from datetime import datetime
import aiocron


async def foo(param):
    print(datetime.now().time(), param)


async def main():
    cron_min = aiocron.crontab('*/1 * * * *', func=foo, args=("At every minute",), start=True)
    cron_hour = aiocron.crontab('0 */1 * * *', func=foo, args=("At minute 0 past every hour.",), start=True)
    cron_day = aiocron.crontab('0 9 */1 * *', func=foo, args=("At 09:00 on every day-of-month",), start=True)
    cron_week = aiocron.crontab('0 9 * * Mon', func=foo, args=("At 09:00 on every Monday",), start=True)

    while True:
        await asyncio.sleep(1)

asyncio.run(main())

输出:

15:26:00.003226 At every minute
15:27:00.002642 At every minute
...