共用方式為


工作區模型登錄 Webhook

重要

這項功能處於公開預覽狀態

Webhook 可讓您接聽工作區模型登錄事件,讓您的整合可以自動觸發動作。 您可以使用 Webhook,將機器學習管線與現有的 CI/CD 工具和工作流程自動化並整合。 例如,您可以在建立新的模型版本時觸發 CI 組建,或每次要求模型轉換至生產環境時,透過 Slack 通知您的小組成員。

Webhook 可透過Databricks REST APIdatabricks-registry-webhooks上的 Python 用戶端取得。

注意

當您使用 Unity 目錄模型時,無法使用 Webhook。 如需替代方案,請參閱我是否可以在事件上使用展示區轉換要求或觸發 Webhook?。 不支援將 Webhook 傳送至私人端點(無法從公用網際網路存取的端點)。

Webhook 事件

您可以指定一個 webhook,以在一個或多個這些事件發生時觸發:

  • MODEL_VERSION_CREATED:已為相關聯的模型建立新的模型版本。
  • MODEL_VERSION_TRANSITIONED_STAGE:模型版本的展示區已變更。
  • TRANSITION_REQUEST_CREATED:使用者要求轉換模型版本的展示區。
  • COMMENT_CREATED:使用者已對已註冊的模型撰寫留言。
  • REGISTERED_MODEL_CREATED:已建立新的已註冊模型。 這種事件類型僅能為全登錄 Webhook 指定,可透過在建立要求中不指定模型名稱來建立。
  • MODEL_VERSION_TAG_SET:使用者設定模型版本的標記。
  • MODEL_VERSION_TRANSITIONED_TO_STAGING:模型版本已轉換為預備版本。
  • MODEL_VERSION_TRANSITIONED_TO_PRODUCTION:模型版本已轉換為生產環境。
  • MODEL_VERSION_TRANSITIONED_TO_ARCHIVED:已封存模型版本。
  • TRANSITION_REQUEST_TO_STAGING_CREATED:使用者要求將模型版本轉換為預備版本。
  • TRANSITION_REQUEST_TO_PRODUCTION_CREATED:使用者要求將模型版本轉換為生產環境。
  • TRANSITION_REQUEST_TO_ARCHIVED_CREATED:使用者要求封存模型版本。

Webhook 的類型

根據 Webhook 的觸發目標有兩種類型:

  • 具有 HTTP 端點的 Webhook (HTTP 登錄 Webhooks):將觸發程式傳送至 HTTP 端點。
  • 具有工作觸發的 Webhook (工作登錄 Webhooks):在 Azure Databricks 工作區中觸發工作。 如果在工作的工作區中啟用 IP 允許清單,您必須加入允許清單模型登錄的工作區 IP。 如需詳細資訊,請參閱 工作登錄 Webhook 的 IP 允許清單。

根據範圍,Webhook 也分為兩種類型,各有不同的存取控制需求:

  • 模型特定的 Webhook:Webhook 會套用至特定已註冊模型。 您必須擁有已註冊模型的 CAN MANAGE 權限才能建立、修改、刪除或測試模型特定的 Webhook。
  • 全登錄 Webhook:Webhook 是由工作區中任何已註冊模型上的事件所觸發,包括新的已註冊模型的建立。 若要建立全登錄的 Webhook,在建立時請省略 model_name。 您必須擁有工作區管理員權限,才能建立、修改、刪除或測試全登錄的 Webhook。

Webhook 酬載

每個事件觸發程序在 Webhook 端點的傳出要求酬載中包括最小欄位。

  • 敏感性資訊,如 Artifacts 路徑位置已被排除。 具有適當 ACL 的使用者和主體可以使用用戶端或 REST API 來查詢模型登錄以取得這項資訊。
  • 酬載不會加密。 如需如何驗證 Azure Databricks 是否為 Webhook 來源的資訊,請參閱 安全性
  • 欄位 text 輔助 Slack 整合。 若要傳送 Slack 訊息,請提供 Slack Webhook 端點作為 Webhook URL。

工作登錄 Webhook 酬載

工作登錄 Webhook 的酬載取決於工作類型,並傳送至 jobs/run-now 目標工作區中的端點。

單一工作作業

單一工作作業根據任務類型,有三個酬載其中之一。

筆記本和 Python Wheel工作

筆記本和 Python Wheel 工作具有包含欄位 event_message 的參數字典的 JSON 酬載。

{
  "job_id": 1234567890,
  "notebook_params": {
    "event_message": "<Webhook Payload>"
  }
}
Python、JAR 和 Spark 提交工作

Python、JAR 和 Spark 提交工作具有含參數清單的 JSON 酬載。

{
  "job_id": 1234567890,
  "python_params": ["<Webhook Payload>"]
}
其他全部工作

所有其他類型的工作都有沒有參數的 JSON 酬載。

{
  "job_id": 1234567890
}

多任務工作

多任務工作具有 JSON 酬載,其中包含填入所有參數以考慮不同的任務類型。

{
  "job_id": 1234567890,
  "notebook_params": {
    "event_message": "<Webhook Payload>"
  },
  "python_named_params": {
    "event_message": "<Webhook Payload>"
  },
  "jar_params": ["<Webhook Payload>"],
  "python_params": ["<Webhook Payload>"],
  "spark_submit_params": ["<Webhook Payload>"]
}

酬載範例

事件:MODEL_VERSION_TRANSITIONED_STAGE

回應

POST
/your/endpoint/for/event/model-versions/stage-transition
--data {
  "event": "MODEL_VERSION_TRANSITIONED_STAGE",
  "webhook_id": "c5596721253c4b429368cf6f4341b88a",
  "event_timestamp": 1589859029343,
  "model_name": "Airline_Delay_SparkML",
  "version": "8",
  "to_stage": "Production",
  "from_stage": "None",
  "text": "Registered model 'someModel' version 8 transitioned from None to Production."
}

事件:MODEL_VERSION_TAG_SET

回應

POST
/your/endpoint/for/event/model-versions/tag-set
--data {
  "event": "MODEL_VERSION_TAG_SET",
  "webhook_id": "8d7fc634e624474f9bbfde960fdf354c",
  "event_timestamp": 1589859029343,
  "model_name": "Airline_Delay_SparkML",
  "version": "8",
  "tags": [{"key":"key1","value":"value1"},{"key":"key2","value":"value2"}],
  "text": "example@yourdomain.com set version tag(s) 'key1' => 'value1', 'key2' => 'value2' for registered model 'someModel' version 8."
}

事件:COMMENT_CREATED

回應

POST
/your/endpoint/for/event/comments/create
--data {
  "event": "COMMENT_CREATED",
  "webhook_id": "8d7fc634e624474f9bbfde960fdf354c",
  "event_timestamp": 1589859029343,
  "model_name": "Airline_Delay_SparkML",
  "version": "8",
  "comment": "Raw text content of the comment",
  "text": "A user commented on registered model 'someModel' version 8."
}

安全性

為了安全性,Azure Databricks 會在從酬載計算的標頭中包括 X-Databricks-Signature,以及使用 HMAC 搭配 SHA-256 演算法與 Webhook 相關聯的共用祕密金鑰。

另外,您可以在 Webhook 的第 HttpUrlSpec 項中指定一個標準的授權標頭,以便在傳出要求中包含該標頭。

用戶端驗證

如果已設定共用祕密,酬載收件者應該使用共用祕密來驗證 HTTP 要求的來源,以將酬載編碼為 HMAC 編碼,然後將編碼的值與標頭中的 X-Databricks-Signature 比較。 這一點尤其重要,如果 SSL 憑證驗證已停用(即,如果該 enable_ssl_verification 欄位設定為 false)。

注意

enable_ssl_verification 預設為 true。 自我簽署憑證時,此欄位必須是 false,而且目的地伺服器必須停用憑證驗證。

基於安全性考慮,Databricks 建議您使用酬載的 HMAC 編碼部分執行秘密驗證。 如果您停用主機名稱驗證,將增加要求可能被惡意導向至非預期主機的風險。

import hmac
import hashlib
import json

secret = shared_secret.encode('utf-8')
signature_key = 'X-Databricks-Signature'

def validate_signature(request):
  if not request.headers.has_key(signature_key):
    raise Exception('No X-Signature. Webhook not be trusted.')

  x_sig = request.headers.get(signature_key)
  body = request.body.encode('utf-8')
  h = hmac.new(secret, body, hashlib.sha256)
  computed_sig = h.hexdigest()

  if not hmac.compare_digest(computed_sig, x_sig.encode()):
    raise Exception('X-Signature mismatch. Webhook not be trusted.')

HTTP 登錄 Webhook 的授權標頭

如果已設定授權標頭,用戶端應該藉由驗證授權標頭中的持有人權杖或授權認證來驗證 HTTP 要求的來源。

工作登錄 Webhook 的 IP 允許清單

為了使用一個觸發不同工作區中工作執行的 Webhook,該工作區若啟用了 IP 允許清單,您必須將 Webhook 所在地區的 NAT IP 加入允許清單,以接受進來的要求。

如果 Webhook 和工作位於相同的工作區中,您就不需要將任何 IP 新增至允許清單。

如果您的工作位於 Azure 多組織用戶共享區域,請參閱Azure Databricks 控制平面位址。 針對所有其他區域,請連絡您的帳戶團隊,以識別您需要允許清單的 IP。

稽核記錄

如果已啟用工作區的稽核記錄,稽核記錄中會包含下列事件:

  • 建立 Webhook
  • 更新 Webhook
  • 列出 Webhook
  • 刪除 Webhook
  • 測試 Webhook
  • Webhook 觸發程序

Webhook 觸發稽核記錄

對於設有 HTTP 端點的 Webhook,發送到 Webhook 指定 URL 的 HTTP 要求以及 URL 和 enable_ssl_verification 值將被記錄。

針對具有工作觸發的 Webhook,會記錄 job_idworkspace_url 值。

範例

本節包含:

HTTP 登錄 Webhook 範例工作流程

1. 建立 Webhook

當 HTTPS 端點準備好接收 Webhook 事件要求時,您可以使用 Webhooks Databricks REST API 來建立 Webhook。 例如,Webhook 的 URL 可以指向 Slack,將訊息張貼至通道。

$ curl -X POST -H "Authorization: Bearer <access-token>" -d \
'{"model_name": "<model-name>",
  "events": ["MODEL_VERSION_CREATED"],
  "description": "Slack notifications",
  "status": "TEST_MODE",
  "http_url_spec": {
    "url": "https://hooks.slack.com/services/...",
    "secret": "anyRandomString"
    "authorization": "Bearer AbcdEfg1294"}}' https://<databricks-instance>/api/2.0/mlflow/registry-webhooks/create
from databricks_registry_webhooks import RegistryWebhooksClient, HttpUrlSpec

http_url_spec = HttpUrlSpec(
  url="https://hooks.slack.com/services/...",
  secret="secret_string",
  authorization="Bearer AbcdEfg1294"
)
http_webhook = RegistryWebhooksClient().create_webhook(
  model_name="<model-name>",
  events=["MODEL_VERSION_CREATED"],
  http_url_spec=http_url_spec,
  description="Slack notifications",
  status="TEST_MODE"
)

回應

{"webhook": {
   "id":"1234567890",
   "creation_timestamp":1571440826026,
   "last_updated_timestamp":1582768296651,
   "status":"TEST_MODE",
   "events":["MODEL_VERSION_CREATED"],
   "http_url_spec": {
     "url": "https://hooks.slack.com/services/...",
     "enable_ssl_verification": True
}}}

您也可以使用Databricks Terraform 供應商databricks_mlflow_webhook建立 HTTP 登錄 Webhook。

2. 測試 Webhook

先前的 Webhook 是在 TEST_MODE 建立,因此可以觸發模擬事件以將要求傳送至指定的 URL。 不過,Webhook 不會在實際事件上觸發。 測試端點會從指定的 URL 傳回接收的狀態代碼和本文。

$ curl -X POST -H "Authorization: Bearer <access-token>" -d \
'{"id": "1234567890"}' \
https://<databricks-instance>/api/2.0/mlflow/registry-webhooks/test
from databricks_registry_webhooks import RegistryWebhooksClient

http_webhook = RegistryWebhooksClient().test_webhook(
  id="1234567890"
)

回應

{
 "status":200,
 "body":"OK"
}

3. 將 Webhook 更新為活動狀態

若要啟用真實事件的 Webhook,請透過更新呼叫將其狀態設定為 ACTIVE,這也可用來變更其任何其他屬性。

$ curl -X PATCH -H "Authorization: Bearer <access-token>" -d \
'{"id": "1234567890", "status": "ACTIVE"}' \
https://<databricks-instance>/api/2.0/mlflow/registry-webhooks/update
from databricks_registry_webhooks import RegistryWebhooksClient

http_webhook = RegistryWebhooksClient().update_webhook(
  id="1234567890",
  status="ACTIVE"
)

回應

{"webhook": {
   "id":"1234567890",
   "creation_timestamp":1571440826026,
   "last_updated_timestamp":1582768296651,
   "status": "ACTIVE",
   "events":["MODEL_VERSION_CREATED"],
   "http_url_spec": {
     "url": "https://hooks.slack.com/services/...",
     "enable_ssl_verification": True
}}}

4. 刪除 Webhook

若要停用 Webhook,請將其狀態設定為 DISABLED (如上所示使用類似的更新命令),或刪除它。

$ curl -X DELETE -H "Authorization: Bearer <access-token>" -d \
'{"id": "1234567890"}' \
https://<databricks-instance>/api/2.0/mlflow/registry-webhooks/delete
from databricks_registry_webhooks import RegistryWebhooksClient

http_webhook = RegistryWebhooksClient().delete_webhook(
  id="1234567890"
)

回應

{}

工作登錄 Webhook 範例工作流程

管理工作登錄 Webhook 的工作流程類似於 HTTP 登錄 Webhook,唯一的差異在於 job_spec 欄位取代 http_url_spec 欄位。

使用 Webhook,您可以觸發相同工作區或不同工作區中的工作。 工作區是使用選擇性參數 workspace_url 來指定。 如果沒有 workspace_url 存在,預設行為就是在與 Webhook 相同的工作區中觸發工作。

需求

  • 現有的工作
  • 個人存取權杖。 請注意,存取權杖只能由 MLflow 服務讀取,而且無法由模型登錄 API 中的 Azure Databricks 使用者傳回。

注意

作為安全性最佳做法,當您使用自動化工具、系統、指令碼和應用程式進行驗證時,Databricks 建議您使用屬於服務主體的個人存取權杖,而不是工作區使用者。 若要建立服務主體的權杖,請參閱管理服務主體的權杖

建立工作登錄 Webhook

$ curl -X POST -H "Authorization: Bearer <access-token>" -d \ '{"model_name": "<model-name>",
  "events": ["TRANSITION_REQUEST_CREATED"],
  "description": "Job webhook trigger",
  "status": "TEST_MODE",
  "job_spec": {
    "job_id": "1",
    "workspace_url": "https://my-databricks-workspace.com",
    "access_token": "dapi12345..."}}'
https://<databricks-instance>/api/2.0/mlflow/registry-webhooks/create
from databricks_registry_webhooks import RegistryWebhooksClient, JobSpec

job_spec = JobSpec(
  job_id="1",
  workspace_url="https://my-databricks-workspace.com",
  access_token="dapi12345..."
)
job_webhook = RegistryWebhooksClient().create_webhook(
  model_name="<model-name>",
  events=["TRANSITION_REQUEST_CREATED"],
  job_spec=job_spec,
  description="Job webhook trigger",
  status="TEST_MODE"
)

回應

{"webhook": {
   "id":"1234567891",
   "creation_timestamp":1591440826026,
   "last_updated_timestamp":1591440826026,
   "status":"TEST_MODE",
   "events":["TRANSITION_REQUEST_CREATED"],
   "job_spec": {
     "job_id": "1",
     "workspace_url": "https://my-databricks-workspace.com"
}}}

您也可以使用 Databricks Terraform 供應商databricks_mlflow_webhook來建立工作登錄 Webhook。

列出登錄 Webhook 範例

$ curl -X GET -H "Authorization: Bearer <access-token>" -d \ '{"model_name": "<model-name>"}'
https://<databricks-instance>/api/2.0/mlflow/registry-webhooks/list
from databricks_registry_webhooks import RegistryWebhooksClient

webhooks_list = RegistryWebhooksClient().list_webhooks(model_name="<model-name>")

回應

{"webhooks": [{
   "id":"1234567890",
   "creation_timestamp":1571440826026,
   "last_updated_timestamp":1582768296651,
   "status": "ACTIVE",
   "events":["MODEL_VERSION_CREATED"],
   "http_url_spec": {
     "url": "https://hooks.slack.com/services/...",
     "enable_ssl_verification": True
}},
{
   "id":"1234567891",
   "creation_timestamp":1591440826026,
   "last_updated_timestamp":1591440826026,
   "status":"TEST_MODE",
   "events":["TRANSITION_REQUEST_CREATED"],
   "job_spec": {
     "job_id": "1",
     "workspace_url": "https://my-databricks-workspace.com"
}}]}

Notebooks

MLflow 模型登錄 Webhook REST API 範例筆記本

取得筆記本

MLflow 模型登錄 Webhooks Python 用戶端範例筆記本

取得筆記本