Date: 2026-05-11
Time: 15:16
FTL2's event streaming system enables real-time progress reporting during module execution. Modules can emit progress, log, and data events that stream to callers, supporting use cases like progress bars for file transfers, live log output, multi-host tracking, and rich terminal UIs. Events work for both local and remote (SSH) execution and are always captured in results even without an explicit callback.
progress (percent/bytes tracking), log (leveled messages: info/warning/error), and data (raw stdout/stderr streams)result.events regardless of whether a callback is registeredEventProgressDisplay (Rich library, full-featured progress bars) and SimpleEventDisplay (lightweight text, no Rich dependency)"event" key indicating typedisplay.make_callback(host.name) to create per-host callbacks that render parallel progress barsftlcopy and ftlget_url emit progress events automatically during chunked transfersftl2.events and emit events using the same APIRunning examples:
uv run python example_streaming.py # local, no setup
docker-compose up -d && uv run python example_remote_streaming.py # remote via Docker
Emitting events from modules:
from ftl2.events import emit_progress, emit_log, emit_data
emit_progress(percent=50, message="Copying file", current=512000, total=1024000, task_id="copy-1")
emit_log("message", level="info") # levels: info, warning, error
emit_data("output\n", stream="stdout")
Streaming executor signatures:
executelocalstreaming(modulepath, params, timeout=300, checkmode=False, event_callback=None) -> ExecutionResultexecuteremotestreaming(host, bundle_path, params, ...) -> ExecutionResultexecuteremotewithstagingstreaming(host, bundle, params, ...) -> ExecutionResultDisplay setup:
# Rich display — use as context manager
display = EventProgressDisplay(console=None, show_log_events=True, show_data_events=False)
with display:
result = await execute_local_streaming(path, params, event_callback=display.handle_event)
# Simple display — no context manager needed
display = SimpleEventDisplay(output=sys.stderr, show_log_events=True, show_data_events=False)
executelocalstreaming, executeremotestreaming) extend the standard executor API with an event_callback parameterexecuteremotewithstagingstreaming handles staging automaticallyftl2.events directly, bridging the Ansible-to-FTL2 migration pathcheck_mode=bool, tying into FTL2's idempotency/dry-run systememitprogress(), emitlog(), emit_data()result.events even with no callback — callbacks are optional, not requiredEventProgressDisplay requires Rich; SimpleEventDisplay has no Rich dependencydisplay.makecallback(host.name) — not display.handleevent directlyemitprogress optional parameters: current, total, taskid (for multi-task tracking)emit_log levels: info, warning, errorawait) and return ExecutionResultftl2.events — this is an FTL2-specific extension, not standard Ansible