#!/usr/bin/env python3 """ Deployment Helper Script for Power Systems Mini-Consultant Automates the setup and deployment process for Hugging Face Spaces """ import os import json import shutil import subprocess import sys from pathlib import Path from typing import Dict, List, Optional class PowerSystemsDeployer: """ Automated deployment helper for Power Systems Mini-Consultant """ def __init__(self): self.project_root = Path.cwd() self.required_files = [ 'app.py', 'requirements.txt', 'data/knowledge_base.json', 'utils/__init__.py', 'utils/rag_system.py', 'utils/diagram_generator.py' ] self.optional_files = [ 'README.md', '.gitignore', '.env.example' ] def check_requirements(self) -> bool: """Check if all required files exist""" print("๐Ÿ” Checking project requirements...") missing_files = [] for file_path in self.required_files: if not (self.project_root / file_path).exists(): missing_files.append(file_path) if missing_files: print("โŒ Missing required files:") for file in missing_files: print(f" - {file}") return False print("โœ… All required files found!") return True def validate_knowledge_base(self) -> bool: """Validate the knowledge base JSON structure""" print("๐Ÿ” Validating knowledge base...") try: kb_path = self.project_root / 'data' / 'knowledge_base.json' with open(kb_path, 'r', encoding='utf-8') as f: kb_data = json.load(f) # Check for essential sections required_sections = ['faults', 'protection', 'standards', 'formulas'] missing_sections = [s for s in required_sections if s not in kb_data] if missing_sections: print(f"โš ๏ธ Missing knowledge base sections: {missing_sections}") print(" The app will still work but with limited knowledge.") else: print("โœ… Knowledge base structure validated!") return True except json.JSONDecodeError as e: print(f"โŒ Invalid JSON in knowledge base: {e}") return False except Exception as e: print(f"โŒ Error validating knowledge base: {e}") return False def setup_environment(self) -> bool: """Set up the development environment""" print("๐Ÿ”ง Setting up environment...") try: # Create virtual environment if it doesn't exist venv_path = self.project_root / 'venv' if not venv_path.exists(): print("Creating virtual environment...") subprocess.run([sys.executable, '-m', 'venv', 'venv'], check=True) # Determine the correct pip path if os.name == 'nt': # Windows pip_path = venv_path / 'Scripts' / 'pip' else: # Unix/Linux/MacOS pip_path = venv_path / 'bin' / 'pip' # Install requirements print("Installing requirements...") subprocess.run([str(pip_path), 'install', '-r', 'requirements.txt'], check=True) print("โœ… Environment setup complete!") return True except subprocess.CalledProcessError as e: print(f"โŒ Error setting up environment: {e}") return False except Exception as e: print(f"โŒ Unexpected error: {e}") return False def test_local_deployment(self) -> bool: """Test the application locally""" print("๐Ÿงช Testing local deployment...") try: # Check if .env file exists env_path = self.project_root / '.env' if not env_path.exists(): print("โš ๏ธ No .env file found. Creating template...") self.create_env_template() print(" Please add your GROQ_API_KEY to .env file and run again.") return False # Try importing the main application import importlib.util spec = importlib.util.spec_from_file_location("app", self.project_root / "app.py") app_module = importlib.util.module_from_spec(spec) # This will test if the imports work spec.loader.exec_module(app_module) print("โœ… Local deployment test passed!") return True except ImportError as e: print(f"โŒ Import error: {e}") print(" Please check your dependencies in requirements.txt") return False except Exception as e: print(f"โŒ Error testing deployment: {e}") return False def create_env_template(self): """Create .env template file""" env_template = """# Environment Variables for Power Systems Mini-Consultant # Required: Groq API Key (Get from https://console.groq.com) GROQ_API_KEY=your_groq_api_key_here # Optional: Debug settings DEBUG=False LOG_LEVEL=INFO # Optional: Model settings MODEL_NAME=mixtral-8x7b-32768 MAX_TOKENS=2000 TEMPERATURE=0.7 """ with open(self.project_root / '.env', 'w') as f: f.write(env_template) def prepare_huggingface_deployment(self) -> bool: """Prepare files for Hugging Face Spaces deployment""" print("๐Ÿš€ Preparing Hugging Face deployment...") try: # Create deployment directory deploy_dir = self.project_root / 'hf_deployment' if deploy_dir.exists(): shutil.rmtree(deploy_dir) deploy_dir.mkdir() # Copy required files for file_path in self.required_files: src = self.project_root / file_path dst = deploy_dir / file_path # Create parent directories if needed dst.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(src, dst) # Copy optional files if they exist for file_path in self.optional_files: src = self.project_root / file_path if src.exists(): dst = deploy_dir / file_path shutil.copy2(src, dst) # Create HuggingFace README self.create_hf_readme(deploy_dir) print(f"โœ… Deployment files prepared in: {deploy_dir}") print("\n๐Ÿ“‹ Next steps for Hugging Face deployment:") print(" 1. Create a new Space on Hugging Face") print(" 2. Choose 'Gradio' as the SDK") print(" 3. Upload all files from the hf_deployment folder") print(" 4. Add GROQ_API_KEY as a secret in Space settings") print(" 5. Your Space will automatically build and deploy!") return True except Exception as e: print(f"โŒ Error preparing deployment: {e}") return False def create_hf_readme(self, deploy_dir: Path): """Create Hugging Face specific README""" hf_readme = """--- title: Power Systems Mini-Consultant emoji: โšก colorFrom: blue colorTo: cyan sdk: gradio sdk_version: 4.44.0 app_file: app.py pinned: false license: mit short_description: AI-powered assistant for power systems engineering tags: - power-systems - electrical-engineering - fault-analysis - protection-systems - education - RAG - groq --- # โšก Power Systems Mini-Consultant An advanced AI-powered chatbot for Power Systems engineering education and professional support. ## Setup Instructions 1. **Configure API Key**: Add your GROQ_API_KEY as a secret in the Space settings 2. **Launch**: The app will automatically start once configured ## Features - ๐Ÿ’ฌ **AI Consultant Chat**: Technical assistance for power systems - ๐Ÿ“š **Practice Pack Generator**: Custom exam preparation materials - ๐Ÿ“‹ **Standards Explorer**: IEEE and IEC standards guidance - ๐Ÿ“– **Study Resources**: Formulas and reference materials ## Usage Simply start chatting with the AI consultant about power systems topics, or use the specialized tools for practice questions and standards exploration. --- *For complete documentation, visit the project repository.* """ with open(deploy_dir / 'README.md', 'w', encoding='utf-8') as f: f.write(hf_readme) def generate_deployment_report(self) -> Dict: """Generate a deployment report""" report = { "timestamp": str(Path.cwd()), "files_checked": len(self.required_files + self.optional_files), "status": "ready" if self.check_requirements() else "incomplete", "recommendations": [] } # Check file sizes large_files = [] for file_path in self.required_files: file_full_path = self.project_root / file_path if file_full_path.exists(): size_mb = file_full_path.stat().st_size / (1024 * 1024) if size_mb > 10: # Files larger than 10MB large_files.append(f"{file_path} ({size_mb:.1f}MB)") if large_files: report["recommendations"].append(f"Large files detected: {large_files}") # Check for sensitive information env_file = self.project_root / '.env' if env_file.exists(): report["recommendations"].append("Ensure .env file is in .gitignore") return report def run_deployment_checklist(self): """Run complete deployment checklist""" print("๐Ÿš€ Power Systems Mini-Consultant Deployment Checklist") print("=" * 60) steps = [ ("Check requirements", self.check_requirements), ("Validate knowledge base", self.validate_knowledge_base), ("Setup environment", self.setup_environment), ("Test local deployment", self.test_local_deployment), ("Prepare HF deployment", self.prepare_huggingface_deployment) ] passed_steps = 0 total_steps = len(steps) for i, (step_name, step_func) in enumerate(steps, 1): print(f"\n[{i}/{total_steps}] {step_name}...") if step_func(): passed_steps += 1 else: print(f"โŒ Step {i} failed. Please fix the issues and try again.") if i < 4: # Don't break on HF deployment prep failure break print(f"\n๐ŸŽฏ Deployment Summary: {passed_steps}/{total_steps} steps completed") if passed_steps == total_steps: print("๐ŸŽ‰ All checks passed! Your app is ready for deployment.") elif passed_steps >= 3: print("โš ๏ธ Basic requirements met. Review warnings and deploy when ready.") else: print("โŒ Critical issues found. Please fix them before deploying.") # Generate report report = self.generate_deployment_report() report_path = self.project_root / 'deployment_report.json' with open(report_path, 'w') as f: json.dump(report, f, indent=2) print(f"\n๐Ÿ“„ Detailed report saved to: {report_path}") def main(): """Main deployment script""" print("๐Ÿ”ง Power Systems Mini-Consultant Deployment Helper") print("=" * 50) deployer = PowerSystemsDeployer() if len(sys.argv) > 1: command = sys.argv[1].lower() if command == 'check': deployer.check_requirements() elif command == 'setup': deployer.setup_environment() elif command == 'test': deployer.test_local_deployment() elif command == 'prepare': deployer.prepare_huggingface_deployment() elif command == 'full': deployer.run_deployment_checklist() else: print(f"Unknown command: {command}") print("Available commands: check, setup, test, prepare, full") else: # Run full checklist by default deployer.run_deployment_checklist() if __name__ == "__main__": main()