| import os |
| import logging |
| import requests |
| from datetime import datetime |
| from flask import Flask, jsonify |
| from apscheduler.schedulers.background import BackgroundScheduler |
|
|
| |
| logging.basicConfig( |
| level=logging.INFO, |
| format='%(asctime)s - %(levelname)s - %(message)s' |
| ) |
| logger = logging.getLogger(__name__) |
|
|
| app = Flask(__name__) |
|
|
| |
| ping_status = { |
| "last_ping": None, |
| "results": [] |
| } |
|
|
| def get_spaces(): |
| """Parse SPACES_URLS from environment variable.""" |
| spaces = os.environ.get("SPACES_URLS", "") |
| if not spaces: |
| logger.warning("SPACES_URLS not set") |
| return [] |
| return [url.strip() for url in spaces.split(",") if url.strip()] |
|
|
|
|
| def get_headers(): |
| """Build request headers including HF token if available.""" |
| headers = {} |
| hf_token = os.environ.get("HF_TOKEN", "") |
| if hf_token: |
| headers["Authorization"] = f"Bearer {hf_token}" |
| return headers |
|
|
|
|
| def ping_space(url): |
| """Ping a single space and return result.""" |
| try: |
| headers = get_headers() |
| response = requests.get(url, headers=headers, timeout=30) |
| return { |
| "url": url, |
| "status": "success", |
| "status_code": response.status_code, |
| "timestamp": datetime.now().isoformat() |
| } |
| except requests.exceptions.Timeout: |
| return { |
| "url": url, |
| "status": "timeout", |
| "error": "Request timed out", |
| "timestamp": datetime.now().isoformat() |
| } |
| except requests.exceptions.RequestException as e: |
| return { |
| "url": url, |
| "status": "error", |
| "error": str(e), |
| "timestamp": datetime.now().isoformat() |
| } |
|
|
|
|
| def ping_all_spaces(): |
| """Ping all configured spaces.""" |
| spaces = get_spaces() |
| if not spaces: |
| logger.info("No spaces configured, skipping ping") |
| return |
|
|
| logger.info(f"Pinging {len(spaces)} space(s)...") |
| results = [] |
| for url in spaces: |
| result = ping_space(url) |
| results.append(result) |
| |
| if result["status"] == "success": |
| logger.info(f"✓ {url} - OK ({result['status_code']})") |
| else: |
| logger.error(f"✗ {url} - {result.get('status', 'unknown')}: {result.get('error', 'unknown error')}") |
|
|
| ping_status["last_ping"] = datetime.now().isoformat() |
| ping_status["results"] = results |
|
|
|
|
| @app.route("/") |
| def index(): |
| """Status page.""" |
| spaces = get_spaces() |
| return jsonify({ |
| "status": "running", |
| "configured_spaces": len(spaces), |
| "spaces": spaces, |
| "last_ping": ping_status["last_ping"], |
| "last_results": ping_status["results"] |
| }) |
|
|
|
|
| @app.route("/health") |
| def health(): |
| """Health check endpoint.""" |
| return jsonify({"status": "healthy"}) |
|
|
|
|
| if __name__ == "__main__": |
| |
| ping_interval_seconds = int(os.environ.get("PING_INTERVAL_SECONDS", 3600)) |
| |
| |
| scheduler = BackgroundScheduler() |
| scheduler.add_job( |
| ping_all_spaces, |
| 'interval', |
| seconds=ping_interval_seconds, |
| id='pinger_job' |
| ) |
| scheduler.start() |
| logger.info(f"Pinger started. Will ping every {ping_interval_seconds} seconds") |
| |
| |
| ping_all_spaces() |
| |
| |
| app.run(host="0.0.0.0", port=7860) |
|
|