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.x | v1.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.x | v1.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.x | v1.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.x | v1.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.x | v1.5.x |
|---|
entity.state == "SOME_STATE"
| entity.state == "SOME_STATE"
|
isinstance(entity.state, SomeEnum)
| isinstance(entity.state, SomeEnum)
|
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.x | v1.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.
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.x | v1.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.x | v1.5.x |
|---|
r: MLOpsRuntime = scoring_runtime.runtime
| r: MLOpsScoringRuntimeInfo = scoring_runtime.runtime
|
From v1.3.x to v1.4.x
Imports
| v1.3.x | v1.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.x | v1.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.x | v1.4.x |
|---|
| mlops.configs.allowed_k8s_affinities
|
mlops.allowed_tolerations
| mlops.configs.allowed_k8s_tolerations
|
Get the current user
| v1.3.x | v1.4.x |
|---|
| |
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.x | v1.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.x | v1.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. |
- 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.x | v1.4.x |
|---|
artifact.update( parent_experiment=experiment, )
| artifact.update( parent_entity=experiment, )
|
| v1.3.x | v1.4.x |
|---|
artifact.get_model_info()
| |
Convert JSON artifact to a dictionary
Get the experiment associated with a model version
| v1.3.x | v1.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.x | v1.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=... )
|
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.x | v1.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=..., ), )
|
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.x | v1.4.x |
|---|
project.deployments.create_single( ..., monitoring_record_options=options.MonitoringRecordOptions( ..., ), )
| workspace.deployments.create( ..., monitoring_options=options.MonitoringOptions( ..., ), )
|
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.x | v1.4.x |
|---|
while not deployment.is_healthy(): deployment.raise_for_failure() time.sleep(5)
| deployment.wait_for_healthy()
|
Get deployment state
Update a deployment
| v1.3.x | v1.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( ..., )
|
In v1.4.x, you can update multiple settings at once.
Access deployment scorer
| v1.3.x | v1.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
| |
deployment.url_for_capabilities
| scorer.capabilities_endpoint
|
deployment.url_for_schema
| |
deployment.url_for_sample_request
| scorer.sample_request_endpoint
|
deployment.url_for_scoring
| |
deployment.get_capabilities(...)
| |
deployment.get_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.x | v1.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.x | v1.4.x |
|---|
project.batch_scoring_jobs.create( ..., resource_spec=options.BatchKubernetesOptions( ..., ), )
| workspace.batch_scoring_jobs.create( ..., kubernetes_options=options.BatchKubernetesOptions( ..., ), )
|
| |
Get entity creator (if applicable)
View the complete Table
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.x | v1.3.x |
|---|
environment = project.environments.get(uid=...)
| You do not need to fetch the environment. |
| |
| |
environment.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
Create a deployment
| v1.0.x | v1.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=..., ), )
|
- 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()