Spaces:
Sleeping
Sleeping
File size: 6,522 Bytes
78d6c11 1c49b9c cf124ab 1c49b9c cf124ab 1c49b9c 78d6c11 1c49b9c cf124ab 1c49b9c 3778828 5f1940c 3778828 cf124ab 5f1940c cf124ab 5f1940c cf124ab 5f1940c cf124ab 5f1940c cf124ab 5f1940c cf124ab 5f1940c 3778828 1c49b9c cf124ab 1c49b9c 3778828 cf124ab 3778828 cf124ab 3778828 78d6c11 3778828 cf124ab 78d6c11 3778828 78d6c11 3778828 cf124ab 3778828 cf124ab 3778828 78d6c11 cf124ab 78d6c11 1c49b9c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | import os
import requests
import uvicorn
import logging
from fastapi import FastAPI, Request, Header, HTTPException
from typing import Optional
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()
TEAMS_WEBHOOK_URL = os.getenv("TEAMS_WEBHOOK_URL")
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET")
HF_TOKEN = os.getenv("HF_TOKEN")
@app.get("/")
def root():
return {"status": "running"}
def get_commit_info(repo_type, repo_name, head_sha):
type_map = {"model": "models", "dataset": "datasets", "space": "spaces"}
api_type = type_map.get(repo_type, "models")
headers = {}
if HF_TOKEN:
headers["Authorization"] = f"Bearer {HF_TOKEN}"
commit_title = head_sha[:8]
commit_author = "unknown"
parent_sha = None
changed_files = []
# 1) ์ปค๋ฐ ๋ชฉ๋ก์์ ์ปค๋ฐ ๋ฉ์์ง, ์์ฑ์, ๋ถ๋ชจ SHA ์กฐํ
try:
commits_url = f"https://huggingface.co/api/{api_type}/{repo_name}/commits/main"
resp = requests.get(commits_url, headers=headers, timeout=10)
if resp.ok:
commits = resp.json()
for i, commit in enumerate(commits):
if commit.get("id", "").startswith(head_sha[:8]):
commit_title = commit.get("title", head_sha[:8])
authors = commit.get("authors", [])
if authors:
commit_author = authors[0].get("user", "unknown")
# ๋ฐ๋ก ๋ค์์ด ๋ถ๋ชจ ์ปค๋ฐ
if i + 1 < len(commits):
parent_sha = commits[i + 1].get("id")
break
except Exception as e:
logger.error(f"Commits API error: {e}")
# 2) ํ์ฌ ์ปค๋ฐ๊ณผ ๋ถ๋ชจ ์ปค๋ฐ์ ํ์ผ ํธ๋ฆฌ ๋น๊ต
if parent_sha:
try:
def get_tree(revision):
tree_url = f"https://huggingface.co/api/{api_type}/{repo_name}/tree/{revision}"
logger.info(f"Fetching tree: {tree_url}")
r = requests.get(tree_url, headers=headers, timeout=10, params={"recursive": "true"})
logger.info(f" Tree status: {r.status_code}")
if r.ok:
return {f.get("path"): f.get("oid") for f in r.json() if f.get("type") == "file"}
return {}
current_files = get_tree(head_sha)
parent_files = get_tree(parent_sha)
# ์ถ๊ฐ๋ ํ์ผ
for path in current_files:
if path not in parent_files:
changed_files.append(f"๐ {path}")
elif current_files[path] != parent_files[path]:
changed_files.append(f"โ๏ธ {path}")
# ์ญ์ ๋ ํ์ผ
for path in parent_files:
if path not in current_files:
changed_files.append(f"๐๏ธ {path}")
except Exception as e:
logger.error(f"Tree compare error: {e}")
return commit_title, commit_author, changed_files
@app.post("/webhook")
async def handle_webhook(
request: Request,
x_webhook_secret: Optional[str] = Header(default=None)
):
if WEBHOOK_SECRET:
if x_webhook_secret != WEBHOOK_SECRET:
raise HTTPException(status_code=403, detail="Invalid secret")
payload = await request.json()
# ์ ์ฒด payload ๋ก๊น
(๋๋ฒ๊น
์ฉ)
logger.info(f"=== WEBHOOK RECEIVED ===")
logger.info(f"Full payload keys: {list(payload.keys())}")
logger.info(f"Event: {payload.get('event')}")
logger.info(f"Repo: {payload.get('repo')}")
event = payload.get("event", {})
repo = payload.get("repo", {})
if event.get("action") == "update" and event.get("scope", "").startswith("repo.content"):
repo_name = repo.get("name", "unknown")
repo_type = repo.get("type", "model")
head_sha = repo.get("headSha", "")
commit_title, commit_author, changed_files = get_commit_info(repo_type, repo_name, head_sha)
if changed_files:
files_text = "\n".join(changed_files[:15])
if len(changed_files) > 15:
files_text += f"\n...์ธ {len(changed_files) - 15}๊ฐ ํ์ผ"
else:
files_text = "(๋ณ๊ฒฝ ํ์ผ ์กฐํ ์คํจ - Space ๋ก๊ทธ๋ฅผ ํ์ธํ์ธ์)"
card = {
"type": "message",
"attachments": [{
"contentType": "application/vnd.microsoft.card.adaptive",
"contentUrl": None,
"content": {
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": f"๐ฆ {repo_name}",
"wrap": True, "weight": "Bolder", "size": "Large"
},
{
"type": "FactSet",
"facts": [
{"title": "์ปค๋ฐ", "value": commit_title},
{"title": "์์ฑ์", "value": commit_author},
{"title": "SHA", "value": head_sha[:8]}
]
},
{
"type": "TextBlock",
"text": "**๋ณ๊ฒฝ๋ ํ์ผ:**",
"wrap": True, "spacing": "Medium"
},
{
"type": "TextBlock",
"text": files_text,
"wrap": True, "fontType": "Monospace", "size": "Small"
},
{
"type": "ActionSet",
"actions": [{
"type": "Action.OpenUrl",
"title": "์ปค๋ฐ ๋ณด๊ธฐ",
"url": f"https://huggingface.co/{repo_name}/commit/{head_sha}"
}]
}
]
}
}]
}
resp = requests.post(TEAMS_WEBHOOK_URL, json=card)
return {"sent": True, "teams_status": resp.status_code}
return {"sent": False, "reason": "not a repo content update"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860) |