Label Studio 怎么创建自定义 webhook 事件触发器?
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
Label Studio 内置的 webhook 事件只覆盖任务、注释和项目的增删改等固定动作。如果你的集成需要在自己代码里定义的时机收到通知——比如某个内部流程执行完毕、某类业务数据入库——就需要扩展 webhook 事件模型,注册一个自定义 action,然后在事件发生处调用触发函数。完成后,Label Studio 会在该事件发生时向你的 webhook URL 发送一个 HTTP POST 请求,body 中带有自定义的action值和 payload。
本文的操作路径来自 webhook 扩展文档 和 webhook 配置文档,配合仓库源码 label_studio/webhooks/models.py 与 label_studio/webhooks/utils.py 核对。前提是你能够修改 Label Studio 的后端代码并重新加载服务,且有一个可以接收 HTTP POST 请求的接收端点。
内置事件与自定义事件的边界
内置事件分两类:项目级任务事件和组织级事件。在 webhooks.md 中列出的事件有:Task Created、Task Deleted、Annotation Created、Annotation Updated、Annotation Deleted、Project Created、Project Updated、Project Deleted。其中 Project Created 和 Project Deleted 属于组织级事件,需要先设置环境变量启用:
LABEL_STUDIO_ALLOW_ORGANIZATION_WEBHOOKS=true自定义事件走的是另一条路:把新 action 加进WebhookAction模型,由你的代码主动触发。下面按「注册 action → 触发 → 订阅 → 验证」四步走。
第一步:在 WebhookAction 模型中注册自定义 action
内置 action 都定义在 label_studio/webhooks/models.py 的WebhookAction类里,例如TASKS_CREATED、ANNOTATION_CREATED。文档给出的扩展方式是在这个类中加一条常量和一条ACTIONS元数据记录:
class WebhookAction(models.Model): ... SOMETHING_HAPPENED = 'SOMETHING_HAPPENED' ... ACTIONS = { SOMETHING_HAPPENED: { 'name': _('Something happened'), 'description': _("A thing happened. We wanted to let you know."), 'key': 'something', }, ... ...对照仓库中现有的ACTIONS条目(如 models.py 中的 TASKS_CREATED),实际条目通常还会声明model、serializer、many、project-field等字段:key决定 payload 中该事件实例数据所用的键名。文档特别说明,如果后续要用emit_webhooks_for_instances()这类函数发送序列化实例,必须在WebhookAction.ACTIONS中声明serializer。
注册完成后,这个 action 会自动进入 webhook 的 action 选项列表——models.py 中 action 字段的 choices 是直接从ACTIONS字典动态生成的。
第二步:在事件发生处触发 action
在事件实际发生的代码位置调用触发函数。文档给出的最小示例:
result = do_something() emit_webhooks(organization, WebhookAction.SOMETHING_HAPPENED, {'something': [result]})其中 organization 可以通过Organization.objects.first()获取。
文档列出了四个可用的 Python 触发函数,定义在 label_studio/webhooks/utils.py 中:
| Python function | When to use | Additional details |
|---|---|---|
get_active_webhooks() | 获取所有处于激活状态的 webhook | |
run_webhook() | 触发单个 webhook 并传入 payload | |
emit_webhooks() | 对某个 action 触发其下所有 webhook | |
emit_webhooks_for_instances() | 用序列化实例作为 webhook 请求的 payload | 必须在WebhookAction.ACTIONS中声明serializer |
如果你的事件发生在 API 源码里,可以用装饰器替代手工调用。文档给出的两个装饰器:
| 装饰器语法 | 适用请求 | 说明 |
|---|---|---|
@api_webhook() | POST/PUT/PATCH请求 | 期望响应中带id,请求完成后通过.get_object()获取对象再发送 |
@api_webhook_for_delete() | DELETE | 删除成功后只发送id字段 |
文档示例(api_webhook()的用法,来自 utils.py 中的 docstring):
@api_webhook(WebhookAction.PROJECT_UPDATED) def put(self, request, *args, **kwargs): return super(ProjectAPI, self).put(request, *args, **kwargs)@api_webhook_for_delete()的用法类似,加在视图类的delete方法上即可,例如文档示例中的@api_webhook_for_delete(WebhookAction.ANNOTATIONS_DELETED)。
第三步:注册 webhook URL 并订阅自定义事件
自定义 action 只是“事件源”,还要有一个 webhook 订阅它。两种注册方式:
UI 方式(来自 webhooks.md):
- 打开要关联 webhook 的项目;
- 进入Settings,点击Webhooks;
- 点击Add Webhook;
- 在Payload URL字段填入你的接收端点 URL,例如
https://www.example.com/webhook。该端点必须能接收 HTTP POST 请求,且 Label Studio 实例能够访问到它; - 可选:关闭Is Active,在端点就绪前保持 webhook 停用;
- 可选:点击 + 号添加请求头(如
Authorization),用于对接收端鉴权; - 可选:选择是否随事件发送 payload。默认发送;不发送时只有
action键; - 可选:选择订阅全部事件还是特定事件。默认订阅全部,也可以只勾选某个事件;
- 保存。
API 方式:向POST /api/webhooks/发起请求(对应 label_studio/webhooks/urls.py 注册的WebhookListAPI)。请求体字段来自 label_studio/webhooks/serializers.py 的WebhookSerializer,最小示例(<你的端点URL>替换为你的接收地址,<项目ID>替换为目标项目,组织级 webhook 则省略project):
{ "url": "<你的端点URL>", "project": "<项目ID>", "send_payload": true, "send_for_all_actions": false, "actions": ["SOMETHING_HAPPENED"], "is_active": true }两个字段值得注意:
send_for_all_actions默认为true,表示该 webhook 接收所有事件;想只接收自定义事件时设为false并用actions列表精确指定(对应模型字段 help text:If value is False - used only for actions from WebhookAction)。actions会经过validate_actions校验:如果 webhook 挂在项目上,则不能包含标记了organization-only的 action(见 models.py 的 validate_actions)。
验证触发是否成功
你的接收端点会收到一个 HTTP POST 请求。按 utils.py 中 run_webhook_sync 的实现,body 结构是:action键始终存在(值为SOMETHING_HAPPENED),当send_payload为真且你传入了 payload 时,payload 内容(如上例中的{"something": [...]})会合并进 body;如果事件与项目关联,emit_webhooks还会自动附带project字段的序列化内容。
文档明确给出的失败现象与排查线索(webhooks.md Troubleshoot 一节):
- 如果 webhook URL 无法被 Label Studio 访问,可以在日志中看到一个 traceback;
- Label Studio 不会重试失败的 webhook 连接;
- 成功的 webhook 投递记录只能在 DEBUG 模式的日志中看到;
- 连接默认会超时,可通过环境变量
WEBHOOK_TIMEOUT调整。注意两处来源不一致:webhooks.md 写的是“1 second”,而当前代码 settings/base.py 中WEBHOOK_TIMEOUT的默认值是10.0秒,部署时以你环境实际加载的配置为准。
另外,当前代码会为每个 webhook 记录连续失败次数(consecutive_failures字段,随 webhook 一起返回),达到WEBHOOK_MAX_CONSECUTIVE_FAILURES阈值(默认 50)后会自动停用该 webhook,需要到 webhook 设置中重新激活;重新激活或修改 URL/请求头时该计数会重置(见 serializers.py 的 update 逻辑)。
限制与参考
- 自定义 action 必须先在
ACTIONS字典中完整声明,actions参数校验和触发函数都依赖这个字典,未注册的 action 不会被接受。 - 组织级事件(
organization-only: true)不能挂在项目级 webhook 上;如果你的自定义 action 面向组织,按文档要求启用LABEL_STUDIO_ALLOW_ORGANIZATION_WEBHOOKS=true。 - 各事件 payload 的完整字段说明(含内置事件的示例 payload)见 webhook 事件格式参考。
完成以上步骤后,在你的自定义逻辑执行处触发一次,确认接收端点收到带action: SOMETHING_HAPPENED的 POST 请求,即说明自定义事件触发器已经工作。后续新增事件时,重复「注册 action → 调用emit_webhooks或加装饰器 → 在 webhook 的actions中订阅」这三步即可。
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考