-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path03_webhooks_setup.py
202 lines (151 loc) · 6.22 KB
/
03_webhooks_setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# Databricks notebook source
# MAGIC %md
# MAGIC ## Model Registry Webhooks
# MAGIC
# MAGIC <img src="https://github.com/RafiKurlansik/laughing-garbanzo/blob/main/step3.png?raw=true">
# MAGIC
# MAGIC ### Supported Events
# MAGIC * Registered model created
# MAGIC * Model version created
# MAGIC * Transition request created
# MAGIC * Model version transitioned stage
# MAGIC
# MAGIC ### Types of webhooks
# MAGIC * HTTP webhook -- send triggers to endpoints of your choosing such as slack, AWS Lambda, Azure Functions, or GCP Cloud Functions
# MAGIC * Job webhook -- trigger a job within the Databricks workspace
# MAGIC
# MAGIC ### Use Cases
# MAGIC * Automation - automated introducing a new model to accept shadow traffic, handle deployments and lifecycle when a model is registered, etc..
# MAGIC * Model Artifact Backups - sync artifacts to a destination such as S3 or ADLS
# MAGIC * Automated Pre-checks - perform model tests when a model is registered to reduce long term technical debt
# MAGIC * SLA Tracking - Automatically measure the time from development to production including all the changes inbetween
# COMMAND ----------
# MAGIC %md
# MAGIC ### Create Webhooks
# MAGIC
# MAGIC ___
# MAGIC
# MAGIC <img src="https://github.com/RafiKurlansik/laughing-garbanzo/blob/main/webhooks2.png?raw=true" width = 600>
# MAGIC
# MAGIC - [mlflow REST API](https://mlflow.org/docs/latest/rest-api.html#)
# MAGIC - [Secrets API](https://docs.databricks.com/dev-tools/api/latest/secrets.html#secretsecretserviceputsecret)
# COMMAND ----------
# MAGIC %run ./00_includes
# COMMAND ----------
# Helper Functions
import mlflow
from mlflow.utils.rest_utils import http_request
import json
def client():
return mlflow.tracking.client.MlflowClient()
host_creds = client()._tracking_client.store.get_host_creds()
host = host_creds.host
token = host_creds.token
def mlflow_call_endpoint(endpoint, method, body='{}'):
if method == 'GET':
response = http_request(
host_creds=host_creds, endpoint="/api/2.0/mlflow/{}".format(endpoint), method=method, params=json.loads(body))
else:
response = http_request(
host_creds=host_creds, endpoint="/api/2.0/mlflow/{}".format(endpoint), method=method, json=json.loads(body))
return response.json()
# COMMAND ----------
# MAGIC %md
# MAGIC #### Transition Request Created
# MAGIC
# MAGIC These fire whenever a transition request is created for a model.
# COMMAND ----------
# MAGIC %md
# MAGIC ##### Trigger Job
# COMMAND ----------
dbutils.widgets.text("model_name", "cchalc_e2eml_churn")
model_name = dbutils.widgets.get("model_name")
# COMMAND ----------
# Which model in the registry will we create a webhook for?
trigger_job = json.dumps({
"model_name": model_name,
"events": ["TRANSITION_REQUEST_CREATED"],
"description": "Trigger the ops_validation job when a model is moved to staging.",
"status": "ACTIVE",
"job_spec": {
"job_id": "90916", # This is our 05_ops_validation notebook
"workspace_url": host,
"access_token": token
}
})
mlflow_call_endpoint("registry-webhooks/create", method = "POST", body = trigger_job)
# COMMAND ----------
# MAGIC %md
# MAGIC ##### Notifications
# MAGIC
# MAGIC Webhooks can be used to send emails, Slack messages, and more. In this case we use Slack. We also use `dbutils.secrets` to not expose any tokens, but the URL looks more or less like this:
# MAGIC
# MAGIC `https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX`
# MAGIC
# MAGIC You can read more about Slack webhooks [here](https://api.slack.com/messaging/webhooks#create_a_webhook).
# COMMAND ----------
import urllib
import json
# slack_webhook = dbutils.secrets.get("cchalc-webhooks", "e2eml-slack") # You have to set up your own webhook!
# slack_webhook = dbutils.secrets.get("akv-secrets", "e2demowest-slack-webhook") # You have to set up your own webhook!
# consider REGISTERED_MODEL_CREATED to run tests and autoamtic deployments to stages
trigger_slack = json.dumps({
"model_name": model_name,
"events": ["TRANSITION_REQUEST_CREATED"],
"description": "Notify the MLOps team that a model has moved from None to Staging.",
"status": "ACTIVE",
"http_url_spec": {
"url": slack_webhook
}
})
mlflow_call_endpoint("registry-webhooks/create", method = "POST", body = trigger_slack)
# COMMAND ----------
# MAGIC %md
# MAGIC #### Model Version Transitioned Stage
# MAGIC
# MAGIC These fire whenever a model successfully transitions to a particular stage.
# COMMAND ----------
# MAGIC %md
# MAGIC ##### Notifications
# COMMAND ----------
# Did not configure Slack webhook
import urllib
import json
trigger_slack = json.dumps({
"model_name": model_name,
"events": ["MODEL_VERSION_TRANSITIONED_STAGE"],
"description": "Notify the MLOps team that a model has moved from None to Staging.",
"http_url_spec": {
"url": slack_webhook
}
})
mlflow_call_endpoint("registry-webhooks/create", method = "POST", body = trigger_slack)
# COMMAND ----------
# MAGIC %md
# MAGIC #### Manage Webhooks
# COMMAND ----------
# MAGIC %md
# MAGIC ##### List
# COMMAND ----------
list_model_webhooks = json.dumps({"model_name": model_name})
mlflow_call_endpoint("registry-webhooks/list", method = "GET", body = list_model_webhooks)
# COMMAND ----------
# MAGIC %md
# MAGIC ##### Delete
# COMMAND ----------
# Remove a webhook
mlflow_call_endpoint("registry-webhooks/delete",
method="DELETE",
body = json.dumps({'id': '2b1e92b3a83640fbaefa3b5360a6da2f'}))
# COMMAND ----------
# MAGIC %md
# MAGIC ## Additional Topics & Resources
# MAGIC
# MAGIC **Q:** Where can I find out more information on MLflow Model Registry?
# MAGIC **A:** Check out <a href="https://mlflow.org/docs/latest/registry.html#concepts" target="_blank"> for the latest API docs available for Model Registry</a>
# COMMAND ----------
# MAGIC %md-sandbox
# MAGIC © 2021 Databricks, Inc. All rights reserved.<br/>
# MAGIC Apache, Apache Spark, Spark and the Spark logo are trademarks of the <a href="http://www.apache.org/">Apache Software Foundation</a>.<br/>
# MAGIC <br/>
# MAGIC <a href="https://databricks.com/privacy-policy">Privacy Policy</a> | <a href="https://databricks.com/terms-of-use">Terms of Use</a> | <a href="http://help.databricks.com/">Support</a>