""" Quick Error Checker for RAG API Similar to 'npm run build' for JavaScript, this checks for Python errors. Usage: python check_errors.py """ import sys import os from pathlib import Path import py_compile import importlib.util # Colors for output GREEN = '\033[92m' RED = '\033[91m' YELLOW = '\033[93m' RESET = '\033[0m' BOLD = '\033[1m' def print_header(text): """Print section header""" print(f"\n{BOLD}{'='*60}{RESET}") print(f"{BOLD}{text}{RESET}") print(f"{BOLD}{'='*60}{RESET}\n") def check_syntax(file_path): """Check Python syntax (like tsc --noEmit)""" try: py_compile.compile(file_path, doraise=True) return True, None except py_compile.PyCompileError as e: return False, str(e) def check_imports(file_path): """Check if file can be imported""" try: spec = importlib.util.spec_from_file_location("module", file_path) if spec and spec.loader: module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return True, None except Exception as e: return False, str(e) def find_python_files(directory): """Find all Python files in directory""" return list(Path(directory).rglob("*.py")) def main(): """Main error checking function""" print(f"{BOLD}🐍 Python Error Checker{RESET}") print(f"Similar to 'npm run build' for JavaScript\n") # Get source directory src_dir = Path(__file__).parent / "src" if not src_dir.exists(): print(f"{RED}❌ Source directory not found: {src_dir}{RESET}") return 1 # Find all Python files python_files = find_python_files(src_dir) print(f"Found {len(python_files)} Python files\n") # Track results syntax_errors = [] import_errors = [] # ── Stage 1: Syntax Check ────────────────────────────────────────────── print_header("Stage 1: Syntax Check (like tsc --noEmit)") for file_path in python_files: relative_path = file_path.relative_to(Path.cwd()) success, error = check_syntax(file_path) if success: print(f"{GREEN}✓{RESET} {relative_path}") else: print(f"{RED}✗{RESET} {relative_path}") print(f" {RED}Error: {error}{RESET}") syntax_errors.append((relative_path, error)) # ── Stage 2: Import Check ────────────────────────────────────────────── print_header("Stage 2: Import Check") # Only check files that passed syntax check files_to_import = [f for f in python_files if f not in [e[0] for e in syntax_errors]] # Add src to path for imports sys.path.insert(0, str(src_dir.parent)) for file_path in files_to_import: relative_path = file_path.relative_to(Path.cwd()) # Skip __init__.py files if file_path.name == "__init__.py": print(f"{YELLOW}⊘{RESET} {relative_path} (skipped)") continue success, error = check_imports(file_path) if success: print(f"{GREEN}✓{RESET} {relative_path}") else: print(f"{RED}✗{RESET} {relative_path}") print(f" {RED}Error: {error[:200]}...{RESET}") import_errors.append((relative_path, error)) # ── Summary ──────────────────────────────────────────────────────────── print_header("Summary") total_files = len(python_files) syntax_ok = total_files - len(syntax_errors) import_ok = len(files_to_import) - len(import_errors) print(f"Total files checked: {total_files}") print(f"Syntax check: {GREEN}{syntax_ok} passed{RESET}, {RED}{len(syntax_errors)} failed{RESET}") print(f"Import check: {GREEN}{import_ok} passed{RESET}, {RED}{len(import_errors)} failed{RESET}") # ── Exit Code ────────────────────────────────────────────────────────── if syntax_errors or import_errors: print(f"\n{RED}{BOLD}❌ Build Failed{RESET}") print(f"\nFix the errors above and try again.") return 1 else: print(f"\n{GREEN}{BOLD}✅ Build Successful{RESET}") print(f"\nAll files are error-free!") return 0 if __name__ == "__main__": sys.exit(main())