# ================================================================ # validate_local.py - Script completo con todos los imports # ================================================================ import asyncio import httpx import json import sys import traceback from datetime import datetime from typing import Optional, Dict, Any # Configuración AUTH_URL = "http://localhost:8001" DATA_URL = "http://localhost:8004" GATEWAY_URL = "http://localhost:8000" # Si usas gateway class DataServiceValidator: """Validador completo para el Data Service""" def __init__(self, use_gateway: bool = False): self.auth_token: Optional[str] = None self.use_gateway = use_gateway self.base_url = GATEWAY_URL if use_gateway else DATA_URL self.auth_base_url = GATEWAY_URL if use_gateway else AUTH_URL async def test_service_health(self) -> bool: """Verificar que los servicios estén funcionando""" print("🔍 Checking service health...") try: async with httpx.AsyncClient(timeout=10.0) as client: # Test auth service auth_response = await client.get(f"{AUTH_URL}/health") if auth_response.status_code == 200: print("✅ Auth service is healthy") else: print(f"❌ Auth service unhealthy: {auth_response.status_code}") return False # Test data service data_response = await client.get(f"{DATA_URL}/health") if data_response.status_code == 200: print("✅ Data service is healthy") else: print(f"❌ Data service unhealthy: {data_response.status_code}") return False return True except httpx.ConnectError as e: print(f"❌ Connection error: {e}") print("💡 Make sure services are running with: docker-compose up -d") return False except Exception as e: print(f"❌ Health check failed: {e}") return False async def authenticate(self) -> bool: """Autenticar y obtener token""" print("🔐 Authenticating...") try: async with httpx.AsyncClient(timeout=15.0) as client: # Datos de usuario de prueba user_data = { "email": "test@bakery.es", "password": "TestPass123", "full_name": "Test User", "language": "es" } # Intentar registrar usuario (puede fallar si ya existe) register_endpoint = f"{self.auth_base_url}/api/v1/auth/register" register_response = await client.post(register_endpoint, json=user_data) if register_response.status_code == 200: print("✅ User registered successfully") elif register_response.status_code == 409: print("ℹ️ User already exists, proceeding with login") else: print(f"⚠️ Registration response: {register_response.status_code}") # Login login_data = { "email": user_data["email"], "password": user_data["password"] } login_endpoint = f"{self.auth_base_url}/api/v1/auth/login" login_response = await client.post(login_endpoint, json=login_data) if login_response.status_code == 200: response_data = login_response.json() self.auth_token = response_data["access_token"] print("✅ Authentication successful") return True else: print(f"❌ Login failed: {login_response.status_code}") print(f"Response: {login_response.text}") return False except Exception as e: print(f"❌ Authentication failed: {e}") return False def get_headers(self) -> Dict[str, str]: """Obtener headers con token de autenticación""" if not self.auth_token: raise ValueError("No authentication token available") return {"Authorization": f"Bearer {self.auth_token}"} async def test_weather_endpoints(self) -> bool: """Probar endpoints de clima""" print("🌤️ Testing weather endpoints...") try: headers = self.get_headers() madrid_coords = {"latitude": 40.4168, "longitude": -3.7038} async with httpx.AsyncClient(timeout=20.0) as client: # Current weather current_endpoint = f"{self.base_url}/api/v1/weather/current" if not self.use_gateway else f"{self.base_url}/api/v1/data/weather/current" current_response = await client.get( current_endpoint, params=madrid_coords, headers=headers ) if current_response.status_code == 200: weather = current_response.json() print(f"✅ Current weather: {weather.get('temperature')}°C, {weather.get('description')}") else: print(f"❌ Current weather failed: {current_response.status_code}") print(f"Response: {current_response.text}") return False # Weather forecast forecast_endpoint = f"{self.base_url}/api/v1/weather/forecast" if not self.use_gateway else f"{self.base_url}/api/v1/data/weather/forecast" forecast_response = await client.get( forecast_endpoint, params={**madrid_coords, "days": 3}, headers=headers ) if forecast_response.status_code == 200: forecast = forecast_response.json() print(f"✅ Weather forecast: {len(forecast)} days") else: print(f"❌ Weather forecast failed: {forecast_response.status_code}") return False return True except Exception as e: print(f"❌ Weather tests failed: {e}") return False async def test_traffic_endpoints(self) -> bool: """Probar endpoints de tráfico""" print("🚦 Testing traffic endpoints...") try: headers = self.get_headers() madrid_coords = {"latitude": 40.4168, "longitude": -3.7038} async with httpx.AsyncClient(timeout=20.0) as client: # Current traffic current_endpoint = f"{self.base_url}/api/v1/traffic/current" if not self.use_gateway else f"{self.base_url}/api/v1/data/traffic/current" current_response = await client.get( current_endpoint, params=madrid_coords, headers=headers ) if current_response.status_code == 200: traffic = current_response.json() print(f"✅ Current traffic: {traffic.get('traffic_volume')} vehicles, {traffic.get('congestion_level')} congestion") return True else: print(f"❌ Current traffic failed: {current_response.status_code}") print(f"Response: {current_response.text}") return False except Exception as e: print(f"❌ Traffic tests failed: {e}") return False async def test_sales_endpoints(self) -> bool: """Probar endpoints de ventas""" print("📊 Testing sales endpoints...") try: headers = self.get_headers() # Datos de prueba sales_data = { "tenant_id": "123e4567-e89b-12d3-a456-426614174000", "date": datetime.now().isoformat(), "product_name": "Pan Integral Test", "quantity_sold": 25, "revenue": 37.50, "location_id": "madrid_centro", "source": "test" } async with httpx.AsyncClient(timeout=20.0) as client: # Create sales record create_endpoint = f"{self.base_url}/api/v1/sales/" if not self.use_gateway else f"{self.base_url}/api/v1/data/sales/" create_response = await client.post( create_endpoint, json=sales_data, headers=headers ) if create_response.status_code == 200: record = create_response.json() print(f"✅ Sales record created: ID {record.get('id')}") else: print(f"❌ Sales creation failed: {create_response.status_code}") print(f"Response: {create_response.text}") return False # Test import template template_endpoint = f"{self.base_url}/api/v1/sales/import/template/csv" if not self.use_gateway else f"{self.base_url}/api/v1/data/sales/import/template/csv" template_response = await client.get( template_endpoint, headers=headers ) if template_response.status_code == 200: print("✅ Import template generated successfully") else: print(f"❌ Template generation failed: {template_response.status_code}") return False return True except Exception as e: print(f"❌ Sales tests failed: {e}") return False async def test_import_functionality(self) -> bool: """Probar funcionalidad de importación""" print("📄 Testing import functionality...") try: headers = self.get_headers() # Crear CSV de prueba csv_content = """fecha,producto,cantidad,ingresos 15/01/2024,Pan Integral,25,37.50 15/01/2024,Croissant,15,22.50 15/01/2024,Café con Leche,10,20.00""" # Test CSV import import_data = { "tenant_id": "123e4567-e89b-12d3-a456-426614174000", "data_format": "csv", "data": csv_content } async with httpx.AsyncClient(timeout=30.0) as client: import_endpoint = f"{self.base_url}/api/v1/sales/import/json" if not self.use_gateway else f"{self.base_url}/api/v1/data/sales/import/json" import_response = await client.post( import_endpoint, json=import_data, headers=headers ) if import_response.status_code == 200: result = import_response.json() if result.get("success"): print(f"✅ CSV import successful: {result.get('records_created')} records created") return True else: print(f"❌ CSV import failed: {result.get('error')}") return False else: print(f"❌ Import request failed: {import_response.status_code}") print(f"Response: {import_response.text}") return False except Exception as e: print(f"❌ Import tests failed: {e}") return False async def main(): """Función principal de validación""" print("🚀 Starting Data Service Validation") print("=" * 50) # Preguntar si usar gateway use_gateway_input = input("Use API Gateway? (y/N): ").lower() use_gateway = use_gateway_input == 'y' if use_gateway: print("📡 Testing via API Gateway") else: print("🔗 Testing direct service connections") validator = DataServiceValidator(use_gateway=use_gateway) try: # 1. Health checks if not await validator.test_service_health(): print("\n❌ Health checks failed. Ensure services are running.") return False # 2. Authentication if not await validator.authenticate(): print("\n❌ Authentication failed.") return False # 3. Weather tests if not await validator.test_weather_endpoints(): print("\n❌ Weather endpoint tests failed.") return False # 4. Traffic tests if not await validator.test_traffic_endpoints(): print("\n❌ Traffic endpoint tests failed.") return False # 5. Sales tests if not await validator.test_sales_endpoints(): print("\n❌ Sales endpoint tests failed.") return False # 6. Import tests if not await validator.test_import_functionality(): print("\n❌ Import functionality tests failed.") return False print("\n" + "=" * 50) print("🎉 ALL TESTS PASSED! Data Service is working correctly!") print("=" * 50) return True except KeyboardInterrupt: print("\n⚠️ Tests interrupted by user") return False except Exception as e: print(f"\n❌ Unexpected error: {e}") print("Traceback:") traceback.print_exc() return False def check_dependencies(): """Verificar que las dependencias estén instaladas""" try: import httpx print("✅ httpx is available") except ImportError: print("❌ httpx not found. Install with: pip install httpx") return False return True if __name__ == "__main__": print("🔧 Checking dependencies...") if not check_dependencies(): print("\n💡 Install dependencies with:") print("pip install httpx") sys.exit(1) print("✅ All dependencies available") print() # Ejecutar validación success = asyncio.run(main()) if success: print("\n🎯 Next steps:") print("1. Check logs: docker-compose logs -f data-service") print("2. Connect to DB: docker-compose exec data-db psql -U data_user -d data_db") print("3. Test with real data imports") sys.exit(0) else: print("\n🔧 Troubleshooting:") print("1. Check services: docker-compose ps") print("2. Restart services: docker-compose restart") print("3. Check logs: docker-compose logs data-service") sys.exit(1)