Skip to navigation

Python SDK API

View as Markdown

Install the SDK and any data-source extras by following Deploy, Install, and Connect. This reference documents the public sdm_client interfaces used by the Kumo Relational workflow.

What is public is defined precisely: everything named in sdm_client.__all__, sdm_api.__all__, sdm_connectors.__all__, and sdm_connectors.databricks.__all__. Anything beginning with _, and every submodule not re-exported at the top level (sdm_client.core, .adapters, .materializers, .wire), is an implementation detail that can change in any release. sdm_relational_engine is reached only through sdm_client; importing it directly is at your own risk. See the stability contract for the full rules and the deprecation policy.

Import the supported public interfaces from sdm_client:

from sdm_client import (
SDMClient, Schema, Request, PredictiveQuery, KumoRelational, PredictionResult,
)

SDMClient

SDMClient(
url: str,
api_key: str | None = None,
*,
verify_ssl: bool = True,
timeout: float = 60.0,
max_retries: int = 3,
)

A connection to one NIM, serving every model it can reach. Use it as a context manager for a scoped sequence of requests. For an application or notebook that makes multiple requests, create one client, reuse it, and call close() when finished. Calling close() retires the client permanently; construct a new client instead of attempting to reuse a closed one.

MethodDescription
health_ready()Checks whether the NIM is ready to serve requests.
models()Model ids the endpoint advertises, read from /v1/models.
capabilities(model)What model supports, as far as this client knows. Client-side, tagged source='sdk'; needs no live connection.
predict(request, *, model, outputs=None)Answer request with model. Returns a PredictionResult.
fit(request, *, model, outputs=None, holdout=None)Pin request’s context on the endpoint and return a FittedModel. Raises SESSIONS_UNSUPPORTED if the endpoint does not serve sessions, or if the request materialized into more than one call.
close()Releases pooled connections and permanently retires the client.

Several clients can target different endpoints or tenants concurrently, including from multiple threads. Each prediction remains bound to the endpoint and credential of the client that started it.

Connecting through Databricks Model Serving

SDMClient.for_databricks_serving(
endpoint: str,
*,
workspace_client: Any | None = None,
timeout: float | None = None,
) -> SDMClient
with SDMClient.for_databricks_serving("kumo-relational") as client:
result = client.predict(request, model=KumoRelational())

endpoint is the model’s name on the serving endpoint, not a URL — there is no key, since the call authenticates through the Databricks SDK with workspace_client’s identity (the notebook’s own, when omitted). Requires pip install "structured-data-models-client[relational,databricks-serving]" for the Kumo Relational workflow. fit() is refused there: a serving endpoint answers one request at a time and has no session to pin a context in. There is no for_snowflake_serving.

KumoRelational

from sdm_client import KumoRelational
client.predict(request, model=KumoRelational())

A thin, stateless handle naming the relational model. Requires the structured-data-models-client[relational] extra, which pulls in the native structured-data-models-relational-engine — CPython 3.10 through 3.13 only.

Task kindsclassification, binary_classification, multiclass_classification, regression, forecasting, temporal_link_prediction
Output fields declaredprediction, probabilities, scores, rankings, embeddings, quantiles, explanation
Output fields a typical deployment servesprediction, probabilities, quantiles natively; rankings via client-side decomposition. scores, embeddings, and explanation are commonly refused — see Prediction Types
Request sourceMust come from PredictiveQuery(...).materialize(...); a directly-built Request is refused, even with related_tables=
Extra requiredstructured-data-models-client[relational]

Schema

Schema.from_data(
tables: Mapping[str, pandas.DataFrame],
*,
primary_keys: Mapping[str, str | Sequence[str]] | None = None,
time_columns: Mapping[str, str | None] | None = None,
relationships: Sequence[Relationship] | None = None,
) -> Schema
Schema.from_source(
source: Source,
tables: Mapping[str, str] | None = None,
*,
primary_keys: Mapping[str, str | Sequence[str]] | None = None,
time_columns: Mapping[str, str | None] | None = None,
relationships: Sequence[Relationship] | None = None,
check_keys: bool = True,
) -> Schema

from_data() builds a schema from DataFrames already in memory, inferring dtype, semantic type, primary key, time column, and relationships for every table. from_source() describes tables that stay where they are — a warehouse or database — without reading any table in full; building the schema still queries the source for column metadata, a row preview per table, and (unless check_keys=False) a key-uniqueness scan. Only materialize() samples the rows a prediction actually needs, with SQL. See Build a Schema.

schema = Schema.from_data({"customers": customers, "orders": orders})
schema["customers"].primary_key = "customer_id"
schema["orders"].time_column = "order_time"

Index it by table name, and index a table by column name. There is no visualize(), print_metadata(), or print_links() — inspect a schema with print(schema), schema.tables, and schema.relationships. Call schema.check_consistent() to validate. schema.conversion_notes records what a semantic-model conversion resolved, for reading — its wording is not part of the contract.

Relationship

Relationship(source_table: str, source_column: str | Sequence[str], target_table: str, target_column: str | Sequence[str])

A foreign key pointing at a table’s primary key, directed from the many side to the one side. See Define Relationships.

PredictiveQuery

PredictiveQuery(query: str, data: Schema | Mapping[str, pandas.DataFrame])
.materialize(
*,
indices: Sequence[Any] | None = None,
predict: pandas.DataFrame | None = None,
num_context_samples: int | None = None,
model: str | Model | None = None,
candidates: Sequence[Any] | None = None,
task: str | None = None,
num_neighbors: Sequence[int] | None = ...,
num_hops: int | None = ...,
anchor_time: Any = ...,
context_anchor_time: Any = ...,
use_prediction_time: bool = ...,
lag_timesteps: int = ...,
random_seed: int | None = ...,
max_pq_iterations: int = ...,
exclude_cols_dict: Mapping[str, Sequence[str]] | None = ...,
return_embeddings: bool = ...,
top_k: int | None = ...,
prediction_statistic: str = ...,
rows_per_call: int | None = ...,
inference_config: Mapping[str, Any] | None = ...,
) -> Request

Resolves and validates the query when materialize() builds a request. For a relational schema, indices selects existing entities by key; the direct-row form (predict=) is tabular-only. candidates= is required for a RANK TOP K query. See Configuration for every option and its default, and Limits for size caps.

Request

The wire envelope minus the two things that are predict() arguments: which model answers it, and which output fields you want back. For Kumo Relational, build it only through PredictiveQuery(...).materialize(...).

Read-only properties: is_relational, context_rows, predict_rows, nothing_to_score. request.task is a Task(kind, target, entity_table, options); request.task.target is a Target(column_name, dtype, table_name); request.context/request.predict are each a Split(instance_table, related_tables). These are read-only descriptions of a request, not something you construct by hand.

SourceTable

What schema["table"] returns for a table built with Schema.from_source(), in place of a Table. Holds column metadata and keys but no rows — sampling reads them from the source when a query is materialized. Keys, time columns, and semantic types are corrected the same way as on a Table.

ModelCapabilities

What client.capabilities(model) returns: model, tasks, outputs, single_table, multiple_tables, relationships, explanation_formats, and sessions. Describes this client, not the endpoint — see Prediction Types.

PredictionResult

Attribute / MethodDescription
modelThe model id that answered.
request_idThe endpoint’s id for the call.
itemsThe response items, in the order the endpoint returned them.
metadataWhatever the endpoint reported alongside the predictions.
explanations.gradients maps prediction identities to gradient records; .columns holds labelled-context cohort statistics or None. Requires a compatible client and deployment; see Explainability.
unscored_candidatesFor a ranking: the candidates left out because no entity’s sampled context linked to them, in the order passed. Empty when every candidate was scored.
to_pandas()The predictions as a DataFrame. See Prediction Results.
absent(requested)Which of requested the answer does not carry.

FittedModel

Returned by SDMClient.fit(). predict(request) scores rows against the pinned context; close() releases it. Use as a context manager or call close() explicitly. The constructor is not public — call client.fit().

Errors

from sdm_client import (
StructuredDataError, UnknownModelError, UnsupportedRequestError,
MissingExtraError, NimRequestError,
)

Every call on SDMClient raises StructuredDataError or a subclass, so except StructuredDataError catches anything the client reports. Every error carries a stable code; branch on it and on the exception type, never on the message text — message wording is not part of the public contract.

ClasscodeRaised when
UnknownModelErrorUNKNOWN_MODELmodel is not one the contract carries.
UnsupportedRequestErrorUNSUPPORTED_REQUESTThe model cannot answer this request — an unmaterialized request, more entities than a limit allows, an output field it does not produce, or a size over a limit. Raised before anything is sent.
MissingExtraErrorMISSING_EXTRAAn optional dependency the call needs is not installed.
NimRequestErrorvaries, plus status_codeThe NIM answered, and the answer was an error.

A call that fails partway through a batched request carries what it already answered on the error’s details: answered/rows_answered for entities, parts_answered for a forecast’s completed steps.

Typed relational connection and graph-construction failures are translated to StructuredDataError when they cross the client boundary; sdm_relational_engine’s own exception types are not public API.

sdm_connectors

from sdm_connectors import (
read, read_table,
DatabricksSource, SnowflakeSource, PostgresSource, DuckDBSource, SQLiteSource,
)
from sdm_connectors.databricks import warehouse, lakebase

read()/read_table() load a table into a DataFrame for Schema.from_data(). Each *Source class describes tables that stay in their backend for Schema.from_source(), built from that backend’s own driver connection. DatabricksSource and SnowflakeSource additionally offer .semantic_model(name) for a metric view or semantic view. See the connector pages under Connect Data Sources.