Overview

Date: 2026-05-11

Time: 15:44

Overview

This is an example script demonstrating FTL2's real-time event streaming system. It shows how modules can emit progress and log events to stderr during execution, and how calling code can consume those events via callbacks or post-execution from the result object. The file serves as both documentation and runnable reference for five streaming patterns: basic callbacks, Rich progress bars, simple text display, concurrent multi-task tracking, and post-hoc event access.

Usage Patterns

Run the full example suite:


uv run python example_streaming.py

Basic callback pattern — pass a function to event_callback:


result = await execute_local_streaming(
    module_path,
    {"steps": 5},
    event_callback=on_event,
)

Rich progress bar — use EventProgressDisplay as a context manager:


display = EventProgressDisplay()
with display:
    result = await execute_local_streaming(
        module_path, params, event_callback=display.handle_event,
    )

Concurrent tasks with per-task progress — use display.makecallback(taskid):


display = EventProgressDisplay()
async def run_task(task_id, task_name, duration):
    callback = display.make_callback(task_id)
    return await execute_local_streaming(module_path, params, event_callback=callback)

with display:
    results = await asyncio.gather(
        run_task("download", "Downloading package", 0.8),
        run_task("extract", "Extracting files", 1.2),
    )

No callback — events are still captured on result.events:


result = await execute_local_streaming(module_path, {})
for event in result.events:
    print(event)

API and Configuration

Module-side event protocol: Modules emit JSON objects to stderr, one per line. Two event types are shown:

Module input arrives on stdin as JSON with params under ANSIBLEMODULEARGS. Final result is printed to stdout as JSON.

Executor functions:

Display classes:

Key Behaviors

Relationships