You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastAPI中用AsyncIOScheduler每日执行带起止时间的调度任务

解决FastAPI中AsyncIOScheduler每日6-8点执行间隔任务的问题

你的核心问题是启动时固定的start/end_time无法每日更新,因为lifespan仅在应用启动时执行一次。要实现每日6点启动、持续到8点的间隔任务,有两种可靠方案:

方案一:每日6点动态创建当日的间隔任务

通过cron任务触发,每天6点时创建一个仅在当日6:00-8:00运行的间隔任务,到时间后任务会自动停止,无需手动清理。

修改后的代码:

@asynccontextmanager
async def lifespan(app: FastAPI):
    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from datetime import datetime, timedelta

    def print_hello():
        print("Hello", datetime.now())

    def create_daily_interval_job():
        # 计算当日的6点和8点
        today = datetime.now().date()
        start_time = datetime(today.year, today.month, today.day, 6, 0, 0)
        end_time = datetime(today.year, today.month, today.day, 8, 0, 0)
        
        # 添加当日的间隔任务,每秒执行一次,到8点自动停止
        scheduler.add_job(
            print_hello, 
            "interval", 
            seconds=1, 
            start_date=start_time,
            end_date=end_time,
            id="daily_interval_job",  # 给任务加ID,避免重复创建
            replace_existing=True
        )

    scheduler = AsyncIOScheduler()
    
    # 每天6点触发创建当日的间隔任务
    scheduler.add_job(
        create_daily_interval_job, 
        'cron', 
        hour=6, 
        minute=0,
        id="create_daily_job"
    )

    # 首次启动时如果当前时间在6-8点,立即创建任务
    now = datetime.now()
    today_start = datetime(now.year, now.month, now.day, 6, 0, 0)
    today_end = datetime(now.year, now.month, now.day, 8, 0, 0)
    if today_start <= now <= today_end:
        create_daily_interval_job()

    scheduler.start()
    
    yield
    scheduler.shutdown()

方案二:直接让间隔任务仅在每日6-8点运行

无需动态创建任务,直接给间隔任务设置时间范围,或在任务内部判断当前时间是否符合要求:

方式A:任务内部判断时间区间

@asynccontextmanager
async def lifespan(app: FastAPI):
    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from datetime import datetime

    def print_hello():
        now = datetime.now()
        # 仅在6-8点执行逻辑
        if 6 <= now.hour < 8:
            print("Hello", now)

    scheduler = AsyncIOScheduler()
    
    # 每秒执行一次任务,内部判断时间是否符合要求
    scheduler.add_job(print_hello, "interval", seconds=1)

    scheduler.start()
    
    yield
    scheduler.shutdown()

方式B:用cron直接约束运行窗口

利用cron表达式指定任务仅在每日6:00-7:59:59之间每秒执行:

@asynccontextmanager
async def lifespan(app: FastAPI):
    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from datetime import datetime

    def print_hello():
        print("Hello", datetime.now())

    scheduler = AsyncIOScheduler()
    
    # 每天6:00-7:59:59之间,每秒执行一次
    scheduler.add_job(
        print_hello, 
        "cron", 
        hour="6-7",
        minute="*",
        second="*"
    )

    scheduler.start()
    
    yield
    scheduler.shutdown()

关键说明

  • 方案一适合严格要求6点准时启动、8点准时停止的场景,任务仅在当日指定时间段内存在,资源占用更低。
  • 方案二的方式A逻辑简单,但会每秒触发一次任务(即使不在目标时间),适合对性能要求不高的场景;方式B用cron直接约束时间,更高效,无需内部判断。

内容的提问来源于stack exchange,提问作者Puja Neve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:21:13