Rajhuggingface4253 commited on
Commit
56af151
Β·
verified Β·
1 Parent(s): a67fc2a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +172 -127
app.py CHANGED
@@ -1,98 +1,159 @@
1
- from flask import Flask, jsonify
2
- import requests
 
 
3
  import time
4
  from datetime import datetime
5
- import threading
6
  import os
7
 
8
- app = Flask(__name__)
9
 
10
- # List of other pinger Spaces that will ping each other (add your Space URLs here)
 
 
 
 
11
  pinger_spaces = [
12
  "https://rajhuggingface4253-ping2.hf.space",
13
 
14
-
15
  ]
16
 
17
  # Your target servers to keep warm
18
- servers = [
19
- "google.com",
20
- "github.com",
21
- "stackoverflow.com",
22
- "docker.com",
23
- "python.org"
 
 
24
  ]
25
 
26
- results = {}
27
- last_run = None
28
- health_pings = {}
 
29
 
30
- def ping_server(url):
 
31
  try:
32
- start = time.time()
33
- response = requests.get(url if '://' in url else f'https://{url}', timeout=10)
 
 
 
 
 
 
 
 
 
 
 
34
  return {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  'status': 'success',
36
- 'response_time': round((time.time() - start) * 1000, 1),
37
- 'status_code': response.status_code
 
38
  }
 
39
  except Exception as e:
40
- return {'status': 'error', 'error': str(e)}
 
 
 
 
 
41
 
42
- def ping_health_endpoints():
43
- """Ping other pinger Spaces to keep them awake"""
44
- for space_url in pinger_spaces:
 
 
 
 
 
 
 
45
  try:
46
- health_url = f"{space_url}/health"
47
- start = time.time()
48
- response = requests.get(health_url, timeout=10)
49
- response_time = round((time.time() - start) * 1000, 1)
50
 
51
- health_pings[space_url] = {
52
- 'status': 'success',
53
- 'response_time': response_time,
54
- 'status_code': response.status_code,
55
- 'last_ping': datetime.now().isoformat()
56
- }
57
- print(f"βœ… Health ping to {space_url}: {response_time}ms")
 
 
 
58
 
59
  except Exception as e:
60
- health_pings[space_url] = {
61
- 'status': 'error',
62
- 'error': str(e),
63
- 'last_ping': datetime.now().isoformat()
64
- }
65
- print(f"❌ Health ping failed for {space_url}: {e}")
66
 
67
- def ping_all():
68
- global results, last_run
69
- while True:
70
- print(f"{datetime.now().strftime('%H:%M:%S')} - Pinging {len(servers)} servers...")
71
-
72
- # Ping target servers
73
- for server in servers:
74
- results[server] = ping_server(server)
75
- last_run = datetime.now()
76
-
77
- success = sum(1 for r in results.values() if r['status'] == 'success')
78
- print(f"βœ… {success}/{len(servers)} servers OK")
79
-
80
- # Ping other pinger Spaces every 30 minutes to keep them awake
81
- if int(time.time()) % 1800 < 10: # Every 30 minutes
82
- print("πŸ”„ Pinging other pinger Spaces...")
83
- ping_health_endpoints()
84
-
85
- time.sleep(300) # 5 minutes
86
 
87
- @app.route('/')
88
- def home():
89
- success = sum(1 for r in results.values() if r['status'] == 'success') if results else 0
90
- health_success = sum(1 for r in health_pings.values() if r.get('status') == 'success')
 
91
 
92
- return f"""
93
  <html>
94
  <head>
95
- <title>Mutual Pinger</title>
96
  <style>
97
  body {{ font-family: Arial, sans-serif; margin: 40px; }}
98
  .success {{ color: green; }}
@@ -102,83 +163,67 @@ def home():
102
  </head>
103
  <body>
104
  <div class="container">
105
- <h1>πŸ”„ Mutual Pinger</h1>
106
- <p>Monitoring {len(servers)} target servers</p>
107
- <p>Connected to {len(pinger_spaces)} other pinger spaces</p>
108
- <p><strong>Last run:</strong> {last_run or 'Not yet'}</p>
109
- <p><strong>Target servers:</strong> {success}/{len(servers)} OK</p>
110
- <p><strong>Pinger spaces:</strong> {health_success}/{len(pinger_spaces)} OK</p>
111
 
112
  <h3>Endpoints:</h3>
113
  <ul>
114
- <li><a href="/health">Health Check</a> (for other pingers)</li>
115
- <li><a href="/results">Ping Results</a></li>
116
- <li><a href="/network">Network Status</a></li>
117
- <li><a href="/ping-now">Force Ping Now</a></li>
118
  </ul>
119
  </div>
120
  </body>
121
  </html>
122
  """
 
123
 
124
- @app.route('/health')
125
- def health():
126
- """Health endpoint for other pinger Spaces to ping"""
127
- return jsonify({
128
- 'status': 'healthy',
129
- 'service': 'mutual-pinger',
130
- 'timestamp': datetime.now().isoformat(),
131
- 'server_count': len(servers),
132
- 'pinger_network_count': len(pinger_spaces),
133
- 'last_ping_run': last_run.isoformat() if last_run else None
134
  })
135
 
136
- @app.route('/results')
137
- def show_results():
138
- return jsonify({
139
- 'last_run': last_run.isoformat() if last_run else None,
140
- 'target_servers': results,
141
- 'timestamp': datetime.now().isoformat()
 
 
142
  })
143
 
144
- @app.route('/network')
145
- def network_status():
146
- return jsonify({
147
- 'pinger_spaces': pinger_spaces,
148
- 'health_pings': health_pings,
149
- 'this_space_url': os.getenv('SPACE_URL', 'Unknown')
150
- })
151
-
152
- @app.route('/ping-now')
153
- def ping_now():
154
  """Manually trigger a ping cycle"""
155
- global results, last_run
156
- print("πŸ”„ Manual ping triggered")
157
-
158
- # Ping target servers
159
- for server in servers:
160
- results[server] = ping_server(server)
161
- last_run = datetime.now()
162
 
163
- # Ping other pinger spaces
164
- ping_health_endpoints()
165
 
166
- success = sum(1 for r in results.values() if r['status'] == 'success')
167
- health_success = sum(1 for r in health_pings.values() if r.get('status') == 'success')
168
-
169
- return jsonify({
170
- 'message': 'Manual ping completed',
171
- 'target_servers_ok': f'{success}/{len(servers)}',
172
- 'pinger_spaces_ok': f'{health_success}/{len(pinger_spaces)}',
173
- 'timestamp': datetime.now().isoformat()
174
  })
175
 
176
- # Start background pinging
177
- threading.Thread(target=ping_all, daemon=True).start()
 
 
 
178
 
179
- if __name__ == '__main__':
180
- print("πŸš€ Mutual Pinger Started!")
181
- print(f"πŸ“Š Monitoring {len(servers)} target servers")
182
- print(f"πŸ”— Connected to {len(pinger_spaces)} pinger spaces")
183
- print("⏰ Pinging every 5 minutes, health checks every 30 minutes")
184
- app.run(host='0.0.0.0', port=7860)
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.responses import HTMLResponse, JSONResponse
3
+ import httpx
4
+ import asyncio
5
  import time
6
  from datetime import datetime
7
+ from typing import Dict, List
8
  import os
9
 
10
+ app = FastAPI(title="FastAPI Pinger", description="High-performance server warming service")
11
 
12
+ # Configuration
13
+ PING_INTERVAL = 300 # 5 minutes
14
+ HEALTH_CHECK_INTERVAL = 1800 # 30 minutes
15
+
16
+ # List of other pinger Spaces (add your Space URLs here)
17
  pinger_spaces = [
18
  "https://rajhuggingface4253-ping2.hf.space",
19
 
 
20
  ]
21
 
22
  # Your target servers to keep warm
23
+ target_servers = [
24
+ "https://rajhuggingface4253-qwen.hf.space",
25
+ "https://rajhuggingface4253-qwen2.hf.space",
26
+ "https://rajhuggingface4253-qwen3.hf.space",
27
+ "https://rajhuggingface4253-backend-compressorpro.hf.space",
28
+ "https://rajhuggingface4253-backend-compressorpro2.hf.space"
29
+ "https://rajhuggingface4253-compressor3pro.hf.space"
30
+ "https://rajhuggingface4253-koko.hf.space"
31
  ]
32
 
33
+ # Global state
34
+ ping_results: Dict[str, Dict] = {}
35
+ health_results: Dict[str, Dict] = {}
36
+ last_ping_run: datetime = None
37
 
38
+ async def ping_server(url: str) -> Dict:
39
+ """Ping a single server asynchronously"""
40
  try:
41
+ start_time = time.time()
42
+ async with httpx.AsyncClient(timeout=10.0) as client:
43
+ full_url = url if '://' in url else f'https://{url}'
44
+ response = await client.get(full_url)
45
+ response_time = round((time.time() - start_time) * 1000, 1)
46
+
47
+ return {
48
+ 'status': 'success',
49
+ 'response_time_ms': response_time,
50
+ 'status_code': response.status_code,
51
+ 'timestamp': datetime.now().isoformat()
52
+ }
53
+ except Exception as e:
54
  return {
55
+ 'status': 'error',
56
+ 'error': str(e),
57
+ 'timestamp': datetime.now().isoformat()
58
+ }
59
+
60
+ async def ping_all_servers():
61
+ """Ping all target servers concurrently"""
62
+ global ping_results, last_ping_run
63
+
64
+ tasks = [ping_server(server) for server in target_servers]
65
+ results = await asyncio.gather(*tasks)
66
+
67
+ # Store results
68
+ for i, server in enumerate(target_servers):
69
+ ping_results[server] = results[i]
70
+
71
+ last_ping_run = datetime.now()
72
+
73
+ # Log results
74
+ success_count = sum(1 for result in results if result['status'] == 'success')
75
+ print(f"{datetime.now().strftime('%H:%M:%S')} - {success_count}/{len(target_servers)} servers OK")
76
+
77
+ return results
78
+
79
+ async def ping_health_endpoints():
80
+ """Ping other pinger Spaces concurrently"""
81
+ global health_results
82
+
83
+ async with httpx.AsyncClient(timeout=10.0) as client:
84
+ tasks = []
85
+ for space_url in pinger_spaces:
86
+ health_url = f"{space_url}/health"
87
+ tasks.append(ping_single_health(client, space_url, health_url))
88
+
89
+ await asyncio.gather(*tasks)
90
+
91
+ async def ping_single_health(client: httpx.AsyncClient, space_url: str, health_url: str):
92
+ """Ping a single health endpoint"""
93
+ try:
94
+ start_time = time.time()
95
+ response = await client.get(health_url)
96
+ response_time = round((time.time() - start_time) * 1000, 1)
97
+
98
+ health_results[space_url] = {
99
  'status': 'success',
100
+ 'response_time_ms': response_time,
101
+ 'status_code': response.status_code,
102
+ 'last_ping': datetime.now().isoformat()
103
  }
104
+ print(f"βœ… Health ping to {space_url}: {response_time}ms")
105
  except Exception as e:
106
+ health_results[space_url] = {
107
+ 'status': 'error',
108
+ 'error': str(e),
109
+ 'last_ping': datetime.now().isoformat()
110
+ }
111
+ print(f"❌ Health ping failed for {space_url}: {e}")
112
 
113
+ async def continuous_pinging():
114
+ """Main pinging loop"""
115
+ print("πŸš€ FastAPI Pinger Started!")
116
+ print(f"πŸ“Š Monitoring {len(target_servers)} target servers")
117
+ print(f"πŸ”— Connected to {len(pinger_spaces)} pinger spaces")
118
+ print(f"⏰ Pinging every {PING_INTERVAL//60} minutes")
119
+
120
+ last_health_check = 0
121
+
122
+ while True:
123
  try:
124
+ # Ping target servers
125
+ await ping_all_servers()
 
 
126
 
127
+ # Ping health endpoints every 30 minutes
128
+ current_time = time.time()
129
+ if current_time - last_health_check >= HEALTH_CHECK_INTERVAL:
130
+ if pinger_spaces:
131
+ print("πŸ”„ Pinging other pinger spaces...")
132
+ await ping_health_endpoints()
133
+ last_health_check = current_time
134
+
135
+ # Wait for next cycle
136
+ await asyncio.sleep(PING_INTERVAL)
137
 
138
  except Exception as e:
139
+ print(f"❌ Error in pinging loop: {e}")
140
+ await asyncio.sleep(60) # Wait 1 minute before retrying
 
 
 
 
141
 
142
+ @app.on_event("startup")
143
+ async def startup_event():
144
+ """Start the pinging loop when the app starts"""
145
+ asyncio.create_task(continuous_pinging())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
+ @app.get("/", response_class=HTMLResponse)
148
+ async def home():
149
+ """Main dashboard"""
150
+ success_count = sum(1 for result in ping_results.values() if result.get('status') == 'success')
151
+ health_success = sum(1 for result in health_results.values() if result.get('status') == 'success')
152
 
153
+ html_content = f"""
154
  <html>
155
  <head>
156
+ <title>FastAPI Pinger</title>
157
  <style>
158
  body {{ font-family: Arial, sans-serif; margin: 40px; }}
159
  .success {{ color: green; }}
 
163
  </head>
164
  <body>
165
  <div class="container">
166
+ <h1>⚑ FastAPI Pinger</h1>
167
+ <p><strong>Target Servers:</strong> {len(target_servers)}</p>
168
+ <p><strong>Pinger Network:</strong> {len(pinger_spaces)}</p>
169
+ <p><strong>Last Run:</strong> {last_ping_run.strftime('%Y-%m-%d %H:%M:%S') if last_ping_run else 'Not yet'}</p>
170
+ <p><strong>Status:</strong> {success_count}/{len(target_servers)} servers OK β€’ {health_success}/{len(pinger_spaces)} pingers OK</p>
 
171
 
172
  <h3>Endpoints:</h3>
173
  <ul>
174
+ <li><a href="error</a></li>
 
 
 
175
  </ul>
176
  </div>
177
  </body>
178
  </html>
179
  """
180
+ return HTMLResponse(content=html_content)
181
 
182
+ @app.get("/health")
183
+ async def health():
184
+ """Health endpoint for other pingers"""
185
+ return JSONResponse({
186
+ "status": "healthy",
187
+ "service": "fastapi-pinger",
188
+ "timestamp": datetime.now().isoformat(),
189
+ "server_count": len(target_servers),
190
+ "network_count": len(pinger_spaces),
191
+ "last_ping": last_ping_run.isoformat() if last_ping_run else None
192
  })
193
 
194
+ @app.get("/results")
195
+ async def get_results():
196
+ """Get current ping results"""
197
+ return JSONResponse({
198
+ "last_run": last_ping_run.isoformat() if last_ping_run else None,
199
+ "target_servers": ping_results,
200
+ "pinger_network": health_results,
201
+ "timestamp": datetime.now().isoformat()
202
  })
203
 
204
+ @app.get("/ping-now")
205
+ async def ping_now():
 
 
 
 
 
 
 
 
206
  """Manually trigger a ping cycle"""
207
+ results = await ping_all_servers()
208
+ if pinger_spaces:
209
+ await ping_health_endpoints()
 
 
 
 
210
 
211
+ success_count = sum(1 for result in results if result['status'] == 'success')
212
+ health_success = sum(1 for result in health_results.values() if result.get('status') == 'success')
213
 
214
+ return JSONResponse({
215
+ "message": "Manual ping completed",
216
+ "servers_ok": f"{success_count}/{len(target_servers)}",
217
+ "pingers_ok": f"{health_success}/{len(pinger_spaces)}",
218
+ "timestamp": datetime.now().isoformat()
 
 
 
219
  })
220
 
221
+ @app.get("/docs")
222
+ async def get_docs():
223
+ """Redirect to interactive docs"""
224
+ from fastapi.responses import RedirectResponse
225
+ return RedirectResponse(url="/docs")
226
 
227
+ if __name__ == "__main__":
228
+ import uvicorn
229
+ uvicorn.run(app, host="0.0.0.0", port=7860)