1

I need to schedule a periodic function call in python (ie. called every minute), without blocking the event loop (I'm using Quart framework with asyncio).

Essentially need to submit work onto the event loop, with a timer, so that the webserver keeps serving incoming requests in the meantime and roughly every minute it calls my function.

I tried many ways, for instance:

def do_work(): print("WORK", flush=True) async def schedule(): await asyncio.sleep(0) print("scheduling") loop = asyncio.get_running_loop() t = loop.call_later(2, do_work) print("scheduled") asyncio.run(schedule()) 

But it either never gets executed (like the code above), or it blocks the webserver main event loop. For instance, with the code above I would expect (since it's done within asyncio.run and schedule awaits timer) that "scheduling" would be printed after (or during) the server setup, but that's not the case, it blocks.

1 Answer 1

5

You can use a background task that is started on startup,

async def schedule(): while True: await asyncio.sleep(1) await do_work() @app.before_serving async def startup(): app.add_background_task(schedule) 

which will run schedule for the lifetime of the app, being cancelled at shutdown.

Edit 2024:

Quart-Tasks now exists which allows the following,

from quart import Quart from quart_tasks import QuartTasks app = Quart(__name__) tasks = QuartTasks(app) @tasks.periodic(timedelta(seconds=1)) async def schedule(): ... # Do something 

It also allows the schedule to be defined using the CRON syntax.

Sign up to request clarification or add additional context in comments.

1 Comment

Note: this requires quart 0.16.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.