testbot commited on
Commit
a5e8053
1 Parent(s): 8b1b383

Use huggingface_hub.WebhooksServer

Browse files
Files changed (5) hide show
  1. app.py +5 -5
  2. gradio_webhooks.py +0 -110
  3. requirements.txt +2 -2
  4. simple.py +0 -12
  5. ui.py +1 -1
app.py CHANGED
@@ -16,8 +16,8 @@ from huggingface_hub import (
16
  )
17
  from huggingface_hub.repocard import RepoCard
18
  from requests import HTTPError
19
- from gradio_webhooks import GradioWebhookApp, WebhookPayload
20
  from huggingface_hub import login
 
21
  from huggingface_hub.utils import RepositoryNotFoundError
22
  from ui import generate_ui
23
 
@@ -25,11 +25,11 @@ login(token=os.getenv("HF_TOKEN"))
25
 
26
  CI_BOT_NAME = "spaces-ci-bot"
27
 
28
- app = GradioWebhookApp(ui=generate_ui())
29
 
30
 
31
- @app.add_webhook("/webhook")
32
- async def post_webhook(payload: WebhookPayload, task_queue: BackgroundTasks):
33
  if payload.repo.type != "space":
34
  raise HTTPException(400, f"Must be a Space, not {payload.repo.type}")
35
 
@@ -232,4 +232,4 @@ _(This is an automated message.)_
232
  """
233
 
234
 
235
- app.ready()
16
  )
17
  from huggingface_hub.repocard import RepoCard
18
  from requests import HTTPError
 
19
  from huggingface_hub import login
20
+ from huggingface_hub import WebhooksServer, WebhookPayload
21
  from huggingface_hub.utils import RepositoryNotFoundError
22
  from ui import generate_ui
23
 
25
 
26
  CI_BOT_NAME = "spaces-ci-bot"
27
 
28
+ app = WebhooksServer(ui=generate_ui())
29
 
30
 
31
+ @app.add_webhook
32
+ async def trigger_ci_on_pr(payload: WebhookPayload, task_queue: BackgroundTasks):
33
  if payload.repo.type != "space":
34
  raise HTTPException(400, f"Must be a Space, not {payload.repo.type}")
35
 
232
  """
233
 
234
 
235
+ app.run()
gradio_webhooks.py DELETED
@@ -1,110 +0,0 @@
1
- import os
2
- from typing import Literal, Optional, Set
3
-
4
- import gradio as gr
5
- from fastapi import Request
6
- from fastapi.responses import JSONResponse
7
- from pydantic import BaseModel
8
-
9
-
10
- class GradioWebhookApp:
11
- """
12
- ```py
13
- from gradio_webhooks import GradioWebhookApp
14
-
15
- app = GradioWebhookApp()
16
-
17
-
18
- @app.add_webhook("/test_webhook")
19
- async def hello():
20
- return {"in_gradio": True}
21
-
22
-
23
- app.ready()
24
- ```
25
- """
26
-
27
- def __init__(
28
- self,
29
- ui: gr.Blocks,
30
- webhook_secret: Optional[str] = None,
31
- ) -> None:
32
- # Launch gradio app:
33
- # - as non-blocking so that webhooks can be added afterwards
34
- # - as shared if launch locally (to receive webhooks)
35
- app, _, _ = ui.launch(prevent_thread_lock=True, share=not ui.is_space)
36
- self.gradio_app = ui
37
- self.fastapi_app = app
38
- self.webhook_paths: Set[str] = set()
39
-
40
- # Add auth middleware to check the "X-Webhook-Secret" header
41
- self._webhook_secret = webhook_secret or os.getenv("WEBHOOK_SECRET")
42
- if self._webhook_secret is None:
43
- print(
44
- "\nWebhook secret is not defined. This means your webhook endpoints will be open to everyone."
45
- )
46
- print(
47
- "To add a secret, set `WEBHOOK_SECRET` as environment variable or pass it at initialization: "
48
- "\n\t`app = GradioWebhookApp(webhook_secret='my_secret', ...)`"
49
- )
50
- print(
51
- "For more details about Webhook secrets, please refer to https://huggingface.co/docs/hub/webhooks#webhook-secret."
52
- )
53
- else:
54
- print("\nWebhook secret is correctly defined.")
55
- app.middleware("http")(self._webhook_secret_middleware)
56
-
57
- def add_webhook(self, path: str):
58
- """Decorator to add a webhook to the server app."""
59
- self.webhook_paths.add(path)
60
- return self.fastapi_app.post(path)
61
-
62
- def ready(self) -> None:
63
- """Set the app as "ready" and block main thread to keep it running."""
64
- url = (
65
- self.gradio_app.share_url
66
- if self.gradio_app.share_url is not None
67
- else self.gradio_app.local_url
68
- ).strip("/")
69
- print("\nWebhooks are correctly setup and ready to use:")
70
- print("\n".join(f" - POST {url}{webhook}" for webhook in self.webhook_paths))
71
- print("Go to https://huggingface.co/settings/webhooks to setup your webhooks.")
72
- self.gradio_app.block_thread()
73
-
74
- async def _webhook_secret_middleware(self, request: Request, call_next) -> None:
75
- """Middleware to check "X-Webhook-Secret" header on every webhook request."""
76
- if request.url.path in self.webhook_paths:
77
- if self._webhook_secret is not None:
78
- request_secret = request.headers.get("x-webhook-secret")
79
- if request_secret is None:
80
- return JSONResponse(
81
- {"error": "x-webhook-secret header not set."}, status_code=401
82
- )
83
- if request_secret != self._webhook_secret:
84
- return JSONResponse(
85
- {"error": "Invalid webhook secret."}, status_code=403
86
- )
87
- return await call_next(request)
88
-
89
-
90
- class WebhookPayloadEvent(BaseModel):
91
- action: Literal["create", "update", "delete"]
92
- scope: str
93
-
94
-
95
- class WebhookPayloadRepo(BaseModel):
96
- type: Literal["dataset", "model", "space"]
97
- name: str
98
- private: bool
99
-
100
-
101
- class WebhookPayloadDiscussion(BaseModel):
102
- num: int
103
- isPullRequest: bool
104
- status: Literal["open", "closed", "merged"]
105
-
106
-
107
- class WebhookPayload(BaseModel):
108
- event: WebhookPayloadEvent
109
- repo: WebhookPayloadRepo
110
- discussion: Optional[WebhookPayloadDiscussion]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,2 +1,2 @@
1
- fastapi
2
- huggingface_hub==0.12.*
1
+ gradio
2
+ git+https://github.com/huggingface/huggingface_hub@feat-webhook-app#egg=huggingface_hub
simple.py DELETED
@@ -1,12 +0,0 @@
1
- from gradio_webhooks import GradioWebhookApp, WebhookPayload
2
-
3
- app = GradioWebhookApp(webhook_secret="my_dummy_secret")
4
-
5
-
6
- @app.add_webhook("/my_webhook")
7
- async def hello(payload: WebhookPayload):
8
- print(f"Received webhook for repo {payload.repo.name}")
9
- return {"processed": True}
10
-
11
-
12
- app.ready()
 
 
 
 
 
 
 
 
 
 
 
 
ui.py CHANGED
@@ -21,7 +21,7 @@ You are a few clicks away from having the CI Bot configured on your Spaces. No c
21
  #### 1. Go to your [settings page](https://huggingface.co/settings/webhooks) > "Add a new webhook"
22
  #### 2. Configure your webhook (see image below)
23
  1. Filter which user, organization or Space you want to watch. It can be a Space you own or not. In this example, all Spaces from `Wauplin` are watched.
24
- 2. Set the webhook URL to <https://spaces-ci-bot-webhook.hf.space/webhook>.
25
  3. Make sure to watch both "repo changes" and "community"
26
 
27
  ![](https://huggingface.co/spaces/spaces-ci-bot/webhook/resolve/main/configure_webhook.jpg)
21
  #### 1. Go to your [settings page](https://huggingface.co/settings/webhooks) > "Add a new webhook"
22
  #### 2. Configure your webhook (see image below)
23
  1. Filter which user, organization or Space you want to watch. It can be a Space you own or not. In this example, all Spaces from `Wauplin` are watched.
24
+ 2. Set the webhook URL to <https://spaces-ci-bot-webhook.hf.space/webhooks/trigger_ci_on_pr>.
25
  3. Make sure to watch both "repo changes" and "community"
26
 
27
  ![](https://huggingface.co/spaces/spaces-ci-bot/webhook/resolve/main/configure_webhook.jpg)