| import requests |
| import json |
| import os |
| import time |
| from datetime import datetime |
| from huggingface_hub import InferenceClient |
| import logging |
|
|
| logging.basicConfig(level=logging.INFO) |
| logger = logging.getLogger(__name__) |
|
|
| class WaveDataPuller: |
| def __init__(self, space_url="https://huggingface.co/spaces/nakas/NWPS_SWAN"): |
| self.space_url = space_url |
| self.api_url = f"{space_url}/api/predict" |
| self.output_dir = os.getenv('OUTPUT_DIR', '/tmp/wave_data') |
| self.poll_interval = int(os.getenv('POLL_INTERVAL', '3600')) |
| |
| |
| try: |
| os.makedirs(self.output_dir, exist_ok=True) |
| except PermissionError: |
| |
| self.output_dir = '/tmp/wave_data' |
| os.makedirs(self.output_dir, exist_ok=True) |
| |
| |
| self.client = InferenceClient(model="nakas/NWPS_SWAN") |
|
|
| def fetch_wave_data(self): |
| """Fetch wave data from the Hugging Face space""" |
| try: |
| logger.info("Fetching wave data from Hugging Face space...") |
| |
| |
| endpoints_to_try = [ |
| f"{self.space_url}/api/predict", |
| f"{self.space_url}/api/data", |
| f"{self.space_url}/gradio_api/call/predict", |
| ] |
| |
| for endpoint in endpoints_to_try: |
| try: |
| response = requests.get(endpoint, timeout=30) |
| if response.status_code == 200: |
| return response.json() |
| except Exception as e: |
| logger.debug(f"Failed to fetch from {endpoint}: {e}") |
| continue |
| |
| |
| try: |
| result = self.client.text_generation("get_wave_data", max_new_tokens=100) |
| return {"data": result, "source": "inference_client"} |
| except Exception as e: |
| logger.error(f"Inference client failed: {e}") |
| |
| logger.warning("No accessible endpoints found, returning mock data") |
| return self.generate_mock_data() |
| |
| except Exception as e: |
| logger.error(f"Error fetching wave data: {e}") |
| return None |
|
|
| def generate_mock_data(self): |
| """Generate mock SWAN wave data for testing""" |
| import random |
| |
| return { |
| "timestamp": datetime.utcnow().isoformat(), |
| "location": {"lat": 40.0, "lon": -74.0}, |
| "wave_data": { |
| "significant_wave_height": round(random.uniform(0.5, 3.0), 2), |
| "peak_wave_period": round(random.uniform(4.0, 12.0), 2), |
| "wave_direction": round(random.uniform(0, 360), 1), |
| "wind_speed": round(random.uniform(2.0, 15.0), 2), |
| "wind_direction": round(random.uniform(0, 360), 1) |
| }, |
| "model": "NWPS_SWAN", |
| "forecast_hours": [0, 6, 12, 18, 24] |
| } |
|
|
| def save_data(self, data): |
| """Save wave data to file""" |
| if not data: |
| return |
| |
| timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S") |
| filename = f"wave_data_{timestamp}.json" |
| filepath = os.path.join(self.output_dir, filename) |
| |
| try: |
| with open(filepath, 'w') as f: |
| json.dump(data, f, indent=2) |
| logger.info(f"Data saved to {filepath}") |
| except Exception as e: |
| logger.error(f"Error saving data: {e}") |
|
|
| def run_continuous(self): |
| """Run continuous data pulling""" |
| logger.info(f"Starting continuous wave data pulling every {self.poll_interval} seconds") |
| |
| while True: |
| try: |
| data = self.fetch_wave_data() |
| if data: |
| self.save_data(data) |
| logger.info("Wave data fetched and saved successfully") |
| else: |
| logger.warning("No data received") |
| |
| time.sleep(self.poll_interval) |
| |
| except KeyboardInterrupt: |
| logger.info("Stopping wave data puller...") |
| break |
| except Exception as e: |
| logger.error(f"Unexpected error: {e}") |
| time.sleep(60) |
|
|
| def run_once(self): |
| """Run a single data pull""" |
| logger.info("Fetching wave data once...") |
| data = self.fetch_wave_data() |
| if data: |
| self.save_data(data) |
| logger.info("Wave data fetched and saved successfully") |
| else: |
| logger.error("Failed to fetch wave data") |
|
|
| if __name__ == "__main__": |
| puller = WaveDataPuller() |
| |
| |
| run_mode = os.getenv('RUN_MODE', 'once') |
| |
| if run_mode.lower() == 'continuous': |
| puller.run_continuous() |
| else: |
| puller.run_once() |