All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Major Feature: Full compatibility with Celery workers through Celery Protocol v2 support
AioTasks can now seamlessly interoperate with Celery, enabling:
- FastAPI + Celery: Use AioTasks in your FastAPI app, process tasks with existing Celery workers
- Gradual Migration: Migrate from Celery to AioTasks incrementally with zero downtime
- Mixed Deployments: Run both Celery and AioTasks workers processing the same queue
- Best of Both Worlds: Use Celery for CPU tasks, AioTasks for async I/O tasks
Python API:
# Enable Celery compatibility
app = AioTasks(
'myapp',
broker='redis://localhost:6379/0',
celery_compat=True, # ✨ Sends/receives Celery Protocol v2 messages
)
@app.task()
async def send_email(to: str, subject: str):
# This task can be processed by BOTH AioTasks and Celery workers!
return {"status": "sent", "to": to}
# Queue the task - sent in Celery format
await send_email.delay("user@example.com", "Hello")Celery Worker (processes tasks sent by AioTasks):
from celery import Celery
app = Celery('myapp', broker='redis://localhost:6379/0')
@app.task(name='send_email')
def send_email(to: str, subject: str):
# Celery worker processes tasks sent by AioTasks!
return {"status": "sent", "to": to}Key Features:
- ✅ Full Celery Protocol v2 support: properties, headers, body
- ✅ Auto-detection: Workers auto-detect and process both Celery and AioTasks formats
- ✅ UUID4 task IDs: Celery-compatible task ID generation
- ✅ JSON serialization: Celery default format (also supports msgpack)
- ✅ No code changes: Existing Celery workers work without modifications
- ✅ Backward compatible: Default is AioTasks native format (celery_compat=False)
Implementation:
- New module:
aiotasks/celery_compat.pyserialize_celery_message()- Create Celery v2 message structuredeserialize_celery_message()- Parse Celery v2 messagesencode_celery_task()- Full message encoding for brokerdecode_celery_task()- Full message decoding from brokeris_celery_message()- Auto-detect message formatgenerate_task_id()- UUID4 generation
- Updated
AsyncTaskDelayBase: Auto-detection of message format - Updated
AsyncWaitContextManager: Dual-format message building - All backends support
celery_compatparameter
Documentation:
- Comprehensive guide:
docs/celery_interoperability.md - Complete working example with Docker Compose:
examples_new/celery_interop/- FastAPI producer using AioTasks
- Celery worker processing tasks
- AioTasks worker (alternative)
- Docker Compose stack with Redis and Flower
Tests:
- 29 unit tests covering all serialization/deserialization scenarios
- 8 integration tests verifying interoperability
- Round-trip tests (encode → decode)
- Format detection tests
Use Cases:
- Gradual Migration: Migrate from Celery to AioTasks without downtime
- FastAPI + Legacy Workers: Modern async API with existing Celery infrastructure
- Mixed Worker Pools: CPU tasks → Celery, I/O tasks → AioTasks
- Multi-Language: Share tasks between Python, Node.js, etc. (via Celery protocol)
Major Feature: Support for thread and process pools (Celery-like pool types)
AioTasks now supports multiple execution pool types, enabling you to choose the best execution strategy for your workload:
asyncpool (default): asyncio coroutines - best for I/O-bound async tasksthreadpool: ThreadPoolExecutor - best for blocking I/O and sync librariesprocesspool: ProcessPoolExecutor - best for CPU-intensive tasks (bypasses GIL)
Python API:
# Async pool (default) - I/O-bound async tasks
app = AioTasks('myapp', broker='redis://localhost', pool='async')
@app.task()
async def fetch_data(url: str):
await asyncio.sleep(1)
return data
# Thread pool - blocking I/O, sync libraries
app = AioTasks('myapp', broker='redis://localhost', pool='thread', concurrency=20)
@app.task()
def blocking_io(file_path: str):
import time
time.sleep(1) # Blocking call OK in thread pool
return result
# Process pool - CPU-intensive tasks
app = AioTasks('myapp', broker='redis://localhost', pool='process', concurrency=4)
@app.task()
def cpu_intensive(n: int):
return sum(i*i for i in range(n)) # True parallel executionCLI Support:
# Async pool (default)
aiotasks -A app worker -c 10
# Thread pool for blocking tasks
aiotasks -A app worker --pool=thread -c 20
# Process pool for CPU-intensive tasks
aiotasks -A app worker --pool=process -c 4Why This Matters:
- ✅ CPU-Intensive Tasks: Process pool bypasses the GIL for true parallel execution
- ✅ Legacy Code: Thread pool allows using sync functions (def) instead of requiring async def
- ✅ Blocking Libraries: Thread pool handles blocking I/O without blocking the event loop
- ✅ Celery Compatibility: Similar to Celery's
--poolparameter (prefork, threads, solo)
Implementation Details:
- Automatic executor creation (ThreadPoolExecutor / ProcessPoolExecutor)
- Seamless integration with existing retry logic and ACK/NACK
- Proper resource cleanup (executor shutdown on worker stop)
- Full backward compatibility (async pool is default)
Examples:
- New example:
examples_new/pool_types_example.py - Demonstrates all three pool types
- Shows appropriate use cases for each
AsyncTaskDelayBase.__init__(): Addedpoolandcelery_compatparametersAsyncWaitContextManager.__init__(): Addedcelery_compatparameter (5th positional arg)AioTasks.__init__(): Addedpoolandcelery_compatparametersbuild_manager(): Addedpoolandcelery_compatparameters- All backend classes (Memory, Redis, AMQP, ZMQ): Added
poolandcelery_compatparameter support AsyncTaskDelayMemory,AsyncTaskDelayRedis,AsyncTaskDelayAMQP,AsyncTaskDelayZMQ: Updated to passpoolandcelery_compatto parent- Worker CLI: Added
-P/--poolparameter - Worker model: Added
poolfield with validation
- Pool type validation: Only accepts "async", "thread", or "process"
- Thread pool: Uses
asyncio.run_in_executor()with ThreadPoolExecutor - Process pool: Uses
asyncio.run_in_executor()with ProcessPoolExecutor - Async pool: Direct coroutine execution with
asyncio.create_task()(existing behavior) - Function validation:
- async pool: Requires
async deffunctions - thread/process pools: Accepts both
defandasync def(with warning for async def)
- async pool: Requires
- Python 3.12+ Required: Updated minimum Python version from 3.11 to 3.12
- Full Installation by Default:
pip install aiotasksnow installs ALL features (Redis, AMQP, ZeroMQ, FastAPI, ujson, uvloop)
- Simplified Installation: Single command installs everything
pip install aiotasksnow includes all brokers (Redis, AMQP, ZeroMQ)- FastAPI integration included by default
- Performance optimizations (uvloop, ujson) included by default
- No more optional dependencies - everything is batteries-included!
- Legacy
[all]extra kept for compatibility (now empty)
- Requires Python >=3.12 (was >=3.11)
- Updated all documentation to reference Python 3.12+
- Updated CI/CD workflows to use Python 3.12
- Updated tooling configuration (ruff, mypy, pylint) for Python 3.12
- Removed Python 3.11 from test matrix
- Test matrix now: Python 3.12, 3.13 on Ubuntu, macOS, Windows
- Concurrency Control: Only one publish workflow can run at a time
- Previous publish runs are automatically canceled when a new one starts
- Prevents conflicting releases and race conditions
- Updated README.md: Simplified installation section
- Updated all examples: Changed
aiotasks[...]toaiotasks - Updated FastAPI integration guide
- Updated 10+ documentation and example files
Simpler for Users: No need to figure out which extras to install - everything works out of the box
Better Developer Experience: Install once, use all features
Production Ready: All production-critical dependencies (Redis, uvloop, etc.) included by default
Modern Python: Take advantage of Python 3.12+ features (type aliases, improved pattern matching, etc.)
Installation:
# Before (v2.1.0)
pip install aiotasks[redis,fastapi]
# After (v2.2.0) - everything included!
pip install aiotasksPython Version:
- Ensure you're using Python 3.12 or higher
- Update your project's
requires-pythonif needed
Dependencies:
- All optional dependencies are now included
- Remove any
aiotasks[...]references from requirements.txt - Simply use
aiotaskseverywhere
- Broker-Specific Installation: Optional dependencies by broker type for leaner installations
pip install aiotasks[redis]- Redis backend with hiredis optimizationpip install aiotasks[amqp]- RabbitMQ/AMQP backend (aio-pika)pip install aiotasks[zeromq]- ZeroMQ backend (pyzmq)pip install aiotasks[fastapi]- FastAPI + uvicorn integrationpip install aiotasks[performance]- ujson for faster JSON serializationpip install aiotasks[all]- All features and backends included
- uvloop by Default: High-performance event loop (uvloop) now included in base installation for improved performance
-
Comprehensive FastAPI Integration Guide (
docs/examples/fastapi.md, ~500 lines)- Quick start with step-by-step instructions
- Three architecture patterns with pros/cons:
- Pattern 1: Separate workers (production-recommended)
- Pattern 2: In-process with threading (development)
- Pattern 3: Hybrid approach (quick + heavy tasks)
- Advanced examples: error handling, priority queues, task chaining, result retrieval
- Production configuration best practices
- Docker Compose deployment example
- Performance tuning guidelines
- Comprehensive troubleshooting section
- Monitoring and health checks
-
Enhanced Installation Documentation
- Detailed comparison table showing what each installation option includes
- Clear broker selection guide
- Performance optimization recommendations
- Memory backend vs Redis vs RabbitMQ vs ZeroMQ comparison
- Complete FastAPI Integration Examples (
examples_new/fastapi/)simple_integration.py: Recommended pattern - API queues tasks, workers run separatelysimple_integration_threaded.py: Development pattern using threading.Thread for in-process workersproduction_app.py: Production-ready app with:- Priority queues (high, normal, low)
- Pydantic models for validation
- Environment-based configuration
- Health checks and metrics endpoints
- Comprehensive logging
docker-compose.yml: Complete production deployment with:- Redis broker
- FastAPI API (4 workers)
- Separate task workers by priority (high: 2×20, normal: 3×10, low: 1×5)
- Redis Commander for monitoring
Dockerfile: Production-ready container with security best practicesrequirements.txt: Example dependenciesREADME.md: Comprehensive guide (400+ lines) with:- Architecture diagrams
- Comparison of all patterns
- Configuration examples
- Troubleshooting guide
- Performance tips
- Enhanced Publish Workflow (
.github/workflows/publish.yml)- Manual trigger with explicit inputs:
version: Version to publish (e.g., 2.1.0)tag: Git tag to create (e.g., v2.1.0)test_pypi: Optional TestPyPI publishing
- Automated version management:
- Updates
pyproject.tomlwith specified version - Commits version bump
- Creates and pushes git tag
- Updates
- Multi-stage pipeline:
- Update version and create tag
- Build distribution from tag
- Publish to PyPI (production) or TestPyPI (testing)
- Create GitHub Release automatically
- Improved safety with separate environments for PyPI and TestPyPI
- Manual trigger with explicit inputs:
-
README.md: Restructured installation section
- Added "Choose Your Broker" subsection
- Installation options table with feature matrix
- Updated FastAPI integration example to show recommended pattern (separate workers)
- Added alternative threading pattern for development
- Clear warnings about production vs development patterns
-
Documentation Navigation: Added "FastAPI Integration" to mkdocs.yml examples section
- FastAPI Integration Anti-Pattern: Removed and corrected incorrect worker initialization examples
- Problem: Previous examples incorrectly called
tasks.run()directly in@api.on_event("startup")async handlers - Why it's wrong:
tasks.run()manages the event loop and blocks, causing conflicts when called in async context - Solution:
- Recommended: Run workers in separate processes (production pattern)
- Alternative: Use
threading.Threadfor in-process workers (development only)
- Files corrected:
README.md: Updated FastAPI exampledocs/examples/fastapi.md: Added clear warnings and correct patternsexamples_new/fastapi/simple_integration.py: Removed startup handlers, API only queues tasksexamples_new/fastapi/simple_integration_threaded.py: NEW - Shows correct threading patternexamples_new/fastapi/README.md: Updated with pattern comparison
- Problem: Previous examples incorrectly called
-
README.md:
- Broker-specific installation table with feature matrix
- Enhanced FastAPI integration section with:
- Recommended pattern (separate workers)
- Alternative pattern (threading for development)
- Clear execution instructions for both patterns
- Visual separation between development and production approaches
-
docs/examples/fastapi.md:
- Warning banners about not calling
.run()in async context - Three complete architecture patterns with code examples
- Advanced integration examples
- Docker Compose production setup
- Performance optimization guide
- Troubleshooting common issues
- Warning banners about not calling
-
examples_new/fastapi/README.md:
- Comparison table of all integration approaches
- ASCII architecture diagrams for each pattern
- Step-by-step setup instructions
- Configuration best practices (development vs production)
- Docker deployment guide
- Monitoring and health check examples
- Celery-Style API: New AioTasks class with familiar Celery-like interface
- Modern Python 3.11+ Support: Pattern matching, StrEnum, modern type hints
- Retry Logic: Automatic retry with exponential backoff using tenacity
- ACK/NACK Support: Task acknowledgment for reliable processing
- TTL (Time-To-Live): Configurable task expiration
- Comprehensive Testing: Modern pytest test suite (40%+ coverage baseline)
- CI/CD Pipeline: GitHub Actions workflows for testing and deployment
- Documentation: MkDocs-based docs with multi-language support
- Pydantic Migration: Migrated from deprecated booby to pydantic
- Python Requirement: Now requires Python >=3.12
- msgpack Compatibility: Updated for msgpack 1.0+
- Circular import issues in actions/ modules
- Event loop handling in async contexts