Skip to main content

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.

Metadata

Release files for atevery 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for atevery 0.1.2
File Size Uploaded
atevery-0.1.2.tar.gz 3.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for atevery 0.1.2
File Interpreter ABI Platform
atevery-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 8.1 kB

Release files / atevery-0.1.2.tar.gz

Download URL atevery-0.1.2.tar.gz
Size 3.8 kB
Tags Source
SHA-256 checksum
How to use checksums
1bb60b499ce5465120e7d04f03c4ce9f2dd9fa7d79699a6c385848f5b29cde5b
BLAKE2b-256 checksum
How to use checksums
2381e4eeb37fc4421178a7e5b1d7dab1152b2f27ca31b14105ed8286b601a455
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.3 CPython/3.12.5 Linux/6.5.0-1025-azure

Release files / atevery-0.1.2-py3-none-any.whl

Download URL atevery-0.1.2-py3-none-any.whl
Size 4.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bea53817e5a6668f67159276151fd1a099505e7448a91dc504faab9da5250521
BLAKE2b-256 checksum
How to use checksums
0e01295fbfd0181c44717143da6e6606656d4b933c8a730071dd52bd250c186c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.8.3 CPython/3.12.5 Linux/6.5.0-1025-azure

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page