简体   繁体   English

Python 3.9 - 使用不同参数调度异步 function 的定期调用

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

How to in python 3.9 implement the functionality of calling the async functions with different parameters, by scheduled periods?如何在 python 3.9 中实现按计划周期调用具有不同参数的异步函数的功能? The functionality should be working on any OS (Linux, Windows, Mac)该功能应适用于任何操作系统(Linux、Windows、Mac)

I have a function fetchOHLCV which downloads market data from exchanges.我有一个 function fetchOHLCV,它从交易所下载市场数据。 The function has two input parameters - pair, timeframe. function 有两个输入参数 - 对,时间范围。 Depending on the pair and timeframe values the function download data from exchanges and stores them in DB.根据货币对和时间帧值,function 从交易所下载数据并将其存储在数据库中。

The goal - call this function with different periods with different parameters.目标 - 用不同的周期和不同的参数调用这个 function。

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

At this moment I don't have experience working with scheduling in python and I don't know which libraries will optimal for my task and I'm interested in the best practices of implementing similar tasks.目前我没有在 python 中进行调度的经验,我不知道哪些库最适合我的任务,我对实现类似任务的最佳实践感兴趣。

Here you use apschedulers AsyncIOScheduler which works naturally with async functions在这里,您使用apschedulers AsyncIOScheduler 它自然地与异步函数一起工作

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

tr is trigger object. tr 是触发器 object。 You can use either IntervalTrigger or a CronTrigger to schedule it.您可以使用IntervalTriggerCronTrigger来安排它。 Its recommended to do a shutdown() on the scheduler object after the end of program建议在程序结束后对调度程序 object 执行shutdown()

OR alternatively或者

You can use run_coroutine_threadsafe to schedule a coroutine to the event loop您可以使用run_coroutine_threadsafe将协程安排到事件循环

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

Working example of asyncio on Python3.9 Python3.9 上asyncio的工作Python3.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

执行

So as you can see async function was called with the scheduling of 1second and stop function was called at 5th second .如您所见,异步 function 被调用,调度为1secondstop function 被调用在5th second Try implementing this and could possibly solve your problem尝试实现这一点,可能会解决您的问题

As a ready-to-use solution, you could use aiocron library.作为即用型解决方案,您可以使用aiocron库。 If you are not familiar with cron expression syntax, you can use this online editor to check.如果你对cron表达式语法不熟悉,可以使用这个在线编辑器来检查。

Example (this will work on any 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())

Output: Output:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM