# Вебхуки

Webhooks являются основой для функций, связанных с MLOps. Они позволяют отслеживать новые изменения в конкретных репозиториях или во всех репозиториях, принадлежащих определённым пользователям или организациям, за которыми вы хотите следить. В этом руководстве сначала объясняется, как управлять вебхуками программно. Затем мы рассмотрим, как использовать `huggingface_hub` для создания сервера, слушающего вебхуки, и его развёртывания в Space.

В этом руководстве предполагается, что вы знакомы с концепцией вебхуков в Huggingface Hub. Чтобы узнать больше о самих вебхуках, сначала прочитайте это [руководство](https://huggingface.co/docs/hub/webhooks).

## Управление вебхуками

`huggingface_hub` позволяет управлять вебхуками программно. Вы можете получить список существующих вебхуков, создать новые, а также обновлять, включать, отключать или удалять их. В этом разделе описаны процедуры с использованием функций API Hugging Face Hub.

### Создание Webhook

Чтобы создать новый вебхук, используйте [create_webhook()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.create_webhook) и укажите URL, на который следует отправлять данные, события, за которыми нужно следить, а также, при необходимости, задайте домен и секрет для обеспечения безопасности.

```python
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"
)
```

Вебхук также может запускать Job на инфраструктуре Hugging Face вместо отправки полезной нагрузки по URL. В этом случае необходимо передать ID исходного Job.

```python
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"
)
```

Webhook запускает Job, передавая payload вебхука в переменной окружения `WEBHOOK_PAYLOAD`. Секреты исходного Job не копируются в вебхук. Если запущенному Job требуются секреты (например, `HF_TOKEN`), передайте их с помощью `secrets={"HF_TOKEN": "hf_***"}`. При использовании [update_webhook()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.update_webhook) необходимо передать `job_id` вместе с `secrets`. Перечисленные секреты заменяют сохранённые значения, пустая строка удаляет секрет, а все остальные секреты сохраняются. Дополнительную информацию о Hugging Face Jobs, доступном оборудовании (CPU, GPU) и скриптах UV см. в [документации по Jobs](./jobs).

### Список вебхуков

Чтобы просмотреть все настроенные вами вебхуки, вы можете получить их список с помощью [list_webhooks()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.list_webhooks). Это полезно для проверки их идентификаторов, URL-адресов и статусов.

```python
from huggingface_hub import list_webhooks

# Example: Listing all webhooks
webhooks = list_webhooks()
for webhook in webhooks:
    print(webhook)
```

### Обновление Webhook

Если вам нужно изменить конфигурацию существующего вебхука, например, его URL или отслеживаемые события, вы можете обновить его с помощью [update_webhook()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.update_webhook).

```python
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"]
)
```

### Включение и отключение вебхуков

Возможно, вам потребуется временно отключить вебхук, не удаляя его. Это можно сделать с помощью [disable_webhook()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.disable_webhook), а затем снова включить вебхук с помощью [enable_webhook()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.enable_webhook).

```python
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()](/docs/huggingface_hub/v2.4.0/ru/package_reference/hf_api#huggingface_hub.HfApi.delete_webhook).

```python
from huggingface_hub import delete_webhook

# Example: Deleting a webhook
delete_webhook("your-webhook-id")
```

### Управление вебхуками из CLI

Все перечисленные выше операции также доступны через интерфейс командной строки `hf`. Это особенно удобно для написания скриптов и агентных рабочих процессов.

```bash
# 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](./cli#hf-webhooks).

## Сервер вебхуков

Базовым классом, который мы будем использовать в этом разделе руководства, является [WebhooksServer()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhooksServer). Это класс для простой настройки сервера, способного принимать вебхуки от Huggingface Hub. Сервер основан на приложении [Gradio](https://gradio.app/). Он имеет интерфейс для отображения инструкций для вас или ваших пользователей, а также API для прослушивания вебхуков.

> [!TIP]
> Чтобы увидеть работающий пример вебхук-сервера, посмотрите на [Spaces CI Bot](https://huggingface.co/spaces/spaces-ci-bot/webhook). Это Space, который запускает эфемерные окружения при открытии PR в Space.

> [!WARNING]
> Это [экспериментальная функция](../package_reference/environment_variables#hfhubdisableexperimentalwarning). Это означает, что мы продолжаем дорабатывать API. В будущем могут быть внесены изменения, нарушающие обратную совместимость, без предварительного уведомления. Убедитесь, что вы зафиксировали версию `huggingface_hub` в своих требованиях.

### Создание конечной точки

Реализация вебхук-эндпоинта сводится к декорированию функции. Рассмотрим первый пример, чтобы объяснить основные концепции:

```python
# 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'`. Вы должны увидеть сообщение такого вида:

```text
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.
```

Отличная работа! Вы только что запустили вебхук-сервер! Давайте разберёмся, что именно произошло:

1. При декорировании функции с помощью [webhook_endpoint()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.webhook_endpoint) в фоне создаётся объект [WebhooksServer()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhooksServer).
Как видно, этот сервер представляет собой приложение Gradio, работающее по адресу http://127.0.0.1:7860. Если открыть этот URL в браузере, вы увидите страницу с инструкциями по зарегистрированным вебхукам.
2. Приложение Gradio представляет собой сервер FastAPI. В него добавлен новый маршрут POST `/webhooks/trigger_training`.
Это маршрут, который будет слушать вебхуки и запускать функцию `trigger_training` при срабатывании. FastAPI автоматически разберет полезную нагрузку и передаст её в функцию в виде объекта [WebhookPayload](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhookPayload). Это объект `pydantic`, содержащий всю информацию о событии, которое вызвало вебхук.
3. Приложение Gradio также открыло туннель для получения запросов из интернета. Вот интересная часть: вы можете
настройте Webhook на https://huggingface.co/settings/webhooks, указав адрес вашего локального компьютера. Это удобно для отладки вашего webhook-сервера и быстрой итерации перед развёртыванием в Space.
4. Наконец, в логах также указано, что ваш сервер в настоящее время не защищен секретным ключом. Это не является проблемой для
локальная отладка, но об этом стоит помнить на будущее.

> [!WARNING]
> По умолчанию сервер запускается в конце вашего скрипта. Если вы работаете в ноутбуке, вы можете запустить сервер вручную, вызвав `decorated_function.launch()`. Поскольку используется уникальный сервер, вам нужно запускать его только один раз, даже если у вас несколько конечных точек.

### Настройка Webhook

Теперь, когда у вас работает вебхук-сервер, вам нужно настроить Webhook, чтобы начать получать сообщения. Перейдите на https://huggingface.co/settings/webhooks, нажмите «Add a new webhook» и настройте ваш Webhook. Укажите целевые репозитории, за которыми вы хотите следить, и URL вебхука, в данном случае `https://1fadb0f52d8bf825fc.gradio.live/webhooks/trigger_training`.

И всё! Теперь вы можете активировать этот webhook, обновив целевой репозиторий (например, отправив коммит). Откройте вкладку Activity вашего Webhook, чтобы просмотреть сработавшие события. Теперь, когда у вас настроена рабочая среда, вы можете протестировать её и быстро итерировать. Если вы измените код и перезапустите сервер, ваш публичный URL может измениться. При необходимости обновите конфигурацию webhook на Hub.

### Развернуть в Space

Теперь, когда у вас есть рабочий вебхук-сервер, цель — развернуть его в Space. Перейдите по адресу https://huggingface.co/new-space, чтобы создать Space. Придумайте название, выберите Gradio SDK и нажмите «Create Space». Загрузите ваш код в Space в файл `app.py`. Ваш Space запустится автоматически! Подробнее о Spaces читайте в этом [руководстве](https://huggingface.co/docs/hub/spaces-overview).

Ваш вебхук-сервер теперь работает в публичном Space. В большинстве случаев вы захотите защитить его с помощью секрета. Перейдите в настройки вашего Space > раздел «Repository secrets» > «Add a secret». Установите переменную окружения `WEBHOOK_SECRET` в значение по вашему выбору. Вернитесь в [настройки вебхуков](https://huggingface.co/settings/webhooks) и укажите секрет в конфигурации вебхука. Теперь ваш сервер будет принимать только запросы с правильным секретом.

И это всё! Ваше Space теперь готово принимать вебхуки от Hub. Обратите внимание, что если вы запускаете Space на бесплатном оборудовании 'cpu-basic', оно будет остановлено после 48 часов бездействия. Если вам нужен постоянный Space, стоит рассмотреть вариант с [обновлённым оборудованием](https://huggingface.co/docs/hub/spaces-gpus#hardware-specs).

### Расширенное использование

В руководстве выше описан самый быстрый способ настройки [WebhooksServer()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhooksServer). В этом разделе мы рассмотрим, как дополнительно настроить его.

#### Несколько конечных точек

Вы можете зарегистрировать несколько конечных точек на одном сервере. Например, вы можете создать одну конечную точку для запуска задачи обучения и другую — для запуска оценки модели. Для этого добавьте несколько декораторов `@webhook_endpoint`:

```python
# 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
        ...
```

В результате будут созданы два конечных пункта:

```text
(...)
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()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhooksServer). Это полезно, если вы хотите настроить страницу приветствия вашего сервера. Для этого передайте [Gradio UI](https://gradio.app/docs/#blocks), который заменит стандартный. Например, вы можете добавить инструкции для пользователей или форму для ручного запуска вебхуков. При создании [WebhooksServer()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhooksServer) вы можете регистрировать новые вебхуки с помощью декоратора `add_webhook()`.

Вот полный пример:

```python
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()
```

1. Мы определяем пользовательский интерфейс с помощью блоков Gradio. Этот интерфейс будет отображаться на главной странице сервера.
2. Создаём объект [WebhooksServer()](/docs/huggingface_hub/v2.4.0/ru/package_reference/webhooks_server#huggingface_hub.WebhooksServer) с пользовательским интерфейсом и секретом. Секрет является необязательным и может быть установлен с помощью
переменной окружения `WEBHOOK_SECRET`.
3. Мы регистрируем вебхук с явным именем. Это создаст конечную точку по адресу `/webhooks/say_hello`.
4. Мы регистрируем вебхук с неявным именем. Это создаст конечную точку по адресу `/webhooks/goodbye`.
5. Мы запускаем сервер. Это необязательно, так как сервер будет запущен автоматически в конце скрипта.

