← Back to DevBytes

Building Web APIs with Huey: A Comprehensive Guide

Building Web APIs with Huey: A Comprehensive Guide

What is Huey?

Huey is a lightweight, multi-threaded task queue for Python. It is designed to be simple to set up and use, yet powerful enough for production workloads. Huey allows you to execute tasks asynchronously (in the background) and supports task scheduling, periodic tasks, retries, and result storage. It uses a lightweight backend (by default Redis) to store task metadata and results.

Unlike heavier task queues like Celery, Huey has a minimal footprint and a single-file core, making it ideal for small to medium-sized projects, microservices, and Web APIs where you need to offload time-consuming operations without introducing complex infrastructure.

Why Use Huey for Web APIs?

Web APIs often need to handle requests that involve slow or blocking operations: sending emails, processing uploaded files, generating reports, calling external services, or performing heavy computations. If these operations run synchronously inside the request handler, the API response time increases, and the server can become unresponsive under load.

Huey solves this by letting you:

Integrating Huey with a web framework like Flask, FastAPI, or Django is straightforward and keeps your API endpoints fast and responsive.

Setting Up Huey

First, install Huey and its Redis backend:

pip install huey[redis]

Huey can also work with filesystem or SQLite backends, but Redis is recommended for production.

Create a configuration module (e.g., huey_config.py) to define your Huey instance:

from huey import RedisHuey

# Redis connection details
huey = RedisHuey(
    'my_app',
    host='localhost',
    port=6379,
    db=0,
    result_store=True,    # store task results
    events=True,          # enable event broadcasting
    store_none=False      # don't store None results
)

This single huey object will be imported by both your web application and your worker process.

Integrating Huey with a Web API (Flask Example)

We'll build a simple Flask API that accepts a long-running task (simulating a report generation) and returns a task ID. The client can later poll for the result.

# tasks.py
from huey_config import huey

@huey.task()
def generate_report(user_id):
    # Simulate a time-consuming operation
    import time
    time.sleep(10)
    return f"Report for user {user_id} generated at {time.time()}"

# app.py
from flask import Flask, request, jsonify
from huey_config import huey
from tasks import generate_report

app = Flask(__name__)

@app.route('/report', methods=['POST'])
def create_report():
    user_id = request.json.get('user_id')
    if not user_id:
        return jsonify({'error': 'user_id required'}), 400

    # Enqueue the task – returns immediately
    task = generate_report(user_id)
    return jsonify({'task_id': task.id, 'status': 'queued'}), 202

@app.route('/report/<task_id>', methods=['GET'])
def get_report(task_id):
    # Retrieve the task result from Huey's result store
    task = huey.get_task(task_id)
    if task is None:
        return jsonify({'error': 'task not found'}), 404

    if task.result is not None:
        return jsonify({'status': 'completed', 'result': task.result})
    elif task.error:
        return jsonify({'status': 'failed', 'error': str(task.error)})
    else:
        return jsonify({'status': 'pending'}), 200

if __name__ == '__main__':
    app.run(debug=True)

Running Tasks Asynchronously

To process the enqueued tasks, you need to run the Huey consumer (worker). Open a terminal and start the worker:

python -m huey.consumer tasks.huey -w 2 -k process

Explanation:

The worker will listen for new tasks, execute them, and store results. You can also run the consumer in the background using a process manager like Supervisor or systemd.

Task Scheduling and Periodic Tasks

Huey supports @huey.periodic_task and @huey.scheduled_task decorators for recurring or one-off future tasks.

from huey_config import huey
from datetime import timedelta

# Run every 30 minutes
@huey.periodic_task(crontab(minute='*/30'))
def clean_expired_sessions():
    print("Cleaning expired sessions...")
    # Your cleanup logic here

# Run once after 5 seconds
@huey.task()
def send_welcome_email(user_email):
    print(f"Sending welcome email to {user_email}")

# In your API, schedule a future task
def schedule_welcome(user_email):
    send_welcome_email.schedule(args=(user_email,), delay=timedelta(seconds=5))

To enable periodic tasks, you must run the consumer with the --periodic flag:

python -m huey.consumer tasks.huey -w 2 -k process --periodic

Error Handling and Retries

Huey provides built-in retry support. Use the @huey.task(retries=3, retry_delay=10) decorator to automatically retry failed tasks.

@huey.task(retries=3, retry_delay=10)
def send_email(to, subject, body):
    # If this raises an exception, Huey will retry up to 3 times
    # with a 10-second delay between attempts.
    mailer.send(to, subject, body)

# In the API, you can also mark a task as failed manually
@huey.task()
def fragile_operation(data):
    try:
        # risky code
        pass
    except Exception as e:
        # Log and re-raise to trigger retry
        huey.logger.error(f"Task failed: {e}")
        raise

Best Practices

Conclusion

Huey provides a clean, minimalistic approach to adding asynchronous task processing to your Web APIs. Its simplicity, built-in scheduling, retry mechanism, and result store make it an excellent choice for projects that need background processing without the overhead of larger task queues. By integrating Huey with frameworks like Flask or FastAPI, you can keep your API endpoints fast and responsive while offloading heavy work to dedicated workers. Follow the best practices outlined here to ensure your tasks are reliable, maintainable, and production-ready. Whether you're sending emails, processing uploads, or generating reports, Huey gives you the power to build scalable, asynchronous Web APIs with minimal friction.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles