Flask-Threads

0.2.0 · active · verified Sat Apr 11

Flask-Threads is a helper library designed to simplify working with threads within Flask applications. It addresses the common challenge of maintaining the Flask application context (e.g., `flask.g`, `request`) when executing code in background threads or using concurrent futures, which are typically thread-local. The library ensures that thread-local proxies remain accessible, preventing `RuntimeError` exceptions that occur when trying to access context outside the main request thread. The current version is 0.2.0, released on May 20, 2025, with an infrequent release cadence, primarily focusing on Flask compatibility.

Warnings

Install

Imports

Quickstart

This example demonstrates how to use `AppContextThread` and `ThreadPoolWithAppContextExecutor` to run background tasks while retaining access to Flask's application context, specifically `flask.g`. The `user-id` is set in `flask.g` within the main request thread and then accessed correctly by the function running in a separate thread.

from flask import g, request, Flask
from flaskthreads import AppContextThread, ThreadPoolWithAppContextExecutor
import time

app = Flask('my_app')

def do_some_user_work_in_another_thread():
    # Accessing flask.g from a different thread, enabled by Flask-Threads
    user_id = g.user_id
    print(f"[Thread] User ID from g: {user_id}")
    time.sleep(1) # Simulate work
    return f"Processed user {user_id}"

@app.route('/user/thread')
def get_user_with_thread():
    g.user_id = request.headers.get('user-id', 'default_user_id_thread')
    print(f"[Main] Setting g.user_id: {g.user_id}")

    t = AppContextThread(target=do_some_user_work_in_another_thread)
    t.start()
    t.join() # Wait for the thread to complete
    return 'OK via AppContextThread'

@app.route('/user/executor')
def get_user_with_executor():
    g.user_id = request.headers.get('user-id', 'default_user_id_executor')
    print(f"[Main] Setting g.user_id: {g.user_id}")

    with ThreadPoolWithAppContextExecutor(max_workers=2) as pool:
        future = pool.submit(do_some_user_work_in_another_thread)
        result = future.result() # Wait for the future to complete
        print(f"[Main] Future result: {result}")
    return 'OK via ThreadPoolWithAppContextExecutor'

if __name__ == '__main__':
    # For demonstration, use a simple run. In production, use a WSGI server.
    # Set 'user-id' header (e.g., with curl -H 'user-id: 123' http://127.0.0.1:5000/user/thread)
    app.run(debug=True, use_reloader=False) # use_reloader=False to avoid double thread start in dev

view raw JSON →