Registry / workflow / futurist

futurist

JSON →
library3.3.0pypypi✓ verified 89d ago

Futurist is a Python library from OpenStack that provides useful additions to `concurrent.futures`, aiming to offer enhanced transparency in asynchronous work execution. It includes features like statistics gathering for executors, an eventlet executor, a synchronous executor, and more. Currently at version 3.3.0, it is actively maintained with a regular release cadence.

pip install futurist
INSTALL
IMPORT
SIG · FUTURIST
F
futurist
workflowpythonv3.3.0
Install
2.0s avg
Import
331ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v3.3.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.353s · 19MB
glibc
py 3.10–3.920 runs
installs and imports cleanly · install 2.0s · import 0.309s · 20MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

ThreadPoolExecutor
✓ from futurist import ThreadPoolExecutor
A primary executor for concurrent operations, extending concurrent.futures.ThreadPoolExecutor with added features like statistics.
ProcessPoolExecutor
✓ from futurist import ProcessPoolExecutor
An executor for concurrent operations using processes, extending concurrent.futures.ProcessPoolExecutor.
ExecutorStatistics
✓ from futurist.ext.futures import ExecutorStatistics
Provides statistics about tasks submitted and executed by a Futurist executor. Accessible via the 'statistics' property of executors.

This quickstart demonstrates how to use `futurist.ThreadPoolExecutor` to run tasks concurrently and collect execution statistics. It submits multiple tasks, waits for their completion, retrieves results, and then displays the executor's performance metrics.

import time from futurist import ThreadPoolExecutor def my_task(value): """A simple task to demonstrate execution and statistics.""" time.sleep(0.01) # Simulate some work return value * 2 if __name__ == "__main__": # Initialize ThreadPoolExecutor with a maximum of 2 workers with ThreadPoolExecutor(max_workers=2) as executor: print("Submitting tasks...") # Submit 5 tasks to the executor futures = [executor.submit(my_task, i) for i in range(5)] # Retrieve results from completed futures results = [f.result() for f in futures] print(f"Results: {results}") # Access and print execution statistics stats = executor.statistics print(f"Executed tasks: {stats.executed}") print(f"Failed tasks: {stats.failures}") print(f"Cancelled tasks: {stats.cancelled}") print(f"Total runtime: {stats.runtime:.4f}s")
Debug
Known issues
gotchaDo not confuse `futurist` (from OpenStack, extending `concurrent.futures`) with `python-future` (a compatibility library for Python 2/3). They serve entirely different purposes, and their usage patterns are distinct. Searching for 'futurist quickstart' may sometimes lead to `python-future` documentation, which is incorrect for this library.
fix
Always verify you are consulting the official OpenStack `futurist` documentation, typically found at `docs.openstack.org/futurist/` or the `openstack/futurist` GitHub repository.
affects: All versions
gotchaThe `futurist.ThreadPoolExecutor` (like `concurrent.futures.ThreadPoolExecutor`) does not shrink its thread pool once it has expanded. The pool will eventually reach its `max_workers` capacity and remain at that size for its lifetime, which can lead to higher memory consumption if many temporary workers are created.
fix
If dynamic pool sizing is required, consider `futurist.DynamicThreadPoolExecutor` (if available and suitable for your version) or manage thread pool lifecycles explicitly. For applications with highly variable workloads, be mindful of `max_workers` setting.
affects: All versions
gotchaWhen using `futurist.ProcessPoolExecutor`, be aware of limitations inherited from `concurrent.futures.ProcessPoolExecutor`, particularly on Windows. Processes cannot be spawned directly if a main module has importable code (e.g., global statements outside of an `if __name__ == '__main__':` block).
fix
Ensure that the code which creates and uses the `ProcessPoolExecutor` (and any functions it executes) is protected by `if __name__ == '__main__':` guards, especially on Windows.
affects: All versions
Errors
Common errors & fixes
eventlet hangs when using futures.ProcessPoolExecutor
Using `eventlet.monkey_patch()` in combination with `concurrent.futures.ProcessPoolExecutor` (or `futurist`'s `ProcessPoolExecutor` which inherits from it) can lead to deadlocks or hanging processes due to conflicts in how they manage concurrency and I/O.
fix
Avoid using `eventlet.monkey_patch()` when working with `ProcessPoolExecutor`. If eventlet is required, consider using `futurist.GreenThreadPoolExecutor` (if your tasks are I/O bound and compatible) or carefully manage when and what parts of eventlet are monkey-patched, or consider migrating to native Python threading/asyncio where possible, as eventlet support in `futurist` is being deprecated for some components.
ThreadPoolExecutor doesn't print errors
Exceptions raised within tasks submitted to `ThreadPoolExecutor` (and thus `futurist`'s executors) are 'swallowed' by default and stored within the `Future` object; they are not automatically re-raised in the main thread unless `future.result()` or `future.exception()` is explicitly called on the completed future.
fix
Always retrieve the result of a submitted `Future` object using `future.result()` within a `try-except` block, or call `future.exception()` to check for and handle any exceptions that occurred in the worker thread. Iterate over futures using `concurrent.futures.as_completed` for robust error handling.
TypeError: cannot unpack non-iterable Future object
This error occurs when attempting to iterate directly over a `Future` object returned by `executor.submit()`. A `Future` object is not an iterable; it's a proxy for the eventual result of an asynchronous operation.
fix
To get the result of a `Future` object, call its `.result()` method. If you need to process results as they complete from multiple futures, use `concurrent.futures.as_completed()`.
ModuleNotFoundError: No module named 'futurist'
The `futurist` library is not installed in your current Python environment or the Python interpreter cannot find it.
fix
Install the `futurist` library using pip: `pip install futurist`. Ensure you are running your code with the same Python interpreter where the library was installed.
TypeError: 'module' object is not callable (e.g., futurist.ThreadPoolExecutor())
This error often happens when you try to call a module directly as if it were a class or function. For example, if you import `futurist` and then try `futurist.ThreadPoolExecutor()`, but `ThreadPoolExecutor` is a class nested within `futurist`, you need to import it specifically.
fix
Import the specific executor class directly from the `futurist` library, for example: `from futurist import ThreadPoolExecutor`. Then you can instantiate it as `executor = ThreadPoolExecutor()`. Check the `futurist` documentation for the correct import path of the specific class you intend to use.
Upgrade
Version history
3.3.0latest on PyPI · released Mar 24, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
13 hits · last 30 days
node
12
OpenAI (training)
1
Resources
futurist — pip install futurist · libregistry