Rolaficus commited on
Commit
123ce06
·
verified ·
1 Parent(s): 6ba67c6

improvement to main.py

Browse files
Files changed (1) hide show
  1. main.py +66 -13
main.py CHANGED
@@ -3,16 +3,23 @@ from pydantic import BaseModel
3
  from typing import Optional, Any, Dict, List
4
  import httpx
5
  import os
 
 
6
 
7
  app = FastAPI()
8
 
9
- # --- Configuration ---
10
- # Set these in your Space's "Settings" -> "Variables and secrets"
11
- DISCORD_WEBHOOK_URL = os.environ.get("DISCORD_WEBHOOK_URL")
12
- # Optional: Secure your webhook so only HF can trigger it
13
- WEBHOOK_SECRET = os.environ.get("WEBHOOK_SECRET")
 
 
14
 
15
- # --- Pydantic Models for HF Payload ---
 
 
 
16
  class HFRepo(BaseModel):
17
  type: str
18
  name: str
@@ -30,6 +37,38 @@ class HFPayload(BaseModel):
30
  comment: Optional[Dict[str, Any]] = None
31
  webhook: Optional[Dict[str, Any]] = None
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  @app.get("/")
34
  def home():
35
  return {"status": "Webhook listener is running"}
@@ -41,6 +80,7 @@ async def handle_webhook(
41
  ):
42
  # 1. Security Check
43
  if WEBHOOK_SECRET and x_webhook_secret != WEBHOOK_SECRET:
 
44
  raise HTTPException(status_code=401, detail="Invalid Secret")
45
 
46
  # 2. Format for Discord
@@ -48,12 +88,22 @@ async def handle_webhook(
48
 
49
  # 3. Send to Discord
50
  if DISCORD_WEBHOOK_URL:
51
- async with httpx.AsyncClient() as client:
52
- resp = await client.post(
53
- DISCORD_WEBHOOK_URL,
54
- json={"embeds": [embed]}
55
- )
56
- print(f"Sent to Discord: {resp.status_code}")
 
 
 
 
 
 
 
 
 
 
57
 
58
  return {"message": "Processed"}
59
 
@@ -82,7 +132,10 @@ def build_discord_embed(data: HFPayload):
82
  title = f"Discussion Update: {disc_title}"
83
 
84
  if data.comment:
85
- description = f"**New Comment** on {repo_name}:\n> {data.comment.get('content', '')[:200]}..."
 
 
 
86
  else:
87
  description = f"Discussion status: **{event_action}**"
88
 
 
3
  from typing import Optional, Any, Dict, List
4
  import httpx
5
  import os
6
+ import socket
7
+ from urllib.parse import urlparse
8
 
9
  app = FastAPI()
10
 
11
+ # --- Configuration & Cleaning ---
12
+ def get_clean_env(key):
13
+ val = os.environ.get(key)
14
+ if val:
15
+ # Remove whitespace, single quotes, and double quotes
16
+ return val.strip().strip("'").strip('"')
17
+ return None
18
 
19
+ DISCORD_WEBHOOK_URL = get_clean_env("DISCORD_WEBHOOK_URL")
20
+ WEBHOOK_SECRET = get_clean_env("WEBHOOK_SECRET")
21
+
22
+ # --- Pydantic Models ---
23
  class HFRepo(BaseModel):
24
  type: str
25
  name: str
 
37
  comment: Optional[Dict[str, Any]] = None
38
  webhook: Optional[Dict[str, Any]] = None
39
 
40
+ @app.on_event("startup")
41
+ async def startup_event():
42
+ print("--- STARTUP DIAGNOSTICS ---")
43
+ # 1. Check if Variable Exists
44
+ if DISCORD_WEBHOOK_URL:
45
+ # Mask the URL for safety in logs
46
+ masked = DISCORD_WEBHOOK_URL[:8] + "..." + DISCORD_WEBHOOK_URL[-4:]
47
+ print(f"INFO: Webhook URL loaded: {masked}")
48
+
49
+ # 2. Extract Hostname
50
+ try:
51
+ parsed = urlparse(DISCORD_WEBHOOK_URL)
52
+ hostname = parsed.hostname
53
+ if not hostname:
54
+ print("ERROR: Could not extract hostname from URL. Is the format 'https://...'?")
55
+ else:
56
+ print(f"DEBUG: Hostname extracted: '{hostname}'")
57
+
58
+ # 3. Test DNS Resolution (The "Network Doctor")
59
+ try:
60
+ # Note: socket.gethostbyname is blocking, but okay for a quick startup check
61
+ ip = socket.gethostbyname(hostname)
62
+ print(f"SUCCESS: DNS resolved {hostname} to {ip}")
63
+ except socket.gaierror as e:
64
+ print(f"CRITICAL FAILURE: Could not resolve {hostname}. Error: {e}")
65
+ print("-> This means the URL is wrong OR the container has no internet access.")
66
+ except Exception as e:
67
+ print(f"ERROR parsing URL: {e}")
68
+ else:
69
+ print("WARNING: No DISCORD_WEBHOOK_URL found. Discord messages will not be sent.")
70
+ print("---------------------------")
71
+
72
  @app.get("/")
73
  def home():
74
  return {"status": "Webhook listener is running"}
 
80
  ):
81
  # 1. Security Check
82
  if WEBHOOK_SECRET and x_webhook_secret != WEBHOOK_SECRET:
83
+ print(f"Unauthorized access attempt. Header: {x_webhook_secret}")
84
  raise HTTPException(status_code=401, detail="Invalid Secret")
85
 
86
  # 2. Format for Discord
 
88
 
89
  # 3. Send to Discord
90
  if DISCORD_WEBHOOK_URL:
91
+ print(f"Sending notification for {payload.repo.name}...")
92
+ try:
93
+ # Added a timeout to prevent hanging
94
+ async with httpx.AsyncClient(timeout=10.0) as client:
95
+ resp = await client.post(
96
+ DISCORD_WEBHOOK_URL,
97
+ json={"embeds": [embed]}
98
+ )
99
+ resp.raise_for_status()
100
+ print(f"Sent to Discord: {resp.status_code}")
101
+ except httpx.ConnectError as e:
102
+ print(f"CONNECTION ERROR: Could not connect to Discord. Check DNS/Network. Details: {e}")
103
+ return {"message": "Connection Failed", "error": str(e)}
104
+ except Exception as e:
105
+ print(f"ERROR connecting to Discord: {e}")
106
+ return {"message": "Error sending to Discord", "error": str(e)}
107
 
108
  return {"message": "Processed"}
109
 
 
132
  title = f"Discussion Update: {disc_title}"
133
 
134
  if data.comment:
135
+ content = data.comment.get('content', '')
136
+ if len(content) > 200:
137
+ content = content[:200] + "..."
138
+ description = f"**New Comment** on {repo_name}:\n> {content}"
139
  else:
140
  description = f"Discussion status: **{event_action}**"
141