Skip to main content
Version: v1.0.0

Manage deployments

This page describes how to create, view, update, and delete deployments, as well as how to view logs and configure endpoints using the H2O MLOps Python client.

To learn more about deployments, see Understand deployments in MLOps.

Prerequisites

Before you begin,

  1. Import the necessary Python packages. For instructions, see Step 1: Import the required packages.
  2. Connect to H2O MLOps. For instructions, see Connect to H2O MLOps.
  3. Create a workspace. For instructions, see Create a workspace.
  4. Create one or two experiments. For instructions, see Create an experiment.
  5. Create models and register the experiments with them. For instructions, see Register an experiment with a model.

Create a deployment

Create a deployment within the workspace using the create() method by specifying the deployment name, composition options, and security options.

deployment = workspace.deployments.create(
name="my-deployment",
composition_options=options.CompositionOptions(
model=model,
scoring_runtime=mlops.runtimes.scoring.get(
artifact_type="h2o3_mojo",
runtime_uid="h2o3_mojo_runtime",
),
),
security_options=options.SecurityOptions(
security_type=types.SecurityType.DISABLED,
),
)

The create() method supports the following optional arguments:

  • mode: types.DeploymentModeType = types.DeploymentModeType.SINGLE_MODEL – The type of deployment.
    Available values:
    • SINGLE_MODEL
    • AB_TEST
    • CHAMPION_CHALLENGER
  • description: Optional[str] = None – The deployment description.
  • kubernetes_options: Optional[options.KubernetesOptions] = None – Customize Kubernetes deployment settings.
  • vpa_options: Optional[List[options.VPAOptions]] = None – Configure Vertical Pod Autoscaler (VPA) settings.
  • pdb_options: Optional[options.PDBOptions] = None – Control pod availability during voluntary disruptions.
  • environment_variables: Optional[Dict[str, str]] = None – Specify environment variables to add to the scoring runtime.
  • cors_origins: Optional[List[str]] = None – Define allowed CORS origins.
  • monitoring_options: Optional[options.MonitoringOptions] = None – Configure monitoring settings for the deployment.

For more details on these configuration options, see Configure deployments.

The deployment might take a few seconds. Use the following command to wait until the deployment is healthy and ready to use:

deployment.wait_for_healthy()
note

To retry a failed deployment, use the following command. It checks the current deployment status and, if it's in a failed state, attempts to redeploy it:

deployment.redeploy_if_failed()

View deployments

List deployments

List all deployments in a workspace:

Input:

deployments = workspace.deployments.list()
deployments

Output:

   | name          | mode         | uid
---+---------------+--------------+--------------------------------------
0 | my-deployment | Single Model | 48ece40f-8608-473a-92a6-388e164e995
note
  • The output of list() method is displayed in a neatly formatted view. By default, only the first 50 rows are displayed to keep the output concise and manageable.

  • Calling len(deployments) returns the total number of rows it contains, not just the number currently displayed.

  • To customize the number of rows displayed, you can call the show() method with the n argument. This allows more rows to be shown when needed. For example:

    deployments.show(n=100)

    This will display up to 100 deployments.

  • The deployments can be iterated over, as it is designed to behave like an iterator.

List deployment statuses

Use the statuses() method to view the statuses of all deployments.

Input:

workspace.deployments.statuses()

This returns a list of deployments and their statuses in a table.

Output:

   | uid                                  | state
---+--------------------------------------+---------
0 | 48ece40f-8608-473a-92a6-388e164e9952 | HEALTHY

Possible status values:

  • PREPARING: Preparing the deployment for launch (for example, building assets).
  • LAUNCHING: Deployment is launching to an environment (for example, waiting for the environment to start).
  • FAILED: Deployment failed during preparation or launch.
  • HEALTHY: Deployment is alive and healthy.
  • UNHEALTHY: Health issues detected in the launched deployment.
  • TERMINATING: Deployment is terminating (that is, environment resources are being brought down).
  • PENDING: Deployment created and awaiting processing.
  • STOPPED: The deployment is scaled down.

Filter deployments

Use the list() method with key-value arguments to filter deployments.

Input:

workspace.deployments.list(name="my-deployment")

This returns a list of matching deployments as a table.

Output:

   | name          | mode         | uid
---+---------------+--------------+--------------------------------------
0 | my-deployment | Single Model | 48ece40f-8608-473a-92a6-388e164e9952

Retrieve a deployment

Retrieve a deployment by UID:

Input:

deployment = workspace.deployments.get(uid="48ece40f-8608-473a-92a6-388e164e9952")
deployment
note

You can also retrieve a deployment from the list returned by list() using indexing.
For example, deployment = workspace.deployments.list(key=value)[index]. The key and value arguments are optional.

Output:

<class 'h2o_mlops._deployments.MLOpsScoringDeployment(
uid='48ece40f-8608-473a-92a6-388e164e9952',
name='my-deployment',
description='',
mode=<DeploymentModeType.SINGLE_MODEL: 'Single Model'>,
creator_uid='4c4eb198-bcbc-4442-91f6-a27deb53e9c1',
created_time=datetime.datetime(2025, 6, 27, 5, 4, 32, 14134, tzinfo=tzutc()),
last_modified_time=datetime.datetime(2025, 6, 27, 5, 4, 32, 14134, tzinfo=tzutc()),
)'>

Deployment properties

A deployment has the following main properties:

  • uid: The unique identifier for the deployment.
  • name: The name of the deployment.
  • description: A description of the deployment.
  • mode: The deployment mode (for example, SINGLE_MODEL or AB_TEST).
  • creator: The user who created the deployment.
  • created_time: The timestamp when the deployment was created.
  • last_modified_time: The timestamp of the last update.
  • revision_uid: The revision ID of the deployment.
  • state: The current status of the deployment.
  • is_healthy: A boolean indicating whether the deployment is healthy.
  • composition_options: Define how models are composed for deployment.
  • security_options: Security configuration options.
  • kubernetes_options: Kubernetes deployment configuration.
  • vpa_options: Vertical Pod Autoscaler (VPA) settings.
  • pdb_options: Pod disruption budget settings.
  • environment_variables: Environment variables to add to the scoring runtime.
  • cors_origins: A list of allowed CORS origins.
  • monitoring_options: Monitoring configuration.
  • experiments: The associated experiment(s) for the deployment.

View deployment logs

Call the logs() method to access the logs for a deployment:

logs = deployment.logs()

This returns a dictionary of log entries from different deployment pods.

To see which pods' log entries were retrieved, use the keys() method:

Input:

keys = list(logs.keys())
keys

Output:

['primary.pr-48ece40f-8608-473a-92a6-388e164e9952-769f88644b-7qzcs.artifact-fetcher',
'primary.pr-48ece40f-8608-473a-92a6-388e164e9952-769f88644b-7qzcs.artifact-processor',
'primary.pr-48ece40f-8608-473a-92a6-388e164e9952-769f88644b-7qzcs.events',
'primary.pr-48ece40f-8608-473a-92a6-388e164e9952-769f88644b-7qzcs.proxy',
'primary.pr-48ece40f-8608-473a-92a6-388e164e9952-769f88644b-7qzcs.runtime']

As you already know the available dictionary keys, you can access the log entries for a specific pod.

For example, to view the full log for the runtime pod:

Input:

logs["primary.pr-48ece40f-8608-473a-92a6-388e164e9952-769f88644b-7qzcs.runtime"]

Output:

['2025-06-27 05:04:36.423321198 +0000 UTC: Picked up _JAVA_OPTIONS: -Dmojo.path=/data/model',
'2025-06-27 05:04:36.63684369 +0000 UTC: Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts',
'2025-06-27 05:04:37.092592485 +0000 UTC: ',
'2025-06-27 05:04:37.092627005 +0000 UTC: . ____ _ __ _ _',
"2025-06-27 05:04:37.092634066 +0000 UTC: /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\",
"2025-06-27 05:04:37.092639646 +0000 UTC: ( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
'2025-06-27 05:04:37.092645106 +0000 UTC: \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )',
"2025-06-27 05:04:37.092650616 +0000 UTC: ' |____| .__|_| |_|_| |_\\__, | / / / /",
'2025-06-27 05:04:37.092656126 +0000 UTC: =========|_|==============|___/=/_/_/_/',
'2025-06-27 05:04:37.092661606 +0000 UTC: ',
'2025-06-27 05:04:37.094651073 +0000 UTC: :: Spring Boot :: (v3.3.12)',
'2025-06-27 05:04:37.094674983 +0000 UTC: ',
'2025-06-27 05:04:37.143507059 +0000 UTC: 2025-06-27T05:04:37.142Z INFO 1 --- [ main] a.h.m.d.local.rest.ScorerApplication : Starting ScorerApplication v0.0.0.dev0+main.3c6156731c9d1c63d27498637cd3b4fea8bfd29e using Java 21.0.7 with PID 1 (/app/BOOT-INF/classes started by ? in /app)',
'2025-06-27 05:04:37.144078602 +0000 UTC: 2025-06-27T05:04:37.143Z INFO 1 --- [ main] a.h.m.d.local.rest.ScorerApplication : No active profile set, falling back to 1 default profile: "default"',
'2025-06-27 05:04:37.974359799 +0000 UTC: 2025-06-27T05:04:37.974Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)',
'2025-06-27 05:04:37.984421453 +0000 UTC: 2025-06-27T05:04:37.984Z INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]',
'2025-06-27 05:04:37.984547596 +0000 UTC: 2025-06-27T05:04:37.984Z INFO 1 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.42]',
'2025-06-27 05:04:38.01826987 +0000 UTC: 2025-06-27T05:04:38.017Z INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext',
'2025-06-27 05:04:38.01910209 +0000 UTC: 2025-06-27T05:04:38.018Z INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 742 ms',
'2025-06-27 05:04:38.021103686 +0000 UTC: Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts',
'2025-06-27 05:04:38.071485518 +0000 UTC: 2025-06-27T05:04:38.070Z INFO 1 --- [ main] a.h.m.d.common.transform.MojoScorer : Loading Mojo pipeline from path /data/model',
'2025-06-27 05:04:38.075504291 +0000 UTC: 2025-06-27T05:04:38.075Z INFO 1 --- [ main] a.h.m.r.a.backend.ZipFileReaderBackend : Opening mojo file: /data/model',
'2025-06-27 05:04:38.165548915 +0000 UTC: 2025-06-27T05:04:38.165Z INFO 1 --- [ main] a.h.m.d.common.transform.MojoScorer : Loading Mojo pipeline from path /data/model',
'2025-06-27 05:04:38.165589516 +0000 UTC: 2025-06-27T05:04:38.165Z INFO 1 --- [ main] a.h.m.r.a.backend.ZipFileReaderBackend : Opening mojo file: /data/model',
'2025-06-27 05:04:38.18428143 +0000 UTC: 2025-06-27T05:04:38.183Z INFO 1 --- [ main] a.h.m.d.common.transform.MojoScorer : Mojo pipeline successfully loaded (4295412422633975888).',
"2025-06-27 05:04:38.486280193 +0000 UTC: 2025-06-27T05:04:38.485Z INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'",
'2025-06-27 05:04:38.50331213 +0000 UTC: 2025-06-27T05:04:38.502Z INFO 1 --- [ main] a.h.m.d.local.rest.ScorerApplication : Started ScorerApplication in 1.708 seconds (process running for 2.079)',
"2025-06-27 05:04:39.403663076 +0000 UTC: 2025-06-27T05:04:39.403Z INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'",
"2025-06-27 05:04:39.4038616 +0000 UTC: 2025-06-27T05:04:39.403Z INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'",
'2025-06-27 05:04:39.40514298 +0000 UTC: 2025-06-27T05:04:39.404Z INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms']

View deployment logs from a specific time

To get logs starting from a specific date and time:

from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

since_time = datetime(2025, 6, 25, 9, 0, 0, tzinfo=ZoneInfo("Asia/Colombo"))
logs = deployment.logs(since_time=since_time)
note

You can retrieve logs relative to the deployment’s creation time by using timedelta. For example, to get logs starting 5 minutes after the deployment was created:

since_time = deployment.created_time + timedelta(minutes=5)
logs = deployment.logs(since_time=since_time)

Alternatively, you can get recent logs by subtracting a time duration from the current time. Make sure to use timezone-aware datetime values. For example, to get logs from the past 5 minutes using the Asia/Colombo timezone:

since_time = datetime.now(ZoneInfo("Asia/Colombo")) - timedelta(minutes=5)
logs = deployment.logs(since_time=since_time)

Manage endpoint

Configure endpoint

Configure a static path for the MLOps deployment REST endpoint:

endpoint = deployment.configure_endpoint(
path="static-path",
)
note
  • You can use the configured path as an alias for the deployment ID in the deployment scorer API base URL.
  • This path must be globally unique within the H2O MLOps environment to ensure proper routing and avoid collisions.
  • For example, while the default scoring endpoint, f"https://model.dummy-env.h2o.ai/{deployment.uid}/model/score" is always available and pre-configured, you can also use f"https://model.dummy-env.h2o.ai/{endpoint.path}/model/score" for scoring.
  • Both endpoints are valid and functional. The same applies to other endpoint types.

The configure_endpoint() method supports the following arguments:

  • path: str - Path to use for the target deployment URLs.
  • name: Optional[str] = None - Display name for the MLOps endpoint. (Used only if a new endpoint is created.)
  • description: Optional[str] = None - Description for the MLOps endpoint. (Used only if a new endpoint is created.)
  • force: bool = False - Whether to attempt to reassign the path if it’s already in use by another deployment.

List deployment endpoints

To list all the endpoints attached to the deployment:

Input:

endpoints = deployment.endpoints
endpoints

Output:

   | name        | path        | uid                                  | target_deployment_uid
---+-------------+-------------+--------------------------------------+--------------------------------------
0 | static-path | static-path | 6ab2b92e-98c0-4c38-b4ef-4f6d9ba66e6f | 48ece40f-8608-473a-92a6-388e164e9952
note

To list all the endpoints available within the workspace:

endpoints = workspace.endpoints.list()
note
  • The output of list() method is displayed in a neatly formatted view. By default, only the first 50 rows are displayed to keep the output concise and manageable.

  • Calling len(endpoints) returns the total number of rows it contains, not just the number currently displayed.

  • To customize the number of rows displayed, you can call the show() method with the n argument. This allows more rows to be shown when needed. For example:

    endpoints.show(n=100)

    This will display up to 100 endpoints.

  • The endpoints can be iterated over, as it is designed to behave like an iterator.

Retrieve a deployment endpoint

To retrieve a deployment endpoint:

Input:

endpoint = endpoints[0]
endpoint

Output:

<class 'h2o_mlops._endpoints.MLOpsEndpoint(
uid='6ab2b92e-98c0-4c38-b4ef-4f6d9ba66e6f',
name='static-path',
description='',
path='static-path',
created_time=datetime.datetime(2025, 6, 27, 5, 5, 40, 146102, tzinfo=tzutc()),
last_modified_time=datetime.datetime(2025, 6, 27, 5, 5, 40, 146481, tzinfo=tzutc()),
)'>
note

To retrieve an endpoint available within the workspace:

workspace.endpoints.get(uid=...)

Detach a configured endpoint

To detach an endpoint from its current deployment, unset its target deployment as shown below:

endpoint.update(target_deployment=None)

You can then reuse the detached endpoint with another deployment without recreating it.

To verify that the endpoint is detached:

Input:

deployment.endpoints

Output:

   | name   | path   | uid   | target_deployment_uid
---+--------+--------+-------+-------------------------

Delete an endpoint

warning

Deleting an endpoint also detaches the deployment associated with it.

To delete the endpoint:

endpoint.delete()

To verify deletion:

Input:

workspace.endpoints.list()

Output:

   | name   | path   | uid   | target_deployment_uid
---+--------+--------+-------+-------------------------

Update a deployment

You can update a deployment's properties, including name, description, security_options, kubernetes_options, vpa_options, pdb_options, environment_variables, cors_origins, and monitoring_options. For details on how to configure these properties, see Configure deployments.

Make sure to retrieve the deployment before updating it. See Retrieve a deployment.

Input:

deployment.update(name="my-new-deployment")
deployment

Output:

<class 'h2o_mlops._deployments.MLOpsScoringDeployment(
uid='48ece40f-8608-473a-92a6-388e164e9952',
name='my-new-deployment',
description='',
mode=<DeploymentModeType.SINGLE_MODEL: 'Single Model'>,
creator_uid='4c4eb198-bcbc-4442-91f6-a27deb53e9c1',
created_time=datetime.datetime(2025, 6, 27, 5, 4, 32, 14134, tzinfo=tzutc()),
last_modified_time=datetime.datetime(2025, 6, 27, 5, 6, 7, 730844, tzinfo=tzutc()),
)'>

Delete a deployment

note

Deleting a deployment doesn’t delete the endpoint attached to it. Instead, the endpoint becomes detached and enters a dangling state. You can reuse the same endpoint in a future deployment.

To delete a deployment:

deployment.delete()

Feedback