#!/usr/bin/env python3 """ FRED ML - Integration and Testing Script Comprehensive integration of all updates and system testing """ import os import sys import subprocess import logging from pathlib import Path from datetime import datetime import json # Setup logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) class FREDMLIntegration: """Comprehensive integration and testing for FRED ML system""" def __init__(self): self.root_dir = Path(__file__).parent.parent self.test_results = {} self.integration_status = {} def run_integration_checklist(self): """Run comprehensive integration checklist""" logger.info("๐Ÿš€ Starting FRED ML Integration and Testing") logger.info("=" * 60) # 1. Directory Structure Validation self.validate_directory_structure() # 2. Dependencies Check self.check_dependencies() # 3. Configuration Validation self.validate_configurations() # 4. Code Quality Checks self.run_code_quality_checks() # 5. Unit Tests self.run_unit_tests() # 6. Integration Tests self.run_integration_tests() # 7. Advanced Analytics Tests self.test_advanced_analytics() # 8. Streamlit UI Test self.test_streamlit_ui() # 9. Documentation Check self.validate_documentation() # 10. Final Integration Report self.generate_integration_report() def validate_directory_structure(self): """Validate and organize directory structure""" logger.info("๐Ÿ“ Validating directory structure...") required_dirs = [ 'src/analysis', 'src/core', 'src/visualization', 'src/lambda', 'scripts', 'tests/unit', 'tests/integration', 'tests/e2e', 'docs', 'config', 'data/exports', 'data/processed', 'frontend', 'infrastructure', 'deploy' ] for dir_path in required_dirs: full_path = self.root_dir / dir_path if not full_path.exists(): full_path.mkdir(parents=True, exist_ok=True) logger.info(f"โœ… Created directory: {dir_path}") else: logger.info(f"โœ… Directory exists: {dir_path}") # Check for required files required_files = [ 'src/analysis/economic_forecasting.py', 'src/analysis/economic_segmentation.py', 'src/analysis/statistical_modeling.py', 'src/analysis/comprehensive_analytics.py', 'src/core/enhanced_fred_client.py', 'frontend/app.py', 'scripts/run_advanced_analytics.py', 'scripts/comprehensive_demo.py', 'config/pipeline.yaml', 'requirements.txt', 'README.md' ] missing_files = [] for file_path in required_files: full_path = self.root_dir / file_path if not full_path.exists(): missing_files.append(file_path) else: logger.info(f"โœ… File exists: {file_path}") if missing_files: logger.error(f"โŒ Missing files: {missing_files}") self.integration_status['directory_structure'] = False else: logger.info("โœ… Directory structure validation passed") self.integration_status['directory_structure'] = True def check_dependencies(self): """Check and validate dependencies""" logger.info("๐Ÿ“ฆ Checking dependencies...") try: # Check if requirements.txt exists and is valid requirements_file = self.root_dir / 'requirements.txt' if requirements_file.exists(): with open(requirements_file, 'r') as f: requirements = f.read() # Check for key dependencies key_deps = [ 'fredapi', 'pandas', 'numpy', 'scikit-learn', 'scipy', 'statsmodels', 'streamlit', 'plotly', 'boto3' ] missing_deps = [] for dep in key_deps: if dep not in requirements: missing_deps.append(dep) if missing_deps: logger.warning(f"โš ๏ธ Missing dependencies: {missing_deps}") else: logger.info("โœ… All key dependencies found in requirements.txt") self.integration_status['dependencies'] = True else: logger.error("โŒ requirements.txt not found") self.integration_status['dependencies'] = False except Exception as e: logger.error(f"โŒ Error checking dependencies: {e}") self.integration_status['dependencies'] = False def validate_configurations(self): """Validate configuration files""" logger.info("โš™๏ธ Validating configurations...") config_files = [ 'config/pipeline.yaml', 'config/settings.py', '.github/workflows/scheduled.yml' ] config_status = True for config_file in config_files: full_path = self.root_dir / config_file if full_path.exists(): logger.info(f"โœ… Configuration file exists: {config_file}") else: logger.error(f"โŒ Missing configuration file: {config_file}") config_status = False # Check cron job configuration pipeline_config = self.root_dir / 'config/pipeline.yaml' if pipeline_config.exists(): with open(pipeline_config, 'r') as f: content = f.read() if 'schedule: "0 0 1 */3 *"' in content: logger.info("โœ… Quarterly cron job configuration found") else: logger.warning("โš ๏ธ Cron job configuration may not be quarterly") self.integration_status['configurations'] = config_status def run_code_quality_checks(self): """Run code quality checks""" logger.info("๐Ÿ” Running code quality checks...") try: # Check for Python syntax errors python_files = list(self.root_dir.rglob("*.py")) syntax_errors = [] for py_file in python_files: try: with open(py_file, 'r') as f: compile(f.read(), str(py_file), 'exec') except SyntaxError as e: syntax_errors.append(f"{py_file}: {e}") if syntax_errors: logger.error(f"โŒ Syntax errors found: {syntax_errors}") self.integration_status['code_quality'] = False else: logger.info("โœ… No syntax errors found") self.integration_status['code_quality'] = True except Exception as e: logger.error(f"โŒ Error in code quality checks: {e}") self.integration_status['code_quality'] = False def run_unit_tests(self): """Run unit tests""" logger.info("๐Ÿงช Running unit tests...") try: # Check if tests directory exists tests_dir = self.root_dir / 'tests' if not tests_dir.exists(): logger.warning("โš ๏ธ Tests directory not found") self.integration_status['unit_tests'] = False return # Run pytest if available try: result = subprocess.run( [sys.executable, '-m', 'pytest', 'tests/unit/', '-v'], capture_output=True, text=True, cwd=self.root_dir ) if result.returncode == 0: logger.info("โœ… Unit tests passed") self.integration_status['unit_tests'] = True else: logger.error(f"โŒ Unit tests failed: {result.stderr}") self.integration_status['unit_tests'] = False except FileNotFoundError: logger.warning("โš ๏ธ pytest not available, skipping unit tests") self.integration_status['unit_tests'] = False except Exception as e: logger.error(f"โŒ Error running unit tests: {e}") self.integration_status['unit_tests'] = False def run_integration_tests(self): """Run integration tests""" logger.info("๐Ÿ”— Running integration tests...") try: # Test FRED API connection from config.settings import FRED_API_KEY if FRED_API_KEY: logger.info("โœ… FRED API key configured") self.integration_status['fred_api'] = True else: logger.warning("โš ๏ธ FRED API key not configured") self.integration_status['fred_api'] = False # Test AWS configuration try: import boto3 logger.info("โœ… AWS SDK available") self.integration_status['aws_sdk'] = True except ImportError: logger.warning("โš ๏ธ AWS SDK not available") self.integration_status['aws_sdk'] = False # Test analytics modules try: sys.path.append(str(self.root_dir / 'src')) from src.analysis.comprehensive_analytics import ComprehensiveAnalytics from src.core.enhanced_fred_client import EnhancedFREDClient logger.info("โœ… Analytics modules available") self.integration_status['analytics_modules'] = True except ImportError as e: logger.error(f"โŒ Analytics modules not available: {e}") self.integration_status['analytics_modules'] = False except Exception as e: logger.error(f"โŒ Error in integration tests: {e}") self.integration_status['integration_tests'] = False def test_advanced_analytics(self): """Test advanced analytics functionality""" logger.info("๐Ÿ”ฎ Testing advanced analytics...") try: # Test analytics modules import sys.path.append(str(self.root_dir / 'src')) # Test Enhanced FRED Client try: from src.core.enhanced_fred_client import EnhancedFREDClient logger.info("โœ… Enhanced FRED Client available") self.integration_status['enhanced_fred_client'] = True except ImportError as e: logger.error(f"โŒ Enhanced FRED Client not available: {e}") self.integration_status['enhanced_fred_client'] = False # Test Economic Forecasting try: from src.analysis.economic_forecasting import EconomicForecaster logger.info("โœ… Economic Forecasting available") self.integration_status['economic_forecasting'] = True except ImportError as e: logger.error(f"โŒ Economic Forecasting not available: {e}") self.integration_status['economic_forecasting'] = False # Test Economic Segmentation try: from src.analysis.economic_segmentation import EconomicSegmentation logger.info("โœ… Economic Segmentation available") self.integration_status['economic_segmentation'] = True except ImportError as e: logger.error(f"โŒ Economic Segmentation not available: {e}") self.integration_status['economic_segmentation'] = False # Test Statistical Modeling try: from src.analysis.statistical_modeling import StatisticalModeling logger.info("โœ… Statistical Modeling available") self.integration_status['statistical_modeling'] = True except ImportError as e: logger.error(f"โŒ Statistical Modeling not available: {e}") self.integration_status['statistical_modeling'] = False # Test Comprehensive Analytics try: from src.analysis.comprehensive_analytics import ComprehensiveAnalytics logger.info("โœ… Comprehensive Analytics available") self.integration_status['comprehensive_analytics'] = True except ImportError as e: logger.error(f"โŒ Comprehensive Analytics not available: {e}") self.integration_status['comprehensive_analytics'] = False except Exception as e: logger.error(f"โŒ Error testing advanced analytics: {e}") def test_streamlit_ui(self): """Test Streamlit UI""" logger.info("๐ŸŽจ Testing Streamlit UI...") try: # Check if Streamlit app exists streamlit_app = self.root_dir / 'frontend/app.py' if streamlit_app.exists(): logger.info("โœ… Streamlit app exists") # Check for required imports with open(streamlit_app, 'r') as f: content = f.read() required_imports = [ 'streamlit', 'plotly', 'pandas', 'boto3' ] missing_imports = [] for imp in required_imports: if imp not in content: missing_imports.append(imp) if missing_imports: logger.warning(f"โš ๏ธ Missing imports in Streamlit app: {missing_imports}") else: logger.info("โœ… All required imports found in Streamlit app") self.integration_status['streamlit_ui'] = True else: logger.error("โŒ Streamlit app not found") self.integration_status['streamlit_ui'] = False except Exception as e: logger.error(f"โŒ Error testing Streamlit UI: {e}") self.integration_status['streamlit_ui'] = False def validate_documentation(self): """Validate documentation""" logger.info("๐Ÿ“š Validating documentation...") doc_files = [ 'README.md', 'docs/ADVANCED_ANALYTICS_SUMMARY.md', 'docs/CONVERSATION_SUMMARY.md' ] doc_status = True for doc_file in doc_files: full_path = self.root_dir / doc_file if full_path.exists(): logger.info(f"โœ… Documentation exists: {doc_file}") else: logger.warning(f"โš ๏ธ Missing documentation: {doc_file}") doc_status = False self.integration_status['documentation'] = doc_status def generate_integration_report(self): """Generate comprehensive integration report""" logger.info("๐Ÿ“Š Generating integration report...") # Calculate overall status total_checks = len(self.integration_status) passed_checks = sum(1 for status in self.integration_status.values() if status) overall_status = "โœ… PASSED" if passed_checks == total_checks else "โŒ FAILED" # Generate report report = { "timestamp": datetime.now().isoformat(), "overall_status": overall_status, "summary": { "total_checks": total_checks, "passed_checks": passed_checks, "failed_checks": total_checks - passed_checks, "success_rate": f"{(passed_checks/total_checks)*100:.1f}%" }, "detailed_results": self.integration_status } # Save report report_file = self.root_dir / 'integration_report.json' with open(report_file, 'w') as f: json.dump(report, f, indent=2) # Print summary logger.info("=" * 60) logger.info("๐Ÿ“Š INTEGRATION REPORT") logger.info("=" * 60) logger.info(f"Overall Status: {overall_status}") logger.info(f"Total Checks: {total_checks}") logger.info(f"Passed: {passed_checks}") logger.info(f"Failed: {total_checks - passed_checks}") logger.info(f"Success Rate: {(passed_checks/total_checks)*100:.1f}%") logger.info("=" * 60) # Print detailed results logger.info("Detailed Results:") for check, status in self.integration_status.items(): status_icon = "โœ…" if status else "โŒ" logger.info(f" {status_icon} {check}") logger.info("=" * 60) logger.info(f"Report saved to: {report_file}") return report def prepare_for_github(self): """Prepare for GitHub submission""" logger.info("๐Ÿš€ Preparing for GitHub submission...") # Check git status try: result = subprocess.run( ['git', 'status', '--porcelain'], capture_output=True, text=True, cwd=self.root_dir ) if result.stdout.strip(): logger.info("๐Ÿ“ Changes detected:") logger.info(result.stdout) # Suggest git commands logger.info("\n๐Ÿ“‹ Suggested git commands:") logger.info("git add .") logger.info("git commit -m 'feat: Integrate advanced analytics and enterprise UI'") logger.info("git push origin main") else: logger.info("โœ… No changes detected") except Exception as e: logger.error(f"โŒ Error checking git status: {e}") def main(): """Main integration function""" integrator = FREDMLIntegration() try: # Run integration checklist integrator.run_integration_checklist() # Prepare for GitHub integrator.prepare_for_github() logger.info("๐ŸŽ‰ Integration and testing completed!") except Exception as e: logger.error(f"โŒ Integration failed: {e}") sys.exit(1) if __name__ == "__main__": main()