Skip to main content

A periodic task scheduler for asyncio processes.

Project description

atevery

A periodic task scheduler for asyncio processes.

Installation options

pip install atevery
poetry add atevery

Usage

Register entrypoint functions to be run periodically by using the @every decorator:

from datetime import timedelta, datetime

from atevery import every

@every(timedelta(seconds=2), 'fast')
def print_time(name):
    print(name, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

Then start the scheduler in the main entrypoint:

import asyncio

from atevery import start_background_tasks, stop_background_tasks

if __name__ == '__main__':
    loop = asyncio.new_event_loop()
    try:
        loop.run_until_complete(start_background_tasks())
        loop.run_until_complete(...) # or loop.run_forever()
    finally:
        loop.run_until_complete(stop_background_tasks())

The registered functions are ran accordingly to their specified interval. Arguments and keyword arguments passed to the @every decorator are forwarded to the target function.

The target function can also be a coroutine/async function, like:

from datetime import timedelta, datetime

from atevery import every

@every(timedelta(seconds=2), 'fast')
async def print_time(name):
    print(name, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

Stopping and resuming tasks

Tasks can be stopped and restarted at any time by using the stop_background_tasks and start_background_tasks functions. While stopping, tasks that are still running or pending to run are cancelled, and by default waited for. If by any reason you don't want to cancel or wait for them, specify the wait_for=False or wait_for=True, timeout=timedelta(...) arguments to the stop_background_tasks function.

Concurrency

You can expect only a single instance of the same task to be running at the same time. In other words, the tasks are only started once their last execution was finished.

import asyncio
import random
from datetime import datetime, timedelta

from atevery import every, start_background_tasks, stop_background_tasks


@every(timedelta(seconds=2), 'slow')
async def print_time(name):
    print(name, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    await asyncio.sleep(4)


async def run():
    while True:
        await asyncio.sleep(random.random())


if __name__ == '__main__':
    loop = asyncio.new_event_loop()
    try:
        loop.run_until_complete(start_background_tasks())
        loop.run_until_complete(run())
    finally:
        loop.run_until_complete(stop_background_tasks())
        loop.stop()

Outputs something similar to:

slow 2024-03-03 14:24:26
slow 2024-03-03 14:24:30
slow 2024-03-03 14:24:34
slow 2024-03-03 14:24:38

Commitment

The scheduler mechanism makes its best to keep committed to the requested interval, but some delay might happen, specially under heavier loads. It comes from the fact the scheduler competes with the tasks and all other processes for the CPU time.

In order to reduce the event loop and CPU pressure, the scheduler has a minium resolution of 50ms. That means that on every iteration, the scheduler sleeps for 50ms. Attempting to schedule a task for intervals smaller than 50ms result in ValueError being raised.

Contributing

Feel free to create issues or merge requests with any improvement or fix you might find useful.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

atevery-0.1.2.tar.gz (3.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

atevery-0.1.2-py3-none-any.whl (4.3 kB view details)

Uploaded Python 3

File details

Details for the file atevery-0.1.2.tar.gz.

File metadata

  • Download URL: atevery-0.1.2.tar.gz
  • Upload date:
  • Size: 3.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.5 Linux/6.5.0-1025-azure

File hashes

Hashes for atevery-0.1.2.tar.gz
Algorithm Hash digest
SHA256 1bb60b499ce5465120e7d04f03c4ce9f2dd9fa7d79699a6c385848f5b29cde5b
MD5 097a9f707ff24fbc66ccd89159b47fc7
BLAKE2b-256 2381e4eeb37fc4421178a7e5b1d7dab1152b2f27ca31b14105ed8286b601a455

See more details on using hashes here.

File details

Details for the file atevery-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: atevery-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 4.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.5 Linux/6.5.0-1025-azure

File hashes

Hashes for atevery-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 bea53817e5a6668f67159276151fd1a099505e7448a91dc504faab9da5250521
MD5 9a6206f374a41d02d229d43dd10be2e3
BLAKE2b-256 0e01295fbfd0181c44717143da6e6606656d4b933c8a730071dd52bd250c186c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page