Lightweight, high-performance asynchronous task scheduling engine with no external dependencies.
Project description
schedq
schedq is an asynchronous task scheduling and workflow orchestration engine in Python designed to be extremely lightweight, performant, and dependency-free. Relying exclusively on native language primitives and high-performance custom data structures, it eliminates the need for heavy infrastructure in concurrent scenarios.
Current Features (What it already does)
- Custom Optimized Heap: Internal organization powered by a custom-built, pointer-aware
Heapclass using__slots__and an O(1) index dictionary lookup. Evaluates only the root and sleeps for the exact time remaining, resulting in 0% idle CPU usage. - Asynchronous & Non-Blocking Concurrency: Built on top of
asyncio. Long-running tasks and flows are managed cleanly without hijacking the main thread, enabling seamless integration with web frameworks. - Code-as-Workflows (DAGs via
@step): Native support for building sequential or parallel pipelines using Python's nativeasync/await. Steps encapsulate retries, backoffs, and error handling seamlessly. - Dynamic Arguments Support: Full flexibility to pass custom positional (
*args) and keyword (**kwargs) parameters directly into your workflows. - Fault Tolerance & Circuit Breaker: Automated Exponential Backoff retry policies with increasing delays, coupled with an automatic Circuit Breaker that pauses unstable flows after definitive failures to protect the system.
- Concurrency Control (Instance Throttling): Built-in
max_instancesproperty to prevent overlapping executions by skipping or throttling heavy jobs. - Dynamic Control (Runtime Management): Programmatic API with fast in-memory access methods (O(1)) to manipulate flows in real time, such as
schedq.pause(tid),schedq.resume(tid), andschedq.invoke(tid)(forces immediate execution). - Tracking & Logs (Observability): Native separation between TID (Task/Flow ID) and EID (Execution ID). Silent log emission using Python's native
loggingmodule (viaNullHandler), which automatically adapts to the host application's configurations.
How to Use
FastAPI Integration with Workflows (Recommended for Web)
Here is how you can set up a resilient ETL pipeline using @schedq.flow and @schedq.step inside a FastAPI application lifecycle (lifespan)[cite: 6].
import asyncio
import datetime
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI
from schedq import Schedq
# Configure logging for schedq
logger = logging.getLogger("schedq")
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s"))
logger.addHandler(handler)
schedq = Schedq()
@asynccontextmanager
async def lifespan(app: FastAPI):
schedq.start()
app.state.resource = schedq
yield
schedq.stop()
app.state.resource = None
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def root():
return {"flows": list(app.state.resource.taskmap.keys())}
# 1. Resilient step with built-in retries and exponential backoff
@schedq.step(name="External API Call", maxretries=2, retrydelay=1)
async def fetch_data(endpoint: str):
await asyncio.sleep(1)
return {"status": "success", "data": [1, 2, 3]}
# 2. Main flow scheduled in O(1) by the core engine
@schedq.flow(
interval=datetime.timedelta(seconds=5),
name="ETL Pipeline",
maxinstances=1,
args=("[https://api.schedq.dev](https://api.schedq.dev)",)
)
async def pipeline(tid: str, eid: str, name: str, url: str):
print(f"Running pipeline with target: {url}")
result = await fetch_data(url)
print(f"Pipeline finished with result: {result}")
Design Principles
- Zero Blocking: Thread-safe execution using thread pools (
run_in_executor) to prevent synchronous operations from starving the main event loop. - Optional Dependencies: Heavier features (such as databases for persistence) must be pluggable and optional to keep the core engine lightweight at all times.
- Developer Experience (DX) First: Concurrency and scheduling complexity should always remain hidden under the engine's hood.
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 schedq-0.0.3.tar.gz.
File metadata
- Download URL: schedq-0.0.3.tar.gz
- Upload date:
- Size: 6.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
925da252e1cd9b5343c90455ecd1585147b7d60197e9fac20f300f0bb341efdf
|
|
| MD5 |
b8c4e91a0489175cee952f08add678ee
|
|
| BLAKE2b-256 |
23b9baec8f5ef528876c228fd1b5bfb5f84ba545e5c11cc38e121503065a0d46
|
File details
Details for the file schedq-0.0.3-py3-none-any.whl.
File metadata
- Download URL: schedq-0.0.3-py3-none-any.whl
- Upload date:
- Size: 6.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d9ba88d0d9e9f2745621b3c4c8e721ba3ea5772a251641cdbba468875cf728e
|
|
| MD5 |
07635ebc05b52e3da907c91b60ccb803
|
|
| BLAKE2b-256 |
2e2492d285c3f7b282291cfe299ccdc49b3b9c1c419f40ee2241a74c9e8bbe9b
|