Webhooks de Registro de Modelo do MLflow no Azure Databricks
Importante
Esse recurso está em uma versão prévia.
Os Webhooks permitem que você escute eventos de registro de modelo para que suas integrações possam disparar ações automaticamente. Você pode usar webhooks para automatizar e integrar seu pipeline do Machine Learning com ferramentas e fluxos de trabalho existentes de CI/CD. Por exemplo, você pode disparar compilações de CI quando uma nova versão de modelo for criada ou notificar os membros da equipe por meio da margem de atraso sempre que uma transição de modelo para a produção for solicitada.
Os webhooks estão disponíveis por meio da API REST do Databricks ou do cliente Python databricks-registry-webhooks
no PyPI.
Observação
Os webhooks não estão disponíveis quando você usa modelos no Catálogo do Unity. Para ver uma alternativa, confira Posso usar solicitações de transição de fase ou disparar webhooks em eventos?. Não há suporte para o envio de webhooks para pontos de extremidade privados (pontos de extremidade que não são acessíveis da Internet pública).
Eventos de webhook
Você pode especificar um webhook para disparar em um ou mais desses eventos:
- MODEL_VERSION_CREATED: uma nova versão do modelo foi criada para o modelo associado.
- MODEL_VERSION_TRANSITIONED_STAGE: o estágio de uma versão do modelo foi alterado.
- TRANSITION_REQUEST_CREATED: um usuário solicitou a transição do estágio da versão do modelo.
- COMMENT_CREATED: um usuário escreveu um comentário sobre um modelo registrado.
- REGISTERED_MODEL_CREATED: um novo modelo registrado foi criado. Esse tipo de evento só pode ser especificado para um webhook de todo o registro, que pode ser criado ao não especificar um nome de modelo na solicitação de criação.
- MODEL_VERSION_TAG_SET: um usuário define uma marca na versão do modelo.
- MODEL_VERSION_TRANSITIONED_TO_STAGING: uma versão de modelo foi transferida para preparo.
- MODEL_VERSION_TRANSITIONED_TO_PRODUCTION: uma versão de modelo foi transferida para produção.
- MODEL_VERSION_TRANSITIONED_TO_ARCHIVED: uma versão de modelo foi arquivada.
- TRANSITION_REQUEST_TO_STAGING_CREATED: um usuário solicitou a transição de uma versão de modelo para preparo.
- TRANSITION_REQUEST_TO_PRODUCTION_CREATED: um usuário solicitou a transição de uma versão de modelo para produção.
- TRANSITION_REQUEST_TO_ARCHIVED_CREATED: um usuário solicitou uma versão de modelo arquivada.
Tipos de webhooks
Há dois tipos de Webhooks com base em seus destinos de gatilho:
- Webhooks com pontos de extremidade HTTP (webhooks de registro HTTP): enviam gatilhos para um ponto de extremidade HTTP.
- Webhooks com gatilhos de trabalho (webhooks de registro de trabalho): disparam um trabalho em um workspace do Azure Databricks. Se a lista de IPs permitidos estiver habilitada no workspace do trabalho, você deverá incluir os IPs do workspace na lista de permitidos do registro de modelo. Para saber mais, confira Lista de IPs permitidos para o webhook de registro de trabalho.
Há também dois tipos de webhooks com base no escopo, com diferentes requisitos de controle de acesso:
- Webhooks específicos do modelo: o webhook se aplica a um modelo registrado específico. Para criar, modificar, excluir ou testar webhooks específicos do modelo, você precisa ter as permissões PODE GERENCIAR no modelo registrado.
- Webhooks de todo o registro: o webhook é disparado por eventos em qualquer modelo registrado no workspace, incluindo a criação de um novo modelo registrado. Para criar um webhook de todo o registro, omita o campo
model_name
na criação. Você deve ter permissões de administrador de workspace para criar, modificar, excluir ou testar webhooks de todo o registro.
Conteúdo do webhook
Cada gatilho de evento tem campos mínimos incluídos no conteúdo para a solicitação de saída para o ponto de extremidade do webhook.
- Informações confidenciais, como o local do caminho do artefato, são excluídas. Usuários e entidades com ACLs apropriadas podem usar APIs REST ou de cliente para consultar o Registro de Modelo a fim de obter essas informações.
- O conteúdo não é criptografado. Confira Segurança para obter informações sobre como validar que o Azure Databricks é a origem do webhook.
- O campo
text
facilita a integração com o Slack. Para enviar uma mensagem do Slack, forneça um ponto de extremidade de webhook do Slack como a URL do webhook.
Conteúdo de webhook de registro de trabalho
O conteúdo de um webhook de registro de trabalho depende do tipo de trabalho e é enviado para o ponto de extremidade jobs/run-now
o workspace de destino.
Trabalhos de tarefa única
Trabalhos de tarefa única têm um dos três conteúdos com base no tipo de tarefa.
Trabalhos de wheel do Notebook e Python
Os trabalhos de wheel do Notebook e Python têm um conteúdo JSON com um dicionário de parâmetros que contém um campo event_message
.
{
"job_id": 1234567890,
"notebook_params": {
"event_message": "<Webhook Payload>"
}
}
Trabalhos de Envio de Python, JAR e Spark
Trabalhos de envio de Python, JAR e Spark têm uma carga JSON com uma lista de parâmetros.
{
"job_id": 1234567890,
"python_params": ["<Webhook Payload>"]
}
Todos os outros trabalhos
Todos os outros tipos de trabalhos têm um conteúdo JSON sem parâmetros.
{
"job_id": 1234567890
}
Trabalhos de várias tarefas
Trabalhos de várias tarefas têm um conteúdo JSON com todos os parâmetros preenchidos para considerar diferentes tipos de tarefa.
{
"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>"]
}
Exemplo de conteúdo
evento: MODEL_VERSION_TRANSITIONED_STAGE
Resposta
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
Resposta
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
Resposta
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."
}
Segurança
Por segurança, o Azure Databricks inclui a X-Databricks-Signature no cabeçalho computado a partir do conteúdo e da chave secreta compartilhada associada ao webhook usando o algoritmo HMAC com SHA-256.
Além disso, você pode incluir um cabeçalho de autorização padrão na solicitação de saída, especificando um no HttpUrlSpec
do webhook.
Verificação do cliente
Se um segredo compartilhado for definido, o destinatário do conteúdo deverá verificar a origem da solicitação HTTP usando o segredo compartilhado para codificar com HMAC o conteúdo e, em seguida, comparar o valor codificado com o X-Databricks-Signature
do cabeçalho. Isso é particularmente importante se a validação do certificado SSL estiver desabilitada (ou seja, se o campo enable_ssl_verification
for definido como false
).
Observação
enable_ssl_verification
é true
por padrão. Para certificados autoassinados, esse campo deve ser false
e o servidor de destino deve desabilitar a validação do certificado.
Para fins de segurança, o Databricks recomenda que você execute a validação secreta com a parte codificada por HMAC do conteúdo. Se você desabilitar a validação do nome do host, aumentará o risco de que uma solicitação seja roteada de forma mal-intencionada para um host não intencional.
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.')
Cabeçalho de autorização para webhooks de registro HTTP
Se um cabeçalho de autorização for definido, os clientes deverão verificar a origem da solicitação HTTP verificando o token de portador ou as credenciais de autorização no cabeçalho de autorização.
Inclusão de IP na lista de permitidos para webhooks de registro de trabalho
Para usar um webhook que dispara execuções de trabalho em um workspace diferente com a lista de IPs permitidos habilitada, você deve incluir na lista de permitidos o IP NAT da região em que o webhook está localizado para aceitar solicitações de entrada.
Se o webhook e o trabalho estiverem no mesmo workspace, você não precisará adicionar nenhum IP à sua lista de permitidos.
Se o seu trabalho estiver localizado em uma região multilocatário do Azure, consulte Endereços do plano de controle do Azure Databricks. Para todas as outras regiões, entre em contato com sua equipe de conta para identificar os IPs necessários para a lista de permissões.
Log de auditoria
Se o log de auditoria estiver habilitado para seu workspace, os seguintes eventos serão incluídos nos logs de auditoria:
- Criar webhook
- Atualizar webhook
- Listar webhook
- Excluir webhook
- Testar webhook
- Gatilho de webhook
Log de auditoria de gatilho de webhook
Para webhooks com pontos de extremidade HTTP, a solicitação HTTP enviada para a URL especificada para o webhook junto com a URL e os valores enable_ssl_verification
são registrados.
Para webhooks com gatilhos de trabalho, os valores job_id
e workspace_url
são registrados.
Exemplos
Esta seção inclui:
- Exemplo de fluxo de trabalho do webhook do registro HTTP.
- Exemplo de fluxo de trabalho do webhook do registro de trabalho.
- Exemplo de webhooks de lista.
- dois exemplos de notebook: um ilustrando a API REST e um ilustrando o cliente Python.
Exemplo de fluxo de trabalho do webhook do registro HTTP
1. Criar um webhook
Quando um ponto de extremidade HTTPS estiver pronto para receber a solicitação de evento de webhook, você poderá criar um webhook usando a API REST de Databricks de webhooks. Por exemplo, a URL do webhook pode apontar para o Slack para postar mensagens em um 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"
)
Resposta
{"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
}}}
Você também pode criar um webhook de registro HTTP com o provedor Databricks Terraform e databricks_mlflow_webhook.
2. Testar o webhook
O webhook anterior foi criado no TEST_MODE
, portanto, um evento de simulação pode ser disparado para enviar uma solicitação para a URL especificada. No entanto, o webhook não dispara em um evento real. O ponto de extremidade de teste retorna o código de status recebido e o corpo da 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"
)
Resposta
{
"status":200,
"body":"OK"
}
3. Atualizar o webhook para o status ativo
Para habilitar o webhook para eventos reais, defina seu status como ACTIVE
por meio de uma chamada de atualização, que também pode ser usada para alterar qualquer uma de suas outras propriedades.
$ 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"
)
Resposta
{"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. Excluir o webhook
Para desabilitar o webhook, defina seu status como DISABLED
(usando um comando de atualização semelhante como acima) ou exclua-o.
$ 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"
)
Resposta
{}
Exemplo de fluxo de trabalho do webhook do registro de trabalho
O fluxo de trabalho para gerenciar webhooks do registro de trabalho é semelhante aos webhooks de registro HTTP, com a única diferença sendo o campo job_spec
que substitui o campo http_url_spec
.
Com webhooks, você pode disparar trabalhos no mesmo workspace ou em um workspace diferente. O workspace é especificado usando o parâmetro opcional workspace_url
. Se não houver workspace_url
presente, o comportamento padrão será disparar um trabalho no mesmo workspace que o webhook.
Requisitos
- Um trabalho existente.
- Um token de acesso pessoal. Observe que os tokens de acesso só podem ser lidos pelo serviço MLflow e não podem ser retornados por usuários do Azure Databricks na API de Registro do Modelo.
Observação
Como melhor prática de segurança, ao autenticar com ferramentas, sistemas, scripts e aplicativos automatizados, o Databricks recomenda que você use tokens de acesso pertencentes às entidades de serviço e não aos usuários do workspace. Para criar tokens para entidades de serviço, confira Gerenciar tokens para uma entidade de serviço.
Criar um webhook de registro de trabalho
$ 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"
)
Resposta
{"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"
}}}
Você também pode criar um webhook de registro HTTP com o provedor Databricks Terraform e o databricks_mlflow_webhook.
Exemplo de webhooks de 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>")
Resposta
{"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"
}}]}