Hub documentation

Webhooks

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Webhooks

Webhooks là nền tảng cho các tính năng liên quan đến MLOps. Chúng cho phép bạn lắng nghe các thay đổi mới trên các repo cụ thể hoặc trên tất cả các repo thuộc một tập hợp người dùng/tổ chức nhất định (không chỉ các repo của bạn, mà là bất kỳ repo nào).

Bạn có thể sử dụng chúng để tự động chuyển đổi mô hình, xây dựng bot cộng đồng, hoặc xây dựng CI/CD cho các mô hình, bộ dữ liệu, Spaces và buckets của bạn (và nhiều hơn nữa!). Webhooks cũng có thể khởi chạy Jobs để tự động hóa các tác vụ tính toán khi có sự kiện xảy ra trên kho.

Tài liệu về Webhooks nằm bên dưới – hoặc bạn cũng có thể xem các hướng dẫn của chúng tôi giới thiệu một số trường hợp sử dụng có thể của Webhooks:

Tạo Webhook của bạn

Bạn có thể tạo các Webhook mới và chỉnh sửa những Webhook hiện có trong cài đặt Webhook của bạn:

Settings of an individual webhook

Webhooks có thể theo dõi các cập nhật kho, Pull Requests, thảo luận và các bình luận mới. Thậm chí, bạn có thể tạo một Space để phản hồi với các Webhooks của mình!

Webhook Payload

Sau khi đăng ký Webhook, bạn sẽ được thông báo về các sự kiện mới thông qua một cuộc gọi HTTP POST đến URL đích được chỉ định. Payload được mã hóa ở định dạng JSON.

Bạn có thể xem lịch sử các payload đã gửi trong tab hoạt động của trang cài đặt webhook, đồng thời cũng có thể phát lại các webhook trước đó để dễ dàng gỡ lỗi hơn:

image.png

Ví dụ, dưới đây là toàn bộ payload khi một Pull Request được mở:

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

Sự kiện

Thuộc tính cấp cao nhất event luôn được chỉ định và được dùng để xác định bản chất của sự kiện.

Nó có hai thuộc tính con: event.action và event.scope.

event.scope sẽ là một trong các giá trị sau:

  • "repo" - Các sự kiện toàn cục trên các kho. Các giá trị có thể có cho action tương ứng: "create", "delete", "update", "move".
  • "repo.content" - Các sự kiện trên nội dung của repo, chẳng hạn như các commit hoặc tag mới. Nó cũng được kích hoạt khi có Pull Request mới do tham chiếu/commit mới được tạo ra. Đối với Buckets, nó được kích hoạt khi có tệp được thêm hoặc xóa thay vì trên các Git refs. action tương ứng luôn là "update".
  • "repo.config" - Các sự kiện trên config: cập nhật bí mật của Space, cập nhật cài đặt, cập nhật DOI, bị vô hiệu hóa hay không, v.v. action tương ứng luôn là "update".
  • "discussion" - Tạo một discussion hoặc Pull Request, cập nhật tiêu đề hoặc trạng thái, và merge. Các giá trị có thể có của action liên quan: "create", "delete", "update".
  • "discussion.comment" - Tạo, cập nhật và ẩn một bình luận. Các giá trị có thể có cho action liên quan: "create", "update".

Có thể thêm nhiều phạm vi khác trong tương lai. Để xử lý các sự kiện không xác định, trình xử lý webhook của bạn có thể coi bất kỳ hành động nào trên một phạm vi hẹp hơn là hành động "update" trên phạm vi rộng hơn.

Ví dụ, nếu phạm vi "repo.config.dois" được thêm vào trong tương lai, bất kỳ sự kiện nào có phạm vi đó đều có thể được trình xử lý webhook của bạn coi là hành động "update" trên phạm vi "repo.config".

Kho

Trong phiên bản hiện tại của webhooks, thuộc tính cấp trên cùng repo luôn được chỉ định, vì các sự kiện luôn có thể được liên kết với một repo. Ví dụ, hãy xem xét giá trị sau:

"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 là sha của commit mới nhất trên nhánh main của repo. Nó chỉ được gửi khi event.scope bắt đầu bằng "repo", không áp dụng cho các sự kiện cộng đồng như thảo luận và bình luận, và cũng không áp dụng cho buckets, vốn không có lịch sử Git.

Thay đổi mã

Khi có thay đổi mã, thuộc tính cấp cao nhất updatedRefs được chỉ định trong các sự kiện của kho. Đây là một mảng các tham chiếu đã được cập nhật. Dưới đây là một giá trị ví dụ:

"updatedRefs": [
  {
    "ref": "refs/heads/main",
    "oldSha": "ce9a4674fa833a68d5a73ec355f0ea95eedd60b7",
    "newSha": "575db8b7a51b6f85eb06eee540738584589f131c"
  },
  {
    "ref": "refs/tags/test",
    "oldSha": null,
    "newSha": "575db8b7a51b6f85eb06eee540738584589f131c"
  }
]

Các tham chiếu mới được tạo sẽ có oldSha được đặt thành null. Các tham chiếu bị xóa sẽ có newSha được đặt thành null.

Bạn có thể phản hồi với các commit mới trên các pull request cụ thể, các tag mới hoặc các nhánh mới.

Các nhóm

Buckets không phải là kho Git: chúng không có commit, nhánh hay tag. Các sự kiện vòng đời (create, delete, move và các cập nhật cấu hình như khả năng hiển thị) sử dụng cùng các phạm vi "repo" / "repo.config" như các loại kho khác.

Thay đổi tệp sử dụng "repo.content", nhưng payload có thuộc tính updatedFiles thay vì updatedRefs. Việc ghi đè lên một tệp hiện có được báo cáo là "add". Dưới đây là một ví dụ về payload sau khi một tệp được thêm và một tệp khác bị xóa:

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

Khi vượt quá 10.000 mục, danh sách sẽ bị cắt ngắn và updatedFilesTruncated được đặt thành true. Trong trường hợp đó, hãy liệt kê bucket để có cái nhìn tổng thể.

Buckets không có thảo luận hay Pull Requests, vì vậy bạn sẽ không bao giờ nhận được các sự kiện "discussion" và "discussion.comment" cho chúng.

Nếu bạn muốn một client theo dõi trực tiếp các thay đổi tệp của một bucket thay vì thông qua một callback đến server của bạn, các bucket cũng cung cấp một live follow stream.

Thay đổi cấu hình

Khi thuộc tính cấp cao nhất event.scope là "repo.config", thuộc tính updatedConfig được chỉ định. Đây là một đối tượng chứa cấu hình đã cập nhật. Dưới đây là một giá trị ví dụ:

"updatedConfig": {
  "private": false
}

Khi khóa cấu hình đã cập nhật không được webhook hỗ trợ, đối tượng sẽ trống:

"updatedConfig": {}

Hiện tại chỉ hỗ trợ private. Nếu bạn thấy có lợi khi có thêm các khóa cấu hình ở đây, vui lòng cho chúng tôi biết tại website@huggingface.co.

Thảo luận và Pull Requests

Thuộc tính cấp cao nhất discussion được chỉ định trên các sự kiện của cộng đồng (thảo luận và Pull Requests). Thuộc tính discussion.isPullRequest là một giá trị boolean cho biết thảo luận có đồng thời là một Pull Request hay không (trên Hub, một PR là một loại thảo luận đặc biệt). Dưới đây là một giá trị ví dụ:

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

Bình luận

Thuộc tính cấp cao nhất comment được chỉ định khi một bình luận được tạo (bao gồm khi tạo thảo luận) hoặc cập nhật. Dưới đây là một giá trị ví dụ:

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

Bí mật Webhook

Việc đặt một bí mật Webhook hữu ích để đảm bảo rằng các payload được gửi đến URL trình xử lý Webhook của bạn thực sự đến từ Hugging Face.

Nếu bạn đặt một bí mật cho Webhook của mình, nó sẽ được gửi kèm dưới dạng tiêu đề HTTP X-Webhook-Secret trong mỗi yêu cầu. Chỉ các ký tự ASCII được hỗ trợ.

Bạn cũng có thể thêm bí mật trực tiếp vào URL của handler. Ví dụ, đặt nó dưới dạng tham số truy vấn: https://example.com/webhook?secret=XXX.

Điều này có thể hữu ích nếu việc truy cập các tiêu đề HTTP của yêu cầu là phức tạp đối với trình xử lý Webhook của bạn.

Giao hàng và thử lại

Webhook payloads được gửi đi bất đồng bộ, ngay sau khi sự kiện xảy ra trên Hub. Thứ tự không được đảm bảo: nếu nhiều sự kiện xảy ra gần nhau, chúng có thể đến không theo đúng trình tự.

Handler của bạn nên xác nhận việc giao hàng bằng mã trạng thái 2xx. Bất kỳ mã trạng thái nào khác đều được tính là giao hàng thất bại, giống như lỗi kết nối: nó sẽ được thử lại với backoff. Nếu quá trình xử lý của bạn chậm, hãy trả lời bằng 2xx ngay lập tức và thực hiện công việc bất đồng bộ, để việc giao hàng không bị coi là thất bại.

Mỗi lần gửi có một tiêu đề HTTP Webhook-Id duy nhất. Các lần thử lại của một lần gửi thất bại sẽ tái sử dụng cùng một ID, vì vậy bạn có thể coi nó như một khóa idempotency và xử lý mỗi sự kiện chỉ một lần.

Khi các lần gửi đến Webhook liên tục thất bại, Webhook sẽ tự động bị tạm dừng và chủ sở hữu sẽ nhận được thông báo qua email. Bạn có thể khắc phục sự cố và kích hoạt lại từ cài đặt Webhooks của mình.

Giới hạn tần suất

Mỗi Webhook bị giới hạn ở mức 1.000 lần kích hoạt trong 24 giờ. Bạn có thể xem mức sử dụng của mình trong trang cài đặt Webhook, ở tab “Activity”.

Nếu bạn cần tăng số lượng trigger cho Webhook của mình, hãy nâng cấp lên PRO, Team hoặc Enterprise và liên hệ với chúng tôi qua website@huggingface.co.

Phát triển Webhooks của bạn

Nếu bạn không có endpoint/URL HTTPS, bạn có thể thử các công cụ công khai để kiểm tra webhook. Các công cụ này đóng vai trò là catch-all (bắt tất cả các yêu cầu) được gửi đến chúng và trả về mã trạng thái 200 OK. Beeceptor là một công cụ bạn có thể sử dụng để tạo một endpoint HTTP tạm thời và xem xét payload đến. Một công cụ khác tương tự là Webhook.site.

Ngoài ra, bạn có thể định tuyến một payload Webhook thực tế đến mã đang chạy cục bộ trên máy của bạn trong quá trình phát triển. Đây là cách tuyệt vời để kiểm thử và gỡ lỗi nhằm tích hợp nhanh hơn. Bạn có thể thực hiện điều này bằng cách phơi bày cổng localhost của mình ra Internet. Để có thể đi theo hướng này, bạn có thể sử dụng ngrok hoặc localtunnel.

Gỡ lỗi Webhooks

Bạn có thể dễ dàng tìm thấy các sự kiện được tạo gần đây cho webhook của mình. Mở tab hoạt động cho webhook của bạn. Tại đó, bạn sẽ thấy danh sách các sự kiện gần đây.

image.png

Tại đây, bạn có thể xem lại mã trạng thái HTTP và payload của các sự kiện đã được tạo. Ngoài ra, bạn có thể phát lại các sự kiện này bằng cách nhấp vào nút Replay!

Lưu ý: Khi thay đổi URL đích hoặc secret của một Webhook, việc phát lại một sự kiện sẽ gửi payload đến URL đã cập nhật.

Lưu ý: Một sự kiện được phát lại sẽ được gửi với cùng Webhook-Id như lần phân phối ban đầu.

Câu hỏi thường gặp

Tôi có thể định nghĩa webhook cho tổ chức của mình thay vì tài khoản người dùng không?

Không, tính năng này hiện chưa được hỗ trợ.

Làm thế nào để tôi đăng ký tất cả các sự kiện trên HF (hoặc trên toàn bộ một loại kho, chẳng hạn như trên tất cả các mô hình)?

Hiện tại tính năng này chưa được mở cho người dùng cuối, nhưng chúng tôi có thể bật nó cho bạn nếu bạn gửi email đến website@huggingface.co.

Update on GitHub