Skip to main content
Version: v1.1.1

Python client migration guide

This guide compares the H2O MLOps Python client across versions. Each table shows how to perform an operation in the earlier version (left column) and in the later version (right column). Use these comparisons to update your code.

From v1.4.x to v1.5.x

Use Secure Store Secret IDs for batch scoring credentials

In v1.5.x, secret fields in batch scoring source and sink configurations must reference Secure Store Secret IDs rather than raw sensitive values. Pass the secret's key (Secret ID) in the config dict instead of the raw credential.

This applies to both BatchSourceOptions and BatchSinkOptions.

v1.4.xv1.5.x
options.BatchSourceOptions(
spec_uid="...",
config={"password": "my-raw-password"},
...,
)
secret = workspace.secrets.create(
name="batch-source-password",
key="MY_PASSWORD",
value=b"my-raw-password",
)

options.BatchSourceOptions(
spec_uid="...",
config={"password": secret.key},
...,
)

Use new monitoring property for baselines and aggregates

v1.5.0 deprecates these methods; v1.6.0 will remove them. Use the new deployment.monitoring API instead.

v1.4.xv1.5.x
deployment.list_baselines()
deployment.monitoring.baseline_aggregates.list()
deployment.list_aggregates()
deployment.monitoring.scoring_aggregates.list()

Rename scorer HTTP-based health-check methods

In v1.4.x, scorer.state() and scorer.is_ready() are HTTP-based methods that ping the scorer's /readyz endpoint directly. v1.5.x renames these methods to better reflect their purpose, and the names state and is_ready are now used for API-driven properties (see the next section).

v1.4.xv1.5.x
scorer.state(auth_value=...)
scorer.readiness(auth_value=...)
scorer.is_ready(auth_value=...)
scorer.is_reachable(auth_value=...)

Access scorer state and readiness via API-based properties

In v1.5.x, scorer.state and scorer.is_ready are read-only properties that query the MLOps API for the scorer's routing state. They are not the same as the old HTTP-based methods of the same name (renamed to readiness and is_reachable in v1.5.x — see the previous section).

v1.4.xv1.5.x

Not available in v1.4.x.

scorer.state

scorer.is_ready

scorer.wait_for_ready(
timeout=60, interval=5, fail_fast=True
)

scorer.raise_for_error()

Handle entities' state properties

In v1.4.x, any entity's state property returned a proto enum object, which is a subclass of str. In v1.5.x, all state properties return a plain Python string. The string values themselves remain the same, so comparisons against string literals still work, but any code that relied on the object being an enum will break.

v1.4.xv1.5.x
entity.state == "SOME_STATE"  # True
entity.state == "SOME_STATE"  # True
isinstance(entity.state, SomeEnum)  # True
isinstance(entity.state, SomeEnum)  # False

Pair id_field with output_fields_type

v1.5.x adds a new output_fields_type field to ModelRequestParameters. Setting id_field without output_fields_type=OutputFieldsType.INCLUDE_ID now raises a ValueError. Code that previously set only id_field must be updated.

v1.4.xv1.5.x
import h2o_mlops.options as options

params = options.ModelRequestParameters(
id_field="row_id",
contributions=...,
prediction_intervals=...,
)
import h2o_mlops.options as options
import h2o_mlops.types as types

params = options.ModelRequestParameters(
id_field="row_id",
output_fields_type=types.OutputFieldsType.INCLUDE_ID,
contributions=...,
prediction_intervals=...,
)

Expect auto-refresh from job.state

In v1.4.x, accessing job.state returns the cached value with no network call. In v1.5.x, job.state calls job.refresh() automatically every time it is accessed, making a network call to get the current value.

v1.4.xv1.5.x
job.refresh()

job.state
job.state

Add text_aggregate to BaselineData

v1.5.x inserts a text_aggregate field between categorical_aggregate and missing_values. Code using keyword arguments is unaffected, but positional-argument construction must be updated.

v1.4.xv1.5.x
options.BaselineData(
column_name,
logical_type,
numerical_aggregate,
categorical_aggregate,
missing_values,
is_model_output,
)
options.BaselineData(
column_name,
logical_type,
numerical_aggregate,
categorical_aggregate,
text_aggregate,
missing_values,
is_model_output,
)

Rename of MLOpsRuntime

In v1.5.x, the MLOpsRuntime NamedTuple has been renamed to MLOpsScoringRuntimeInfo. A backward-compatibility alias is provided, so existing code using MLOpsRuntime continues to work.

v1.4.xv1.5.x
r: MLOpsRuntime = scoring_runtime.runtime
r: MLOpsScoringRuntimeInfo = scoring_runtime.runtime

From v1.3.x to v1.4.x

Imports

v1.3.xv1.4.x
import time

import httpx
import h2o_authn
import h2o_mlops
import h2o_mlops.options as options
import h2o_mlops
import h2o_mlops.options as options
import h2o_mlops.types as types

Client creation

From v1.4.x onwards, support for creating the client using gateway_url and token_provider has been removed. Instead, you must use refresh_token and h2o_cloud_url.

v1.3.xv1.4.x
token_provider = h2o_authn.TokenProvider(
refresh_token=...,
client_id=...,
token_endpoint_url=...,
)
mlops = h2o_mlops.Client(
gateway_url=...,
token_provider=token_provider,
)
mlops = h2o_mlops.Client(
h2o_cloud_url=<H2O_CLOUD_URL>,
refresh_token=<REFRESH_TOKEN>,
)

Get allowed affinities and tolerations

v1.3.xv1.4.x
mlops.allowed_affinities
mlops.configs.allowed_k8s_affinities
mlops.allowed_tolerations
mlops.configs.allowed_k8s_tolerations

Get the current user

v1.3.xv1.4.x
mlops.get_user_info()
mlops.users.get_me()

Returns the user's information as a Python dictionary.

Returns the user's information as an MLOpsUser instance.

In version 1.4.x, the concept of projects has been replaced by workspaces. Update your code by replacing references to projects with workspaces.

v1.3.xv1.4.x
mlops.projects.<action>()
mlops.workspaces.<action>()

Create and register an experiment into a model

The previous method of creating experiments and registering them with models is still supported.

v1.3.xv1.4.x
experiment = project.experiments.create(
data=..., name=...
)
model = project.models.create(name=...)

or

model = project.models.get(uid=...)
model.register(experiment=experiment)
model.register(
experiment="/path/experiment.zip",
name=...,
)

or

workspace.models.register(
experiment="/path/experiment.zip",
name=...,
)

Users can pass an instance of the MLOpsExperiment as well.

note
  • When you link an experiment to a workspace from H2O Driverless AI, a new model version is automatically registered under the model that matches the experiment’s name.
  • If no matching model exists, a new model is created with the experiment name, and the experiment is registered as its first version.
  • Therefore, you don’t need to manually register experiments in MLOps. You can use the model directly.

Update an artifact’s parent

v1.3.xv1.4.x
artifact.update(
parent_experiment=experiment,
)
artifact.update(
parent_entity=experiment,
)

Get artifact's model-specific metadata (if applicable)

v1.3.xv1.4.x
artifact.get_model_info()
artifact.model_info

Convert JSON artifact to a dictionary

v1.3.xv1.4.x
artifact.to_dictionary()
artifact.to_dict()

Get the experiment associated with a model version

v1.3.xv1.4.x
model.get_experiment(model_version=n)
model.experiment(model_version=n)

List scoring runtimes

The experiment.scoring_artifact_types property was removed in 1.4.x.

v1.3.xv1.4.x
scoring_runtimes = mlops.runtimes.scoring.list(
artifact_type=experiment.scoring_artifact_types[correct_index]
)
scoring_runtimes = experiment.scoring_runtimes
scoring_runtimes = mlops.runtimes.scoring.list(
artifact_type=..., uid=...
)
scoring_runtimes = mlops.runtimes.scoring.list(
artifact_type=..., runtime_uid=...
)
note

When creating a deployment, instead of passing scoring_runtimes[correct_index], you can use mlops.runtimes.scoring.get(artifact_type=..., runtime_uid=...) to get the scoring_runtime, if you already know the corresponding artifact_type and runtime_uid.

Create a deployment

v1.3.xv1.4.x
project.deployments.create_single(
name=...,
model=...,
scoring_runtime=...,
security_options=options.SecurityOptions(
passphrase=...,
hashed_passphrase=...,
disabled_security=...,
oidc_token_auth=...,
),
)
workspace.deployments.create(
name=...,
composition_options=options.CompositionOptions(
model=...,
scoring_runtime=...,
),
security_options=options.SecurityOptions(
security_type=types.SecurityType.<TYPE>,
passphrase=...,
),
)
note

Starting in v1.4.x, when you create a deployment with hash-based security options, provide the passphrase directly. In earlier versions, you had to provide the hashed value instead.

Create a deployment with new model monitoring options

v1.3.xv1.4.x
project.deployments.create_single(
...,
monitoring_record_options=options.MonitoringRecordOptions(
...,
),
)
workspace.deployments.create(
...,
monitoring_options=options.MonitoringOptions(
...,
),
)
note

This is equivalent to how users created deployments with the old monitoring in the previous client. After the old monitoring was removed, this change was introduced. Note that the parameters accepted by options.MonitoringOptions differ from those used in the old monitoring.

Wait for deployment to become healthy

The previous method is still supported.

v1.3.xv1.4.x
while not deployment.is_healthy():
deployment.raise_for_failure()
time.sleep(5)
deployment.wait_for_healthy()

Get deployment state

v1.3.xv1.4.x
deployment.status()
deployment.state
deployment.is_healthy()
deployment.is_healthy

Update a deployment

v1.3.xv1.4.x
deployment.update_security_options(
...,
)
deployment.update(
security_options=options.SecurityOptions(
...,
),
kubernetes_options=options.KubernetesOptions(
...,
),
environment_variables={
"KEY1": "VALUE1",
"KEY2": "VALUE2",
},
monitoring_options=options.MonitoringOptions(
...,
),
)
deployment.update_kubernetes_options(
...,
)
deployment.set_environment_variables(
environment_variables={
"KEY1": "VALUE1",
"KEY2": "VALUE2",
},
)
deployment.update_monitoring_options(
...,
)
note

In v1.4.x, you can update multiple settings at once.

Access deployment scorer

v1.3.xv1.4.x

You do not need to fetch the scorer.

scorer = deployment.scorer

or

scorer = workspace.deployments.scorers(
key=value,
)[index]
deployment.scorer_api_base_url
scorer.api_base_url
deployment.url_for_capabilities
scorer.capabilities_endpoint
deployment.url_for_schema
scorer.schema_endpoint
deployment.url_for_sample_request
scorer.sample_request_endpoint
deployment.url_for_scoring
scorer.scoring_endpoint
deployment.get_capabilities(...)
scorer.capabilities(...)
deployment.get_schema(...)
scorer.schema(...)
deployment.get_sample_request(...)
scorer.sample_request(...)

Score against a deployment

The previous method is still supported if the correct scoring endpoint URL is provided.

v1.3.xv1.4.x
response = httpx.post(
url=deployment.url_for_scoring,
json=...,
)

response.json()
scorer.score(payload=...)

Kubernetes options for a batch scoring job

v1.3.xv1.4.x
project.batch_scoring_jobs.create(
...,
resource_spec=options.BatchKubernetesOptions(
...,
),
)
workspace.batch_scoring_jobs.create(
...,
kubernetes_options=options.BatchKubernetesOptions(
...,
),
)
job.resource_spec
job.kubernetes_options

Get entity creator (if applicable)

v1.3.xv1.4.x
entity.owner
entity.creator

View the complete Table

v1.3.xv1.4.x
table
table.show(n=...)
note

In version 1.4.x, a Table instance renders a nicely formatted view but displays only up to 50 rows by default.

From v1.2.x to v1.3.x

Removal of environments

v1.2.xv1.3.x
environment = project.environments.get(uid=...)

You do not need to fetch the environment.

environment.deployments
project.deployments
environment.endpoints
project.endpoints
environment.allowed_affinities
mlops.allowed_affinities
environment.allowed_tolerations
mlops.allowed_tolerations

From v1.1.x to v1.2.x

There are no breaking changes.

From v1.0.x to v1.1.x

Minimal supported version

v1.0.xv1.1.x
3.8
3.9

Create a deployment

v1.0.xv1.1.x
project.deployments.create_single(
name=...,
model=...,
scoring_runtime=...,
)
project.deployments.create_single(
name=...,
model=...,
scoring_runtime=...,
security_options=options.SecurityOptions(
passphrase=...,
hashed_passphrase=...,
disabled_security=...,
oidc_token_auth=...,
),
)
note
  • The security_options field is no longer optional.
  • To create a deployment with the No Security option:
    • For MLOps version 0.68.0 or later, set:
      security_options = options.SecurityOptions(disabled_security=True)
    • For MLOps versions earlier than 0.68.0, set:
      security_options = options.SecurityOptions()

Feedback