import gradio as gr import requests import time import traceback from functools import wraps # 🛑 PASTE YOUR WEBHOOK URL HERE WEBHOOK_URL = "https://hubnotifier.mergenotifier.com/api/webhooks/f89bdb26411d1c2474debba4e087778b" def hub_notifier(func): @wraps(func) def wrapper(*args, **kwargs): requests.post(WEBHOOK_URL, json={ "title": f"🚀 Job Started: {func.__name__}", "message": "The process has been initiated and is running in the background." }) start_time = time.time() try: # We use 'yield from' because this is a Gradio generator function result = yield from func(*args, **kwargs) # --- 2. SUCCESS SIGNAL --- duration = round(time.time() - start_time, 2) requests.post(WEBHOOK_URL, json={ "title": f"✅ Job Finished: {func.__name__}", "message": f"The task completed successfully in {duration} seconds." }) return result except Exception as e: # --- 3. CRASH SIGNAL --- error_msg = str(e) # Grab the last 4 lines of the traceback for context short_trace = "\n".join(traceback.format_exc().strip().split('\n')[-4:]) requests.post(WEBHOOK_URL, json={ "title": f"🚨 Job Crashed: {func.__name__}", "message": f"A fatal error occurred: {error_msg}", "metrics": { "Exception": type(e).__name__, "Traceback": f"\n{short_trace}" } }) raise e return wrapper # ========================================== # 2. THE TASK TO BE MONITORED # ========================================== @hub_notifier def run_simple_task(): yield "Initializing background worker..." time.sleep(5) yield "Processing data batches..." time.sleep(5) yield "Finalizing results..." time.sleep(2) return "Task Complete!" # ========================================== # 3. GRADIO UI SETUP # ========================================== with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown("# 🔔 HubNotifier: Production MVP Tester") gr.Markdown("Click the button to simulate a long-running training job or background process.") with gr.Row(): output = gr.Textbox(label="Job Status", placeholder="Waiting for start...") btn = gr.Button("Run Monitored Task", variant="primary") # Connect the button to our decorated function btn.click(fn=run_simple_task, outputs=output) if __name__ == "__main__": demo.launch()