How can I periodically execute a function with asyncio?
For Python versions below 3.5:
import asyncio
@asyncio.coroutine
def periodic():
while True:
print('periodic')
yield from asyncio.sleep(1)
def stop():
task.cancel()
loop = asyncio.get_event_loop()
loop.call_later(5, stop)
task = loop.create_task(periodic())
try:
loop.run_until_complete(task)
except asyncio.CancelledError:
pass
For Python 3.5 and above:
import asyncio
async def periodic():
while True:
print('periodic')
await asyncio.sleep(1)
def stop():
task.cancel()
loop = asyncio.get_event_loop()
loop.call_later(5, stop)
task = loop.create_task(periodic())
try:
loop.run_until_complete(task)
except asyncio.CancelledError:
pass
Scheduling periodic function call in Quart/asyncio
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.
Python 3.9 - Scheduling periodic calls of async function with different parameters
As a ready-to-use solution, you could use aiocron
library. If you are not familiar with cron expression syntax, you can use this online editor to check.
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:
15:26:00.003226 At every minute
15:27:00.002642 At every minute
...
asyncio run two different functions periodically with different intervals
Would it be possible using asyncio to run 2 different functions periodically with different interval for each f forever ?
Sure, just create a coroutine that does it in the "obvious" way, by awaiting the coroutine in an infinite loop with asyncio.sleep()
between invocations:
import asyncio, time
async def invoke_forever(period, corofn, *args):
while True:
then = time.time()
await corofn(*args)
elapsed = time.time() - then
await asyncio.sleep(period - elapsed)
Scenario described in the question would be set up with something like:
loop = asyncio.get_event_loop()
loop.create_task(invoke_forever(1, f1, 'host1'))
loop.create_task(invoke_forever(2, f2, 'host2'))
loop.run_forever()
You can also use asyncio.gather
to combine the two invoke_forever
into one awaitable, which allows using the asyncio.run
function introduced in Python 3.7:
async def invoke_both():
await asyncio.gather(invoke_forever(1, f1, 'host1'),
invoke_forever(2, f2, 'host2'))
asyncio.run(invoke_both())
Related Topics
Element That Appear More That Once in the List in Python
Python: String Iteration Replace a Space With a Hyphen (Or Other Character)
Convert a Python Int into a Big-Endian String of Bytes
Python Data Frame How to Find the Local Maximum in a 2D Array
Replace Single Quote to Double Quote Python Pandas Dataframe
Key Error: None of [Int64Index...] Dtype='Int64] Are in the Columns
How to Check If a String Contains 2 of the Same Character
How to Get Elasticsearch to Perform an Exact Match Query
How to Split by Commas That Are Not Within Parentheses
How to Make Multiple Empty Lists in Python
Test a Function Called Twice in Python
How to Share Single Sqlite Connection in Multi-Threaded Python Application
How to Extract Rar Files Inside Google Colab
Pickle - Cpickle.Unpicklingerror: Invalid Load Key, '?'
How to Add Pandas Data to an Existing CSV File
Typeerror: Unsupported Operand Type(S) for ** or Pow(): 'List' and 'Int'