Skip to content

Commit

Permalink
switch docs sections + fix code quality
Browse files Browse the repository at this point in the history
  • Loading branch information
Wauplin committed May 24, 2024
1 parent c2cf626 commit e60bbc8
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 98 deletions.
162 changes: 79 additions & 83 deletions docs/source/en/guides/webhooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,85 @@ rendered properly in your Markdown viewer.

# Webhooks

Webhooks are a foundation for MLOps-related features. They allow you to listen for new changes on specific repos or to
all repos belonging to particular users/organizations you're interested in following. This guide will explain how to
leverage `huggingface_hub` to create a server listening to webhooks and deploy it to a Space. As well as managing them with the `huggingface_hub` API. It assumes you are
familiar with the concept of webhooks on the Huggingface Hub. To learn more about webhooks themselves, you can read
this [guide](https://huggingface.co/docs/hub/webhooks) first.
Webhooks are a foundation for MLOps-related features. They allow you to listen for new changes on specific repos or to all repos belonging to particular users/organizations you're interested in following. This guide will first explain how to manage webhooks programmatically. Then we'll see how to leverage `huggingface_hub` to create a server listening to webhooks and deploy it to a Space.

This guide assumes you are familiar with the concept of webhooks on the Huggingface Hub. To learn more about webhooks themselves, you should read this [guide](https://huggingface.co/docs/hub/webhooks) first.

## Managing Webhooks

`huggingface_hub` allows you to manage your webhooks programmatically. You can list your existing webhooks, create new ones, and update, enable, disable or delete them. This section guides you through the procedures using the Hugging Face Hub's API functions.

### Creating a Webhook

To create a new webhook, use [`create_webhook`] and specify the URL where payloads should be sent, what events should be watched, and optionally set a domain and a secret for security.

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

### Listing Webhooks

To see all the webhooks you have configured, you can list them with [`list_webhooks`]. This is useful to review their IDs, URLs, and statuses.

```python
from huggingface_hub import list_webhooks

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

### Updating a Webhook

If you need to change the configuration of an existing webhook, such as the URL or the events it watches, you can update it using [`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"]
)
```

### Enabling and Disabling Webhooks

You might want to temporarily disable a webhook without deleting it. This can be done using [`disable_webhook`], and the webhook can be re-enabled later with [`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)
```

### Deleting a Webhook

When a webhook is no longer needed, it can be permanently deleted using [`delete_webhook`].

```python
from huggingface_hub import delete_webhook

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

## Webhooks Server

Expand Down Expand Up @@ -199,81 +273,3 @@ the `WEBHOOK_SECRET` environment variable.
3. We register a webhook with an explicit name. This will create an endpoint at `/webhooks/say_hello`.
4. We register a webhook with an implicit name. This will create an endpoint at `/webhooks/goodbye`.
5. We start the server. This is optional as your server will automatically be started at the end of the script.

## Managing Webhooks

Once your webhook server is configured and deployed, you might need to manage your webhooks, such as creating new ones, listing all configured webhooks, updating, enabling, disabling, or deleting them. This section guides you through the procedures using the Hugging Face Hub's API functions.

### Creating a Webhook

To create a new webhook, you need to specify the URL where payloads should be sent, what events should be watched, and optionally set a domain and a secret for security.

```python
from huggingface_hub import create_webhook, WebhookWatchedItem

# Example: Creating a webhook
webhook = create_webhook(
url="https://webhook.site/your-custom-url",
watched=[WebhookWatchedItem(type="user", name="your-username"), WebhookWatchedItem(type="org", name="your-org-name")],
domains=["repo", "discussion"],
secret="your-secret"
)
print(webhook)
```

### Listing Webhooks

To see all the webhooks you have configured, you can list them. This is useful to review their IDs, URLs, and statuses.

```python
from huggingface_hub import list_webhooks

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

### Updating a Webhook

If you need to change the configuration of an existing webhook, such as the URL or the events it watches, you can update it using its ID.

```python
from huggingface_hub import update_webhook, WebhookWatchedItem

# Example: Updating a webhook
updated_webhook = update_webhook(
webhook_id="your-webhook-id",
url="https://new.webhook.site/url",
watched=[WebhookWatchedItem(type="user", name="new-username")],
domains=["repo"]
)
print(updated_webhook)
```

### Enabling and Disabling Webhooks

You might want to temporarily disable a webhook without deleting it. This can be done easily, and the webhook can be re-enabled later.

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

### Deleting a Webhook

When a webhook is no longer needed, it can be permanently deleted using its ID.

```python
from huggingface_hub import delete_webhook

# Example: Deleting a webhook
delete_webhook("your-webhook-id")
```
31 changes: 16 additions & 15 deletions src/huggingface_hub/hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import struct
import warnings
from concurrent.futures import Future, ThreadPoolExecutor
from dataclasses import asdict, dataclass, field, is_dataclass
from dataclasses import asdict, dataclass, field
from datetime import datetime
from functools import wraps
from itertools import islice
Expand Down Expand Up @@ -8585,7 +8585,7 @@ def create_webhook(
self,
*,
url: str,
watched: List[WebhookWatchedItem],
watched: List[Union[Dict, WebhookWatchedItem]],
domains: Optional[List[WEBHOOK_DOMAIN_T]] = None,
secret: Optional[str] = None,
token: Union[bool, str, None] = None,
Expand All @@ -8597,6 +8597,7 @@ def create_webhook(
URL to send the payload to.
watched (`List[WebhookWatchedItem]`):
List of [`WebhookWatchedItem`] to be watched by the webhook. It can be users, orgs, models, datasets or spaces.
Watched items can also be provided as plain dictionaries.
domains (`List[Literal["repo", "discussion"]]`, optional):
List of domains to watch. It can be "repo", "discussion" or both.
secret (`str`, optional):
Expand All @@ -8612,9 +8613,9 @@ def create_webhook(
Example:
```python
>>> from huggingface_hub import create_webhook, WebhookWatchedItem
>>> from huggingface_hub import create_webhook
>>> payload = create_webhook(
... watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
... watched=[{"type": "user", "name": "julien-c"}, {"type": "org", "name": "HuggingFaceH4"}],
... url="https://webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
... domains=["repo", "discussion"],
... secret="my-secret",
Expand All @@ -8630,9 +8631,8 @@ def create_webhook(
)
```
"""
watched_dicts = (
[asdict(item) if is_dataclass(item) else item for item in watched] if watched is not None else []
)
watched_dicts = [asdict(item) if isinstance(item, WebhookWatchedItem) else item for item in watched]

response = get_session().post(
f"{ENDPOINT}/api/settings/webhooks",
json={"watched": watched_dicts, "url": url, "domains": domains, "secret": secret},
Expand All @@ -8659,8 +8659,8 @@ def update_webhook(
webhook_id: str,
*,
url: Optional[str] = None,
watched: Optional[List[WebhookWatchedItem]],
domains: Optional[List[WEBHOOK_DOMAIN_T]],
watched: Optional[List[Union[Dict, WebhookWatchedItem]]] = None,
domains: Optional[List[WEBHOOK_DOMAIN_T]] = None,
secret: Optional[str] = None,
token: Union[bool, str, None] = None,
) -> WebhookInfo:
Expand All @@ -8673,7 +8673,7 @@ def update_webhook(
The URL to which the payload will be sent.
watched (`List[WebhookWatchedItem]`, optional):
List of items to watch. It can be users, orgs, models, datasets, or spaces.
Refer to [`WebhookWatchedItem`] for more details.
Refer to [`WebhookWatchedItem`] for more details. Watched items can also be provided as plain dictionaries.
domains (`List[Literal["repo", "discussion"]]`, optional):
The domains to watch. This can include "repo", "discussion", or both.
secret (`str`, optional):
Expand All @@ -8689,11 +8689,11 @@ def update_webhook(
Example:
```python
>>> from huggingface_hub import update_webhook, WebhookWatchedItem
>>> from huggingface_hub import update_webhook
>>> updated_payload = update_webhook(
... webhook_id="654bbbc16f2ec14d77f109cc",
... url="https://new.webhook.site/a2176e82-5720-43ee-9e06-f91cb4c91548",
... watched=[WebhookWatchedItem(type="user", name="julien-c"), WebhookWatchedItem(type="org", name="HuggingFaceH4")],
... watched=[{"type": "user", "name": "julien-c"}, {"type": "org", "name": "HuggingFaceH4"}],
... domains=["repo"],
... secret="my-secret",
... )
Expand All @@ -8707,9 +8707,10 @@ def update_webhook(
disabled=False,
```
"""
watched_dicts = (
[asdict(item) if is_dataclass(item) else item for item in watched] if watched is not None else []
)
if watched is None:
watched = []
watched_dicts = [asdict(item) if isinstance(item, WebhookWatchedItem) else item for item in watched]

response = get_session().post(
f"{ENDPOINT}/api/settings/webhooks/{webhook_id}",
json={"watched": watched_dicts, "url": url, "domains": domains, "secret": secret},
Expand Down

0 comments on commit e60bbc8

Please sign in to comment.