falaw.events
Structured progress events for fal calls.
Replaces the implicit “stream raw log strings to stdout” model with a small, machine-readable event stream that orchestrators can subscribe to (UI progress bars, cost telemetry, billing dashboards, etc.).
A ProgressEvent is emitted at every major lifecycle transition of
a single call_fal invocation:
queued— call submitted to falprogress— fal pushed an InProgress update with no message bodylog— fal pushed an InProgress update with a log linedone— call returned a resulterror— call raisedcache_hit—falaw.cached_call_fal()found a hit and skipped the network
Subscribers can be registered globally via subscribe() or
per-call via the on_event= argument on call_fal() /
cached_call_fal(). The on_log parameter still works
(legacy: a string-only stream); see call_fal() for compatibility
notes.
- class falaw.events.ProgressEvent(*, kind: Literal['queued', 'progress', 'log', 'done', 'error', 'cache_hit'], application: str, call_id: str, message: str = '', pct: float | None = None, elapsed_s: float = 0.0)[source]
One step in the lifecycle of a fal call.
- kind
Lifecycle stage. See
EventKind.- Type:
Literal[‘queued’, ‘progress’, ‘log’, ‘done’, ‘error’, ‘cache_hit’]
- application
fal model id (e.g.
"fal-ai/flux/dev").- Type:
str
- call_id
A short hex string that uniquely identifies the call. All events for one
call_falinvocation share the samecall_id.- Type:
str
- message
Free-form text. For
"log"events this is the log line; for"error"it’srepr(exc); otherwise empty.- Type:
str
- pct
Optional progress percentage in [0.0, 100.0]. fal’s current API doesn’t surface this; included for forward compatibility.
- Type:
float | None
- elapsed_s
Seconds since the call started.
- Type:
float
- falaw.events.emit(event: ProgressEvent, *, also: Iterable[Callable[[ProgressEvent], None]] = ()) None[source]
Send
eventto every registered subscriber + thealsolist.Subscriber exceptions are swallowed (with a printed warning) so a misbehaving UI hook can’t bring the rendering pipeline down.
- falaw.events.subscribe(callback: Callable[[ProgressEvent], None]) Callable[[ProgressEvent], None][source]
Register
callbackto receive every emitted ProgressEvent.Returns the callback unchanged so it can be used as a decorator:
@subscribe def log_to_file(ev: ProgressEvent) -> None: ...
- falaw.events.unsubscribe(callback: Callable[[ProgressEvent], None]) None[source]
Remove a previously
subscribe()’d callback. No-op if absent.