from fastapi import FastAPI, Request, Response import os import requests import json import logging # Set up logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) HF_WEBHOOK_SECRET = os.environ.get("HF_WEBHOOK_SECRET") SLACK_WEBHOOK_URL = os.environ.get("SLACK_WEBHOOK_URL") def send_slack_message(message: str): """Send a message to Slack using webhook URL""" if not SLACK_WEBHOOK_URL: logger.warning(f"No Slack webhook URL configured. Message: {message}") return payload = {"text": message} try: response = requests.post(SLACK_WEBHOOK_URL, json=payload) response.raise_for_status() logger.info(f"Slack message sent successfully: {message}") except requests.exceptions.RequestException as e: logger.error(f"Failed to send Slack message: {e}") app = FastAPI() @app.post("/webhook") async def webhook(request: Request): logger.info(f"Received webhook request from {request.client.host}") if request.headers.get("X-Webhook-Secret") != HF_WEBHOOK_SECRET: logger.warning("Invalid webhook secret received") return Response("Invalid secret", status_code=401) data = await request.json() logger.info(f"Webhook payload: {json.dumps(data, indent=2)}") event = data.get("event", {}) repo = data.get("repo", {}) # Only process model repo events if repo.get("type") != "model" or event.get("scope") != "repo": logger.info(f"Skipping non-model repo event: type={repo.get('type')}, scope={event.get('scope')}") return Response("Not a model repo event", status_code=200) action = event.get("action") logger.info(f"Processing model repo action: {action}") if action == "move": old_name = repo.get("name", "unknown") new_name = data.get("movedTo", {}).get("name", "unknown") message = f"🔄 Model renamed: {old_name} → https://hf.co/{new_name}" send_slack_message(message) elif action == "delete": name = repo.get("name", "unknown") message = f"🗑️ Model deleted: https://hf.co/{name}" send_slack_message(message) else: logger.info(f"Unhandled action: {action}") return Response("Webhook notification received and processed!", status_code=200)