#!/usr/bin/env python3 """ Development environment management script for the Crypto Trading Bot Dashboard. """ import subprocess import sys import time import os from pathlib import Path def run_command(command: str, check: bool = True) -> subprocess.CompletedProcess: """Run a shell command and return the result.""" print(f"Running: {command}") return subprocess.run(command, shell=True, check=check) def check_docker(): """Check if Docker is installed and running.""" try: result = subprocess.run( "docker --version", shell=True, capture_output=True, text=True ) if result.returncode != 0: print("āŒ Docker is not installed or not in PATH") return False result = subprocess.run( "docker info", shell=True, capture_output=True, text=True ) if result.returncode != 0: print("āŒ Docker daemon is not running") return False print("āœ… Docker is available and running") return True except Exception as e: print(f"āŒ Error checking Docker: {e}") return False def start_services(): """Start all development services.""" print("šŸš€ Starting development environment...") if not check_docker(): sys.exit(1) # Start Docker services run_command("docker-compose up -d") # Wait for services to be ready print("ā³ Waiting for services to be ready...") time.sleep(10) # Check service health check_services() def stop_services(): """Stop all development services.""" print("šŸ›‘ Stopping development environment...") run_command("docker-compose down") def restart_services(): """Restart all development services.""" print("šŸ”„ Restarting development environment...") stop_services() start_services() def check_services(): """Check the status of all services.""" print("šŸ” Checking service status...") # Check Docker containers result = subprocess.run( "docker-compose ps", shell=True, capture_output=True, text=True ) print(result.stdout) # Check database connection check_database() def check_database(): """Check if the database is accessible.""" try: import psycopg2 from dotenv import load_dotenv # Load environment variables env_file = Path(".env") if env_file.exists(): load_dotenv(env_file) conn_params = { "host": os.getenv("POSTGRES_HOST", "localhost"), "port": os.getenv("POSTGRES_PORT", "5434"), "database": os.getenv("POSTGRES_DB", "dashboard"), "user": os.getenv("POSTGRES_USER", "dashboard"), "password": os.getenv("POSTGRES_PASSWORD"), } conn = psycopg2.connect(**conn_params) conn.close() print("āœ… Database connection successful") except ImportError: print("āš ļø psycopg2 not installed, skipping database check") except Exception as e: print(f"āŒ Database connection failed: {e}") def setup_env(): """Set up environment files.""" print("šŸ“ Setting up environment...") env_file = Path(".env") template_file = Path("env.template") if not env_file.exists() and template_file.exists(): import shutil shutil.copy(template_file, env_file) print(f"āœ… Created .env file from template") print(f"āš ļø Please update .env with your actual configuration") elif env_file.exists(): print("āœ… .env file already exists") else: print("āŒ No env.template file found") def install_deps(): """Install project dependencies using UV.""" print("šŸ“¦ Installing dependencies...") run_command("uv sync --dev") def run_dev_server(): """Run the development server with hot reload.""" print("šŸ”„ Starting development server with hot reload...") try: from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler import threading import signal class ChangeHandler(FileSystemEventHandler): def __init__(self, restart_callback): self.restart_callback = restart_callback self.last_modified = 0 def on_modified(self, event): if event.is_directory: return # Only watch Python files if not event.src_path.endswith('.py'): return # Avoid rapid restarts current_time = time.time() if current_time - self.last_modified < 1: return self.last_modified = current_time print(f"\nšŸ“ File changed: {event.src_path}") self.restart_callback() # Application process app_process = None def start_app(): nonlocal app_process if app_process: app_process.terminate() app_process.wait() print("šŸš€ Starting application...") app_process = subprocess.Popen([ sys.executable, "main.py" ]) def restart_app(): print("šŸ”„ Restarting application...") start_app() # Set up file watcher event_handler = ChangeHandler(restart_app) observer = Observer() # Watch main directories watch_dirs = [".", "config", "database", "components", "data", "strategies", "trader"] for watch_dir in watch_dirs: if Path(watch_dir).exists(): observer.schedule(event_handler, watch_dir, recursive=True) print(f"šŸ‘€ Watching: {watch_dir}/") # Start watching observer.start() # Start initial app start_app() def signal_handler(signum, frame): print("\nšŸ›‘ Shutting down development server...") observer.stop() if app_process: app_process.terminate() app_process.wait() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print("šŸ”„ Development server running with hot reload") print("šŸ“ Watching for changes in Python files...") print("Press Ctrl+C to stop") # Keep the main thread alive observer.join() except ImportError: print("āŒ watchdog not installed, running without hot reload") print("Install with: uv add watchdog") # Fallback to regular execution run_command("uv run python main.py") except KeyboardInterrupt: print("\nšŸ›‘ Development server stopped") except Exception as e: print(f"āŒ Error running dev server: {e}") def run_app(): """Run the application without hot reload.""" print("šŸš€ Starting application...") run_command("uv run python main.py") def main(): """Main entry point for the development script.""" if len(sys.argv) < 2: print("Usage: python scripts/dev.py [command]") print("Commands:") print(" setup - Set up environment and install dependencies") print(" start - Start development services (Docker)") print(" stop - Stop development services") print(" restart - Restart development services") print(" status - Check service status") print(" install - Install dependencies") print(" dev-server - Run development server with hot reload") print(" run - Run application without hot reload") sys.exit(1) command = sys.argv[1] if command == "setup": setup_env() install_deps() elif command == "start": start_services() elif command == "stop": stop_services() elif command == "restart": restart_services() elif command == "status": check_services() elif command == "install": install_deps() elif command == "dev-server": run_dev_server() elif command == "run": run_app() else: print(f"Unknown command: {command}") sys.exit(1) if __name__ == "__main__": main()