The public API of geo-mlops-sdk 0.2.0, generated from the package signatures and docstrings. Read the Edge SDK chapter first for how to use it.

CentralClient — central server client

An async client that calls the central server's edge API (/api/v1/edge) with a device token. Use it with async with, or call aclose() when done.

CentralClient(base_url: str, token: str = '', *, timeout: float = 10.0, retry: RetryPolicy = RetryPolicy(attempts=3, initial_backoff_s=0.5, max_backoff_s=30.0, multiplier=2.0, jitter=0.25), verify: bool = True, transport: Optional[httpx.AsyncBaseTransport] = None, user_agent: Optional[str] = None) -> None

HTTP client bound to one Central deployment and one device token.

set_token

def set_token(token: str) -> None

Adopt a rotated token without rebuilding the connection pool.

aclose

async def aclose() -> None

health

async def health() -> dict

Liveness probe. Never retried -- the caller is the retry loop.

register

async def register(*, os: Optional[str] = None, sdk_version: Optional[str] = None, location: Optional[str] = None) -> RegisterResult

Self-register this device (IF-E1).

send_heartbeat

async def send_heartbeat(body: HeartbeatBody, *, retry: Optional[RetryPolicy] = None) -> HeartbeatResult

Report resources and runtime status (IF-E2).

list_models

async def list_models() -> ModelListResult

Models this device's tenant has registered (IF-E6).

model_versions

async def model_versions(name: str) -> ModelVersionsResult

Version history of one model (IF-E6).

resolve_container

async def resolve_container(model: str, version: str) -> ContainerRef

Registry reference for a model version's serving image (IF-E5).

send_records

async def send_records(records: Sequence[Record]) -> BatchResult

Hand over a telemetry batch (IF-E3).

send_inference

async def send_inference(records: Sequence[InferenceRecord]) -> BatchResult

Hand over an inference-result batch (IF-E4). Same idempotency rule.

upload_init

async def upload_init(request: UploadInit) -> UploadCreated

Open a resumable transfer.

upload_chunk

async def upload_chunk(upload_id: str, index: int, data: bytes) -> ChunkAccepted

Send one chunk. Re-sending an index already stored is a no-op.

upload_status

async def upload_status(upload_id: str) -> UploadStatus

Where a restarted transfer should pick up.

upload_complete

async def upload_complete(upload_id: str) -> UploadStatus

Close the transfer. Assembly happens server-side, so poll the status.

poll_commands

async def poll_commands(wait_s: float = 25.0) -> CommandList

Long poll for commands.

ack_command

async def ack_command(command_id: str, ack: CommandAck) -> CommandAckResult

Report what happened to one command.

fetch_policy

async def fetch_policy() -> DevicePolicy

Retrieve the policy in force for this device.

download_model

async def download_model(name: str, version: str, dest: Union[str, Path], *, progress: Optional[ProgressCallback] = None, retry: Optional[RetryPolicy] = None) -> Path

Stream a model version's artifact to dest (IF-E6).

Errors

Every error derives from SdkError. Only 429, 5xx and transport errors are retried.

ExceptionBaseDescription
SdkErrorExceptionBase class for every error raised by this package.
OfflineErrorSdkErrorThe request never got an answer (DNS, refused, reset, timeout).
ApiErrorSdkErrorCentral answered with a non-2xx status.
AuthErrorApiError401 -- the device token is unknown, expired or revoked.
ForbiddenErrorApiError403 -- the token is valid but lacks the scope for this call.
NotFoundErrorApiError404.
ConflictErrorApiError409 -- e.g. completing an upload whose chunks are not all in.
PayloadTooLargeErrorApiError413 -- the body exceeds a server or proxy ceiling. Retrying cannot help.
UnprocessableErrorApiError422 -- the body did not validate.
RateLimitedErrorApiError429 -- back off, honouring Retry-After when present.
ServerErrorApiError5xx -- Central's problem, and worth retrying.

Retry policy

RetryPolicy(attempts: int = 3, initial_backoff_s: float = 0.5, max_backoff_s: float = 30.0, multiplier: float = 2.0, jitter: float = 0.25) -> None

Exponential backoff with jitter.

Contract models (requests and responses)

Pydantic models exchanged with the central server. Unknown fields are ignored, so new server fields never break the client.

Record

One structured observation.

FieldTypeDefaultDescription
idstr(required)
kindstr(required)
tsdatetime(required)
priorityint50
payloaddict[str, Any]{}

RecordBatch

Request body of POST /api/v1/edge/telemetry.

FieldTypeDefaultDescription
recordslist[Record][]

RejectedRecord

One record Central refused, with the reason it refused it.

FieldTypeDefaultDescription
idstr(required)
reasonstr(required)

BatchResult

Response to a telemetry or inference batch.

FieldTypeDefaultDescription
acceptedint0
duplicatesint0
rejectedlist[RejectedRecord][]

UploadInit

Request body of POST /api/v1/edge/uploads.

FieldTypeDefaultDescription
filenamestr(required)
sizeint(required)
sha256str(required)
chunk_sizeint(required)
kindstrblob
dataset_idstr | NoneNone
metadict[str, Any]{}

UploadCreated

Response to upload init.

FieldTypeDefaultDescription
upload_idstr(required)
chunk_sizeint(required)
receivedlist[int][]

ChunkAccepted

Response to a chunk PUT: the indices the server now holds.

FieldTypeDefaultDescription
receivedlist[int][]

UploadStatus

Response to GET /api/v1/edge/uploads/{id} -- the resume point.

FieldTypeDefaultDescription
upload_idstr(required)
stateUploadStateuploading
receivedlist[int][]
sizeint0
chunk_sizeint0
storage_uristr | NoneNone
errorstr | NoneNone

Detection

One detected instance.

FieldTypeDefaultDescription
clsint(required)
namestr""
conffloat0.0
bboxlist[float][]
polygonlist[list[float]][]

InferenceOutput

Result of one predict call.

FieldTypeDefaultDescription
taskstr""
widthint0
heightint0
detectionslist[Detection][]

ModelRef

Registry coordinates of the model that produced a result.

FieldTypeDefaultDescription
namestr(required)
versionstr(required)

InferenceRecord

One inference result queued for Central (IF-E4).

FieldTypeDefaultDescription
idstr(required)
tsdatetime(required)
modelModelRef(required)
input_refstr | NoneNone
outputdict[str, Any]{}
latency_msfloat0.0
priorityint50

InferenceBatch

Request body of POST /api/v1/edge/inference.

FieldTypeDefaultDescription
recordslist[InferenceRecord][]

RegisterRequest

Request body of POST /api/v1/edge/register (IF-E1).

FieldTypeDefaultDescription
osstr(required)
sdk_versionstr(required)
locationstr | NoneNone

RegisterResult

Response to registration.

FieldTypeDefaultDescription
idstr(required)
statusstrACTIVE

BacklogStatus

What is waiting in the local queue.

FieldTypeDefaultDescription
countint0
bytesint0
oldest_tsdatetime | NoneNone
evicted_24hint0
by_kinddict[str, int]{}

SyncStatus

Uploader state as reported to the fleet.

FieldTypeDefaultDescription
stateSyncStateidle
last_ok_atdatetime | NoneNone
last_errorstr | NoneNone
rate_bpsfloat0.0
in_flightint0
deniedstr | NoneNone

ModelStatus

One model present in the local cache.

FieldTypeDefaultDescription
namestr(required)
versionstr(required)
frameworkstr""
activeboolFalse

CollectorStatus

One configured collector.

FieldTypeDefaultDescription
namestr(required)
typestr""
statestrstopped
last_tsdatetime | NoneNone
errorstr | NoneNone

ContainerStatus

A container the edge reports running (populated by the host app).

FieldTypeDefaultDescription
imagestr(required)
versionstr | NoneNone
healthstr | NoneNone

HeartbeatPayload

Free-form half of the heartbeat, given a shape by this SDK.

FieldTypeDefaultDescription
agent_versionstr""
osstr""
uptime_sfloat0.0
policy_revisionint0
backlogBacklogStatus
syncSyncStatus
modelslist[ModelStatus][]
collectorslist[CollectorStatus][]
containerslist[ContainerStatus] | NoneNone

HeartbeatBody

Request body of POST /api/v1/edge/heartbeat (IF-E2).

FieldTypeDefaultDescription
cpufloat0.0
gpufloat | NoneNone
memfloat0.0
diskfloat0.0
payloadHeartbeatPayload

HeartbeatResult

Response to a heartbeat.

FieldTypeDefaultDescription
okboolTrue
policy_revisionint0

RetentionPolicy

Local storage ceiling. Whichever bound trips first wins.

FieldTypeDefaultDescription
max_bytesint53687091200
max_age_daysint30
free_disk_min_bytesint5368709120

SyncPolicy

How aggressively the uploader may work.

FieldTypeDefaultDescription
batch_sizeint500
chunk_bytesint33554432
max_bytes_per_sint0
cpu_pause_percentfloat85.0
windowslist[str][]
concurrencyint1
urgent_priorityint90

DevicePolicy

Response to GET /api/v1/edge/config.

FieldTypeDefaultDescription
revisionint0
heartbeat_interval_sfloat30.0
commands_poll_sfloat25.0
retentionRetentionPolicy
syncSyncPolicy

Command

One queued command.

FieldTypeDefaultDescription
idstr(required)
typestr(required)
argsdict[str, Any]{}
created_atdatetime | NoneNone

CommandList

Response to GET /api/v1/edge/commands (empty when the wait elapsed).

FieldTypeDefaultDescription
itemslist[Command][]

CommandAck

Request body of POST /api/v1/edge/commands/{id}:ack.

FieldTypeDefaultDescription
statusAckStatusok
resultdict[str, Any] | NoneNone

CommandAckResult

Response to an ack.

FieldTypeDefaultDescription
idstr(required)
statestr""

ModelInfo

One registered model.

FieldTypeDefaultDescription
namestr(required)
stagesdict[str, str]{}
tagsdict[str, str]{}

ModelListResult

Response to GET /api/v1/edge/models.

FieldTypeDefaultDescription
itemslist[ModelInfo][]
availableboolFalse

ModelVersionInfo

One version of a model.

FieldTypeDefaultDescription
versionstr(required)
stagestr""
statusstr""
run_idstr""
creation_timestampint0

ModelVersionsResult

Response to GET /api/v1/edge/models/{name}/versions.

FieldTypeDefaultDescription
namestr(required)
versionslist[ModelVersionInfo][]

ContainerRef

Response to GET /api/v1/edge/containers/pull (IF-E5).

FieldTypeDefaultDescription
imagestr(required)
modelstr""
versionstr""

EdgeSettings — agent configuration

The structure of the YAML configuration file. Precedence is environment > file > defaults; environment variables take the GEO_EDGE_ prefix and join levels with __ — e.g. central.tokenGEO_EDGE_CENTRAL__TOKEN.

EdgeSettings

FieldTypeDefaultDescriptionEnvironment variable
centralCentralSettingsGEO_EDGE_CENTRAL
deviceDeviceSettingsGEO_EDGE_DEVICE
data_dirPathPosixPath('/var/lib/geo-mlops-edge')GEO_EDGE_DATA_DIR
disk_pathstr""GEO_EDGE_DISK_PATH
retentionSizedRetentionPolicyGEO_EDGE_RETENTION
syncSizedSyncPolicyGEO_EDGE_SYNC
linkLinkSettingsGEO_EDGE_LINK
heartbeat_interval_sfloat30.0GEO_EDGE_HEARTBEAT_INTERVAL_S
commands_poll_sfloat25.0GEO_EDGE_COMMANDS_POLL_S
apiApiSettingsGEO_EDGE_API
collectorslist[CollectorSettings][]GEO_EDGE_COLLECTORS
modelsModelSettingsGEO_EDGE_MODELS
policy_sourcestrcentralGEO_EDGE_POLICY_SOURCE
log_levelstrINFOGEO_EDGE_LOG_LEVEL

central (CentralSettings)

How to reach the platform.

FieldTypeDefaultDescriptionEnvironment variable
base_urlstr""GEO_EDGE_CENTRAL__BASE_URL
tokenstr""GEO_EDGE_CENTRAL__TOKEN
timeout_sfloat10.0GEO_EDGE_CENTRAL__TIMEOUT_S
verify_tlsboolTrueGEO_EDGE_CENTRAL__VERIFY_TLS

device (DeviceSettings)

Identity overrides. Empty id means "use the hostname".

FieldTypeDefaultDescriptionEnvironment variable
idstr""GEO_EDGE_DEVICE__ID
locationOptional[str]NoneGEO_EDGE_DEVICE__LOCATION

retention (SizedRetentionPolicy)

Retention with human-readable sizes accepted from YAML.

FieldTypeDefaultDescriptionEnvironment variable
max_bytesint53687091200GEO_EDGE_RETENTION__MAX_BYTES
max_age_daysint30GEO_EDGE_RETENTION__MAX_AGE_DAYS
free_disk_min_bytesint5368709120GEO_EDGE_RETENTION__FREE_DISK_MIN_BYTES

sync (SizedSyncPolicy)

Sync policy with human-readable sizes accepted from YAML.

FieldTypeDefaultDescriptionEnvironment variable
batch_sizeint500GEO_EDGE_SYNC__BATCH_SIZE
chunk_bytesint33554432GEO_EDGE_SYNC__CHUNK_BYTES
max_bytes_per_sint0GEO_EDGE_SYNC__MAX_BYTES_PER_S
cpu_pause_percentfloat85.0GEO_EDGE_SYNC__CPU_PAUSE_PERCENT
windowslist[str][]GEO_EDGE_SYNC__WINDOWS
concurrencyint1GEO_EDGE_SYNC__CONCURRENCY
urgent_priorityint90GEO_EDGE_SYNC__URGENT_PRIORITY

Connectivity probing.

FieldTypeDefaultDescriptionEnvironment variable
probe_interval_sfloat5.0GEO_EDGE_LINK__PROBE_INTERVAL_S
backoff_max_sfloat60.0GEO_EDGE_LINK__BACKOFF_MAX_S
online_after_okint2GEO_EDGE_LINK__ONLINE_AFTER_OK
offline_after_failint3GEO_EDGE_LINK__OFFLINE_AFTER_FAIL

api (ApiSettings)

Local HTTP surface for the on-site UI.

FieldTypeDefaultDescriptionEnvironment variable
enabledboolTrueGEO_EDGE_API__ENABLED
hoststr0.0.0.0GEO_EDGE_API__HOST
portint8600GEO_EDGE_API__PORT
tokenstr""GEO_EDGE_API__TOKEN
cors_originslist[str]['*']GEO_EDGE_API__CORS_ORIGINS
max_body_bytesint2147483648GEO_EDGE_API__MAX_BODY_BYTES

collectors (CollectorSettings)

One configured collector. Type-specific keys stay in options.

FieldTypeDefaultDescriptionEnvironment variable
typestr(required)GEO_EDGE_COLLECTORS__TYPE
namestr""GEO_EDGE_COLLECTORS__NAME
enabledboolTrueGEO_EDGE_COLLECTORS__ENABLED
priorityint50GEO_EDGE_COLLECTORS__PRIORITY
optionsdict[str, Any]{}GEO_EDGE_COLLECTORS__OPTIONS

models (ModelSettings)

Local model cache behaviour.

FieldTypeDefaultDescriptionEnvironment variable
auto_activatestrProductionGEO_EDGE_MODELS__AUTO_ACTIVATE
keep_versionsint2GEO_EDGE_MODELS__KEEP_VERSIONS

Extension points

Protocols and functions for registering your own collectors and inference runners.

Sink

What a collector is handed to publish through.

async def record(kind: str, payload: dict, *, priority: int = 50, ts: Optional[datetime] = None, meta: Optional[dict] = None, record_id: str = '') -> Any
async def blob(kind: str, source: Union[str, Path, bytes], *, filename: str = '', priority: int = 50, ts: Optional[datetime] = None, meta: Optional[dict] = None, move: bool = False) -> Any

Collector

A source of data attached to this edge.

async def start(sink: Sink) -> None
async def stop() -> None
def status() -> CollectorStatus

register_collector

def register_collector(type_: str, factory: CollectorFactory) -> None

Make type_ usable in configuration.

build_collector

def build_collector(type_: str, name: str, *, priority: int = 50, options: Optional[dict] = None) -> Collector

Instantiate one configured collector.

Runner

Loads one model and answers predictions for it.

def load(model: LocalModel) -> None
def predict(image: bytes, **params) -> InferenceOutput
def close() -> None

register_runner

def register_runner(framework: str, factory: Callable[[], Runner]) -> None

Teach the SDK about a framework it does not ship support for.

Written for the platform as of 2026-09-21.

© Geo-MLOps