asmaa105 commited on
Commit
74952b9
Β·
verified Β·
1 Parent(s): f7204df

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -103
app.py CHANGED
@@ -1,13 +1,13 @@
1
- # app.py - Main application file for HF Spaces
2
  import os
3
  import re
4
  import json
5
  from datetime import datetime
6
- from typing import List, Dict, Any, Optional
7
 
 
8
  from fastapi import FastAPI, Request, BackgroundTasks
9
  from fastapi.middleware.cors import CORSMiddleware
10
- import gradio as gr
11
  from pydantic import BaseModel
12
 
13
  # Configuration - Use HF Spaces secrets
@@ -89,11 +89,10 @@ async def process_tags_directly(all_tags: List[str], repo_name: str) -> List[str
89
 
90
  hf_api = HfApi(token=HF_TOKEN)
91
 
92
- # First, determine what type of repository this is
93
  repo_type = None
94
  repo_info = None
95
 
96
- # Try different repository types
97
  for repo_type_to_try in ["model", "dataset", "space"]:
98
  try:
99
  print(f"πŸ” Trying to access {repo_name} as {repo_type_to_try}...")
@@ -230,7 +229,7 @@ async def process_webhook_comment(webhook_data: Dict[str, Any]):
230
  }
231
  tag_operations_store.append(interaction)
232
 
233
- # Keep only last 100 operations to prevent memory issues
234
  if len(tag_operations_store) > 100:
235
  tag_operations_store.pop(0)
236
 
@@ -241,47 +240,90 @@ async def process_webhook_comment(webhook_data: Dict[str, Any]):
241
  print(f"❌ {error_msg}")
242
  return error_msg
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  def create_gradio_interface():
245
  """Create Gradio interface for monitoring"""
246
- with gr.Blocks(title="HF Tagging Bot", theme=gr.themes.Soft()) as demo:
247
  gr.Markdown("# 🏷️ HuggingFace Tagging Bot")
248
  gr.Markdown("*Automatically adds tags to repositories when mentioned in discussions*")
249
 
250
- with gr.Tab("🏠 Home"):
251
  gr.Markdown(f"""
252
- ## Bot Status
253
  - πŸ”‘ **HF Token**: {'βœ… Configured' if HF_TOKEN else '❌ Missing'}
254
  - πŸ” **Webhook Secret**: {'βœ… Configured' if WEBHOOK_SECRET else '❌ Missing'}
255
  - πŸ“Š **Operations Processed**: {len(tag_operations_store)}
256
 
257
- ## How to Use
258
- 1. **Configure webhook** in your repository settings:
259
- - Webhook URL: `{os.getenv('SPACE_ID', 'your-space')}.hf.space/webhook`
260
- - Events: Discussion comments
261
- - Secret: Your webhook secret (optional)
 
262
 
263
- 2. **In discussions, mention tags like**:
264
  - "Please add tags: pytorch, transformers"
265
- - "This needs #pytorch and #text-generation tags"
266
  - "tag: computer-vision"
267
 
268
- 3. **Bot will automatically**:
269
- - Detect mentioned tags
270
- - Create PRs to add missing tags
271
- - Post results in logs
272
-
273
  ## Webhook Endpoint
274
- `POST /{os.getenv('SPACE_ID', 'your-space')}.hf.space/webhook`
 
 
 
275
  """)
276
 
277
- with gr.Tab("πŸ“ Recent Operations"):
278
  def get_recent_operations():
279
  if not tag_operations_store:
280
- return "No operations yet. Waiting for webhook events..."
281
 
282
- recent = tag_operations_store[-10:] # Last 10 operations
283
  output = []
284
- for op in reversed(recent): # Most recent first
285
  output.append(f"""
286
  **{op['repo']}** - {op['timestamp'][:19]}
287
  - πŸ‘€ Author: {op['comment_author']}
@@ -297,33 +339,26 @@ def create_gradio_interface():
297
  interactive=False
298
  )
299
 
300
- refresh_btn = gr.Button("πŸ”„ Refresh")
301
  refresh_btn.click(fn=get_recent_operations, outputs=operations_display)
302
 
303
- with gr.Tab("🏷️ Supported Tags"):
304
  gr.Markdown(f"""
305
- ## Recognized Tags ({len(RECOGNIZED_TAGS)} total):
306
-
307
  {', '.join(sorted(RECOGNIZED_TAGS))}
308
 
309
- ## Tag Detection Patterns:
310
  - **Explicit**: `tag: pytorch` or `tags: pytorch, transformers`
311
  - **Hashtag**: `#pytorch #transformers`
312
- - **Natural text**: Any mention of recognized tags in text
313
-
314
- ## Examples:
315
- - βœ… "This model uses pytorch and transformers"
316
- - βœ… "Please add tags: computer-vision, object-detection"
317
- - βœ… "Missing #pytorch #text-generation tags"
318
- - βœ… "tag: nlp"
319
  """)
320
-
321
- with gr.Tab("πŸ”§ Test"):
322
  gr.Markdown("### Test Tag Detection")
323
  test_input = gr.Textbox(
324
  label="Test Comment",
325
  placeholder="Enter a comment to test tag detection...",
326
- lines=3
 
327
  )
328
  test_output = gr.Textbox(
329
  label="Detected Tags",
@@ -337,75 +372,23 @@ def create_gradio_interface():
337
  return "Enter some text to test"
338
  tags = extract_tags_from_text(text)
339
  if tags:
340
- return f"Found tags: {', '.join(tags)}"
341
  else:
342
- return "No tags detected"
343
 
344
  test_btn.click(fn=test_tag_detection, inputs=test_input, outputs=test_output)
345
 
346
- return demo
347
-
348
- # Create FastAPI app for webhook handling
349
- app = FastAPI(title="HF Tagging Bot API")
350
- app.add_middleware(CORSMiddleware, allow_origins=["*"])
351
-
352
- @app.post("/webhook")
353
- async def webhook_handler(request: Request, background_tasks: BackgroundTasks):
354
- """Handle HF Hub webhooks"""
355
- # Verify webhook secret if configured
356
- if WEBHOOK_SECRET:
357
- webhook_secret = request.headers.get("X-Webhook-Secret")
358
- if webhook_secret != WEBHOOK_SECRET:
359
- print("❌ Invalid webhook secret")
360
- return {"error": "Invalid webhook secret"}
361
-
362
- try:
363
- payload = await request.json()
364
- print(f"πŸ“₯ Received webhook: {payload.get('event', {})}")
365
-
366
- event = payload.get("event", {})
367
- scope = event.get("scope")
368
- action = event.get("action")
369
-
370
- # Only process discussion comment creation (not PRs)
371
- if (scope == "discussion" and
372
- action == "create" and
373
- not payload.get("discussion", {}).get("isPullRequest", False)):
374
-
375
- background_tasks.add_task(process_webhook_comment, payload)
376
- return {"status": "processing"}
377
-
378
- return {"status": "ignored"}
379
- except Exception as e:
380
- print(f"❌ Webhook error: {e}")
381
- return {"error": str(e)}
382
-
383
- # Health check endpoint
384
- @app.get("/health")
385
- async def health_check():
386
- return {
387
- "status": "healthy",
388
- "hf_token_configured": bool(HF_TOKEN),
389
- "webhook_secret_configured": bool(WEBHOOK_SECRET),
390
- "operations_processed": len(tag_operations_store)
391
- }
392
-
393
- @app.get("/")
394
- async def root():
395
- return {"message": "HF Tagging Bot is running! Visit /gradio for the interface."}
396
 
397
- # Create and mount Gradio interface
398
- gradio_app = create_gradio_interface()
399
- app = gr.mount_gradio_app(app, gradio_app, path="/gradio")
400
 
401
- # For HF Spaces, we also need to make the Gradio interface the default
402
- demo = gradio_app
403
 
 
404
  if __name__ == "__main__":
405
- # This runs when testing locally
406
- import uvicorn
407
- port = int(os.getenv("PORT", 7860))
408
- print(f"πŸš€ Starting HF Tagging Bot on port {port}")
409
  print(f"πŸ”‘ HF_TOKEN: {'βœ… Configured' if HF_TOKEN else '❌ Missing'}")
410
  print(f"πŸ” Webhook Secret: {'βœ… Configured' if WEBHOOK_SECRET else '❌ Missing'}")
411
- uvicorn.run("app:app", host="0.0.0.0", port=port)
 
1
+ # app.py - HF Spaces compatible version
2
  import os
3
  import re
4
  import json
5
  from datetime import datetime
6
+ from typing import List, Dict, Any
7
 
8
+ import gradio as gr
9
  from fastapi import FastAPI, Request, BackgroundTasks
10
  from fastapi.middleware.cors import CORSMiddleware
 
11
  from pydantic import BaseModel
12
 
13
  # Configuration - Use HF Spaces secrets
 
89
 
90
  hf_api = HfApi(token=HF_TOKEN)
91
 
92
+ # Determine repository type
93
  repo_type = None
94
  repo_info = None
95
 
 
96
  for repo_type_to_try in ["model", "dataset", "space"]:
97
  try:
98
  print(f"πŸ” Trying to access {repo_name} as {repo_type_to_try}...")
 
229
  }
230
  tag_operations_store.append(interaction)
231
 
232
+ # Keep only last 100 operations
233
  if len(tag_operations_store) > 100:
234
  tag_operations_store.pop(0)
235
 
 
240
  print(f"❌ {error_msg}")
241
  return error_msg
242
 
243
+ # Create FastAPI app for webhook handling
244
+ fastapi_app = FastAPI(title="HF Tagging Bot API")
245
+ fastapi_app.add_middleware(CORSMiddleware, allow_origins=["*"])
246
+
247
+ @fastapi_app.post("/webhook")
248
+ async def webhook_handler(request: Request, background_tasks: BackgroundTasks):
249
+ """Handle HF Hub webhooks"""
250
+ # Verify webhook secret if configured
251
+ if WEBHOOK_SECRET:
252
+ webhook_secret = request.headers.get("X-Webhook-Secret")
253
+ if webhook_secret != WEBHOOK_SECRET:
254
+ print("❌ Invalid webhook secret")
255
+ return {"error": "Invalid webhook secret"}
256
+
257
+ try:
258
+ payload = await request.json()
259
+ print(f"πŸ“₯ Received webhook: {payload.get('event', {})}")
260
+
261
+ event = payload.get("event", {})
262
+ scope = event.get("scope")
263
+ action = event.get("action")
264
+
265
+ # Only process discussion comment creation (not PRs)
266
+ if (scope == "discussion" and
267
+ action == "create" and
268
+ not payload.get("discussion", {}).get("isPullRequest", False)):
269
+
270
+ background_tasks.add_task(process_webhook_comment, payload)
271
+ return {"status": "processing"}
272
+
273
+ return {"status": "ignored"}
274
+ except Exception as e:
275
+ print(f"❌ Webhook error: {e}")
276
+ return {"error": str(e)}
277
+
278
+ @fastapi_app.get("/health")
279
+ async def health_check():
280
+ return {
281
+ "status": "healthy",
282
+ "hf_token_configured": bool(HF_TOKEN),
283
+ "webhook_secret_configured": bool(WEBHOOK_SECRET),
284
+ "operations_processed": len(tag_operations_store)
285
+ }
286
+
287
  def create_gradio_interface():
288
  """Create Gradio interface for monitoring"""
289
+ with gr.Blocks(title="HF Tagging Bot", theme=gr.themes.Soft()) as interface:
290
  gr.Markdown("# 🏷️ HuggingFace Tagging Bot")
291
  gr.Markdown("*Automatically adds tags to repositories when mentioned in discussions*")
292
 
293
+ with gr.Tab("🏠 Status"):
294
  gr.Markdown(f"""
295
+ ## Bot Configuration
296
  - πŸ”‘ **HF Token**: {'βœ… Configured' if HF_TOKEN else '❌ Missing'}
297
  - πŸ” **Webhook Secret**: {'βœ… Configured' if WEBHOOK_SECRET else '❌ Missing'}
298
  - πŸ“Š **Operations Processed**: {len(tag_operations_store)}
299
 
300
+ ## Setup Instructions
301
+ 1. **Add webhook to your repository**:
302
+ - Go to repository Settings β†’ Webhooks
303
+ - Add webhook URL: `https://your-space-name.hf.space/webhook`
304
+ - Select "Discussion comments" events
305
+ - Add your webhook secret (optional)
306
 
307
+ 2. **In discussions, mention tags**:
308
  - "Please add tags: pytorch, transformers"
309
+ - "This needs #pytorch and #text-generation"
310
  - "tag: computer-vision"
311
 
 
 
 
 
 
312
  ## Webhook Endpoint
313
+ `POST https://your-space-name.hf.space/webhook`
314
+
315
+ ## Health Check
316
+ Visit: `https://your-space-name.hf.space/health`
317
  """)
318
 
319
+ with gr.Tab("πŸ“ Operations Log"):
320
  def get_recent_operations():
321
  if not tag_operations_store:
322
+ return "No operations yet. Configure webhooks and post comments with tags to see activity here."
323
 
324
+ recent = tag_operations_store[-10:]
325
  output = []
326
+ for op in reversed(recent):
327
  output.append(f"""
328
  **{op['repo']}** - {op['timestamp'][:19]}
329
  - πŸ‘€ Author: {op['comment_author']}
 
339
  interactive=False
340
  )
341
 
342
+ refresh_btn = gr.Button("πŸ”„ Refresh Log")
343
  refresh_btn.click(fn=get_recent_operations, outputs=operations_display)
344
 
345
+ with gr.Tab("🏷️ Tags & Testing"):
346
  gr.Markdown(f"""
347
+ ## Supported Tags ({len(RECOGNIZED_TAGS)} total)
 
348
  {', '.join(sorted(RECOGNIZED_TAGS))}
349
 
350
+ ## Tag Detection Examples
351
  - **Explicit**: `tag: pytorch` or `tags: pytorch, transformers`
352
  - **Hashtag**: `#pytorch #transformers`
353
+ - **Natural**: "This model uses pytorch and transformers"
 
 
 
 
 
 
354
  """)
355
+
 
356
  gr.Markdown("### Test Tag Detection")
357
  test_input = gr.Textbox(
358
  label="Test Comment",
359
  placeholder="Enter a comment to test tag detection...",
360
+ lines=3,
361
+ value="This model should have tags: pytorch, text-generation"
362
  )
363
  test_output = gr.Textbox(
364
  label="Detected Tags",
 
372
  return "Enter some text to test"
373
  tags = extract_tags_from_text(text)
374
  if tags:
375
+ return f"Found {len(tags)} tags: {', '.join(tags)}"
376
  else:
377
+ return "No tags detected in this text"
378
 
379
  test_btn.click(fn=test_tag_detection, inputs=test_input, outputs=test_output)
380
 
381
+ return interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
 
383
+ # Create the Gradio interface
384
+ demo = create_gradio_interface()
 
385
 
386
+ # Mount FastAPI to Gradio (for HF Spaces)
387
+ app = gr.mount_gradio_app(fastapi_app, demo, path="/")
388
 
389
+ # This is the main app that HF Spaces will use
390
  if __name__ == "__main__":
391
+ print("πŸš€ HF Tagging Bot - Gradio interface ready")
 
 
 
392
  print(f"πŸ”‘ HF_TOKEN: {'βœ… Configured' if HF_TOKEN else '❌ Missing'}")
393
  print(f"πŸ” Webhook Secret: {'βœ… Configured' if WEBHOOK_SECRET else '❌ Missing'}")
394
+ demo.launch()