#!/usr/bin/env python3 """ Apply patches for rate limiting fix. This Python script works across all platforms. """ import os import sys import shutil from pathlib import Path def backup_file(filepath): """Create backup of file.""" backup_path = f"{filepath}.backup" shutil.copy2(filepath, backup_path) print(f"✓ Backed up {filepath} to {backup_path}") return backup_path def patch_main_py(): """Patch backend/app/main.py to use analytics_v2.""" filepath = Path("backend/app/main.py") if not filepath.exists(): print(f"❌ Error: {filepath} not found") return False print(f"\n[1/2] Patching {filepath}...") # Backup backup_file(filepath) # Read file with open(filepath, 'r') as f: content = f.read() # Check if already patched if 'analytics_v2 as analytics' in content or 'import analytics_v2' in content: print("✓ Backend already patched (analytics_v2 found)") return True # Apply patch old_import = "from app.api.endpoints import accounts, transactions, positions, analytics" new_import = "from app.api.endpoints import accounts, transactions, positions, analytics_v2 as analytics" if old_import in content: content = content.replace(old_import, new_import) # Write back with open(filepath, 'w') as f: f.write(content) print("✓ Backend patched successfully") return True else: print("❌ Could not find expected import line") print("\nLooking for:") print(f" {old_import}") print("\nPlease manually edit backend/app/main.py") return False def patch_app_tsx(): """Patch frontend/src/App.tsx to use DashboardV2.""" filepath = Path("frontend/src/App.tsx") if not filepath.exists(): print(f"❌ Error: {filepath} not found") return False print(f"\n[2/2] Patching {filepath}...") # Backup backup_file(filepath) # Read file with open(filepath, 'r') as f: content = f.read() # Check if already patched if 'DashboardV2' in content or "components/DashboardV2" in content: print("✓ Frontend already patched (DashboardV2 found)") return True # Apply patch - handle both single and double quotes old_import1 = "import Dashboard from './components/Dashboard'" new_import1 = "import Dashboard from './components/DashboardV2'" old_import2 = 'import Dashboard from "./components/Dashboard"' new_import2 = 'import Dashboard from "./components/DashboardV2"' changed = False if old_import1 in content: content = content.replace(old_import1, new_import1) changed = True if old_import2 in content: content = content.replace(old_import2, new_import2) changed = True if changed: # Write back with open(filepath, 'w') as f: f.write(content) print("✓ Frontend patched successfully") return True else: print("❌ Could not find expected import line") print("\nLooking for:") print(f" {old_import1}") print(f" or {old_import2}") print("\nPlease manually edit frontend/src/App.tsx") return False def main(): print("=" * 60) print("Applying Rate Limiting Fix Patches (Python)") print("=" * 60) # Check we're in the right directory if not Path("docker-compose.yml").exists(): print("\n❌ Error: docker-compose.yml not found") print("Please run this script from the fidelity project directory") sys.exit(1) # Apply patches backend_ok = patch_main_py() frontend_ok = patch_app_tsx() print("\n" + "=" * 60) if backend_ok and frontend_ok: print("✅ All patches applied successfully!") print("=" * 60) print("\nNext steps:") print("") print("1. Rebuild containers:") print(" docker compose down") print(" docker compose build --no-cache backend frontend") print(" docker compose up -d") print("") print("2. Run migration:") print(" sleep 30") print(" docker compose exec backend alembic upgrade head") print("") print("3. Test:") print(" curl http://localhost:8000/api/analytics/overview/1?refresh_prices=false") print("") sys.exit(0) else: print("⚠️ Some patches failed - see manual instructions above") print("=" * 60) sys.exit(1) if __name__ == "__main__": main()