| |
| """ |
| Final verification script for Enhanced Fake News Detection System |
| Comprehensive checks before deployment |
| """ |
|
|
| import os |
| import sys |
| import subprocess |
| import json |
| import time |
| from pathlib import Path |
|
|
| def run_command(cmd, timeout=30): |
| """Run a command with timeout""" |
| try: |
| result = subprocess.run( |
| cmd, shell=True, capture_output=True, |
| text=True, timeout=timeout, check=True |
| ) |
| return True, result.stdout, result.stderr |
| except subprocess.TimeoutExpired: |
| return False, "", f"Command timed out after {timeout}s" |
| except subprocess.CalledProcessError as e: |
| return False, e.stdout, e.stderr |
| except Exception as e: |
| return False, "", str(e) |
|
|
| def check_docker_availability(): |
| """Check if Docker is available and running""" |
| print("π³ Checking Docker availability...") |
| |
| success, stdout, stderr = run_command("docker --version") |
| if not success: |
| print("β Docker not available") |
| return False |
| |
| print(f"β
Docker version: {stdout.strip()}") |
| |
| |
| success, stdout, stderr = run_command("docker ps") |
| if not success: |
| print("β Docker daemon not running") |
| return False |
| |
| print("β
Docker daemon is running") |
| return True |
|
|
| def check_project_structure(): |
| """Verify project structure is complete""" |
| print("\nπ Checking project structure...") |
| |
| required_files = [ |
| "README.md", |
| "requirements.txt", |
| "Dockerfile", |
| "Dockerfile.simple", |
| "docker-compose.yml", |
| "docker-compose.prod.yml", |
| "DEPLOYMENT_GUIDE.md", |
| "backend/main_application.py", |
| "backend/requirements.txt", |
| "docs/README.md", |
| "docs/BACKEND_ARCHITECTURE.md", |
| "docs/ML_MODEL_DOCUMENTATION.md", |
| ] |
| |
| required_dirs = [ |
| "backend/", |
| "frontend/", |
| "docs/", |
| "map/", |
| "data/", |
| "tests/", |
| "scripts/" |
| ] |
| |
| all_good = True |
| |
| for file_path in required_files: |
| if os.path.exists(file_path): |
| print(f"β
{file_path}") |
| else: |
| print(f"β Missing: {file_path}") |
| all_good = False |
| |
| for dir_path in required_dirs: |
| if os.path.isdir(dir_path): |
| print(f"β
{dir_path}") |
| else: |
| print(f"β Missing directory: {dir_path}") |
| all_good = False |
| |
| return all_good |
|
|
| def test_docker_build(): |
| """Test Docker build process""" |
| print("\nπ¨ Testing Docker build...") |
| |
| |
| print("Building simple Docker image...") |
| success, stdout, stderr = run_command( |
| "docker build -f Dockerfile.simple -t fake-news-test:simple .", |
| timeout=300 |
| ) |
| |
| if not success: |
| print(f"β Simple Docker build failed: {stderr}") |
| return False |
| |
| print("β
Simple Docker build successful") |
| |
| |
| run_command("docker rmi fake-news-test:simple") |
| |
| return True |
|
|
| def test_docker_compose(): |
| """Test Docker Compose configuration""" |
| print("\nπ Testing Docker Compose...") |
| |
| |
| success, stdout, stderr = run_command("docker-compose config") |
| if not success: |
| print(f"β Docker Compose validation failed: {stderr}") |
| return False |
| |
| print("β
Docker Compose configuration valid") |
| |
| |
| success, stdout, stderr = run_command("docker-compose -f docker-compose.prod.yml config") |
| if not success: |
| print(f"β Production Docker Compose validation failed: {stderr}") |
| return False |
| |
| print("β
Production Docker Compose configuration valid") |
| return True |
|
|
| def check_git_status(): |
| """Check git repository status""" |
| print("\nπ¦ Checking Git status...") |
| |
| |
| success, stdout, stderr = run_command("git status --porcelain") |
| if not success: |
| print("β οΈ Not a git repository or git not available") |
| return True |
| |
| if stdout.strip(): |
| print("π Uncommitted changes found:") |
| print(stdout) |
| print("π‘ Consider committing changes before deployment") |
| else: |
| print("β
Working directory is clean") |
| |
| |
| success, stdout, stderr = run_command("git log --oneline -1") |
| if success and stdout.strip(): |
| print(f"β
Latest commit: {stdout.strip()}") |
| |
| return True |
|
|
| def check_python_dependencies(): |
| """Check if Python dependencies can be resolved""" |
| print("\nπ Checking Python dependencies...") |
| |
| |
| if os.path.exists("requirements.txt"): |
| print("β
Main requirements.txt found") |
| else: |
| print("β Main requirements.txt missing") |
| return False |
| |
| |
| if os.path.exists("backend/requirements.txt"): |
| print("β
Backend requirements.txt found") |
| else: |
| print("β Backend requirements.txt missing") |
| return False |
| |
| return True |
|
|
| def check_documentation(): |
| """Verify documentation completeness""" |
| print("\nπ Checking documentation...") |
| |
| doc_files = [ |
| "docs/README.md", |
| "docs/BACKEND_ARCHITECTURE.md", |
| "docs/ML_MODEL_DOCUMENTATION.md", |
| "docs/PROJECT_STRUCTURE.md", |
| "DEPLOYMENT_GUIDE.md" |
| ] |
| |
| all_good = True |
| for doc_file in doc_files: |
| if os.path.exists(doc_file): |
| |
| with open(doc_file, 'r', encoding='utf-8') as f: |
| content = f.read().strip() |
| if len(content) > 100: |
| print(f"β
{doc_file} ({len(content)} chars)") |
| else: |
| print(f"β οΈ {doc_file} seems too short") |
| else: |
| print(f"β Missing: {doc_file}") |
| all_good = False |
| |
| return all_good |
|
|
| def generate_deployment_summary(): |
| """Generate deployment summary""" |
| print("\nπ Deployment Summary:") |
| print("=" * 50) |
| |
| |
| if os.path.exists("README.md"): |
| with open("README.md", 'r', encoding='utf-8') as f: |
| first_line = f.readline().strip() |
| print(f"Project: {first_line.replace('#', '').strip()}") |
| |
| |
| backend_files = len([f for f in Path("backend").rglob("*.py") if f.is_file()]) |
| doc_files = len([f for f in Path("docs").rglob("*.md") if f.is_file()]) |
| |
| print(f"Backend Python files: {backend_files}") |
| print(f"Documentation files: {doc_files}") |
| |
| |
| if os.path.exists("Dockerfile"): |
| print("β
Docker support available") |
| if os.path.exists("docker-compose.yml"): |
| print("β
Docker Compose support available") |
| |
| print("\nπ Deployment Options:") |
| print("1. docker-compose up --build") |
| print("2. docker build -f Dockerfile.simple -t fake-news .") |
| print("3. pip install -r requirements.txt && cd backend && python main_application.py") |
| |
| print("\nπ Access URLs (after deployment):") |
| print("- Main Dashboard: http://localhost:8080") |
| print("- Interactive Map: http://localhost:8080/map/enhanced-india-heatmap.html") |
| print("- API Docs: http://localhost:8080/docs") |
| print("- Health Check: http://localhost:8080/health") |
|
|
| def main(): |
| """Main verification function""" |
| print("π Enhanced Fake News Detection System - Final Verification") |
| print("=" * 70) |
| |
| checks = [ |
| ("Project Structure", check_project_structure), |
| ("Python Dependencies", check_python_dependencies), |
| ("Documentation", check_documentation), |
| ("Docker Availability", check_docker_availability), |
| ("Docker Build", test_docker_build), |
| ("Docker Compose", test_docker_compose), |
| ("Git Status", check_git_status), |
| ] |
| |
| results = [] |
| |
| for check_name, check_func in checks: |
| print(f"\n{'='*20} {check_name} {'='*20}") |
| try: |
| result = check_func() |
| results.append((check_name, result)) |
| except Exception as e: |
| print(f"β {check_name} failed with error: {e}") |
| results.append((check_name, False)) |
| |
| |
| print("\n" + "="*70) |
| print("π VERIFICATION RESULTS") |
| print("="*70) |
| |
| passed = 0 |
| total = len(results) |
| |
| for check_name, result in results: |
| status = "β
PASS" if result else "β FAIL" |
| print(f"{status:<10} {check_name}") |
| if result: |
| passed += 1 |
| |
| print(f"\nScore: {passed}/{total} checks passed") |
| |
| if passed == total: |
| print("\nπ ALL CHECKS PASSED!") |
| print("β
Project is ready for deployment") |
| generate_deployment_summary() |
| return 0 |
| else: |
| print(f"\nβ οΈ {total - passed} checks failed") |
| print("π§ Please fix the issues above before deployment") |
| return 1 |
|
|
| if __name__ == "__main__": |
| sys.exit(main()) |