mengfoong123 commited on
Commit
5bf33af
·
verified ·
1 Parent(s): 89439c2

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +91 -0
main.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, Body
2
+ from apscheduler.schedulers.background import BackgroundScheduler
3
+ from datetime import datetime, timedelta
4
+ import pandas as pd
5
+ import requests
6
+ import os
7
+
8
+ app = FastAPI()
9
+ scheduler = BackgroundScheduler()
10
+ scheduler.start()
11
+
12
+ # --- Helper job ---
13
+ def do_post(url: str, payload: dict = None):
14
+ try:
15
+ resp = requests.post(url, json=payload or {})
16
+ print(f"[{datetime.utcnow()}] POST {url} → {resp.status_code}")
17
+ except Exception as e:
18
+ print(f"[{datetime.utcnow()}] ERROR posting to {url}: {e}")
19
+
20
+ # --- 1A: Schedule from uploaded CSV ---
21
+ @app.post("/schedule_csv/")
22
+ async def schedule_csv(
23
+ csv_file: UploadFile = File(...),
24
+ delay_hours: float = Body(2.0, description="Delay before first run, in hours"),
25
+ repeat_hours: float = Body(None, description="If set, job will repeat every N hours")
26
+ ):
27
+ df = pd.read_csv(csv_file.file)
28
+ urls = df["endpoint"].dropna().tolist()
29
+ for url in urls:
30
+ if repeat_hours:
31
+ scheduler.add_job(
32
+ do_post,
33
+ trigger="interval",
34
+ hours=repeat_hours,
35
+ next_run_time=datetime.utcnow() + timedelta(hours=delay_hours),
36
+ args=[url],
37
+ id=f"interval_{url}"
38
+ )
39
+ else:
40
+ scheduler.add_job(
41
+ do_post,
42
+ trigger="date",
43
+ run_date=datetime.utcnow() + timedelta(hours=delay_hours),
44
+ args=[url],
45
+ id=f"once_{url}"
46
+ )
47
+ return {"scheduled": len(urls)}
48
+
49
+ # --- 1B: Schedule from JSON body (n8n could use this) ---
50
+ @app.post("/schedule_json/")
51
+ async def schedule_json(
52
+ endpoints: list[str] = Body(..., description="List of URLs to call"),
53
+ delay_hours: float = Body(2.0),
54
+ repeat_hours: float = Body(None)
55
+ ):
56
+ for url in endpoints:
57
+ if repeat_hours:
58
+ scheduler.add_job(
59
+ do_post,
60
+ trigger="interval",
61
+ hours=repeat_hours,
62
+ next_run_time=datetime.utcnow() + timedelta(hours=delay_hours),
63
+ args=[url],
64
+ id=f"interval_{url}"
65
+ )
66
+ else:
67
+ scheduler.add_job(
68
+ do_post,
69
+ trigger="date",
70
+ run_date=datetime.utcnow() + timedelta(hours=delay_hours),
71
+ args=[url],
72
+ id=f"once_{url}"
73
+ )
74
+ return {"scheduled": len(endpoints)}
75
+
76
+ # --- 2: Self‑ping to prevent idle shutdown (optional) ---
77
+ HF_SPACE_URL = os.getenv("HF_SPACE_URL") # e.g. "https://my-username-hf-space.hf.space"
78
+ if HF_SPACE_URL:
79
+ def heartbeat():
80
+ try:
81
+ requests.get(f"{HF_SPACE_URL}/heartbeat")
82
+ print("Self-ping OK")
83
+ except:
84
+ pass
85
+
86
+ # ping every hour to keep the Space “active” in HF’s eyes
87
+ scheduler.add_job(heartbeat, "interval", hours=1, id="self_ping")
88
+
89
+ @app.get("/heartbeat/")
90
+ async def heartbeat_ok():
91
+ return {"alive": True}