""" Carmodoo Sync Agent - Syncs makers/models from Carmodoo to AutonetSellCar Backend """ import asyncio import os import logging import httpx from dotenv import load_dotenv from .carmodoo_client import CarmodooClient, CarmodooConfig # Setup logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger('sync_agent') class SyncAgent: def __init__(self): load_dotenv() # Carmodoo config self.carmodoo_config = CarmodooConfig( user_id=os.getenv('CARMODOO_USER_ID', ''), password=os.getenv('CARMODOO_PASSWORD', ''), ) # Backend API self.api_url = os.getenv('API_SERVER_URL', 'http://autonet-backend:8000/api') self.api_key = os.getenv('AGENT_API_KEY', '') self.carmodoo: CarmodooClient = None self.http_client: httpx.AsyncClient = None async def start(self): """Initialize connections""" logger.info("Starting Sync Agent...") self.carmodoo = CarmodooClient(self.carmodoo_config) await self.carmodoo.create_session() self.http_client = httpx.AsyncClient(timeout=30.0) # Login to Carmodoo if not await self.carmodoo.login(): logger.error("Failed to login to Carmodoo") return False logger.info("Sync Agent started successfully") return True async def stop(self): """Cleanup connections""" if self.carmodoo: await self.carmodoo.close() if self.http_client: await self.http_client.aclose() logger.info("Sync Agent stopped") async def sync_makers(self): """Sync car makers from Carmodoo to Backend""" logger.info("Syncing car makers...") makers = await self.carmodoo.get_car_makers() logger.info(f"Found {len(makers)} makers from Carmodoo") synced = 0 for maker in makers: try: response = await self.http_client.post( f"{self.api_url}/cars/makers/", json={ "code": maker.code, "name": maker.name, } ) if response.status_code in [200, 201]: synced += 1 except Exception as e: logger.error(f"Error syncing maker {maker.code}: {e}") logger.info(f"Synced {synced}/{len(makers)} makers") return makers async def sync_models(self, makers): """Sync car models for all makers""" logger.info("Syncing car models...") total_models = 0 synced = 0 for maker in makers: await asyncio.sleep(0.5) # Rate limiting models = await self.carmodoo.get_car_models(maker.code) total_models += len(models) # Get maker ID from backend try: response = await self.http_client.get(f"{self.api_url}/cars/makers/") if response.status_code == 200: backend_makers = response.json() maker_id = None for bm in backend_makers: if bm['code'] == maker.code: maker_id = bm['id'] break if maker_id: for model in models: try: resp = await self.http_client.post( f"{self.api_url}/cars/models/", json={ "code": model.code, "maker_id": maker_id, "name": model.name, } ) if resp.status_code in [200, 201]: synced += 1 except Exception as e: logger.error(f"Error syncing model {model.code}: {e}") except Exception as e: logger.error(f"Error getting makers from backend: {e}") logger.debug(f"Maker {maker.name}: {len(models)} models") logger.info(f"Synced {synced}/{total_models} models") async def run_sync(self): """Run full sync""" if not await self.start(): return try: # Sync makers makers = await self.sync_makers() # Sync models await self.sync_models(makers) logger.info("Sync completed successfully!") except Exception as e: logger.error(f"Sync error: {e}") finally: await self.stop() async def main(): agent = SyncAgent() await agent.run_sync() if __name__ == '__main__': asyncio.run(main())