nvflare.app_common.executors.client_api_executor module
The public Client API executor, configured by execution mode.
Design: docs/design/client_api_execution_modes.md (“What We Propose”, “Overview”,
“Execution Modes”, “Configuration Surface”). This module path is normative - job configs
reference nvflare.app_common.executors.client_api_executor.ClientAPIExecutor.
Availability: in_process is fully supported. external_process and attach are
not yet implemented; selecting them fails cleanly at job startup.
Unlike the legacy executors (InProcessClientAPIExecutor / ClientAPILauncherExecutor), this
surface has no parameter-conversion args (params_exchange_format /
params_transfer_type / server_expected_format / converter ids): the Client API
boundary passes parameters through unconverted, and format conversion belongs to
send/receive filters at the client edge. Transfer type (FULL/DIFF) is a model-registry
concern, configured elsewhere.
- class ClientAPIExecutor(execution_mode: str, command: str | None = None, task_script_path: str | None = None, task_script_args: str = '', launch_once: bool = True, launch_timeout: float | None = None, shutdown_timeout: float | None = None, stop_grace_period: float = 30.0, heartbeat_interval: float = 5.0, heartbeat_timeout: float = 30.0, task_wait_timeout: float | None = None, result_wait_timeout: float | None = None, train_task_name: str = 'train', evaluate_task_name: str = 'validate', submit_model_task_name: str = 'submit_model', train_with_evaluation: bool = False, memory_gc_rounds: int = 0, cuda_empty_cache: bool = False, attach_timeout: float | None = None, allow_reconnect: bool = False)[source]
Bases:
ExecutorOne executor for all Client API execution modes.
The trainer-facing Client API (flare.init/receive/send/log) is unchanged; this executor replaces the Pipe/launcher integration stack. It delegates to an internal mode-specific backend (ClientAPIBackendSpec) resolved from
execution_modeat START_RUN:in_process: trainer runs inside the CJ process over DataBus.external_process: NVFlare launches and owns the trainer process tree; control over Cell.attach: an externally started/owned trainer attaches over Cell.
Initializes the ClientAPIExecutor.
Parameter names are part of the public job-config surface: renames are breaking changes (guarded by the surface-freeze test).
- Parameters:
execution_mode (str) – One of “in_process”, “external_process”, or “attach”. Required.
command (Optional[str]) – The trainer launch command, e.g. “python custom/train.py”, “torchrun …”. Required for (and only valid in) “external_process” mode. An empty/whitespace-only string is treated as unset.
task_script_path (Optional[str]) – in_process only. Path to the user training script the in_process backend runs via TaskScriptRunner. An empty/whitespace-only string is treated as unset. (The in_process backend validates presence and “.py” suffix.)
task_script_args (str) – in_process only. Arguments appended to task_script_path.
launch_once (bool) – external_process only. Launch the trainer once per job (default) vs once per task.
launch_timeout (Optional[float]) – external_process only. Bound for the launched trainer to complete its HELLO/session setup (this replaces the legacy external_pre_init_timeout). None means no timeout.
shutdown_timeout (Optional[float]) – external_process only. How long to wait for the trainer to exit naturally after an orderly SHUTDOWN before starting forced process-tree termination. None means the backend default.
stop_grace_period (float) – external_process only. Grace period between SIGTERM and SIGKILL when terminating the trainer process group (design: “Process-tree termination”).
heartbeat_interval (float) – out-of-process only (external_process/attach). Interval (seconds) for session heartbeats.
heartbeat_timeout (float) – out-of-process only (external_process/attach). Session lease timeout (seconds) on missed heartbeats. An in-flight payload transfer keeps the lease alive (design: “Heartbeat and Liveness”).
task_wait_timeout (Optional[float]) – Bound for the trainer to accept a delivered task. None means no timeout.
result_wait_timeout (Optional[float]) – Control-side bound for retrieving the task result. Payload transfer completion is governed by the shared transfer layer, not by this value. None means no timeout.
train_task_name (str) – Task name treated as “train” by flare.is_train() (rank contract). Defaults to AppConstants.TASK_TRAIN.
evaluate_task_name (str) – Task name treated as “evaluate” by flare.is_evaluate(). Defaults to AppConstants.TASK_VALIDATION.
submit_model_task_name (str) – Task name treated as “submit_model” by flare.is_submit_model(). Defaults to AppConstants.TASK_SUBMIT_MODEL.
train_with_evaluation (bool) – Whether the trainer also returns evaluation metrics with the trained model.
memory_gc_rounds (int) – Force a GC cycle every N rounds (0 disables).
cuda_empty_cache (bool) – Whether to also empty the CUDA cache during memory cleanup.
attach_timeout (Optional[float]) – attach only. Bound for the externally started trainer to attach. None means no timeout.
allow_reconnect (bool) – attach only. Whether a trainer may re-attach to an existing session after a disconnect.
- execute(task_name: str, shareable: Shareable, fl_ctx: FLContext, abort_signal: Signal) Shareable[source]
Executes a task.
- Parameters:
task_name (str) – task name.
shareable (Shareable) – input shareable.
fl_ctx (FLContext) – fl context.
abort_signal (Signal) – signal to check during execution to determine whether this task is aborted.
- Returns:
An output shareable.
- fire_log_analytics(fl_ctx: FLContext, dxo: DXO) None[source]
Converts trainer LOG data into an analytics event. Executor-owned surface.
Backends call this for every LOG control message (flare.log from the trainer), regardless of execution mode - this replaces MetricRelay (ex-process) and the in-process executor’s log callback as the single analytics-event ownership point.
The fire path is mode-selectable via
set_analytics_fire_fed_event():False (default): fires the local, un-prefixed ANALYTIC_EVENT_TYPE (“analytix_log_stats”) and relies on the ConvertToFedEvent widget (added by BaseFedJob) to forward it to the server as “fed.analytix_log_stats”.
True: fires a federation-scoped event directly to the server, matching what MetricRelay does today for ex-process metrics. Cell backends may select this path during initialize() by calling
set_analytics_fire_fed_event(True)when no ConvertToFedEvent widget is configured.
The two paths must land on the same server-side event name. ConvertToFedEvent prefixes the local event with “fed.”, so the fed path must fire the already-prefixed FED_ANALYTIC_EVENT_TYPE (“fed.analytix_log_stats”); firing the un-prefixed name federation-scoped would miss every consumer listening on “fed.analytix_log_stats” (MetricRelay in job_config/script_runner.py, flower_job.py).
- Parameters:
fl_ctx – an FLContext to fire the event with.
dxo – the analytics data (e.g. from create_analytic_dxo) carried by the event.
- handle_event(event_type: str, fl_ctx: FLContext)[source]
Handles events.
- Parameters:
event_type (str) – event type fired by workflow.
fl_ctx (FLContext) – FLContext information.
- set_analytics_fire_fed_event(enabled: bool) None[source]
Selects whether trainer LOG data is fired as a federation-scoped analytics event.
Cell backends call this during initialization when no ConvertToFedEvent widget is configured. The default remains the local analytics path used by the in-process backend.
- Parameters:
enabled – True to fire federation-scoped events directly; False to fire local events.