MLflow-Modellregistrierungswebhooks in Azure Databricks

Wichtig

Dieses Feature befindet sich in der Public Preview.

Mit Webhooks können Sie auf Modellregistrierungsereignisse lauschen, damit Ihre Integrationen automatisch Aktionen auslösen können. Sie können Webhooks verwenden, um Ihre Pipeline für maschinelles Lernen zu automatisieren und in vorhandene CI/CD-Tools und Workflows zu integrieren. Beispielsweise können Sie CI-Builds auslösen, wenn eine neue Modellversion erstellt wird, oder Ihre Teammitglieder immer dann über Slack benachrichtigen, wenn ein Modellübergang in die Produktion angefordert wird.

Webhooks sind über die Databricks-REST-API oder den Python-Client databricks-registry-webhooks auf PyPI verfügbar.

Hinweis

Webhooks sind nicht verfügbar, wenn Sie Modelle in Unity Catalog verwenden. Eine Alternative finden Sie unter Kann ich Phasenübergangsanforderungen verwenden oder Webhooks für Ereignisse auslösen?.

Webhookereignisse

Sie können einen Webhook angeben, der bei einem oder mehreren dieser Ereignisse ausgelöst werden soll:

  • MODEL_VERSION_CREATED: Für das zugeordnete Modell wurde eine neue Modellversion erstellt.
  • MODEL_VERSION_TRANSITIONED_STAGE: Die Phase einer Modellversion wurde geändert.
  • TRANSITION_REQUEST_CREATED: Ein Benutzer hat den Übergang der Phase einer Modellversion angefordert.
  • COMMENT_CREATED: Ein Benutzer hat einen Kommentar zu einem registrierten Modell geschrieben.
  • REGISTERED_MODEL_CREATED: Es wurde ein neues registriertes Modell erstellt. Dieser Ereignistyp kann nur für einen registrierungsweiten Webhook angegeben werden, der erstellt werden kann, indem in der Erstellungsanforderung kein Modellname angegeben wird.
  • MODEL_VERSION_TAG_SET: Ein Benutzer legt ein Tag für die Modellversion fest.
  • MODEL_VERSION_TRANSITIONED_TO_STAGING: Eine Modellversion ist in Staging übergegangen.
  • MODEL_VERSION_TRANSITIONED_TO_PRODUCTION: Eine Modellversion ist in die Produktion übergegangen.
  • MODEL_VERSION_TRANSITIONED_TO_ARCHIVED: Eine Modellversion wurde archiviert.
  • TRANSITION_REQUEST_TO_STAGING_CREATED: Ein Benutzer hat den Übergang einer Modellversion in Staging angefordert.
  • TRANSITION_REQUEST_TO_STAGING_CREATED: Ein Benutzer hat den Übergang einer Modellversion in die Produktion angefordert.
  • TRANSITION_REQUEST_TO_ARCHIVED_CREATED: Ein Benutzer hat die Archivierung einer Modellversion angefordert.

Arten von Webhooks

Basierend auf ihren Triggerzielen gibt es zwei Arten von Webhooks:

  • Webhooks mit HTTP-Endpunkten (HTTP Registrierungs-Webhook): Senden von Triggern an einen HTTP-Endpunkt.
  • Webhooks mit Auftragstriggern (Auftrags-Webhook): Auslösen eines Auftrags in einem Azure Databricks-Arbeitsbereich. Wenn Listen zugelassener IP-Adressen im Arbeitsbereich des Auftrags aktiviert sind, müssen Sie die Arbeitsbereichs-IPs der Modellregistrierung in einer Positivliste erfassen. Weitere Informationen finden Sie unter Listen zugelassener IP-Adressen für Auftragsregistrierungs-Webhooks.

Je nach Umfang gibt es auch zwei Arten von Webhooks mit unterschiedlichen Zugriffssteuerungsanforderungen:

  • Modellspezifische Webhooks: Der Webhook gilt für ein bestimmtes registriertes Modell. Zum Erstellen, Ändern, Löschen oder Testen modellspezifischer Webhooks benötigen Sie die KANN VERWALTEN-Berechtigungen für das registrierte Modell.
  • Registrierungsweite Webhooks: Der Webhook wird durch Ereignisse für ein beliebiges registriertes Modell im Arbeitsbereich ausgelöst, einschließlich der Erstellung eines neuen registrierten Modells. Um einen registrierungsweiten Webhook zu erstellen, lassen Sie das Feld model_name bei der Erstellung aus. Sie müssen über Arbeitsbereichsadministrator-Berechtigungen verfügen, um registrierungsweite Webhooks zu erstellen, zu ändern, zu löschen oder zu testen.

Webhooknutzlast

Jeder Ereignistrigger verfügt über minimale Felder, die in der Nutzlast für die ausgehende Anforderung an den Webhookendpunkt enthalten sind.

  • Vertrauliche Informationen wie der Speicherort des Artefaktpfads werden ausgeschlossen. Benutzer und Prinzipale mit entsprechenden ACLs können Client- oder REST-APIs verwenden, um die Modellregistrierung nach diesen Informationen abzufragen.
  • Nutzlasten werden nicht verschlüsselt. Informationen zum Überprüfen, ob Azure Databricks die Quelle des Webhooks ist, finden Sie unter Sicherheit.
  • Das text-Feld erleichtert die Slack-Integration. Um eine Slack-Nachricht zu senden, geben Sie einen Slack-Webhookendpunkt als Webhook-URL an.

Auftragsregistrierungswebhook-Nutzlast

Die Nutzlast für ein Auftragsregistrierungswebhook hängt vom Typ des Auftrags ab und wird an den jobs/run-now-Endpunkt im Zielarbeitsbereich gesendet.

Einzelaufgaben

Einzelaufgaben verfügen über eine von drei Nutzlasten basierend auf dem Vorgangstyp.

Notebook- und Python-Radaufträge

Notebook- und Python-Radaufträge verfügen über eine JSON-Nutzlast mit einem Parameterwörterbuch, das ein Feld event_messageenthält.

{
  "job_id": 1234567890,
  "notebook_params": {
    "event_message": "<Webhook Payload>"
  }
}
Python-, JAR- und Spark-Übermittlungsaufträge

Python-, JAR- und Spark-Übermittlungsaufträge verfügen über eine JSON-Nutzlast mit einer Parameterliste.

{
  "job_id": 1234567890,
  "python_params": ["<Webhook Payload>"]
}
Andere Aufträge anzeigen

Alle anderen Arten von Aufträgen verfügen über eine JSON-Nutzlast ohne Parameter.

{
  "job_id": 1234567890
}

Mehraufgabenaufträge

Multi-Task-Aufträge verfügen über eine JSON-Nutzlast mit allen Parametern, die für unterschiedliche Aufgabentypen ausgefüllt sind.

{
  "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>"]
}

Beispielnutzlasten

Ereignis: MODEL_VERSION_TRANSITIONED_STAGE

Antwort

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."
}

Ereignis: MODEL_VERSION_TAG_SET

Antwort

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."
}

Ereignis: COMMENT_CREATED

Antwort

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."
}

Sicherheit

Aus Sicherheitsgründen schließt Azure Databricks die X-Databricks-Signature in den Header ein, der aus der Nutzlast berechnet wird, und den gemeinsam verwendeten geheimen Schlüssel, der dem Webhook mit dem HMAC mit SHA-256-Algorithmus zugeordnet ist.

Darüber hinaus können Sie einen Standardautorisierungsheader in die ausgehende Anforderung einschließen, indem Sie einen in der HttpUrlSpec des Webhooks angeben.

Clientüberprüfung

Wenn ein gemeinsames Geheimnis festgelegt ist, sollte der Nutzlastempfänger die Quelle der HTTP-Anforderung überprüfen, indem er das gemeinsame Geheimnis verwendet, um die Nutzlast mit HMAC zu codieren, und dann den codierten Wert mit der X-Databricks-Signature aus dem Header vergleichen. Dies ist besonders wichtig, wenn die Überprüfung des SSL-Zertifikats deaktiviert ist (d. h. wenn das Feld enable_ssl_verification auf falsefestgelegt ist).

Hinweis

enable_ssl_verification ist standardmäßig true. Bei selbstsignierten Zertifikaten muss dieses Feld false sein, und der Zielserver muss die Zertifikatüberprüfung deaktivieren.

Aus Sicherheitsgründen empfiehlt Databricks, die Geheimnisüberprüfung mit dem HMAC-codierten Teil der Nutzlast durchzuführen. Wenn Sie die Überprüfung des Hostnamens deaktivieren, erhöhen Sie das Risiko, dass eine Anforderung in böswilliger Absicht an einen nicht vorgesehenen Host weitergeleitet wird.

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.')

Autorisierungsheader für HTTP-Registrierungswebhooks

Wenn ein Autorisierungsheader festgelegt ist, sollten Clients die Quelle der HTTP-Anforderung überprüfen, indem sie das Bearertoken oder die Autorisierungsanmeldeinformationen im Autorisierungsheader überprüfen.

Listen zugelassener IP-Adressen für Auftragsregistrierungswebhooks

Um einen Webhook zu verwenden, der Auftragsausführungen in einem anderen Arbeitsbereich auslöst, für den Listen zugelassener IP-Adressen aktiviert sind, müssen Sie die NAT-IP-Adresse der Region, in der sich der Webhook befindet, auf die Positivliste setzen, damit eingehende Anforderungen akzeptiert werden.

Wenn sich der Webhook und der Auftrag im selben Arbeitsbereich befinden, müssen Sie Ihrer Positivliste keine IP-Adressen hinzufügen.

Wenn Sich Ihr Auftrag in einer Azure-Mehrinstanzenregion befindet, finden Sie weitere Informationen unter Adressen der Azure Databricks Steuerungsebene. Wenden Sie sich für alle anderen Regionen an Ihr Kontoteam, um die IP-Adressen zu identifizieren, die Sie für die Positivliste benötigen.

Überwachungsprotokollierung

Wenn die Überwachungsprotokollierung für Ihren Arbeitsbereich aktiviert ist, sind die folgenden Ereignisse in den Überwachungsprotokollen enthalten:

  • Webhook erstellen
  • Aktualisieren von Webhooks
  • Auflisten von Webhooks
  • Löschen von Webhooks
  • Testen von Webhooks
  • Webhooktrigger

Überwachungsprotokollierung für Webhooktrigger

Bei Webhooks mit HTTP-Endpunkten wird die HTTP-Anforderung, die an die für den Webhook angegebene URL gesendet wird, zusammen mit der URL und enable_ssl_verification-Werten protokolliert.

Für Webhooks mit Auftragstriggern werden die job_id- und workspace_url-Werte protokolliert.

Beispiele

Dieser Abschnitt umfasst:

Beispiel für einen HTTP-Registrierungswebhook-Workflow

1. Erstellen eines Webhooks

Wenn ein HTTPS-Endpunkt für den Empfang der Webhookereignisanforderung bereit ist, können Sie einen Webhook mithilfe der Databricks-REST-API für Webhooks erstellen. Beispielsweise kann die URL des Webhooks auf Slack verweisen, um Nachrichten an einen Kanal zu senden.

$ 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"
)

Antwort

{"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
}}}

Sie können auch einen HTTP-Registrierungswebhook mit dem Databricks Terraform-Anbieter und databricks_mlflow_webhook erstellen.

2. Testen des Webhooks

Der vorherige Webhook wurde in TEST_MODEerstellt, sodass ein Pseudoereignis ausgelöst werden kann, um eine Anforderung an die angegebene URL zu senden. Der Webhook wird jedoch nicht für ein echtes Ereignis ausgelöst. Der Testendpunkt gibt den empfangenen Statuscode und Text von der angegebenen URL zurück.

$ 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"
)

Antwort

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

3. Aktualisieren des Webhooks in den aktiven Status

Um den Webhook für echte Ereignisse zu aktivieren, legen Sie seinen Status über einen Updateaufruf auf ACTIVE fest, der auch verwendet werden kann, um seine anderen Eigenschaften zu ändern.

$ 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"
)

Antwort

{"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. Löschen des Webhooks

Um den Webhook zu deaktivieren, legen Sie seinen Status auf DISABLED fest (mit einem ähnlichen Updatebefehl wie oben), oder löschen Sie ihn.

$ 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"
)

Antwort

{}

Beispiel für einen Auftragsregistrierungswebhook-Workflow

Der Workflow zum Verwalten von Webhooks für die Auftragsregistrierung ähnelt HTTP-Registrierungswebhooks, wobei der einzige Unterschied das job_spec-Feld ist, das das http_url_spec-Feld ersetzt.

Mit Webhooks können Sie Aufträge im gleichen Arbeitsbereich oder in einem anderen Arbeitsbereich auslösen. Der Arbeitsbereich wird mit dem optionalen Parameter workspace_url angegeben. Wenn kein workspace_url vorhanden ist, wird standardmäßig ein Auftrag im selben Arbeitsbereich ausgelöst, in dem sich der Webhook befindet.

Anforderungen

  • Ein vorhandener Auftrag.
  • Ein persönliches Zugriffstoken. Beachten Sie, dass Zugriffstoken nicht in dem Webhookobjekt enthalten sind, das von den APIs zurückgegeben wird.

Hinweis

Als bewährte Methode für die Sicherheit empfiehlt Databricks, dass Sie bei der Authentifizierung mit automatisierten Tools, Systemen, Skripten und Anwendungen persönliche Zugriffstoken verwenden, die zu Dienstprinzipalen und nicht zu Benutzern des Arbeitsbereichs gehören. Informationen zum Erstellen von Token für Dienstprinzipale finden Sie unter Verwalten von Token für einen Dienstprinzipal.

Erstellen eines Auftragsregistrierungs-Webhooks

$ 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"
)

Antwort

{"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"
}}}

Sie können auch einen Auftragsregistrierungs-Webhook mit dem Databricks Terraform-Anbieter und databricks_mlflow_webhook erstellen.

Beispiel zum Auflisten von Registrierungswebhooks

$ 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>")

Antwort

{"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-Modellregistrierungs-Webhooks: REST-API-Beispielnotebook

Notebook abrufen

MLflow-Modellregistrierungs-Webhooks: Python-Client-Beispielnotebook

Notebook abrufen