Hub documentation
Webhooks
Webhooks
WebhooksはMLOps関連の機能の基盤です。特定のリポジトリ、または特定のユーザー/組織に属するすべてのリポジトリ(自分のリポジトリだけでなく、任意のリポジトリ)での新しい変更を監視できます。
これらを使用して、モデルの自動変換、コミュニティボットの構築、またはモデル、データセット、Spaces、バケット(およびその他多くのもの)のCI/CDの構築を行うことができます。Webhooksは、リポジトリのイベントに応じて計算タスクを自動化するために、Jobsをトリガーすることもできます。
Webhooksのドキュメントは以下の通りです。また、Webhooksのいくつかのユースケースを紹介するガイドもご覧いただけます。
- データセットが更新されるたびに新しいモデルをファインチューニングする(Python)
- LLM API(NodeJS)を使用して、Hubにディスカッションボットを作成する
- メタデータの品質レポートを作成する(Python)
- Jobs (CLI) でバケット内の新しいファイルを処理する
- さらに続きます…
Webhookを作成する
Webhooksの設定で、新しいWebhookを作成したり、既存のWebhookを編集したりできます:

Webhooksは、リポジトリの更新、Pull Requests、ディスカッション、新しいコメントの監視を行うことができます。Webhooksに反応するためのSpaceを作成することも可能です。
Webhookペイロード
Webhookを登録すると、指定されたターゲットURLに対してHTTP POSTコールが送信され、新しいイベントについて通知されます。ペイロードはJSONでエンコードされます。
Webhook設定ページのアクティビティタブで、送信されたペイロードの履歴を確認できます。また、デバッグを容易にするために、過去のWebhookをリプレイすることも可能です。

例として、Pull Request がオープンされた場合の完全なペイロードを以下に示します。
{
"event": {
"action": "create",
"scope": "discussion"
},
"repo": {
"type": "model",
"name": "openai-community/gpt2",
"id": "621ffdc036468d709f17434d",
"private": false,
"url": {
"web": "https://huggingface.co/openai-community/gpt2",
"api": "https://huggingface.co/api/models/openai-community/gpt2"
},
"owner": {
"id": "628b753283ef59b5be89e937"
}
},
"discussion": {
"id": "6399f58518721fdd27fc9ca9",
"title": "Update co2 emissions",
"url": {
"web": "https://huggingface.co/openai-community/gpt2/discussions/19",
"api": "https://huggingface.co/api/models/openai-community/gpt2/discussions/19"
},
"status": "open",
"author": {
"id": "61d2f90c3c2083e1c08af22d"
},
"num": 19,
"isPullRequest": true,
"changes": {
"base": "refs/heads/main"
}
},
"comment": {
"id": "6399f58518721fdd27fc9caa",
"author": {
"id": "61d2f90c3c2083e1c08af22d"
},
"content": "Add co2 emissions information to the model card",
"hidden": false,
// Note: when `hidden` is `true`, `content` will be undefined
"url": {
"web": "https://huggingface.co/openai-community/gpt2/discussions/19#6399f58518721fdd27fc9caa"
}
},
"webhook": {
"id": "6390e855e30d9209411de93b",
"version": 3
}
}イベント
トップレベルのプロパティeventは常に指定され、イベントの性質を決定するために使用されます。
2つのサブプロパティがあります: event.actionとevent.scope。
event.scopeは、以下のいずれかの値になります。
"repo"- リポジトリに関するグローバルイベント。関連するactionの値として指定可能なもの:"create"、"delete"、"update"、"move"。"repo.content"- リポジトリのコンテンツに関するイベント。新しいコミットやタグの作成などです。新規に作成されたリファレンス/コミットにより、新しい Pull Request でもトリガーされます。Buckets の場合は、Git リファレンスではなく、ファイルの追加または削除でトリガーされます。関連するactionは常に"update"です。"repo.config"- 設定に関するイベント: Space シークレットの更新、設定の更新、DOI の更新、無効化の有無など。関連するactionは常に"update"です。"discussion"- ディスカッションまたは Pull Request の作成、タイトルまたはステータスの更新、マージ。関連するactionの取り得る値:"create"、"delete"、"update"。"discussion.comment"- コメントの作成、更新、非表示化。関連するactionの可能な値:"create"、"update"。
将来、さらに多くのスコープが追加される可能性があります。不明なイベントを処理するために、Webhookハンドラーでは、狭いスコープに対するあらゆるアクションを、より広いスコープに対する"update"アクションとみなすことができます。
例えば、将来"repo.config.dois"スコープが追加された場合、そのスコープを持つイベントは、"repo.config"スコープに対する"update"アクションとして、Webhookハンドラーによって処理できます。
リポジトリ
現在のwebhooksのバージョンでは、イベントは常にリポジトリに関連付けられるため、トップレベルのプロパティrepoは常に指定されます。例えば、次のような値を考慮してください。
"repo": {
"type": "model",
"name": "some-user/some-repo",
"id": "6366c000a2abcdf2fd69a080",
"private": false,
"url": {
"web": "https://huggingface.co/some-user/some-repo",
"api": "https://huggingface.co/api/models/some-user/some-repo"
},
"headSha": "c379e821c9c95d613899e8c4343e4bfee2b0c600",
"owner": {
"id": "61d2000c3c2083e1c08af22d"
}
}repo.headSha は、リポジトリの main ブランチの最新コミットの sha です。これは event.scope が "repo" で始まる場合のみ送信され、ディスカッションやコメントなどのコミュニティイベントでは送信されません。また、Git の履歴を持たないバケットでも送信されません。
コードの変更
コード変更について、リポジトリイベントではトップレベルのプロパティupdatedRefsが指定されます。これは更新されたリファレンスの配列です。値の例を以下に示します。
"updatedRefs": [
{
"ref": "refs/heads/main",
"oldSha": "ce9a4674fa833a68d5a73ec355f0ea95eedd60b7",
"newSha": "575db8b7a51b6f85eb06eee540738584589f131c"
},
{
"ref": "refs/tags/test",
"oldSha": null,
"newSha": "575db8b7a51b6f85eb06eee540738584589f131c"
}
]新規作成されたリファレンスには、oldShaがnullに設定されます。削除されたリファレンスには、newShaがnullに設定されます。
特定のプルリクエスト、新しいタグ、または新しいブランチへの新しいコミットに対して、リアクションを設定できます。
バケット
BucketsはGitリポジトリではありません。コミット、ブランチ、タグを持ちません。ライフサイクルイベント(create、delete、move、および可視性などの設定更新)は、他のリポジトリタイプと同様に、"repo" / "repo.config"スコープを使用します。
ファイルの変更は"repo.content"を使用しますが、ペイロードにはupdatedRefsの代わりにupdatedFilesプロパティがあります。既存のファイルを上書きすることは"add"として報告されます。1つのファイルが追加され、別のファイルが削除された後のペイロードの例を以下に示します。
{
"event": {
"action": "update",
"scope": "repo.content"
},
"repo": {
"type": "bucket",
"name": "some-user/some-bucket",
"id": "6366c000a2abcdf2fd69a080",
"private": false,
"url": {
"web": "https://huggingface.co/buckets/some-user/some-bucket",
"api": "https://huggingface.co/api/buckets/some-user/some-bucket"
},
"owner": {
"id": "61d2000c3c2083e1c08af22d"
}
},
"updatedFiles": [
{
"path": "data/train.txt",
"action": "add",
"xetHash": "55faef2f2f80cd1a087c35b729f228960739441d38073cd5aa4320751e137166",
"size": 20
},
{
"path": "data/old.txt",
"action": "delete"
},
...
],
"updatedFilesTruncated": true,
"webhook": {
"id": "6390e855e30d9209411de93b",
"version": 3
}
}10,000 件を超える場合、リストは短縮され、updatedFilesTruncated が true に設定されます。その場合は、バケットをリスト表示して全体像を確認してください。
BucketsにはディスカッションやPull Requestが存在しないため、それらに関する"discussion"および"discussion.comment"イベントは受信されません。
クライアントが独自のサーバーへのコールバックを介さず、バケットのファイル変更を直接追跡できるようにしたい場合は、バケットはライブフォローストリームも公開しています。
設定の変更
トップレベルのプロパティevent.scopeが"repo.config"の場合、updatedConfigプロパティが指定されます。これは更新された設定を含むオブジェクトです。値の例を以下に示します。
"updatedConfig": {
"private": false
}更新された設定キーがWebhookによってサポートされていない場合、オブジェクトは空になります:
"updatedConfig": {}現時点ではprivateのみがサポートされています。ここに他の設定キーが存在すると有用な場合は、website@huggingface.coまでお知らせください。
ディスカッションとプルリクエスト
トップレベルのプロパティdiscussionは、コミュニティイベント(ディスカッションとPull Request)で指定されます。discussion.isPullRequestプロパティは、そのディスカッションがPull Requestでもあるかどうかを示すブール値です(Hubでは、PRはディスカッションの特殊なタイプです)。値の例を以下に示します。
"discussion": {
"id": "639885d811ae2bad2b7ba461",
"title": "Hello!",
"url": {
"web": "https://huggingface.co/some-user/some-repo/discussions/3",
"api": "https://huggingface.co/api/models/some-user/some-repo/discussions/3"
},
"status": "open",
"author": {
"id": "61d2000c3c2083e1c08af22d"
},
"isPullRequest": true,
"changes": {
"base": "refs/heads/main"
}
"num": 3
}コメント
最上位のプロパティcommentは、コメントが作成(ディスカッションの作成を含む)または更新されたときに指定されます。値の例を以下に示します。
"comment": {
"id": "6398872887bfcfb93a306f18",
"author": {
"id": "61d2000c3c2083e1c08af22d"
},
"content": "This adds an env key",
"hidden": false,
"url": {
"web": "https://huggingface.co/some-user/some-repo/discussions/4#6398872887bfcfb93a306f18"
}
}Webhookシークレット
Webhookシークレットを設定することで、WebhookハンドラーURLに送信されたペイロードが実際にHugging Faceからのものであることを確認できます。
Webhookにシークレットを設定すると、すべてのリクエストでX-Webhook-Secret HTTPヘッダーとして送信されます。ASCII文字のみがサポートされています。
ハンドラーのURLにシークレットを直接追加することも可能です。例えば、クエリパラメータとして設定します: https://example.com/webhook?secret=XXX。
WebhookハンドラーでリクエストのHTTPヘッダーへのアクセスが複雑な場合、これは役立ちます。
配信とリトライ
Webhookペイロードは、Hub上でイベントが発生した直後に非同期で配信されます。順序は保証されません。複数のイベントが短時間の間に発生した場合、到着順序が入れ替わる可能性があります。
ハンドラーは、2xxステータスコードで配信を承認する必要があります。その他のステータスコードは、接続エラーと同様に配信失敗とみなされ、バックオフを伴って再試行されます。処理が遅い場合は、配信が失敗とみなされないように、すぐに2xxで応答し、処理を非同期で実行してください。
各配信には一意のWebhook-Id HTTP ヘッダーが付与されます。失敗した配信のリトライでは同じ ID が再利用されるため、これを冪等性キーとして扱い、各イベントを一度だけ処理できます。
Webhook への配信が繰り返し失敗すると、Webhook は自動的に停止され、所有者にメールで通知されます。設定からトラブルシューティングを行い、再度有効にできます。
レート制限
各Webhookは24時間あたり1,000回のトリガーに制限されています。使用状況は、Webhook設定ページの「Activity」タブで確認できます。
Webhook のトリガー数を増やす必要がある場合は、PRO、Team、Enterprise にアップグレードし、website@huggingface.co までご連絡ください。
Webhookの開発
HTTPS エンドポイント/URL をお持ちでない場合は、Webhook のテスト用の公開ツールを試すことができます。これらのツールは、送信されたすべてのリクエストをキャッチオール(キャプチャ)し、200 OK ステータスコードを返します。Beeceptor は、一時的な HTTP エンドポイントを作成し、受信したペイロードを確認するために使用できるツールの一つです。同様のツールとして、Webhook.site もあります。
さらに、開発中にローカルマシンで実行されているコードに実際のWebhookペイロードをルーティングできます。これは、より迅速な統合のためにテストやデバッグを行うのに最適な方法です。この方法を実行するには、localhostのポートをインターネットに公開します。このアプローチを取るには、ngrokまたはlocaltunnelを使用できます。
Webhookのデバッグ
Webhookの最近生成されたイベントを簡単に確認できます。Webhookのアクティビティタブを開くと、最近のイベントの一覧が表示されます。

ここでは、生成されたイベントのHTTPステータスコードとペイロードを確認できます。さらに、Replayボタンをクリックすることで、これらのイベントを再生成できます。
Note: WebhookのターゲットURLまたはシークレットを変更した場合、イベントのリプレイではペイロードが更新されたURLに送信されます。
注: リプレイされたイベントは、元の配信と同じWebhook-Idで送信されます。
よくある質問
組織とユーザーアカウントのどちらにWebhookを定義できますか?
いいえ、現在これはサポートされていません。
HF全体(またはモデルなど特定のリポジトリタイプ全体)のすべてのイベントにどのように購読できますか?
現在、これはエンドユーザーには公開されていませんが、website@huggingface.co までメールをお送りいただければ、こちらで切り替えることができます。
Update on GitHub