Workspace Model Registry webhooks
Aperçu
Cette fonctionnalité est en aperçu public.
Les webhooks vous permettent d'écouter les événements du Workspace Model Registry afin que vos intégrations puissent automatiquement Trigger des actions. Vous pouvez utiliser des webhooks pour automatiser et intégrer votre pipeline de Machine Learning avec les outils et workflows CI/CD existants. Par exemple, vous pouvez Trigger des builds CI lorsqu'une nouvelle version de modèle est créée ou avertir les membres de votre équipe via Slack chaque fois qu'une transition de modèle vers la production est demandée.
Les webhooks sont disponibles via l'API REST Databricks ou le client Python databricks-registry-webhooks sur PyPI.
Les webhooks ne sont pas disponibles lorsque vous utilisez Models in Unity Catalog. Pour une alternative, consultez Puis-je utiliser des demandes de transition d'étape ou Trigger des webhooks sur des événements ?. L'envoi de webhooks vers des endpoints privés (endpoints qui ne sont pas accessibles depuis l'internet public) n'est pas pris en charge.
Événements Webhook
Vous pouvez spécifier un webhook à trigger lors d'un ou plusieurs de ces événements :
- MODEL_VERSION_CREATED : Une nouvelle version de modèle a été créée pour le modèle associé.
- **MODEL_VERSION_TRANSITIONED_STAGE** : l'étape d'une version de modèle a été modifiée.
- **TRANSITION_REQUEST_CREATED** : Un utilisateur a demandé la transition de l'étape d'une version de modèle.
- **COMMENT_CREATED** : Un utilisateur a écrit un commentaire sur un modèle enregistré.
- REGISTERED_MODEL_CREATED : Un nouveau modèle enregistré a été créé. Ce type d'événement ne peut être spécifié que pour un webhook à l'échelle du registre, qui peut être créé en ne spécifiant pas de nom de modèle dans la requête de création.
- MODEL_VERSION_TAG_SET : Un utilisateur a défini une balise sur la version du modèle.
- VERSION_DU_MODÈLE_TRANSITIONNÉE_VERS_LA_PRÉ-PRODUCTION : Une version de modèle est passée en pré-production.
- **MODEL_VERSION_TRANSITIONED_TO_PRODUCTION** : Une version de modèle a été transitionnée en production.
- MODEL_VERSION_TRANSITIONED_TO_ARCHIVED : une version de modèle a été archivée.
- TRANSITION_REQUEST_TO_STAGING_CREATED : un utilisateur a demandé qu’une version de modèle soit transférée vers la phase de staging.
- TRANSITION_REQUEST_TO_PRODUCTION_CREATED : Un utilisateur a demandé qu'une version de modèle soit transitionnée en production.
- TRANSITION_REQUEST_TO_ARCHIVED_CREATED : Un utilisateur a demandé qu'une version de modèle soit archivée.
Types de webhooks
Il existe deux types de webhooks selon leurs cibles de Trigger :
- **Webhooks avec des Endpoint HTTP (webhooks de registre HTTP)** : Envoyez des Trigger à un Endpoint HTTP.
- **Webhooks with Job Triggers (Job registry webhooks)** : Trigger a Job dans un Workspace Databricks. Si la liste d'adresses IP autorisées est activée dans le workspace du job, vous devez ajouter les adresses IP du workspace du registre de modèles à la liste d'autorisation. Voir l'inscription des webhooks de registre de Job sur liste blanche d'IP pour plus d'information.
Il existe également deux types de webhooks basés sur leur portée, avec des exigences de contrôle d'accès différentes :
- Webhooks spécifiques au modèle : Le webhook s'applique à un modèle enregistré spécifique. Vous devez disposer des autorisations CAN MANAGE sur le modèle enregistré pour créer, modifier, supprimer ou tester les webhooks spécifiques au modèle.
- **Webhooks à l’échelle du registre** : Le webhook est Trigger par des événements sur n’importe quel modèle enregistré dans le Workspace, y compris la création d’un nouveau modèle enregistré. Pour créer un webhook à l'échelle du registre, omettez le champ
model_namelors de la création. Vous devez disposer des autorisations d'administrateur du Workspace pour créer, modifier, supprimer ou tester des webhooks à l'échelle du registre.
Charge utile du webhook
Each event trigger has minimal fields included in the payload for the outgoing request to the webhook endpoint.
- Les informations sensibles comme l'emplacement du chemin d'artefact sont exclues. Les utilisateurs et les principaux disposant des ACL appropriées peuvent utiliser des API client ou REST pour interroger le Model Registry afin d’obtenir ces informations.
- Les charges utiles ne sont pas chiffrées. Consultez Sécurité pour plus d'informations sur la façon de valider que Databricks est la source du webhook.
- Le champ
textfacilite l'intégration de Slack. Pour envoyer un message Slack, indiquez un endpoint de webhook Slack comme URL de webhook.
Charge utile du webhook du registre Job
La charge utile d'un webhook de registre de Job dépend du type de Job et est envoyée à l'Endpoint jobs/run-now du Workspace cible.
Jobs à tâche unique
Les Jobs à tâche unique ont l'une des trois charges utiles en fonction du type de tâche.
Notebook et Python wheel Jobs
Les jobs de Notebook et de Python wheel comportent une charge utile JSON avec un dictionnaire de paramètres qui contient un champ event_message.
{
"job_id": 1234567890,
"notebook_params": {
"event_message": "<Webhook Payload>"
}
}
Jobs Python, JAR et Spark Submit
Les jobs Spark submit, JAR et Python comportent une charge utile JSON avec une liste de paramètres.
{
"job_id": 1234567890,
"python_params": ["<Webhook Payload>"]
}
Tous les autres jobs
Tous les autres types de Jobs ont une charge utile JSON sans paramètres.
{
"job_id": 1234567890
}
Jobs multitâches
Les Jobs multi-tâches ont une charge utile JSON avec tous les paramètres renseignés pour tenir compte des différents types de tâches.
{
"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>"]
}
Exemples de charges utiles
événement : MODEL_VERSION_TRANSITIONED_STAGE
Réponse
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."
}
événement : MODEL_VERSION_TAG_SET
Réponse
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@example.com set version tag(s) 'key1' => 'value1', 'key2' => 'value2' for registered model 'someModel' version 8."
}
événement : COMMENT_CREATED
Réponse
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."
}
Sécurité
Pour des raisons de sécurité, Databricks inclut la signature X-Databricks-Signature dans l'en-tête, calculée à partir de la charge utile et de la clé secrète partagée associée au webhook, à l'aide de l'algorithme HMAC avec SHA-256.
De plus, vous pouvez inclure un en-tête d'autorisation standard dans la requête sortante en en spécifiant un dans le HttpUrlSpec du webhook.
Vérification du client
Si un secret partagé est défini, le destinataire de la charge utile doit vérifier la source de la requête HTTP en utilisant le secret partagé pour coder la charge utile en HMAC, puis en comparant la valeur codée avec le X-Databricks-Signature de l’en-tête. Ceci est particulièrement important si la validation du certificat SSL est désactivée (c’est-à-dire, si le champ enable_ssl_verification est défini sur false).
enable_ssl_verification est true par default. Pour les certificats auto-signés, ce champ doit être false, et le serveur de destination doit désactiver la validation du certificat.
À des fins de sécurité, Databricks vous recommande d'effectuer la validation du secret avec la partie HMAC-encodée de la charge utile. Si vous désactivez la validation du host name, vous augmentez le risque qu'une requête puisse être acheminée de manière malveillante vers un hôte non intentionnel.
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.')
En-tête d'autorisation pour les webhooks de registre HTTP
Si un en-tête d'autorisation est défini, les clients doivent vérifier la source de la requête HTTP en vérifiant le jeton du porteur ou les identifiants d'autorisation dans l'en-tête d'autorisation.
Liste d'autorisation IP pour les webhooks d'enregistrement de Job
Pour utiliser un webhook qui Trigger des exécutions de Job dans un autre Workspace pour lequel la liste d'adresses IP autorisées est activée, vous devez autoriser l'adresse IP NAT de la région où se trouve le webhook pour accepter les requêtes entrantes.
Si le webhook et le Job se trouvent dans le même Workspace, vous n’avez pas besoin d’ajouter d’adresses IP à votre liste d’autorisation.
Contactez votre équipe de compte pour identifier les adresses IP que vous devez autoriser.
Journalisation d'audit
Si la journalisation d'audit est activée pour votre workspace, les événements suivants sont inclus dans les logs d'audit :
- Créer un webhook
- Mettre à jour le webhook
- Lister le webhook
- Supprimer le webhook.
- Tester un webhook
- Trigger de webhook
Journalisation d'audit du Trigger de webhook
Pour les webhooks avec des endpoints HTTP, la requête HTTP envoyée à l'URL spécifiée pour le webhook, ainsi que l'URL et les valeurs enable_ssl_verification sont journalisées.
Pour les webhooks avec Trigger de Job, les valeurs job_id et workspace_url sont enregistrées.
Exemples
Cette section comprend :
- Exemple de workflow de webhook de registre HTTP.
- exemple de workflow de webhook du registre de Jobs.
- Exemple de liste de webhooks.
- deux notebooks d'exemple: l'un illustrant l'API REST et l'autre illustrant le client Python.
Exemple de workflow de webhook de registre HTTP
1. Créez un webhook
Lorsqu'un Endpoint HTTPS est prêt à recevoir la requête d'événement de webhook, vous pouvez créer un webhook à l'aide de l'API REST Webhooks Databricks. Par exemple, l'URL du webhook peut pointer vers Slack pour publier des messages sur un canal de distribution.
$ 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"
)
Réponse
{"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
Vous pouvez également créer un webhook de registre HTTP avec le fournisseur Databricks Terraform et databricks_mlflow_webhook.
2. Testez le webhook
Le webhook précédent a été créé dans TEST_MODE, de sorte qu'un événement simulé peut être déclenché pour envoyer une requête à l'URL spécifiée. Cependant, le webhook ne Trigger pas sur un événement réel. L'endpoint de test renvoie le code d'état et le corps reçus de l'URL spécifiée.
$ 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"
)
Réponse
{
"status":200,
"body":"OK"
}
3. Mettre à jour le webhook au statut actif
Pour activer le webhook pour des événements réels, définissez son statut sur ACTIVE via un appel de mise à jour, qui peut également être utilisé pour modifier l’une de ses autres propriétés.
$ 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"
)
Réponse
{"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. Supprimez le webhook
Pour désactiver le webhook, définissez son état sur DISABLED (en utilisant une commande de mise à jour similaire à celle ci-dessus) ou supprimez-le.
$ 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"
)
Réponse
{}
Exemple de workflow de webhook de registre des jobs
Le flux de travail pour la gestion des webhooks d'enregistrement de Job est similaire aux webhooks d'enregistrement HTTP, la seule différence étant le champ job_spec qui remplace le champ http_url_spec.
Avec les webhooks, vous pouvez Trigger des Jobs dans le même Workspace ou dans un Workspace différent. Le Workspace est spécifié à l'aide du parameter facultatif workspace_url. Si aucun workspace_url n'est présent, le comportement par default est de Trigger un Job dans le même Workspace que le webhook.
Exigences
- Un Job existant.
- Un jeton d'accès personnel. Notez que les jetons d'accès ne peuvent être lus que par le service MLflow et ne peuvent pas être renvoyés par les utilisateurs Databricks dans l'API Model Registry.
En tant que bonne pratique de sécurité lorsque vous vous authentifiez avec des outils, des systèmes, des scripts et des applications automatisés, Databricks vous recommande d'utiliser des jetons OAuth.
Si vous utilisez l'authentification par jeton d'accès personnel, Databricks recommande d'utiliser des jetons d'accès personnels appartenant aux Service Principal plutôt qu'aux utilisateurs du Workspace. Pour créer des jetons pour les Service Principals, consultez Gérer les jetons pour un Service Principal.
Créer un webhook de registre de Job
$ 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"
)
Réponse
{"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"
Vous pouvez également créer un webhook de registre de Job avec le fournisseur Databricks Terraform et databricks_mlflow_webhook.
Exemple de liste de webhooks du registre
$ 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>")
Réponse
{"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"
}}]}