A reliable distributed scheduler with pluggable storage backends
Project description
Overview
A reliable distributed scheduler with pluggable storage backends for Async Python.
- Free software: MIT license
Installation
Minimal installation (just SQLite persistence):
pip install pyncette
Full installation (all the backends and Prometheus metrics exporter):
pip install pyncette[all]
You can also install the in-development version with:
pip install https://github.com/tibordp/pyncette/archive/master.zip
Documentation
https://tibordp.github.io/pyncette/
Usage example
Simple in-memory scheduler (does not persist state)
from pyncette import Pyncette, Context
app = Pyncette()
@app.task(schedule="* * * * *")
async def foo(context: Context):
print("This will run every minute")
if __name__ == "__main__":
app.main()
Persistent distributed cron using Redis (coordinates execution with parallel instances and survives restarts)
from pyncette import Pyncette, Context
from pyncette.redis import redis_repository
app = Pyncette(repository_factory=redis_repository, redis_url="redis://localhost")
@app.task(schedule="* * * * * */10")
async def foo(context: Context):
print("This will run every 10 seconds")
if __name__ == "__main__":
app.main()
See the examples directory for more examples of usage.
Use cases
Pyncette is designed for reliable (at-least-once or at-most-once) execution of recurring tasks (think cronjobs) whose lifecycles are managed dynamically, but can work effectively for non-reccuring tasks too.
Example use cases:
- You want to perform a database backup every day at noon
- You want a report to be generated daily for your 10M users at the time of their choosing
- You want currency conversion rates to be refreshed every 10 seconds
- You want to allow your users to schedule non-recurring emails to be sent at an arbitrary time in the future
Pyncette might not be a good fit if:
- You want your tasks to be scheduled to run (ideally) once as soon as possible. It is doable, but you will be better served by a general purpose reliable queue like RabbitMQ or Amazon SQS.
- You need tasks to execute at sub-second intervals with low jitter. Pyncette coordinates execution on a per task-instance basis and this corrdination can add overhead and jitter.
Supported backends
Pyncette comes with an implementation for the following backends (used for persistence and coordination) out-of-the-box:
- SQLite (included)
- Redis (
pip install pyncette[redis]) - PostgreSQL (
pip install pyncette[postgres]) - MySQL 8.0+ (
pip install pyncette[mysql]) - MongoDB (
pip install pyncette[mongodb]) - Amazon DynamoDB (
pip install pyncette[dynamodb])
Pyncette imposes few requirements on the underlying datastores, so it can be extended to support other databases or custom storage formats / integrations with existing systems. For best results, the backend needs to provide:
- Some sort of serialization mechanism, e.g. traditional transactions, atomic stored procedures or compare-and-swap
- Efficient range queries over a secondary index, which can be eventually consistent
Development
Prerequisites
Install uv for fast package management:
curl -LsSf https://astral.sh/uv/install.sh | sh
Setup Development Environment
Sync dependencies and install the package in editable mode:
uv sync --extra all
Running Tests
Unit tests (fast, no external dependencies):
uv run pytest -m "not integration" tests
Integration tests (requires Redis, PostgreSQL, MySQL, MongoDB, DynamoDB):
Using Docker Compose to set up all backends:
docker-compose up -d
docker-compose run --rm shell
uv run pytest tests
Or manually with services running locally:
uv run pytest tests
Test on specific Python version:
uv venv --python 3.11
uv sync --extra all
uv run pytest tests
Code Quality
Run linting and type checking:
uv run pre-commit run --all-files
uv run ty check src examples
Building Documentation
uv run mkdocs build
# Or serve locally with live reload
uv run mkdocs serve
Building the Package
uv build
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyncette-1.1.0.tar.gz.
File metadata
- Download URL: pyncette-1.1.0.tar.gz
- Upload date:
- Size: 68.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99199041229a0960c40e954d8ca64e46eca10a8fa28dbb46c6604af81ea89758
|
|
| MD5 |
fca4964d3de44232ee679ce182c1aa33
|
|
| BLAKE2b-256 |
7e6f392902e48b19440d0ecbfc7f64f75769794162143050694a1d276d4c92b2
|
File details
Details for the file pyncette-1.1.0-py3-none-any.whl.
File metadata
- Download URL: pyncette-1.1.0-py3-none-any.whl
- Upload date:
- Size: 48.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84888d7fb67fc82f78a4969c495af643533f9525a9adec13e2b2b9dd32cc0490
|
|
| MD5 |
02ea2525868720e9a8cbd68bd6a54fbe
|
|
| BLAKE2b-256 |
02f90bdd4bbc959a05b6fe81f80db53202a43578e88af6689a4ea88cc730a6ab
|