Create secure deployments
This example demonstrates how you can create three experiments and deploy them in the three security modes supported by MLOps.
- Install Driverless AI and launch a new instance of Driverless AI.
- Install bcrypt.
- You will need the values for the following constants in order to successfully carry out the task. Contact your administrator to obtain deployment specific values.
Constant | Value | Description |
---|---|---|
MLOPS_API_URL | Usually: https://api.mlops.my.domain | Defines the URL for the MLOps Gateway component. You can verify the correct URL by navigating to the API URL in your browser. It should provide a page with a list of available routes. |
TOKEN_ENDPOINT_URL | https://mlops.keycloak.domain/auth/realms/[fill-in-realm-name]/protocol/openid-connect/token | Defines the token endpoint URL of the Identity Provider. This uses Keycloak as the Identity Provider. Keycloak Realm should be provided. |
REFRESH_TOKEN | <your-refresh-token> | Defines the user's refresh token |
CLIENT_ID | <your-client-id> | Sets the client id for authentication. This is the client you will be using to connect to MLOps. |
DRIVERLESS_URL | <your-dai-instance-url> | Defines the URL of the Driverless AI instance you have launched. |
PROJECT_NAME | SecureEndpointsExample | Defines a project name that the script will be using. |
EXPERIMENT_NAME_INSECURE | CC-Example-Insecure | Defines a name for the experiment that will be created and deployed with insecure scoring endpoint with no authorization. |
EXPERIMENT_NAME_SECURE_PLAIN | CC-Example-SecurePlain | Defines a name for the experiment that will be created and deployed with secure scoring endpoint with passphrase stored as plain text. |
EXPERIMENT_NAME_SECURE_HASHED | CC-Example-SecureHashed | Defines a name for the experiment that will be created and deployed with secure scoring endpoint with passphrase stored as a hash. |
SECURE_ENDPOINT_PASSWORD | p@55w0r6 | Defines a password that will be used for securing scoring endpoints. |
TRAIN_FILE_URL | s3://h2o-public-test-data/smalldata/kaggle/CreditCard/creditcard_train_cat.csv | Defines the training dataset. |
TARGET_COLUMN | DEFAULT_PAYMENT_NEXT_MONTH | Defines the target column for the experiment. |
DEPLOYMENT_ENVIRONMENT | DEV | Defines the target deployment environment. |
REFRESH_STATUS_INTERVAL | 1.0 | Defines a refresh interval for the deployment health check. |
MAX_WAIT_TIME | 300 | Defines maximum waiting time for the deployment to become healthy. |
The following steps demonstrate how you can use MLOps Python client to create three experiments and deploy them in the three security modes supported by MLOps.
Change the values of the following constants in your
SecureEndpointsExample.py
file as given in the preceding data table.SecureEndpointsExample.py### Constants
MLOPS_API_URL = <MLOPS_API_URL>
TOKEN_ENDPOINT_URL = <TOKEN_ENDPOINT_URL>
REFRESH_TOKEN = <REFRESH_TOKEN>
CLIENT_ID = <CLIENT_ID>
DRIVERLESS_URL = <DRIVERLESS_URL>
PROJECT_NAME = <PROJECT_NAME>
EXPERIMENT_NAME_INSECURE = <EXPERIMENT_NAME_INSECURE>
EXPERIMENT_NAME_SECURE_PLAIN = <EXPERIMENT_NAME_SECURE_PLAIN>
EXPERIMENT_NAME_SECURE_HASHED = <EXPERIMENT_NAME_SECURE_HASHED>
SECURE_ENDPOINT_PASSWORD = <SECURE_ENDPOINT_PASSWORD>
TRAIN_FILE_URL = <TRAIN_FILE_URL>
TARGET_COLUMN = <TARGET_COLUMN>
DEPLOYMENT_ENVIRONMENT = <DEPLOYMENT_ENVIRONMENT>
REFRESH_STATUS_INTERVAL = <REFRESH_STATUS_INTERVAL>
MAX_WAIT_TIME = <MAX_WAIT_TIME>SecureEndpointsExample.py### Constants
MLOPS_API_URL = "https://api.mlops.my.domain"
TOKEN_ENDPOINT_URL="https://mlops.keycloak.domain/auth/realms/[fill-in-realm-name]/protocol/openid-connect/token"
REFRESH_TOKEN="<your-refresh-token>"
CLIENT_ID="<your-mlops-client>"
DRIVERLESS_URL = "<your-dai-instance-url>"
PROJECT_NAME = "SecureEndpointsExample"
EXPERIMENT_NAME_INSECURE = "CC-Example-Insecure"
EXPERIMENT_NAME_SECURE_PLAIN = "CC-Example-SecurePlain"
EXPERIMENT_NAME_SECURE_HASHED = "CC-Example-SecureHashed"
SECURE_ENDPOINT_PASSWORD = "p@55w0r6"
TRAIN_FILE_URL = "s3://h2o-public-test-data/smalldata/kaggle/CreditCard/creditcard_train_cat.csv"
TARGET_COLUMN = "DEFAULT_PAYMENT_NEXT_MONTH"
DEPLOYMENT_ENVIRONMENT = "DEV"
REFRESH_STATUS_INTERVAL = 1.0
MAX_WAIT_TIME = 300Run the
SecureEndpointsExample.py
file.python3 SecureEndpointsExample.py
Experiment launched at: <your-dai-url>/#/experiment?key=05a0e29e-17f0-11ed-8fb0-22e31155f87d
Complete 100.00% - Status: Complete
INSECURE SCORING ENDPOINT: {'fields': ['DEFAULT_PAYMENT_NEXT_MONTH.0', 'DEFAULT_PAYMENT_NEXT_MONTH.1'], 'id': '05a0e29e-17f0-11ed-8fb0-22e31155f87d', 'score': [['0.65685487', '0.34314513']]}
Experiment launched at: <your-dai-url>/#/experiment?key=6e37a342-17f0-11ed-8fb0-22e31155f87d
Complete 100.00% - Status: Complete
SECURED WITH PLAIN PASSPHRASE SCORING ENDPOINT: {'fields': ['DEFAULT_PAYMENT_NEXT_MONTH.0', 'DEFAULT_PAYMENT_NEXT_MONTH.1'], 'id': '6e37a342-17f0-11ed-8fb0-22e31155f87d', 'score': [['0.7408047', '0.2591953']]}
Experiment launched at: <your-dai-url>/#/experiment?key=da3c95c0-17f0-11ed-8fb0-22e31155f87d
Complete 100.00% - Status: Complete
SECURED WITH HASHED PASSPHRASE SCORING ENDPOINT: {'fields': ['DEFAULT_PAYMENT_NEXT_MONTH.0', 'DEFAULT_PAYMENT_NEXT_MONTH.1'], 'id': 'da3c95c0-17f0-11ed-8fb0-22e31155f87d', 'score': [['0.6093691', '0.3906309']]}Navigate to MLOps and click the project name
SecureEndpointsExample
under Projects to view the deployed models.NoteFor more information about model deployments in MLOps, see Understand deployments in MLOps.
Click each deployment to view the Deployment Overview panel, which contains deployment details and security details.
NoteFor more information about the Deployment Overview panel, see Understanding the Deployment Overview window.
Example walkthrough
The following steps provide a walkthrough of each of the sections in the SecureEndpointsExample.py
file.
Include the following function, which finds the artifact IDs for a given experiment.
SecureEndpointsExample.pydef find_artifact_id_for_experiment(mlops_client: mlops.Client, key: str):
artifact_list = mlops_client.storage.artifact.list_entity_artifacts(
mlops.StorageListEntityArtifactsRequest(entity_id=key)
).artifact
for ar in artifact_list:
if ar.type == "dai/mojo_pipeline":
return ar.id
else:
raise LookupError(f"Could not find 'dai/mojo_pipeline' artifact.")Include the helper function, which waits for the deployment to become healthy.
Include the following function, which generates a hashed password using bcrypt.
SecureEndpointsExample.pydef hash_password(password: str) -> str:
salt = bcrypt.gensalt(
rounds=12, prefix=b"2a"
) # number of rounds and prefix are constants set for the entire MLOps platform
hashed = bcrypt.hashpw(password.encode(), salt)
return hashed.decode()Set up the Driverless AI client.
SecureEndpointsExample.pydai_client = driverlessai.Client(
address=DRIVERLESS_URL, token_provider=mlops_token_provider
)Create a project in Driverless AI. Then fetch the credit card dataset from
S3
and link the dataset to the created project.SecureEndpointsExample.py# Creating a project in DAI.
prj = dai_client.projects.create(PROJECT_NAME)
# Fetching the credit card dataset from S3.
ds_train = dai_client.datasets.create_async(
data=TRAIN_FILE_URL, data_source="s3"
).result(silent=True)
# Linking the dataset to the project.
prj.link_dataset(ds_train, dataset_type="train_dataset")Create three experiments and deploy them in the supported security configurations.
1. Insecure scoring endpoint with no authorization
Create the experiment
exp_insecure
and link the experiment to the projectprj
created in step 7.SecureEndpointsExample.pyexp_insecure = dai_client.experiments.create(
name=EXPERIMENT_NAME_INSECURE,
train_dataset=ds_train,
target_column=TARGET_COLUMN,
task="classification",
accuracy=1,
time=1,
interpretability=1,
scorer="AUC",
enable_gpus=False,
seed=1234,
cols_to_drop=["ID"],
)
# Linking an experiment to the project.
prj.link_experiment(exp_insecure)Look for the ID of the artifact to deploy.
SecureEndpointsExample.pyartifact_id_insecure = find_artifact_id_for_experiment(
mlops_client=mlops_client, key=exp_insecure.key
)Customize the composition of the deployment and specify the deployment as a single deployment with no security protocols.
SecureEndpointsExample.py# Customize the composition of the deployment
composition = mlops.DeployDeploymentComposition(
experiment_id=exp_insecure.key,
artifact_id=artifact_id_insecure,
deployable_artifact_type_name="dai/mojo_pipeline",
artifact_processor_name="dai_mojo_pipeline_extractor",
runtime_name="dai_mojo_runtime"
)
# Specify the deployment as a single deployment with no security protocols
to_deploy = mlops.DeployDeployment(
project_id=prj.key,
deployment_environment_id=deployment_env_id,
single_deployment=mlops.DeploySingleDeployment(
deployment_composition=composition
),
)Send a deployment request to create an insecure endpoint and wait for the deployment to become healthy.
SecureEndpointsExample.py# Sending a deployment request for creating an insecure endpoint.
deployment_insecure: mlops.DeployDeployment = mlops_client.deployer.deployment.create_deployment(
mlops.DeployCreateDeploymentRequest(deployment=to_deploy)
).deployment
# Waiting for the deployment to become healthy.
deployment_status = deployment_should_become_healthy(
mlops_client, deployment_insecure.id
)
if deployment_status.state != mlops.DeployDeploymentState.HEALTHY:
print(
f"Deployment still not healthy after max wait time with state: {deployment_status.state}"
)Get the status and properties of the deployment and create a sample request.
SecureEndpointsExample.py# Getting deployment's status and properties.
status_insecure: mlops.DeployDeploymentStatus = (
mlops_client.deployer.deployment_status.get_deployment_status(
mlops.DeployGetDeploymentStatusRequest(deployment_insecure.id)
)
).deployment_status
# Getting sample request for the deployment and sending a scoring request.
sample_data = request.urlopen(status_insecure.scorer.sample_request.url).read()Finally, send a sample request.
SecureEndpointsExample.pyreq = request.Request(
status_insecure.scorer.score.url,
method=status_insecure.scorer.score.method,
headers={"Content-Type": "application/json"},
)
resp = request.urlopen(req, sample_data).read()
print("INSECURE SCORING ENDPOINT:", json.loads(resp))
2. Secure scoring endpoint with passphrase stored as plain text
Create the experiment
exp_secure_plain
and link the experiment to the projectprj
created in step 7.SecureEndpointsExample.pyexp_secure_plain = dai_client.experiments.create(
name=EXPERIMENT_NAME_SECURE_PLAIN,
train_dataset=ds_train,
target_column=TARGET_COLUMN,
task="classification",
accuracy=1,
time=1,
interpretability=1,
scorer="AUC",
enable_gpus=False,
seed=1234,
cols_to_drop=["ID"],
)
# Linking an experiment to the project.
prj.link_experiment(exp_secure_plain)Look for the ID of the artifact to deploy.
SecureEndpointsExample.pyartifact_id_secure_plain = find_artifact_id_for_experiment(
mlops_client=mlops_client, key=exp_secure_plain.key
)Customize the composition of the deployment and specify the deployment as a single deployment with passphrase stored as plain text.
SecureEndpointsExample.py# Customize the composition of the deployment
composition = mlops.DeployDeploymentComposition(
experiment_id=exp_secure_plain.key,
artifact_id=artifact_id_secure_plain,
deployable_artifact_type_name="dai/mojo_pipeline",
artifact_processor_name="dai_mojo_pipeline_extractor",
runtime_name="dai_mojo_runtime"
)
# Specify the deployment as a single deployment with passphrase stored as plain text.
to_deploy = mlops.DeployDeployment(
project_id=prj.key,
deployment_environment_id=deployment_env_id,
single_deployment=mlops.DeploySingleDeployment(
deployment_composition=composition
),
security=mlops.DeploySecurity(
passphrase=mlops.DeployAuthenticationPassphrase(
hash=SECURE_ENDPOINT_PASSWORD,
passphrase_hash_type=mlops.DeployPassphraseHashType.PLAINTEXT,
)
)
)Send a deployment request to create a secure endpoint without password hashing and wait for the deployment to become healthy.
SecureEndpointsExample.py# Sending a deployment request for creating a secure endpoint without password hashing.
deployment_secure_plain: mlops.DeployDeployment = mlops_client.deployer.deployment.create_deployment(
mlops.DeployCreateDeploymentRequest(deployment=to_deploy)
).deployment
# Waiting for the deployment to become healthy.
deployment_status = deployment_should_become_healthy(
mlops_client, deployment_secure_plain.id
)
if deployment_status.state != mlops.DeployDeploymentState.HEALTHY:
print(
f"Deployment still not healthy after max wait time with state: {deployment_status.state}"
)Get the status and properties of the deployment and create a sample request.
SecureEndpointsExample.py# Getting deployment's status and properties.
status_secure_plain: mlops.DeployDeploymentStatus = (
mlops_client.deployer.deployment_status.get_deployment_status(
mlops.DeployGetDeploymentStatusRequest(deployment_secure_plain.id)
)
).deployment_status
# Getting sample request for the deployment and sending a scoring request.
req = request.Request(status_secure_plain.scorer.sample_request.url)
req.add_header("Authorization", f"Bearer {SECURE_ENDPOINT_PASSWORD}")
sample_data = request.urlopen(req).read()Finally, send a sample request.
SecureEndpointsExample.pyreq = request.Request(
status_secure_plain.scorer.score.url,
method=status_secure_plain.scorer.score.method,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {SECURE_ENDPOINT_PASSWORD}",
},
)
resp = request.urlopen(req, sample_data).read()
print("SECURED WITH PLAIN PASSPHRASE SCORING ENDPOINT:", json.loads(resp))
3. Secure scoring endpoint with passphrase stored as a hash
Create the experiment
exp_secure_hashed
and link the experiment to the projectprj
created in step 7.SecureEndpointsExample.pyexp_secure_hashed = dai_client.experiments.create(
name=EXPERIMENT_NAME_SECURE_HASHED,
train_dataset=ds_train,
target_column=TARGET_COLUMN,
task="classification",
accuracy=1,
time=1,
interpretability=1,
scorer="AUC",
enable_gpus=False,
seed=1234,
cols_to_drop=["ID"],
)
# Linking an experiment to the project.
prj.link_experiment(exp_secure_hashed)Look for the ID of the artifact to deploy.
SecureEndpointsExample.pyartifact_id_secure_hashed = find_artifact_id_for_experiment(
mlops_client=mlops_client, key=exp_secure_hashed.key
)Customize the composition of the deployment and specify the deployment as a single deployment with passphrase stored as a hash.
SecureEndpointsExample.py# Customize the composition of the deployment
composition = mlops.DeployDeploymentComposition(
experiment_id=exp_secure_hashed.key,
artifact_id=artifact_id_secure_hashed,
deployable_artifact_type_name="dai/mojo_pipeline",
artifact_processor_name="dai_mojo_pipeline_extractor",
runtime_name="dai_mojo_runtime"
)
# Specify the deployment as a single deployment with passphrase stored as a hash.
to_deploy = mlops.DeployDeployment(
project_id=prj.key,
deployment_environment_id=deployment_env_id,
single_deployment=mlops.DeploySingleDeployment(
deployment_composition=composition
),
security=mlops.DeploySecurity(
passphrase=mlops.DeployAuthenticationPassphrase(
hash=hash_password(SECURE_ENDPOINT_PASSWORD),
passphrase_hash_type=mlops.DeployPassphraseHashType.BCRYPT,
)
)
)Send a deployment request to create a secure endpoint with password hashing and wait for the deployment to become healthy.
SecureEndpointsExample.py# Sending a deployment request for creating a secure endpoint with password hashing.
deployment_secure_hashed: mlops.DeployDeployment = mlops_client.deployer.deployment.create_deployment(
mlops.DeployCreateDeploymentRequest(deployment=to_deploy)
).deployment
# Waiting for the deployment to become healthy.
deployment_status = deployment_should_become_healthy(
mlops_client, deployment_secure_hashed.id
)
if deployment_status.state != mlops.DeployDeploymentState.HEALTHY:
print(
f"Deployment still not healthy after max wait time with state: {deployment_status.state}"
)Get the status and properties of the deployment and create a sample request.
SecureEndpointsExample.py# Getting deployment's status and properties.
status_secure_hashed: mlops.DeployDeploymentStatus = (
mlops_client.deployer.deployment_status.get_deployment_status(
mlops.DeployGetDeploymentStatusRequest(deployment_secure_hashed.id)
)
).deployment_status
# Getting sample request for the deployment and sending a scoring request.
req = request.Request(status_secure_hashed.scorer.sample_request.url)
req.add_header("Authorization", f"Bearer {SECURE_ENDPOINT_PASSWORD}")
sample_data = request.urlopen(req).read()Finally, send a sample request.
SecureEndpointsExample.pyreq = request.Request(
status_secure_hashed.scorer.score.url,
method=status_secure_hashed.scorer.score.method,
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {SECURE_ENDPOINT_PASSWORD}",
},
)
resp = request.urlopen(req, sample_data).read()
print("SECURED WITH HASHED PASSPHRASE SCORING ENDPOINT:", json.loads(resp))
- Submit and view feedback for this page
- Send feedback about H2O MLOps to cloud-feedback@h2o.ai