Skip to main content

⚡ NeoTask

Distributed Task Scheduling System / 轻量级 Python 异步分布式任务队列管理器

Python License

PyPI Downloads GitHub Stars

中文 • Website • Documentation • PyPI

🚀 Lightweight & Async: Pure Python task queue manager designed for time-consuming jobs (AI generation, video processing, data scraping, etc.)
📦 No External Services: No extra deployment required (no Redis/PostgreSQL needed). Ships with two base dependencies
⏰ Flexible Scheduling: Native support for scheduled, periodic (cron-like), and delayed tasks
⚡ Quick Integration: pip install neotask + few lines of configuration


💡 Why NeoTask?

NeoTask is designed to solve complex task orchestration, async queueing, and priority management for modern distributed systems and AI multi-agent pipelines.

Pain Point NeoTask Solution
Task blockage under heavy concurrency Priority queueing & task worker pool isolation
Unreliable long-running tasks Automatic state persistence, health check & retry mechanism
Complex SDK setup Lightweight Pythonic interface with zero friction

Features

  • No External Services - Pure Python implementation, no Redis/PostgreSQL required
  • Immediate Tasks - Supports priority scheduling, high-priority tasks execute first
  • Scheduled Tasks - Supports delayed execution, fixed intervals, and Cron expressions
  • Asynchronous Concurrency - Based on asyncio, multi-worker concurrent processing
  • Automatic Retry - Failed tasks automatically retry with configurable attempts
  • Persistence - Multiple storage backends: Memory/SQLite/Redis
  • Distributed Support - Redis shared queue, distributed lock, node heartbeat, and failed-task reclaim
  • Event Callbacks - Supports task lifecycle event listeners

Use Cases

Scenario Description Recommended Configuration Entry Point
AI Text-to-Image/Video Generation Queue time-consuming tasks to avoid blocking main flow worker_concurrency=3 TaskPool
Batch File Processing Batch operations like transcoding, compression, uploading worker_concurrency=10 TaskPool
Web Scraping Scheduling Distributed scraping to prevent being blocked storage_type="redis" TaskPool
Scheduled Report Sending Send daily reports at 9 AM cron="0 9 * * *" TaskScheduler
Delayed Notifications Send reminders 5 minutes after user action delay_seconds=300 TaskScheduler
Heartbeat Detection Check service health status every 30 seconds interval_seconds=30 TaskScheduler
Background Data Analysis Execute data aggregation tasks at night cron="0 2 * * *" TaskScheduler

Architecture & Evolution

graph TB
    subgraph User["User Application Layer"]
        APP[User Code]
    end
    
    subgraph NeoTask["NeoTask Core"]
        TP[TaskPool<br/>Immediate Task Entry]
        TS[TaskScheduler<br/>Scheduled Task Entry]
        
        subgraph Core["Shared Core Components"]
            LM[LifecycleManager<br/>Task Lifecycle Management]
            QS[QueueScheduler<br/>Priority + Delayed Queue]
            WP[WorkerPool<br/>Worker Pool/Concurrency Control]
            FM[FutureManager<br/>Async Wait/Result Callback]
        end
        
        subgraph Internal["Internal Components"]
            EB[EventBus<br/>Event Bus]
            MC[MetricsCollector<br/>Metrics Collection]
            LF[LockFactory<br/>Distributed Lock]
        end
        
        EX[TaskExecutor<br/>User Business Logic]
    end
    
    subgraph Storage["Storage Layer"]
        MEM[MemoryStorage]
        SQLITE[(SQLiteStorage)]
        REDIS[(RedisStorage)]
    end
    
    APP -->|Immediate Task| TP
    APP -->|Scheduled Task| TS
    TS -->|Delegates| TP
    TP --> LM
    TP --> QS
    TP --> WP
    TP --> FM
    
    LM --> MEM
    LM --> SQLITE
    LM --> REDIS
    
    WP --> EX
    WP --> EB
    WP --> MC
    WP --> LF

Development Roadmap

timeline
    title NeoTask Architecture Evolution Roadmap
    
    section v0.1
        Basic Task Pool : Local Memory Queue
                        : Async Execution Engine
                        : Memory/SQLite Storage
                        
    section v0.2
        Observability : Event Bus
                      : Metrics Collection
                      : Health Check
                      
    section v0.3
        Scheduled Tasks : Delayed Queue/Time Wheel
                        : Periodic Tasks
                        : Cron Expression
                        
    section v0.4
        Distributed Base : Redis Shared Queue
                         : Distributed Lock
                         
    section v0.5
        Performance Optimization : Prefetch Mechanism
                                : Batch Operations
                                : Connection Pool

    section v1.0
        High Availability : Watchdog Renewal
                          : Timeout Detection
                          : Automatic Fault Recovery

    section v1.5
        Task Orchestration : DAG Workflow
                           : Conditional Branch
                           : Parallel Execution

    section v2.0
        Enterprise Features : Independent Web UI
                            : Multi-Tenancy Isolation
                            : Prometheus Integration

Quick Start

Installation

Requirements: Python ≥ 3.8. The base package depends on aiosqlite (SQLite storage) and croniter (Cron expressions); Redis, psutil, and the Web UI are optional extras.

# Basic installation
pip install neotask

# With Redis distributed support
pip install neotask[redis]

# Full installation
pip install neotask[full]

Immediate Tasks (TaskPool)

from neotask import TaskPool

async def process(data):
    return {"result": "done", "data": data}

# Create task pool
pool = TaskPool(executor=process)

# Submit task
task_id = pool.submit({"id": 123})

# Wait for result
result = pool.wait_for_result(task_id)

pool.shutdown()

Scheduled Tasks (TaskScheduler)

from neotask import TaskScheduler

scheduler = TaskScheduler(executor=process)

# Execute after 60 seconds delay
scheduler.submit_delayed({"id": 123}, delay_seconds=60)

# Execute every 5 minutes
scheduler.submit_interval({"id": 123}, interval_seconds=300)

# Execute daily at 9 AM
scheduler.submit_cron({"id": 123}, "0 9 * * *")

scheduler.shutdown()

Using Context Manager

with TaskPool(executor=process) as pool:
    task_id = pool.submit({"id": 123})
    result = pool.wait_for_result(task_id)

Using Event Callbacks

from neotask import TaskPool

async def on_task_created(event):
    print(f"Task created: {event.task_id}")

async def on_task_completed(event):
    print(f"Task completed: {event.task_id}, Result: {event.data}")

async def on_task_failed(event):
    print(f"Task failed: {event.task_id}, Error: {event.data}")

pool = TaskPool(executor=my_executor)
pool.start()

# Register event callbacks
pool.on_created(on_task_created)
pool.on_completed(on_task_completed)
pool.on_failed(on_task_failed)

task_id = pool.submit({"test": "event"})
result = pool.wait_for_result(task_id)

API Reference

Method Description
pool.submit(data, priority=2, delay=0) Submit task
pool.wait_for_result(task_id, timeout=300) Wait for result
pool.get_status(task_id) Get status
pool.cancel(task_id) Cancel task
scheduler.submit_delayed(data, delay) Delayed task
scheduler.submit_interval(data, interval) Periodic task
scheduler.submit_cron(data, cron) Cron task

Detailed API documentation can be found here

Usage Notes

A few behaviors are easy to trip over, so they are documented explicitly:

  • get_result vs wait_for_result: wait_for_result(task_id) returns the executor's raw value, while get_result(task_id) returns a metadata wrapper dict {task_id, status, result, error, created_at, completed_at} — the real payload is under result.
  • Event keys: lifecycle event types are namespaced as task.created / task.started / task.completed / task.failed / task.cancelled / task.retry (not bare created). Prefer the pool.on_completed(...) helpers.
  • Graceful shutdown scope: shutdown(graceful=True) drains tasks that are already enqueued (pending + running) before returning. Unexpired delayed tasks and periodic/cron schedules are not fired during shutdown — cancel periodic schedules first (cancel_periodic) or use graceful=False for an immediate return.
  • Crash / restart recovery: auto-recovery re-runs tasks that were already enqueued (their ids live in the persisted queue). A record created only via create_pending_task() and never pushed through enqueue_task() is not part of the queue, so it will not auto-run after a restart — enqueue it explicitly.
  • Periodic task persistence: set SchedulerConfig(enable_persistence=True, storage_type="sqlite"|"redis") to persist interval / cron periodic tasks and auto-restore them after a restart; slots missed while down are handled by each task's missed_policy. With storage_type="memory" the store is in-process only and cannot survive a restart.
  • Minimum interval granularity: periodic tasks are driven by a scan loop with SchedulerConfig.scan_interval (default 1.0s). submit_interval with an interval smaller than scan_interval may skip fires; lower scan_interval or enable the time wheel (enable_time_wheel=True) for finer granularity.

Usage Notes

A few behaviors are easy to trip over, so they are documented explicitly:

  • get_result vs wait_for_result: wait_for_result(task_id) returns the executor's raw value, while get_result(task_id) returns a metadata wrapper dict {task_id, status, result, error, created_at, completed_at} — the real payload is under result.
  • Event keys: lifecycle event types are namespaced as task.created / task.started / task.completed / task.failed / task.cancelled / task.retry (not bare created). Prefer the pool.on_completed(...) helpers.
  • Graceful shutdown scope: shutdown(graceful=True) drains tasks that are already enqueued (pending + running) before returning. Unexpired delayed tasks and periodic/cron schedules are not fired during shutdown — cancel periodic schedules first (cancel_periodic) or use graceful=False for an immediate return.
  • Crash / restart recovery: auto-recovery re-runs tasks that were already enqueued (their ids live in the persisted queue). A record created only via create_pending_task() and never pushed through enqueue_task() is not part of the queue, so it will not auto-run after a restart — enqueue it explicitly.
  • Minimum interval granularity: periodic tasks are driven by a scan loop with SchedulerConfig.scan_interval (default 1.0s). submit_interval with an interval smaller than scan_interval may skip fires; lower scan_interval or enable the time wheel (enable_time_wheel=True) for finer granularity.

Configuration Example

from neotask import TaskPool, TaskPoolConfig

config = TaskPoolConfig(
    worker_concurrency=10,      # Number of concurrent workers
    max_retries=3,              # Number of retries
    storage_type="sqlite",      # Storage type
)

pool = TaskPool(executor=process, config=config)

Detailed usage examples can be found here

Contribution Guide

Setting Up Development Environment

# Clone repository
git clone https://github.com/neopen/neotask.git
cd neotask

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/

# View test coverage
pytest --cov=neotask tests/

# Run specific module tests
pytest tests/test_task_pool.py -v
pytest tests/test_task_scheduler.py -v

Contribution Workflow

Welcome to submit Issues and Pull Requests

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/amazing)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push branch (git push origin feature/amazing)
  5. Submit Pull Request

Code Style

Issue Reporting

  • Submit Issue: https://github.com/neopen/neotask/issues
  • Feature Suggestions: Use Enhancement label
  • Bug Reports: Use Bug label and provide reproduction steps
  • Security Vulnerabilities: Please send email directly to the author's email

License

MIT License © 2026 NeoPen


Acknowledgments

Thanks to all contributors and the open source community for their support.


Contact

Metadata

Release files for neotask 1.0.4

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

Source distribution (sdist)

Source distribution for neotask 1.0.4
File Size Uploaded
neotask-1.0.4.tar.gz 290.8 kB Details

Built distribution (wheel)

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

Total release size: 462.3 kB

Release files / neotask-1.0.4.tar.gz

Download URL neotask-1.0.4.tar.gz
Size 290.8 kB
Tags Source
SHA-256 checksum
How to use checksums
00972f57ad59bf9ce0b2462dabf8234f974cf9f1e6c0eadbc4f6c8a5818502ba
BLAKE2b-256 checksum
How to use checksums
d2abe5b86e48e5e8a42252e10d09c0b448f53dceabf235cc50782f8dcea5b0c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / neotask-1.0.4-py3-none-any.whl

Download URL neotask-1.0.4-py3-none-any.whl
Size 171.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4490a8dc9094e625ba6a1799ff3fa97a9ce815ed2bbe44eb99e278aca1eb3b93
BLAKE2b-256 checksum
How to use checksums
0b72d4fa0e830832ef7bbf24230e06839e241d08cf2589d2798c50af903c6ee8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

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