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๋Š” MLOps ๊ด€๋ จ ๊ธฐ๋Šฅ์˜ ๊ธฐ๋ฐ˜์ž…๋‹ˆ๋‹ค. ํŠน์ • ์ €์žฅ์†Œ ๋˜๋Š” ํŠน์ • ์‚ฌ์šฉ์ž/์กฐ์ง์— ์†ํ•œ ๋ชจ๋“  ์ €์žฅ์†Œ(๋ณธ์ธ์˜ ์ €์žฅ์†Œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์–ด๋–ค ์ €์žฅ์†Œ๋“ )์˜ ์ƒˆ๋กœ์šด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋ธ์˜ ์ž๋™ ๋ณ€ํ™˜, ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ด‡ ๊ตฌ์ถ•, ๋ชจ๋ธ/๋ฐ์ดํ„ฐ์…‹/Spaces/๋ฒ„ํ‚ท์— ๋Œ€ํ•œ CI/CD ๊ตฌ์ถ• ๋“ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ ์™ธ ๋‹ค์–‘ํ•œ ์šฉ๋„). Webhooks๋Š” ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•˜์—ฌ ๊ณ„์‚ฐ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•ด Jobs๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Webhooks์— ๋Œ€ํ•œ ๋ฌธ์„œ๊ฐ€ ์•„๋ž˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” Webhooks์˜ ๋ช‡ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฐ€์ด๋“œ๋ฅผ ๋‘˜๋Ÿฌ๋ณด์‹ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

Webhook ์ƒ์„ฑ

Webhooks ์„ค์ •์—์„œ ์ƒˆ Webhook์„ ์ƒ์„ฑํ•˜๊ณ  ๊ธฐ์กด Webhook์„ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Settings of an individual webhook

Webhooks๋Š” ์ €์žฅ์†Œ ์—…๋ฐ์ดํŠธ, Pull Requests, ํ† ๋ก , ์ƒˆ ๋Œ“๊ธ€์„ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Webhooks์— ๋ฐ˜์‘ํ•˜๋Š” Space๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค!

Webhook ํŽ˜์ด๋กœ๋“œ

Webhook์„ ๋“ฑ๋กํ•˜๋ฉด ์ง€์ •๋œ ๋Œ€์ƒ URL์— HTTP POST ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ƒˆ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํŽ˜์ด๋กœ๋“œ๋Š” JSON์œผ๋กœ ์ธ์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค.

webhook ์„ค์ • ํŽ˜์ด์ง€์˜ ํ™œ๋™ ํƒญ์—์„œ ์ „์†ก๋œ ํŽ˜์ด๋กœ๋“œ์˜ ์ด๋ ฅ์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋””๋ฒ„๊น…์„ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๊ณผ๊ฑฐ์˜ webhook์„ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

image.png

์˜ˆ๋ฅผ ๋“ค์–ด, 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์€ ํ•ญ์ƒ ์ง€์ •๋˜๋ฉฐ ์ด๋ฒคํŠธ์˜ ์„ฑ๊ฒฉ์„ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋‘ ๊ฐœ์˜ ํ•˜์œ„ ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค: event.action์™€ event.scope์ž…๋‹ˆ๋‹ค.

event.scope๋Š” ๋‹ค์Œ ๊ฐ’ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค:

  • "repo" - ์ €์žฅ์†Œ ์ „์—ญ ์ด๋ฒคํŠธ. ๊ด€๋ จ action์˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’: "create", "delete", "update", "move".
  • "repo.content" - ์ €์žฅ์†Œ์˜ ์ฝ˜ํ…์ธ ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋กœ, ์ƒˆ๋กœ์šด ์ปค๋ฐ‹์ด๋‚˜ ํƒœ๊ทธ ๋“ฑ์ด ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์ฐธ์กฐ/์ปค๋ฐ‹์œผ๋กœ ์ธํ•ด ์ƒˆ๋กœ์šด Pull Request์—์„œ๋„ ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. Buckets์˜ ๊ฒฝ์šฐ Git refs๊ฐ€ ์•„๋‹ˆ๋ผ ํŒŒ์ผ์ด ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋  ๋•Œ ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ๊ด€๋ จ action์€ ํ•ญ์ƒ "update"์ž…๋‹ˆ๋‹ค.
  • "repo.config" - config์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ: Space secrets ์—…๋ฐ์ดํŠธ, ์„ค์ • ์—…๋ฐ์ดํŠธ, DOI ์—…๋ฐ์ดํŠธ, ๋น„ํ™œ์„ฑํ™” ์—ฌ๋ถ€ ๋“ฑ. ๊ด€๋ จ action์€ ํ•ญ์ƒ "update"์ž…๋‹ˆ๋‹ค.
  • "discussion" - ํ† ๋ก  ๋˜๋Š” Pull Request ์ƒ์„ฑ, ์ œ๋ชฉ ๋˜๋Š” ์ƒํƒœ ์—…๋ฐ์ดํŠธ, ๋ณ‘ํ•ฉ. ๊ด€๋ จ action์˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’: "create", "delete", "update".
  • "discussion.comment" - ๋Œ“๊ธ€ ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ ๋ฐ ์ˆจ๊น€. ๊ด€๋ จ action์˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’: "create", "update".

ํ–ฅํ›„ ๋” ๋งŽ์€ ์Šค์ฝ”ํ”„๊ฐ€ ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•Œ๋ ค์ง€์ง€ ์•Š์€ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด, ์›นํ›… ํ•ธ๋“ค๋Ÿฌ๋Š” ์ขํ˜€์ง„ ์Šค์ฝ”ํ”„์— ๋Œ€ํ•œ ๋ชจ๋“  ์ž‘์—…์„ ๋” ๋„“์€ ์Šค์ฝ”ํ”„์— ๋Œ€ํ•œ "update" ์ž‘์—…์œผ๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํ–ฅํ›„ "repo.config.dois" ์Šค์ฝ”ํ”„๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด, ํ•ด๋‹น ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ์ด๋ฒคํŠธ๋Š” ์›นํ›… ํ•ธ๋“ค๋Ÿฌ์—์„œ "repo.config" ์Šค์ฝ”ํ”„์— ๋Œ€ํ•œ "update" ์•ก์…˜์œผ๋กœ ๊ฐ„์ฃผ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฆฌํฌ์ง€ํ† ๋ฆฌ

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๊ฐ€ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์—…๋ฐ์ดํŠธ๋œ ์ฐธ์กฐ(reference)๋“ค์˜ ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค. ์˜ˆ์‹œ ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

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

์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์ฐธ์กฐ๋Š” oldSha๊ฐ€ null๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์‚ญ์ œ๋œ ์ฐธ์กฐ๋Š” newSha๊ฐ€ null๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

ํŠน์ • pull request, ์ƒˆ ํƒœ๊ทธ, ๋˜๋Š” ์ƒˆ ๋ธŒ๋žœ์น˜์— ๋Œ€ํ•œ ์ƒˆ ์ปค๋ฐ‹์— ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„ํ‚ท

Buckets์€ Git ์ €์žฅ์†Œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ปค๋ฐ‹, ๋ธŒ๋žœ์น˜, ํƒœ๊ทธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ผ์ดํ”„์‚ฌ์ดํด ์ด๋ฒคํŠธ(create, delete, move ๋ฐ ๊ฐ€์‹œ์„ฑ ์„ค์ • ์—…๋ฐ์ดํŠธ ๋“ฑ)๋Š” ๋‹ค๋ฅธ ์ €์žฅ์†Œ ์œ ํ˜•๊ณผ ๋™์ผํ•œ "repo" / "repo.config" ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ผ ๋ณ€๊ฒฝ์€ "repo.content"๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ํŽ˜์ด๋กœ๋“œ์—๋Š” updatedRefs ๋Œ€์‹  updatedFiles ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒŒ์ผ์„ ๋ฎ์–ด์“ฐ๋Š” ๊ฒฝ์šฐ "add"๋กœ ๋ณด๊ณ ๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ํ•˜๋‚˜๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ  ๋‹ค๋ฅธ ํŒŒ์ผ ํ•˜๋‚˜๊ฐ€ ์‚ญ์ œ๋œ ํ›„์˜ ํŽ˜์ด๋กœ๋“œ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

{
  "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" ์ด๋ฒคํŠธ๋ฅผ ์ ˆ๋Œ€ ์ˆ˜์‹ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž์ฒด ์„œ๋ฒ„๋กœ์˜ ์ฝœ๋ฐฑ์„ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์ถ”์ ํ•˜๋Š” ๋Œ€์‹  ๋ฒ„ํ‚ท์˜ ํŒŒ์ผ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ง์ ‘ ์ถ”์ ํ•˜๋ ค๋ฉด, ๋ฒ„ํ‚ท์€ live follow stream๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์„ค์ • ๋ณ€๊ฒฝ

์ตœ์ƒ์œ„ ์†์„ฑ event.scope๊ฐ€ "repo.config"์ธ ๊ฒฝ์šฐ, updatedConfig ์†์„ฑ์ด ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ์ด ์†์„ฑ์€ ์—…๋ฐ์ดํŠธ๋œ config๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๊ฐ’์˜ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

"updatedConfig": {
  "private": false
}

์—…๋ฐ์ดํŠธ๋œ config ํ‚ค๊ฐ€ webhook์— ์˜ํ•ด ์ง€์›๋˜์ง€ ์•Š์œผ๋ฉด ๊ฐ์ฒด๊ฐ€ ๋น„์–ด ์žˆ์Šต๋‹ˆ๋‹ค:

"updatedConfig": {}

ํ˜„์žฌ private๋งŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋” ๋งŽ์€ config ํ‚ค๊ฐ€ ์กด์žฌํ•˜๋ฉด ๋„์›€์ด ๋œ๋‹ค๋ฉด website@huggingface.co๋กœ ์•Œ๋ ค ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

ํ† ๋ก  ๋ฐ Pull Requests

์ตœ์ƒ์œ„ ์†์„ฑ discussion๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ์ด๋ฒคํŠธ(ํ† ๋ก  ๋ฐ Pull Request)์— ์ง€์ •๋ฉ๋‹ˆ๋‹ค. discussion.isPullRequest ์†์„ฑ์€ ํ•ด๋‹น ํ† ๋ก ์ด Pull Request์ด๊ธฐ๋„ ํ•œ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” boolean ๊ฐ’์ž…๋‹ˆ๋‹ค(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 secret

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์ด ์—†๋Š” ๊ฒฝ์šฐ, ์›นํ›… ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๊ณต๊ฐœ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋„๊ตฌ๋Š” ์ˆ˜์‹ ๋œ ๋ชจ๋“  ์š”์ฒญ์„ ์บก์ฒ˜ํ•˜๋Š” catch-all ์—ญํ• ์„ ํ•˜๋ฉฐ 200 OK ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. Beeceptor๋Š” ์ž„์‹œ HTTP ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ˆ˜์‹ ๋œ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๊ฒ€ํ† ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์œ ์‚ฌํ•œ ๋„๊ตฌ๋Š” Webhook.site์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ, ๊ฐœ๋ฐœ ์ค‘์—๋Š” ์‹ค์ œ Webhook ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋กœ์ปฌ ๋จธ์‹ ์—์„œ ์‹คํ–‰ ์ค‘์ธ ์ฝ”๋“œ๋กœ ๋ผ์šฐํŒ…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋” ๋น ๋ฅธ ํ†ตํ•ฉ์„ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ๋ฐ ๋””๋ฒ„๊น…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋กœ์ปฌํ˜ธ์ŠคํŠธ ํฌํŠธ๋ฅผ ์ธํ„ฐ๋„ท์— ๋…ธ์ถœํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ngrok ๋˜๋Š” localtunnel์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Webhook ๋””๋ฒ„๊น…

์›นํ›…์—์„œ ์ตœ๊ทผ ์ƒ์„ฑ๋œ ์ด๋ฒคํŠธ๋ฅผ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›นํ›…์˜ activity ํƒญ์„ ์—ด๋ฉด ์ตœ๊ทผ ์ด๋ฒคํŠธ ๋ชฉ๋ก์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

image.png

์—ฌ๊ธฐ์—์„œ ์ƒ์„ฑ๋œ ์ด๋ฒคํŠธ์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ์™€ ํŽ˜์ด๋กœ๋“œ๋ฅผ ๊ฒ€ํ† ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, Replay ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋‹ค์‹œ ์žฌ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

Note: Webhook์˜ ๋Œ€์ƒ URL ๋˜๋Š” secret์„ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ, ์ด๋ฒคํŠธ๋ฅผ ์žฌ์ƒํ•˜๋ฉด payload๊ฐ€ ์—…๋ฐ์ดํŠธ๋œ URL๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ์žฌ์ „์†ก๋œ ์ด๋ฒคํŠธ๋Š” ์›๋ž˜ ์ „๋‹ฌ๊ณผ ๋™์ผํ•œ Webhook-Id๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ

์กฐ์ง ๊ณ„์ •๊ณผ ์‚ฌ์šฉ์ž ๊ณ„์ • ์ค‘ ์–ด๋””์— ์›นํ›…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‚˜์š”?

์•„๋‹ˆ์š”, ํ˜„์žฌ๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

HF(๋˜๋Š” ๋ชจ๋“  ๋ชจ๋ธ๊ณผ ๊ฐ™์€ ์ „์ฒด ์ €์žฅ์†Œ ์œ ํ˜•)์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ์— ๊ตฌ๋…ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ธ๊ฐ€์š”?

ํ˜„์žฌ ์ตœ์ข… ์‚ฌ์šฉ์ž์—๊ฒŒ ๋…ธ์ถœ๋˜์ง€ ์•Š์ง€๋งŒ, website@huggingface.co๋กœ ์ด๋ฉ”์ผ์„ ๋ณด๋‚ด์ฃผ์‹œ๋ฉด ํ•ด๋‹น ์„ค์ •์„ ๋ณ€๊ฒฝํ•ด ๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Update on GitHub