Webhooks
Webhooks는 MLOps 관련 기능의 기반입니다. 특정 저장소 또는 관심 있는 사용자/조직에 속한 모든 저장소에서 새로운 변경 사항을 수신할 수 있습니다. 이 가이드에서는 먼저 Webhooks를 프로그래매틱으로 관리하는 방법을 설명합니다. 그런 다음 huggingface_hub을 활용하여 Webhooks를 수신하는 서버를 만들고 Space에 배포하는 방법을 살펴봅니다.
이 가이드는 Huggingface Hub의 웹훅 개념에 익숙하다고 가정합니다. 웹훅 자체에 대해 더 자세히 알고 싶다면 먼저 이 가이드를 읽어보시기 바랍니다.
Webhook 관리
huggingface_hub을 사용하면 웹훅을 프로그래매틱으로 관리할 수 있습니다. 기존 웹훅을 나열하고, 새 웹훅을 생성하며, 웹훅을 업데이트하거나 활성화, 비활성화, 삭제할 수 있습니다. 이 섹션에서는 Hugging Face Hub의 API 함수를 사용하여 이러한 절차를 안내합니다.
Webhook 만들기
새로운 웹훅을 생성하려면 create_webhook()를 사용하고, 페이로드를 전송할 URL, 감시할 이벤트, 그리고 보안 설정을 위해 선택적으로 도메인과 시크릿을 지정합니다.
from huggingface_hub import create_webhook
# Example: Creating a webhook
webhook = create_webhook(
url="https://webhook.site/your-custom-url",
watched=[{"type": "user", "name": "your-username"}, {"type": "org", "name": "your-org-name"}],
domains=["repo", "discussion"],
secret="your-secret"
)webhook은 URL로 페이로드를 보내는 대신 Hugging face 인프라에서 Job을 실행하도록 트리거할 수도 있습니다. 이 경우 소스 Job의 ID를 전달해야 합니다.
from huggingface_hub import create_webhook
# Example: Creating a webhook that triggers a Job
webhook = create_webhook(
job_id=job_id,
watched=[{"type": "user", "name": "your-username"}, {"type": "org", "name": "your-org-name"}],
domains=["repo", "discussion"],
secret="your-secret"
)The webhook triggers the Job with the webhook payload in the environment variable WEBHOOK_PAYLOAD.
The source Job’s secrets are not copied to the webhook. If the triggered Job needs secrets (e.g. HF_TOKEN), pass them with secrets={"HF_TOKEN": "hf_***"}. With update_webhook(), you must pass job_id together with secrets. Listed secrets replace the stored values, an empty string removes a secret, and all other secrets are kept.
For more information on Hugging Face Jobs, available hardware (CPU, GPU) and UV scripts, see the Jobs documentation.
Webhooks 나열
구성한 모든 웹훅을 확인하려면 list_webhooks()를 사용하여 목록을 표시할 수 있습니다. 이를 통해 ID, URL, 상태를 검토하는 데 유용합니다.
from huggingface_hub import list_webhooks
# Example: Listing all webhooks
webhooks = list_webhooks()
for webhook in webhooks:
print(webhook)Webhook 업데이트
기존 webhook의 URL이나 모니터링 대상 이벤트와 같은 구성을 변경해야 하는 경우, update_webhook()을 사용하여 업데이트할 수 있습니다.
from huggingface_hub import update_webhook
# Example: Updating a webhook
updated_webhook = update_webhook(
webhook_id="your-webhook-id",
url="https://new.webhook.site/url",
watched=[{"type": "user", "name": "new-username"}],
domains=["repo"]
)Webhook 활성화 및 비활성화
웹훅을 삭제하지 않고 일시적으로 비활성화하려는 경우가 있을 수 있습니다. disable_webhook()을 사용하면 이를 수행할 수 있으며, 이후 enable_webhook()을 사용하여 웹훅을 다시 활성화할 수 있습니다.
from huggingface_hub import enable_webhook, disable_webhook
# Example: Enabling a webhook
enabled_webhook = enable_webhook("your-webhook-id")
print("Enabled:", enabled_webhook)
# Example: Disabling a webhook
disabled_webhook = disable_webhook("your-webhook-id")
print("Disabled:", disabled_webhook)Webhook 삭제
웹훅이 더 이상 필요하지 않을 경우 delete_webhook()을 사용하여 영구적으로 삭제할 수 있습니다.
from huggingface_hub import delete_webhook
# Example: Deleting a webhook
delete_webhook("your-webhook-id")CLI에서 Webhook 관리
위에서 설명한 모든 작업은 hf 명령줄 인터페이스에서도 사용할 수 있습니다. 이는 스크립팅 및 에이전트 워크플로우에 특히 유용합니다.
# List all webhooks
>>> hf webhooks ls
# Get details about a specific webhook
>>> hf webhooks info <webhook_id>
# Create a webhook that pings a URL
>>> hf webhooks create --url https://example.com/hook --watch model:bert-base-uncased --domain repo
# Create a webhook that triggers a Job
>>> hf webhooks create --job-id <job_id> --watch user:julien-c
# Create a webhook that triggers a Job with your HF token as a secret
>>> hf webhooks create --job-id <job_id> --watch bucket:my-org/my-bucket --secrets HF_TOKEN
# Update an existing webhook
>>> hf webhooks update <webhook_id> --url https://new-url.com/hook
# Enable / disable a webhook
>>> hf webhooks enable <webhook_id>
>>> hf webhooks disable <webhook_id>
# Delete a webhook (with confirmation prompt)
>>> hf webhooks delete <webhook_id>--watch 옵션은 type:name 형식을 사용하며, type은 model, dataset, space, org, user 중 하나입니다. 여러 항목을 감시하려면 이 옵션을 반복하여 사용할 수 있습니다. 전체 옵션 목록을 확인하려면 hf webhooks <command> --help를 실행하세요. 자세한 내용은 CLI 가이드를 참고하세요.
Webhooks 서버
이 가이드 섹션에서 사용할 기본 클래스는 WebhooksServer()입니다. Huggingface Hub에서 웹훅을 수신할 수 있는 서버를 쉽게 구성하기 위한 클래스입니다. 이 서버는 Gradio 앱 기반으로 구축되어 있으며, 사용자에게 지침을 표시하는 UI와 웹훅을 수신하는 API를 제공합니다.
웹훅 서버의 실행 예시를 보려면 Spaces CI Bot을 확인해 보세요. 이는 Space에 PR이 열릴 때 임시 환경을 시작하는 Space입니다.
이것은 실험적 기능입니다. 이는 API를 개선하기 위해 계속 작업 중임을 의미합니다. 사전 통보 없이 향후 호환성이 깨지는 변경 사항이 도입될 수 있습니다.
huggingface_hub의 버전을 요구 사항에 고정하도록 하십시오.
엔드포인트 생성
webhook 엔드포인트를 구현하는 것은 함수를 데코레이팅하는 것만큼 간단합니다. 주요 개념을 설명하기 위해 첫 번째 예시를 살펴보겠습니다:
# app.py
from huggingface_hub import webhook_endpoint, WebhookPayload
@webhook_endpoint
async def trigger_training(payload: WebhookPayload) -> None:
if payload.repo.type == "dataset" and payload.event.action == "update":
# Trigger a training job if a dataset is updated
...이 스니펫을 'app.py'라는 파일로 저장하고 'python app.py'로 실행하세요. 다음과 같은 메시지가 표시됩니다:
Webhook secret is not defined. This means your webhook endpoints will be open to everyone.
To add a secret, set `WEBHOOK_SECRET` as environment variable or pass it at initialization:
`app = WebhooksServer(webhook_secret='my_secret', ...)`
For more details about webhook secrets, please refer to https://huggingface.co/docs/hub/webhooks#webhook-secret.
Running on local URL: http://127.0.0.1:7860
Running on public URL: https://1fadb0f52d8bf825fc.gradio.live
This share link expires in 72 hours. For free permanent hosting and GPU upgrades (NEW!), check out Spaces: https://huggingface.co/spaces
Webhooks are correctly setup and ready to use:
- POST https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training
Go to https://huggingface.co/settings/webhooks to setup your webhooks.잘하셨습니다! 이제 웹훅 서버를 실행했습니다. 정확히 어떤 일이 일어났는지 살펴봅시다:
- webhook_endpoint()로 함수를 장식하면 백그라운드에서 WebhooksServer() 객체가 생성됩니다. 보시는 바와 같이 이 서버는 http://127.0.0.1:7860에서 실행되는 Gradio 앱입니다. 브라우저에서 이 URL을 열면 등록된 웹후크에 대한 설명이 포함된 랜딩 페이지가 표시됩니다.
- Gradio 앱은 내부적으로 FastAPI 서버입니다. 새로운 POST 라우트
/webhooks/trigger_training가 추가되었습니다. 이 라우트는 웹훅을 수신하고 트리거가 발생하면trigger_training함수를 실행합니다. FastAPI는 페이로드를 자동으로 파싱하여 WebhookPayload 객체로 함수에 전달합니다. 이 객체는 웹훅을 트리거한 이벤트에 대한 모든 정보를 포함하는pydantic객체입니다. - Gradio 앱은 인터넷에서 요청을 수신하기 위해 터널도 열었습니다. 여기가 흥미로운 부분입니다: https://huggingface.co/settings/webhooks에서 로컬 머신을 가리키도록 Webhook을 구성할 수 있습니다. 이는 Space에 배포하기 전에 Webhook 서버를 디버깅하고 빠르게 반복 개발하는 데 유용합니다.
- 마지막으로, 로그는 현재 서버가 시크릿으로 보호되지 않고 있음을 알려줍니다. 이는 로컬 디버깅에는 문제가 되지 않지만, 이후를 위해 염두에 두어야 합니다.
기본적으로 서버는 스크립트 실행이 끝날 때 시작됩니다. 노트북에서 실행하는 경우
decorated_function.launch()를 호출하여 서버를 수동으로 시작할 수 있습니다. 고유한 서버가 사용되므로 여러 엔드포인트가 있어도 서버를 한 번만 시작하면 됩니다.
Webhook 구성
이제 웹훅 서버가 실행 중이므로, 메시지를 수신하기 시작하도록 Webhook을 구성해야 합니다. https://huggingface.co/settings/webhooks로 이동하여 “Add a new webhook”을 클릭하고 Webhook을 구성하세요. 감시할 대상 저장소와 Webhook URL을 설정합니다. 여기서는 https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training입니다.

그리고 끝입니다! 이제 대상 저장소를 업데이트(예: 커밋을 push)하여 해당 webhook을 트리거할 수 있습니다. Webhook의 Activity 탭을 확인하여 트리거된 이벤트를 살펴보세요. 이제 작동하는 설정을 갖추었으므로 테스트하고 빠르게 반복할 수 있습니다. 코드를 수정하고 서버를 다시 시작하면 공개 URL이 변경될 수 있습니다. 필요 시 Hub에서 webhook 구성을 업데이트하세요.
Space에 배포
작동하는 webhook 서버를 갖추셨으니, 이제 이를 Space에 배포하는 것이 목표입니다. https://huggingface.co/new-space로 이동하여 Space를 생성하세요. 이름을 지정하고 Gradio SDK를 선택한 후 “Create Space”를 클릭합니다. 코드를 app.py라는 파일로 Space에 업로드하세요. Space가 자동으로 시작됩니다. Spaces에 대한 자세한 내용은 이 가이드를 참고하세요.
웹훅 서버가 이제 공개 Space에서 실행되고 있습니다. 대부분의 경우, 시크릿으로 이를 보호하는 것이 좋습니다. Space 설정 > “Repository secrets” 섹션 > “Add a secret”으로 이동하여 WEBHOOK_SECRET 환경 변수를 원하는 값으로 설정하세요. Webhooks settings로 돌아가서 웹훅 구성에 시크릿을 설정합니다. 이제 올바른 시크릿을 가진 요청만 서버에 의해 허용됩니다.
이제 준비가 끝났습니다! 이제 Space가 Hub에서 웹훅을 수신할 수 있습니다. Space를 무료 ‘cpu-basic’ 하드웨어에서 실행하는 경우, 48시간 동안 비활성 상태가 되면 종료됩니다. 영구적인 Space가 필요하면 업그레이드된 하드웨어로 설정하는 것을 고려해 보세요.
고급 사용
위 가이드에서는 WebhooksServer()를 설정하는 가장 빠른 방법을 설명했습니다. 이 섹션에서는 이를 더 자세히 커스터마이징하는 방법을 살펴보겠습니다.
여러 엔드포인트
같은 서버에 여러 엔드포인트를 등록할 수 있습니다. 예를 들어, 학습 작업을 트리거하는 엔드포인트 하나와 모델 평가를 트리거하는 엔드포인트 하나를 두고 싶을 수 있습니다. 여러 @webhook_endpoint 데코레이터를 추가하여 이를 수행할 수 있습니다:
# app.py
from huggingface_hub import webhook_endpoint, WebhookPayload
@webhook_endpoint
async def trigger_training(payload: WebhookPayload) -> None:
if payload.repo.type == "dataset" and payload.event.action == "update":
# Trigger a training job if a dataset is updated
...
@webhook_endpoint
async def trigger_evaluation(payload: WebhookPayload) -> None:
if payload.repo.type == "model" and payload.event.action == "update":
# Trigger an evaluation job if a model is updated
...두 개의 엔드포인트를 생성합니다:
(...) Webhooks are correctly setup and ready to use: - POST https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training - POST https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_evaluation
커스텀 서버
더 많은 유연성을 위해 WebhooksServer() 객체를 직접 생성할 수도 있습니다. 이는 서버의 랜딩 페이지를 커스터마이즈하려는 경우에 유용합니다. 기본값을 덮어쓰는 Gradio UI를 전달하여 이를 수행할 수 있습니다. 예를 들어, 사용자를 위한 지침을 추가하거나 웹훅을 수동으로 트리거하기 위한 양식을 추가할 수 있습니다. WebhooksServer()를 생성할 때 add_webhook() 데코레이터를 사용하여 새로운 웹훅을 등록할 수 있습니다.
다음은 완전한 예시입니다:
import gradio as gr
from fastapi import Request
from huggingface_hub import WebhooksServer, WebhookPayload
# 1. Define UI
with gr.Blocks() as ui:
...
# 2. Create WebhooksServer with custom UI and secret
app = WebhooksServer(ui=ui, webhook_secret="my_secret_key")
# 3. Register webhook with explicit name
@app.add_webhook("/say_hello")
async def hello(payload: WebhookPayload):
return {"message": "hello"}
# 4. Register webhook with implicit name
@app.add_webhook
async def goodbye(payload: WebhookPayload):
return {"message": "goodbye"}
# 5. Start server (optional)
app.launch()- Gradio blocks를 사용하여 사용자 정의 UI를 정의합니다. 이 UI는 서버의 랜딩 페이지에 표시됩니다.
- 커스텀 UI와 시크릿을 사용하여 WebhooksServer() 객체를 생성합니다. 시크릿은 선택 사항이며
WEBHOOK_SECRET환경 변수로 설정할 수 있습니다. - 명시적인 이름을 지정하여 웹훅을 등록합니다. 이렇게 하면
/webhooks/say_hello에 엔드포인트가 생성됩니다. - 암시적 이름으로 웹훅을 등록합니다. 이렇게 하면
/webhooks/goodbye에 엔드포인트가 생성됩니다. - 서버를 시작합니다. 스크립트 끝에서 서버가 자동으로 시작되므로 이 단계는 선택 사항입니다.