ashhal's picture
Create deploy.py
e27fb95 verified
#!/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()