mainak555 commited on
Commit
e9c08e5
·
verified ·
1 Parent(s): b8bf8d2

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. Dockerfile +20 -0
  2. app.py +68 -0
  3. requirements.txt +5 -0
  4. watch_list.py +14 -0
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ FROM python:3.12.10-slim-bookworm
3
+
4
+ # Non-root user (HF Spaces requirement)
5
+ # UID 1000 is the standard user for HF Spaces
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV HOME=/home/user \
9
+ PATH=/home/user/.local/bin:$PATH
10
+
11
+ WORKDIR $HOME/app
12
+
13
+ COPY --chown=user app.py .
14
+ COPY --chown=user watch_list.py .
15
+ COPY --chown=user requirements.txt .
16
+
17
+ RUN python -m pip install --upgrade pip
18
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
19
+
20
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from fastapi import FastAPI, Header, HTTPException, Query
3
+ from watch_list import TRACKING_PATHS
4
+ from huggingface_hub import HfApi
5
+ import httpx
6
+ import os
7
+
8
+ HF_WEBHOOK_SECRET = os.getenv("HF_WEBHOOK_SECRET")
9
+ GH_PAT = os.getenv("GH_PAT")
10
+
11
+ app = FastAPI(
12
+ title="Hugging Face Webhook Relay",
13
+ description="Trigger Actions from HF Webhook",
14
+ version="1.0.0"
15
+ )
16
+
17
+ @app.get("/")
18
+ def liveProbe():
19
+ return app.title
20
+
21
+ @app.post("/v1/github_hook")
22
+ async def github_hook(
23
+ x_webhook_secret: str = Header(None),
24
+ hf_repo: str = Query(..., description="Hugging Face repo (format: user/repo)"),
25
+ gh_repo: str = Query(..., description="GitHub repo to trigger (format: user/repo)"),
26
+ hf_repo_type: str = Query(..., description="Hugging Face repo type (format: dataset|model|space)")
27
+ ):
28
+ # Verifying request is from HF Webhook
29
+ if x_webhook_secret != HF_WEBHOOK_SECRET:
30
+ raise HTTPException(status_code=401, detail="Invalid Secret")
31
+ elif hf_repo not in TRACKING_PATHS or hf_repo_type not in TRACKING_PATHS[hf_repo]:
32
+ return {"filtered": True}
33
+ else:
34
+ ## check tracking files affected
35
+ hfApi = HfApi(token=os.getenv("HF_TOKEN"))
36
+ commit = hfApi.list_repo_commits(
37
+ repo_type=hf_repo_type,
38
+ repo_id=hf_repo
39
+ )[0]
40
+
41
+ changes = []
42
+ tree = list(hfApi.list_repo_tree(hf_repo, repo_type=hf_repo_type, expand=True))
43
+ for item in tree:
44
+ if hasattr(item, 'last_commit') and item.last_commit:
45
+ if item.last_commit['oid'] == commit.commit_id:
46
+ changes.append(item.path)
47
+
48
+ exists = any(f in changes for f in TRACKING_PATHS[hf_repo][hf_repo_type])
49
+ if not exists:
50
+ return {"ignored": True}
51
+
52
+ # Trigger GitHub Action
53
+ url = f"https://api.github.com/repos/{gh_repo}/dispatches"
54
+ async with httpx.AsyncClient() as client:
55
+ response = await client.post(url, headers={
56
+ "Authorization": f"Bearer {GH_PAT}",
57
+ "Accept": "application/vnd.github.v3+json",
58
+ }, json={
59
+ "event_type": "hf_webhook_event", # match 'on' type in github action
60
+ "client_payload": {
61
+ "description": "Hugging Face Webhook",
62
+ "hf_repo_type": hf_repo_type,
63
+ "hf_repo": hf_repo,
64
+ }
65
+ })
66
+
67
+ print(f"HF Repo: {hf_repo} | HF Type: {hf_repo_type} | GitHub Repo: {gh_repo} | GitHub Status: {response.status_code}")
68
+ return {"success": True}
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+
2
+ huggingface_hub==0.34.3
3
+ fastapi==0.116.1
4
+ uvicorn==0.35.0
5
+ httpx==0.28.1
watch_list.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ repo_id: {
4
+ repo_type: [files....]
5
+ }
6
+ """
7
+ TRACKING_PATHS = {
8
+ "mainak555/mlops-tourism": {
9
+ "dataset": ["tourism.csv"]
10
+ },
11
+ "mainak555/predictive-maintenance": {
12
+ "dataset": ["engine_data.csv"]
13
+ }
14
+ }