Scaleout Edge Clients
This section documents the client implementations available for Scaleout Edge. Clients run on edge nodes and communicate with the Scaleout Edge network to perform local training, evaluation, and model exchange. Multiple client implementations exist to support different environments and programming languages.
Python Client
The Python client provides a high-level API for integrating local training code with the Scaleout Edge network. It is suitable for servers, development machines, notebooks, and lightweight edge nodes.
- class scaleout.EdgeClient(train_callback: Callable[[ScaleoutModel, Dict], Tuple[ScaleoutModel | None, Dict]] | None = None, validate_callback: Callable[[ScaleoutModel], Dict] | None = None, runtime: EdgeClientRuntime | None = None)[source]
Bases:
objectUser-facing interface for an edge client.
Users instantiate this class directly. The runtime defaults to
GrpcEdgeClientRuntime; passingruntime=at construction time swaps the implementation — useful for tests and alternative transports.- __init__(train_callback: Callable[[ScaleoutModel, Dict], Tuple[ScaleoutModel | None, Dict]] | None = None, validate_callback: Callable[[ScaleoutModel], Dict] | None = None, runtime: EdgeClientRuntime | None = None) None[source]
Initialize the EdgeClient.
- check_task_abort() None[source]
Check if the ongoing task has been aborted.
This function should be called periodically from the task callback to ensure that the task can be interrupted if needed. If called from a thread that do not run the task, this function is a no-op.
- Raises:
StoppedException – If the task was aborted.
- connect_to_api(url: str, json: dict | None = None, token: str | None = None, token_refresh_callback: Callable[[...], None] | None = None) Tuple[ConnectToApiResult, Any][source]
Connect to the Scaleout API via the runtime.
- property current_logging_context: LoggingContext | None
Get the current logging context for the running thread.
- init_grpchandler(config: GrpcConnectionOptions, token: str | None = None, url: str | None = None, token_refresh_callback: Callable[[...], None] | None = None) bool[source]
Initialize the runtime’s transport handler.
- log_attributes(attributes: dict, check_task_abort: bool = True) bool[source]
Log the attributes to the server.
- log_metric(metrics: dict, step: int = None, commit: bool = True, check_task_abort: bool = True, context: LoggingContext = None) bool[source]
Log the metrics to the server.
- Parameters:
metrics (dict) – The metrics to log.
step (int, optional) – The step number.
value. (If provided the context step will be set to this)
provided (If not)
used. (the step from the context will be)
commit (bool, optional) – Whether or not to increment the step. Defaults to True.
check_task_abort (bool, optional) – Whether or not to check for task abort. Defaults to True.
context (LoggingContext, optional) – The logging context to use. Defaults to None, which uses the current context.
- Returns:
True if the metrics were logged successfully, False otherwise.
- Return type:
- log_telemetry(telemetry: dict, check_task_abort: bool = True) bool[source]
Log the telemetry data to the server.
- logging_context(context: LoggingContext)[source]
Set the logging context for the duration of the block.
- run(with_heartbeat: bool = False, with_polling: bool = True) None[source]
Run the client’s event loop via the runtime.
- run_inference(model: ScaleoutModel | str = None, params: Dict = None) None[source]
Run inference using the specified model.
- Parameters:
model – The ScaleoutModel or model ID string to use for inference.
params – Additional parameters for inference.
- set_custom_callback(callback_name: str, callback: Callable[[scaleoututil.grpc.scaleout_pb2.TaskRequest], Dict]) None[source]
Set a custom task callback.
- set_inference_callback(callback: Callable[[ScaleoutModel, Dict], Any]) None[source]
Set the inference callback.
- set_stage_model_callback(callback: Callable[[ScaleoutModel], None]) None[source]
Set the stage-model callback, invoked after a model is staged for inference.
- stage_model(model: ScaleoutModel | str) ScaleoutModel[source]
Stage a model for inference.
- Parameters:
model – The ScaleoutModel or model id to stage.
- class scaleout.ScaleoutModel[source]
Bases:
objectThe ScaleoutModel class is the primary model representation in the Scaleout framework.
A ScaleoutModel is a self-describing, immutable container holding: - The serialized model weights (raw bytes, via a helper) - An optional full model representation (e.g. ONNX, .pt, …) - A metadata dict (eagerly loaded): model_id, helper, inference_model_format, and any user-supplied key-value pairs
Models are always immutable after construction. To create a modified copy, use
to_builder()to obtain a pre-seededScaleoutModelBuilder:new_model = model.to_builder().set_model_id("m-002").build() new_model = model.to_builder().set_metadata("tag", "v2").build()
API
Reading metadata:
model.metadata # shallow copy of the metadata dict model.model_id # convenience property
Model parameters:
with model.get_training_model_stream() as s: # read directly from ZIP, no temp file data = s.read() params = model.get_training_model(helper) # decodes from ZIP
Full model representation:
model.has_inference_model # bool model.get_inference_model_format() # format string or None with model.get_inference_model_stream() as s: # stream inference_model.bin directly from ZIP data = s.read()
On-disk format
- Files are ZIP archives (stdlib zipfile, DEFLATED) containing:
metadata.json – eagerly loaded on open training_model.bin – serialized weights inference_model.bin – optional full model representation
Legacy raw-binary streams (no ZIP header, e.g. bare NPZ) are detected automatically and loaded with empty metadata for backward compatibility.
Storage
A single ZIP file (
_zip_path) is the canonical representation from construction time onwards. The model always owns its ZIP and deletes it on garbage collection.get_training_model_stream()andget_inference_model_stream()stream entries directly from the ZIP without extracting to a temp file.- static detect_format(stream: BytesIO) str[source]
Returns ‘zip’ if data is our ZIP container format, else ‘legacy’.
Legacy NPZ files (produced by NumpyHelper) are also ZIP-based and start with the PK magic bytes. We distinguish them from our container by checking for the presence of ‘metadata.json’ inside the archive.
- static detect_format_file(file_path: str) str[source]
Returns ‘zip’ if the file is our ZIP container format, else ‘legacy’.
Reads only the central directory — does not load the entire file.
- static from_file(file_path: str) ScaleoutModel[source]
Creates a ScaleoutModel from a file (ZIP or legacy raw binary).
Delegates to
ScaleoutModelBuilder.
- static from_filechunk_stream(filechunk_stream: Iterable[scaleoututil.grpc.scaleout_pb2.FileChunk]) ScaleoutModel[source]
Creates a ScaleoutModel from a gRPC FileChunk iterator.
Delegates to
ScaleoutModelBuilder.
- static from_stream(stream: BinaryIO) ScaleoutModel[source]
Creates a ScaleoutModel from a stream (ZIP or legacy raw binary).
Delegates to
ScaleoutModelBuilder.
- static from_training_model(model_params, helper=None, metadata: dict | None = None) ScaleoutModel[source]
Creates a ScaleoutModel from model parameters.
Delegates to
ScaleoutModelBuilder. A freshmodel_idis always generated; anymodel_idkey present inmetadatais ignored.- Parameters:
model_params – Parameters accepted by the helper’s
save()method.helper – Serialization helper. Falls back to NumpyHelper if not provided.
metadata – Optional initial metadata dict.
- get_filechunk_stream(chunk_size=1048576)[source]
Yields gRPC FileChunk messages of the raw model bytes.
- get_inference_model_format() str | None[source]
Returns the format string of the full model representation, or
None.
- get_inference_model_stream()[source]
Context manager yielding a read stream of the full model representation binary.
Reads directly from the ZIP entry — no temp-file extraction.
Usage:
if model.has_inference_model: with model.get_inference_model_stream() as stream: data = stream.read()
- get_training_model_stream()[source]
Context manager yielding a read stream of the raw model binary.
Reads directly from the ZIP entry — no temp-file extraction.
Usage:
with model.get_training_model_stream() as stream: data = stream.read()
- sign(private_key, signer_id: str | None = None) dict[source]
Compute and return a signature dict for this model.
Does not modify the ZIP. POST the returned dict to
/api/v1/model-signatures/to persist it.- Parameters:
private_key – An
Ed25519PrivateKeyfrom thecryptographypackage.signer_id – Optional free-form string identifying the signer.
- Returns:
A dict with keys
model_id,algorithm,signature(base64-encoded), and optionallysigner_id.
Additional Clients
Support for additional client implementations (e.g., C++ and Kotlin) will be included here in future versions of the documentation.