Share via


Webhooks de MLflow Model Registry en Azure Databricks

Importante

Esta característica está en versión preliminar pública.

Los webhooks permiten escuchar eventos de Model Registry para que las integraciones puedan desencadenar acciones automáticamente. Puede usar webhooks para automatizar e integrar una canalización de aprendizaje automático con flujos de trabajo y herramientas de CI/CD existentes. Por ejemplo, puede desencadenar compilaciones de integración continua cuando se crea una versión del modelo o enviar una notificación a los miembros del equipo a través de Slack cada vez que se solicita una transición del modelo a producción.

Los webhooks están disponibles a través de la API REST de Databricks o el cliente de Python databricks-registry-webhooks en PyPI.

Nota:

Los webhooks no están disponibles cuando se usan modelos en Unity Catalog. Para obtener una alternativa, consulte ¿Puedo usar solicitudes de transición de fase o desencadenar webhooks en eventos?. No se admite el envío de webhooks a puntos de conexión privados (puntos de conexión que no son accesibles desde la red pública de Internet).

Eventos de webhook

Puede especificar un webhook para desencadenar uno o varios de los eventos siguientes:

  • MODEL_VERSION_CREATED: Se creó una nueva versión de modelo para el modelo asociado.
  • MODEL_VERSION_TRANSITIONED_STAGE: Se cambió la fase de una versión del modelo.
  • TRANSITION_REQUEST_CREATED: Un usuario solicitó que se realizara la transición de la fase de una versión del modelo.
  • COMMENT_CREATED: Un usuario escribió un comentario en un modelo registrado.
  • REGISTERED_MODEL_CREATED: Se creó un nuevo modelo registrado. Este tipo de evento solo se puede especificar para un webhook de todo el registro, que se puede crear si no se especifica un nombre de modelo en la solicitud de creación.
  • MODEL_VERSION_TAG_SET: Un usuario establece una etiqueta en la versión del modelo.
  • MODEL_VERSION_TRANSITIONED_TO_STAGING: Se pasó una versión del modelo al almacenamiento provisional.
  • MODEL_VERSION_TRANSITIONED_TO_PRODUCTION: Se pasó una versión del modelo a producción.
  • MODEL_VERSION_TRANSITIONED_TO_ARCHIVED: Se archivó una versión del modelo.
  • TRANSITION_REQUEST_TO_STAGING_CREATED: Un usuario solicitó que una versión del modelo pasara al almacenamiento provisional.
  • TRANSITION_REQUEST_TO_PRODUCTION_CREATED: Un usuario solicitó que una versión del modelo pasara a producción.
  • TRANSITION_REQUEST_TO_ARCHIVED_CREATED: Un usuario solicitó que se archivara una versión del modelo.

Tipos de webhooks

Hay dos tipos de webhooks basados en sus destinos de desencadenador:

  • Webhooks con puntos de conexión HTTP: envíe desencadenadores a un punto de conexión HTTP.
  • Webhooks con desencadenadores de trabajo (webhooks de registro de trabajo): desencadene un trabajo en un área de trabajo de Azure Databricks. Si la lista de direcciones IP permitidas está habilitada en el área de trabajo del trabajo, debe agregar a la lista de permitidos las direcciones IP del área de trabajo del registro de modelos. Consulte Creación de lista de direcciones IP permitidas para webhooks del registro de trabajos para obtener más información.

También hay dos tipos de webhooks en función de su ámbito, con distintos requisitos de control de acceso:

  • Webhooks específicos del modelo: El webhook se aplica a un modelo registrado específico. Debe tener permisos PUEDE ADMINISTRAR en el modelo registrado para crear, modificar, eliminar o probar webhooks específicos del modelo.
  • Webhooks de todo el registro: Los eventos desencadenan el webhook en cualquier modelo registrado en el área de trabajo, incluida la creación de un nuevo modelo registrado. Para crear un webhook para todo el registro, omita el campo model_name en el momento de la creación. Debe tener permisos de administrador del área de trabajo para crear, modificar, eliminar o probar webhooks en todo el registro.

Carga útil de webhooks

Cada desencadenador de eventos tiene campos mínimos incluidos en la carga útil para la solicitud saliente al punto de conexión de webhook.

  • Se excluye la información confidencial, como la ubicación de la ruta de acceso del artefacto. Los usuarios y entidades de seguridad con las ACL adecuadas pueden usar las API REST o de cliente para consultar esta información en Model Registry.
  • Las cargas útiles no se cifran. Consulte Seguridad para obtener información sobre cómo validar que Azure Databricks es el origen del webhook.
  • El campo text facilita la integración de Slack. Para enviar un mensaje de Slack, proporcione un punto de conexión de webhook de Slack como dirección URL del webhook.

Carga de webhook del registro de trabajos

La carga de un webhook del registro de trabajos depende del tipo de trabajo y se envía al punto de conexión jobs/run-now del área de trabajo de destino.

Trabajos de una sola tarea

Los trabajos de una sola tarea tienen una de tres cargas basadas en el tipo de tarea.

Trabajos de rueda de Notebook y Python

Los trabajos de rueda de Notebook y Python tienen una carga JSON con un diccionario de parámetros que contiene un campo event_message.

{
  "job_id": 1234567890,
  "notebook_params": {
    "event_message": "<Webhook Payload>"
  }
}
Trabajos de envío de Python, JAR y Spark

Los trabajos de envío de Python, JAR y Spark tienen una carga JSON con una lista de parámetros.

{
  "job_id": 1234567890,
  "python_params": ["<Webhook Payload>"]
}
Todos los demás trabajos

Todos los demás tipos de trabajos tienen una carga JSON sin parámetros.

{
  "job_id": 1234567890
}

Trabajos de varias tareas

Los trabajos de varias tareas tienen una carga JSON con todos los parámetros rellenados para tener en cuenta diferentes tipos de tareas.

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

Cargas útiles de ejemplo

evento: MODEL_VERSION_TRANSITIONED_STAGE

Respuesta

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

evento: MODEL_VERSION_TAG_SET

Respuesta

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

evento: COMMENT_CREATED

Respuesta

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

Seguridad

Por seguridad, Azure Databricks incluye X-Databricks-Signature en el encabezado calculado a partir de la carga útil y la clave secreta compartida asociada al webhook mediante HMAC con el algoritmo SHA-256.

Además, para incluir un encabezado de autorización estándar en la solicitud saliente, puede especificar uno en HttpUrlSpec del webhook.

Comprobación del cliente

Si se establece un secreto compartido, el destinatario de la carga útil debe comprobar el origen de la solicitud HTTP mediante el secreto compartido para codificar en HMAC la carga y, a continuación, comparar el valor codificado con X-Databricks-Signature del encabezado. Esto es especialmente importante si la validación de certificados SSL está deshabilitada (es decir, si el campo enable_ssl_verification está establecido en false).

Nota:

enable_ssl_verification es true de forma predeterminada. Para los certificados autofirmados, este campo debe ser false, y el servidor de destino debe deshabilitar la validación de certificados.

Por motivos de seguridad, Databricks recomienda realizar la validación de secretos con la parte codificada en HMAC de la carga útil. Si deshabilita la validación de nombres de host, aumenta el riesgo de que una solicitud se pueda enrutar malintencionadamente a un host no deseado.

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

Encabezado de autorización para webhooks del registro HTTP

Si se establece un encabezado de autorización, los clientes deben comprobar el origen de la solicitud HTTP comprobando el token de portador o las credenciales de autorización en el encabezado de autorización.

Creación de lista de direcciones IP permitidas para webhooks del registro de trabajos

Para usar un webhook que desencadene ejecuciones de trabajo en un área de trabajo diferente que tenga habilitada la lista de direcciones IP permitidas, debe agregar a la lista de permitidos la IP de NAT de la región donde se encuentra el webhook para que acepte las solicitudes entrantes.

Si el webhook y el trabajo están en la misma área de trabajo, no es necesario agregar ninguna dirección IP a la lista de permitidos.

Si el trabajo se encuentra en una región multiinquilino de Azure, consulte Direcciones del plano de control de Azure Databricks. Para todas las demás regiones, comuníquese con el equipo de cuentas para conocer las direcciones IP que debe agregar a la lista de permitidos.

Registro de auditoría

Si el registro de auditoría está habilitado para el área de trabajo, se incluyen los siguientes eventos en los registros de auditoría:

  • Crear webhook
  • Actualizar webhook
  • Enumerar webhook
  • Eliminación del webhook
  • Webhook de prueba
  • Desencadenador de webhook

Registro de auditoría de desencadenadores de webhook

Para webhooks con puntos de conexión HTTP, se registra la solicitud HTTP enviada a la dirección URL especificada para el webhook, junto con la dirección URL y los valores de enable_ssl_verification.

Para los webhooks con desencadenadores de trabajo, se registran los valores de job_id y workspace_url.

Ejemplos

Esta sección incluye:

Ejemplo de flujo de trabajo de webhook del registro HTTP

1. Creación de un webhook

Cuando un punto de conexión HTTPS está listo para recibir la solicitud de evento de webhook, puede crear un webhook mediante la API REST webhooks de Databricks. Por ejemplo, la dirección URL del webhook puede apuntar a Slack para publicar mensajes en un canal.

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

Respuesta

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

También puede crear un webhook del registro HTTP con el proveedor de Databricks Terraform y databricks_mlflow_webhook.

2. Prueba del webhook

El webhook anterior se creó en TEST_MODE, por lo que se puede desencadenar un evento ficticio para enviar una solicitud a la dirección URL especificada. Sin embargo, el webhook no se desencadena en un evento real. El punto de conexión de prueba devuelve el código de estado y el cuerpo recibidos de la dirección URL especificada.

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

Respuesta

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

3. Actualización del webhook al estado activo

Para habilitar el webhook para eventos reales, establezca su estado en ACTIVE a través de una llamada de actualización, que también se puede usar para cambiar cualquiera de sus otras propiedades.

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

Respuesta

{"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. Eliminación del webhook

Para deshabilitar el webhook, establezca su estado en DISABLED (con un comando de actualización similar al anterior) o elimínelo.

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

Respuesta

{}

Ejemplo de flujo de trabajo de webhook del registro de trabajos

El flujo de trabajo para administrar webhooks del registro de trabajos es similar a los webhooks del registro HTTP, donde la única diferencia reside en el campo job_spec que reemplaza al campo http_url_spec.

Con los webhooks, puede desencadenar trabajos en la misma área de trabajo o en otra distinta. El área de trabajo se especifica mediante el parámetro opcional workspace_url. Si no hay ninguna workspace_url, el comportamiento predeterminado es desencadenar un trabajo en la misma área de trabajo del webhook.

Requisitos

Nota:

Como procedimiento recomendado de seguridad, cuando se autentique con herramientas, sistemas, scripts y aplicaciones automatizados, Databricks recomienda usar los tokens de acceso personal pertenecientes a las entidades de servicio en lugar de a los usuarios del área de trabajo. Para crear tókenes para entidades de servicio, consulte Administración de tokens de acceso para una entidad de servicio.

Creación de un webhook del registro de trabajos

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

Respuesta

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

También puede crear un webhook del registro de trabajo con el proveedor de Databricks Terraform y databricks_mlflow_webhook.

Ejemplo de webhooks del registro de lista

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

Respuesta

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

Cuaderno

Cuaderno de ejemplo de la API REST de webhooks de MLflow Model Registry

Obtener el cuaderno

Cuaderno de ejemplo de cliente Python de webhooks de MLflow Model Registry

Obtener el cuaderno