huey, a little task queue - lightweight task queue library for Python with asynchronous execution and comprehensive task management features
—
Multiple storage backend implementations with their specific configurations and capabilities for different deployment scenarios. Huey supports various storage backends to accommodate different infrastructure requirements and performance needs.
Redis-based storage backends offering high performance, persistence, and distributed capabilities.
class RedisHuey(Huey):
"""
Huey with Redis storage backend.
Storage parameters:
- host (str): Redis server host (default: 'localhost')
- port (int): Redis server port (default: 6379)
- db (int): Redis database number (default: 0)
- password (str): Redis password (optional)
- connection_pool: Custom Redis connection pool (optional)
- url (str): Redis URL (optional, overrides other connection params)
- client_name (str): Redis client name (optional)
- health_check_interval (int): Connection health check interval (default: 0)
"""
class RedisExpireHuey(RedisHuey):
"""
Redis storage with automatic result expiration.
Additional parameters:
- expire_time (int): Result expiration time in seconds (default: 86400)
"""
class PriorityRedisHuey(RedisHuey):
"""
Redis storage with priority queue support.
Features:
- Priority-based task ordering
- Higher priority tasks execute first
- Maintains FIFO order within same priority level
"""
class PriorityRedisExpireHuey(PriorityRedisHuey):
"""
Redis storage with both priority queues and result expiration.
Combines features of PriorityRedisHuey and RedisExpireHuey.
"""File-based SQLite storage for single-node deployments without external dependencies.
class SqliteHuey(Huey):
"""
Huey with SQLite storage backend.
Storage parameters:
- filename (str): SQLite database file path (default: 'huey.db')
- cache_mb (int): SQLite cache size in MB (default: 8)
- fsync (bool): Force filesystem sync (default: False)
- timeout (int): Database lock timeout in seconds (default: 60)
- strict_fifo (bool): Maintain strict FIFO ordering (default: False)
"""In-memory storage for development, testing, and immediate execution modes.
class MemoryHuey(Huey):
"""
Huey with in-memory storage backend.
Features:
- No persistence (data lost on restart)
- Very fast operations
- Suitable for testing and immediate mode
- Thread-safe operations
"""File-system based storage using directories and files for task and result storage.
class FileHuey(Huey):
"""
Huey with file-system storage backend.
Storage parameters:
- path (str): Base directory for storage (default: '/tmp/huey')
- levels (int): Directory nesting levels (default: 2)
- use_thread_lock (bool): Use thread locks (default: True)
"""Storage backend that discards all data, useful for testing and benchmarking.
class BlackHoleHuey(Huey):
"""
Huey with BlackHole storage backend.
Features:
- Discards all tasks and results
- No storage overhead
- Useful for performance testing
- Tasks appear to execute but do nothing
"""Base class for implementing custom storage backends.
class BaseStorage:
"""
Base storage interface for custom implementations.
Required methods to implement:
- enqueue(data, priority=None)
- dequeue()
- queue_size()
- enqueued_items(limit=None)
- flush_queue()
- add_to_schedule(data, timestamp)
- read_schedule(timestamp)
- scheduled_items(limit=None)
- schedule_size()
- flush_schedule()
- put_data(key, value)
- peek_data(key)
- pop_data(key)
- has_data_for_key(key)
- put_if_empty(key, value)
- delete_data(key)
- flush_all()
"""
blocking = False # Whether dequeue() blocks or polls
priority = True # Whether storage supports priority queuesfrom huey import RedisHuey
# Basic Redis connection
huey = RedisHuey('my-app', host='localhost', port=6379, db=0)
# Redis with authentication
huey = RedisHuey('my-app',
host='redis.example.com',
port=6379,
password='secret123',
db=1)
# Redis with URL
huey = RedisHuey('my-app', url='redis://user:pass@localhost:6379/0')
# Redis with connection pool
import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=0, max_connections=20)
huey = RedisHuey('my-app', connection_pool=pool)
# Redis with priority support
huey = PriorityRedisHuey('my-app', host='localhost')
@huey.task()
def normal_task():
return "Normal priority"
@huey.task(priority=10)
def high_priority_task():
return "High priority"
# High priority tasks execute first
normal_result = normal_task()
high_result = high_priority_task()from huey import SqliteHuey
# Basic SQLite storage
huey = SqliteHuey('my-app', filename='tasks.db')
# SQLite with performance tuning
huey = SqliteHuey('my-app',
filename='/var/data/huey.db',
cache_mb=64, # 64MB cache
fsync=True, # Force sync for durability
timeout=120, # 2 minute lock timeout
strict_fifo=True) # Maintain strict orderingfrom huey import FileHuey
# Basic file storage
huey = FileHuey('my-app', path='/var/huey_data')
# File storage with custom configuration
huey = FileHuey('my-app',
path='/tmp/huey_tasks',
levels=3, # 3 levels of subdirectories
use_thread_lock=True)from huey import MemoryHuey
# Memory storage for unit tests
def test_task_execution():
huey = MemoryHuey('test-app', immediate=True)
@huey.task()
def add_numbers(a, b):
return a + b
result = add_numbers(2, 3)
assert result() == 5
# Memory storage for development
huey = MemoryHuey('dev-app')
@huey.task()
def debug_task(data):
print(f"Processing: {data}")
return f"Processed: {data}"# Production: Redis for distributed systems
production_huey = RedisHuey('prod-app',
host='redis-cluster.example.com',
port=6379,
db=0)
# Development: SQLite for simplicity
dev_huey = SqliteHuey('dev-app', filename='dev.db')
# Testing: Memory for speed
test_huey = MemoryHuey('test-app', immediate=True)
# Benchmarking: BlackHole to test task overhead
benchmark_huey = BlackHoleHuey('benchmark-app')
# File storage for simple single-node deployments
simple_huey = FileHuey('simple-app', path='/opt/tasks')from huey.storage import BaseStorage
import sqlite3
import json
import time
class CustomSqliteStorage(BaseStorage):
def __init__(self, name, filename='custom.db'):
super().__init__(name)
self.filename = filename
self._initialize_db()
def _initialize_db(self):
conn = sqlite3.connect(self.filename)
conn.execute('''
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
data TEXT NOT NULL,
priority INTEGER DEFAULT 0,
created_at REAL NOT NULL
)
''')
conn.commit()
conn.close()
def enqueue(self, data, priority=None):
conn = sqlite3.connect(self.filename)
conn.execute(
'INSERT INTO tasks (data, priority, created_at) VALUES (?, ?, ?)',
(data.decode('utf-8'), priority or 0, time.time())
)
conn.commit()
conn.close()
def dequeue(self):
conn = sqlite3.connect(self.filename)
cursor = conn.execute('''
SELECT id, data FROM tasks
ORDER BY priority DESC, created_at ASC
LIMIT 1
''')
row = cursor.fetchone()
if row:
task_id, data = row
conn.execute('DELETE FROM tasks WHERE id = ?', (task_id,))
conn.commit()
conn.close()
return data.encode('utf-8')
conn.close()
return None
def queue_size(self):
conn = sqlite3.connect(self.filename)
cursor = conn.execute('SELECT COUNT(*) FROM tasks')
count = cursor.fetchone()[0]
conn.close()
return count
# Use custom storage
class CustomHuey(Huey):
def get_storage(self, **kwargs):
return CustomSqliteStorage(self.name, **kwargs)
huey = CustomHuey('custom-app', filename='custom_tasks.db')# Choose storage based on requirements:
# High throughput, distributed: Redis
if high_throughput and distributed:
huey = PriorityRedisHuey('app', host='redis-cluster')
# Simple single-node: SQLite
elif single_node and persistent:
huey = SqliteHuey('app', filename='tasks.db')
# Development/testing: Memory
elif development or testing:
huey = MemoryHuey('app', immediate=True)
# No external dependencies: File
elif no_dependencies:
huey = FileHuey('app', path='/var/huey')
# Performance testing: BlackHole
elif benchmarking:
huey = BlackHoleHuey('app')Install with Tessl CLI
npx tessl i tessl/pypi-huey