Skip to main content

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 Heap class 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 native async/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_instances property 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), and schedq.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 logging module (via NullHandler), 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

  1. Zero Blocking: Thread-safe execution using thread pools (run_in_executor) to prevent synchronous operations from starving the main event loop.
  2. Optional Dependencies: Heavier features (such as databases for persistence) must be pluggable and optional to keep the core engine lightweight at all times.
  3. Developer Experience (DX) First: Concurrency and scheduling complexity should always remain hidden under the engine's hood.

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

schedq-0.0.3.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

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

schedq-0.0.3-py3-none-any.whl (6.1 kB view details)

Uploaded Python 3

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

Hashes for schedq-0.0.3.tar.gz
Algorithm Hash digest
SHA256 925da252e1cd9b5343c90455ecd1585147b7d60197e9fac20f300f0bb341efdf
MD5 b8c4e91a0489175cee952f08add678ee
BLAKE2b-256 23b9baec8f5ef528876c228fd1b5bfb5f84ba545e5c11cc38e121503065a0d46

See more details on using hashes here.

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

Hashes for schedq-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3d9ba88d0d9e9f2745621b3c4c8e721ba3ea5772a251641cdbba468875cf728e
MD5 07635ebc05b52e3da907c91b60ccb803
BLAKE2b-256 2e2492d285c3f7b282291cfe299ccdc49b3b9c1c419f40ee2241a74c9e8bbe9b

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