"""TSU-WAVE Command Line Interface""" import click import sys import asyncio from pathlib import Path import json from datetime import datetime @click.group() @click.version_option(version="1.0.0") def cli(): """TSU-WAVE - Tsunami analysis and forecasting system""" pass @cli.command() @click.option('--host', default='0.0.0.0', help='Host to bind to') @click.option('--port', default=8000, help='Port to bind to') @click.option('--reload', is_flag=True, help='Enable auto-reload') def serve(host, port, reload): """Start the API server""" import uvicorn from .api.main import app click.echo(f"Starting TSU-WAVE API server on {host}:{port}") uvicorn.run("tsuwave.api.main:app", host=host, port=port, reload=reload) @cli.command() @click.option('--host', default='0.0.0.0', help='Host to bind to') @click.option('--port', default=8080, help='Port to bind to') def dashboard(host, port): """Start the Streamlit dashboard""" import subprocess import sys cmd = [ "streamlit", "run", "src/tsuwave/dashboard/app.py", f"--server.address={host}", f"--server.port={port}" ] subprocess.run(cmd) @cli.command() @click.argument('zone') @click.option('--event', help='Event ID') def monitor(zone, event): """Monitor a coastal zone""" from .hazard import AlertManager from .utils import setup_logging setup_logging('monitor') click.echo(f"Monitoring zone: {zone}") # Placeholder for monitoring loop try: while True: click.echo(f"[{datetime.now()}] Monitoring {zone}...") import time time.sleep(5) except KeyboardInterrupt: click.echo("\nMonitoring stopped") @cli.command() @click.argument('event_id') @click.option('--output', '-o', help='Output file') def validate(event_id, output): """Validate against historical event""" from .hazard import RunupForecast click.echo(f"Validating event: {event_id}") # Placeholder validation result = { 'event_id': event_id, 'validated_at': datetime.now().isoformat(), 'accuracy': 91.3, 'rmse': 11.7 } if output: with open(output, 'w') as f: json.dump(result, f, indent=2) click.echo(f"Results saved to {output}") else: click.echo(json.dumps(result, indent=2)) @cli.command() @click.argument('zone') @click.option('--source', help='Source region') def forecast(zone, source): """Generate run-up forecast""" from .hazard import RunupForecast click.echo(f"Generating forecast for zone: {zone}") forecast = RunupForecast() result = forecast.forecast_from_chi(0.72) click.echo(json.dumps(result, indent=2)) @cli.command() @click.option('--all', 'all_zones', is_flag=True, help='Check all zones') def status(all_zones): """Check system status""" import requests try: r = requests.get("http://localhost:8000/health") if r.status_code == 200: click.echo("✅ API server: RUNNING") click.echo(json.dumps(r.json(), indent=2)) else: click.echo("❌ API server: ERROR") except: click.echo("❌ API server: NOT CONNECTED") if all_zones: click.echo("\nActive zones:") zones = ['hilo_bay_hawaii', 'miyako_japan', 'banda_aceh_indonesia'] for zone in zones: click.echo(f" • {zone}") @cli.command() def init(): """Initialize TSU-WAVE system""" from .utils.config import create_example_config from .utils.logger import setup_logging click.echo("Initializing TSU-WAVE system...") # Create directories dirs = ['data', 'logs', 'config', 'output'] for d in dirs: Path(d).mkdir(exist_ok=True) click.echo(f" Created {d}/") # Create example config create_example_config('config/config.example.yml') click.echo(" Created config/config.example.yml") click.echo("\n✅ Initialization complete!") click.echo("\nNext steps:") click.echo(" 1. Edit config/config.yml with your settings") click.echo(" 2. Run 'tsu-wave serve' to start the API") click.echo(" 3. Run 'tsu-wave dashboard' to start the dashboard") @cli.command() @click.argument('file') def load(file): """Load data file (DART, tide gauge, etc.)""" from .data import load_dart, load_tide_gauge path = Path(file) if not path.exists(): click.echo(f"Error: File {file} not found") return click.echo(f"Loading {path.suffix} file: {file}") if path.suffix == '.nc': data = load_dart(file) click.echo(f"Loaded DART data: {len(data)} records") elif path.suffix == '.csv': data = load_tide_gauge(file) click.echo(f"Loaded tide gauge data: {len(data)} records") else: click.echo(f"Unknown file type: {path.suffix}") @cli.command() def test(): """Run system tests""" import subprocess click.echo("Running TSU-WAVE tests...") result = subprocess.run(['pytest', 'tests/', '-v']) sys.exit(result.returncode) def main(): """Main entry point""" cli() if __name__ == '__main__': main()