#!/usr/bin/env python3 """ Step 7 — Verifica ambiente Controlla che tutti i prerequisiti per la vettorizzazione siano soddisfatti: 1. ollama è nel PATH e risponde 2. Almeno un modello di embedding è scaricato 3. Almeno un modello LLM è scaricato 4. chromadb è importabile Output: report a schermo con ✅ / ❌ per ogni componente. Nessun file scritto. Exit 0 se tutto OK, 1 altrimenti. Uso: python step-7/check_env.py """ import shutil import subprocess import sys # Modelli riconosciuti come embedding (basta che uno sia presente) # Tutto il resto viene considerato LLM EMBED_MODELS = ["bge-m3", "nomic-embed-text", "mxbai-embed-large", "all-minilm"] REQUIRED_LIBS = ["chromadb"] # ─── Checks ─────────────────────────────────────────────────────────────────── def check_ollama_in_path() -> bool: """Verifica che ollama sia nel PATH.""" found = shutil.which("ollama") is not None if found: print("✅ ollama trovato nel PATH") else: print("❌ ollama non trovato nel PATH") print(" → Installa con: curl -fsSL https://ollama.com/install.sh | sh") return found def check_ollama_running() -> list[str] | None: """ Esegue 'ollama list' e ritorna la lista dei modelli disponibili. Ritorna None se ollama non risponde. """ try: result = subprocess.run( ["ollama", "list"], capture_output=True, text=True, timeout=10 ) if result.returncode != 0: print("❌ ollama non risponde (errore all'avvio)") print(" → Avvia il servizio con: ollama serve") return None lines = result.stdout.strip().splitlines() models = [] for line in lines[1:]: # salta l'header parts = line.split() if parts: models.append(parts[0]) print("✅ ollama risponde correttamente") return models except FileNotFoundError: print("❌ ollama non trovato (FileNotFoundError)") return None except subprocess.TimeoutExpired: print("❌ ollama non risponde (timeout)") print(" → Avvia il servizio con: ollama serve") return None def _match(model_name: str, available: list[str]) -> str | None: """ Ritorna il nome completo del modello trovato in 'available' che corrisponde a 'model_name' (confronto per prefisso), oppure None. """ for m in available: if m == model_name or m.startswith(model_name + ":") or m.startswith(model_name + "-"): return m return None def check_embed_model(available: list[str]) -> bool: """Verifica che almeno un modello di embedding sia presente.""" for candidate in EMBED_MODELS: found = _match(candidate, available) if found: print(f"✅ modello embedding trovato: {found}") return True print("❌ nessun modello di embedding trovato") print(f" → Consigliato per italiano: ollama pull bge-m3") print(f" → Alternativa leggera: ollama pull nomic-embed-text") return False def check_llm_model(available: list[str]) -> bool: """Verifica che almeno un modello non-embedding sia presente.""" llm_candidates = [ m for m in available if not any(m == e or m.startswith(e + ":") or m.startswith(e + "-") for e in EMBED_MODELS) ] if llm_candidates: print(f"✅ modello LLM trovato: {llm_candidates[0]}") return True print("❌ nessun modello LLM trovato") print(f" → Consigliato per 8 GB RAM: ollama pull qwen3.5:4b") return False def check_library(lib: str) -> bool: """Verifica che una libreria Python sia importabile.""" try: __import__(lib) print(f"✅ {lib} importabile") return True except ImportError: print(f"❌ {lib} non importabile") print(f" → Installa con: pip install {lib}") return False # ─── Entry point ────────────────────────────────────────────────────────────── def main() -> int: print("─── Step 7 — Verifica ambiente ───────────────────────────────────────\n") results: list[bool] = [] # 1. ollama nel PATH in_path = check_ollama_in_path() results.append(in_path) # 2. ollama risponde + modelli if in_path: available = check_ollama_running() if available is None: results.extend([False, False, False]) else: results.append(True) results.append(check_embed_model(available)) results.append(check_llm_model(available)) else: results.extend([False, False, False]) print("⚠️ modelli non verificabili (ollama non trovato)") # 3. Librerie Python print() for lib in REQUIRED_LIBS: results.append(check_library(lib)) # ── Riepilogo ───────────────────────────────────────────────────────────── print() print("──────────────────────────────────────────────────────────────────────") all_ok = all(results) if all_ok: print("✅ Ambiente pronto — procedi con la vettorizzazione:") print(" python step-8/ingest.py --stem ") else: n_fail = sum(1 for r in results if not r) print(f"⚠️ {n_fail} problema/i rilevato/i — risolvi prima di procedere con step-8.") return 0 if all_ok else 1 if __name__ == "__main__": sys.exit(main())