STABLE: Final schema sync, optimized gitignore
This commit is contained in:
109
backend/app/workers/discovery_engine.py
Normal file
109
backend/app/workers/discovery_engine.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/workers/discovery_engine.py
|
||||
import asyncio
|
||||
import httpx
|
||||
import logging
|
||||
from sqlalchemy import text, select
|
||||
from app.db.session import AsyncSessionLocal
|
||||
from app.models.asset import AssetCatalog
|
||||
from app.models.vehicle_definitions import VehicleModelDefinition
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')
|
||||
logger = logging.getLogger("Discovery-Engine-v2.0")
|
||||
|
||||
class DiscoveryEngine:
|
||||
"""
|
||||
A Robot-ökoszisztéma 'etetője'.
|
||||
Kombinálja a külső API felfedezést és a manuális alapozó adatokat.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
async def seed_manual_bootstrap():
|
||||
"""
|
||||
1. FÁZIS: Manuális alapozás (Bootstrap).
|
||||
Azonnali, biztos pontok a katalógusban a teszteléshez.
|
||||
"""
|
||||
initial_data = [
|
||||
{"make": "AUDI", "model": "A4", "generation": "B8 (2008-2015)", "vehicle_class": "car"},
|
||||
{"make": "BMW", "model": "3 SERIES", "generation": "F30 (2012-2019)", "vehicle_class": "car"},
|
||||
{"make": "VOLKSWAGEN", "model": "PASSAT", "generation": "B8 (2014-)", "vehicle_class": "car"},
|
||||
{"make": "SUZUKI", "model": "VITARA", "generation": "LY (2015-)", "vehicle_class": "car"}
|
||||
]
|
||||
|
||||
async with AsyncSessionLocal() as db:
|
||||
logger.info("🛠️ Manuális bootstrap indul...")
|
||||
for item in initial_data:
|
||||
stmt = select(AssetCatalog).where(
|
||||
AssetCatalog.make == item["make"],
|
||||
AssetCatalog.model == item["model"]
|
||||
)
|
||||
exists = (await db.execute(stmt)).scalar_one_or_none()
|
||||
|
||||
if not exists:
|
||||
db.add(AssetCatalog(**item))
|
||||
|
||||
await db.commit()
|
||||
logger.info("✅ Manuális bootstrap kész.")
|
||||
|
||||
@staticmethod
|
||||
async def seed_from_rdw():
|
||||
"""
|
||||
2. FÁZIS: Külső prioritásos felfedezés (RDW API).
|
||||
Feltölti a várólistát a Hunter robot számára.
|
||||
"""
|
||||
RDW_URL = (
|
||||
"https://opendata.rdw.nl/resource/m9d7-ebf2.json?"
|
||||
"$select=merk,voertuigsoort,count(*)%20as%20total"
|
||||
"&$group=merk,voertuigsoort"
|
||||
"&$having=total%20>=%2010"
|
||||
)
|
||||
|
||||
logger.info("📥 RDW adatgyűjtés indul a várólistához...")
|
||||
|
||||
async with httpx.AsyncClient(timeout=60) as client:
|
||||
try:
|
||||
resp = await client.get(RDW_URL)
|
||||
if resp.status_code != 200:
|
||||
logger.error(f"❌ RDW API hiba: {resp.status_code}")
|
||||
return
|
||||
|
||||
raw_data = resp.json()
|
||||
async with AsyncSessionLocal() as db:
|
||||
for entry in raw_data:
|
||||
make = str(entry.get("merk", "")).upper().strip()
|
||||
v_kind = entry.get("voertuigsoort", "")
|
||||
|
||||
if not make: continue
|
||||
|
||||
# Prioritás és Kategória meghatározása
|
||||
if "Personenauto" in v_kind:
|
||||
status, v_class = 'pending', 'car'
|
||||
elif "Motorfiets" in v_kind:
|
||||
status, v_class = 'queued_motor', 'motorcycle'
|
||||
else:
|
||||
status, v_class = 'queued_heavy', 'truck'
|
||||
|
||||
# UPSERT (Ütközéskezelés)
|
||||
query = text("""
|
||||
INSERT INTO data.catalog_discovery (make, model, vehicle_class, source, status)
|
||||
VALUES (:make, 'ALL_VARIANTS', :v_class, 'discovery_engine_v2', :status)
|
||||
ON CONFLICT (make, model, vehicle_class) DO NOTHING;
|
||||
""")
|
||||
|
||||
await db.execute(query, {"make": make, "v_class": v_class, "status": status})
|
||||
|
||||
await db.commit()
|
||||
logger.info(f"✅ Discovery lista frissítve ({len(raw_data)} márka).")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Hiba az RDW szinkron alatt: {e}")
|
||||
|
||||
@classmethod
|
||||
async def run_full_initialization(cls):
|
||||
""" A teljes rendszerindító folyamat. """
|
||||
logger.info("🚀 Discovery Engine: TELJES INICIALIZÁLÁS")
|
||||
await cls.seed_manual_bootstrap()
|
||||
await cls.seed_from_rdw()
|
||||
logger.info("🏁 Minden alapozó folyamat lefutott.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(DiscoveryEngine.run_full_initialization())
|
||||
Reference in New Issue
Block a user