#!/usr/bin/env python3 """ Bootstrap environnement portable pour BOB. Force l'utilisation des ressources locales (ffmpeg, modèles, caches) et offre un point unique pour configurer les variables d'environnement. """ from __future__ import annotations import os import sys from pathlib import Path def _prepend_path(dir_path: Path) -> None: p = str(dir_path) current = os.environ.get("PATH", "") if p and p not in current: os.environ["PATH"] = p + (";" if current else "") + current def setup_portable_env(base_dir: Path | None = None, force_ollama_portable: bool | None = None) -> Path: """ Configure l'environnement pour n'utiliser que le dossier courant. - Ajoute vendor/ffmpeg/bin au PATH - Fige les caches HF/Transformers/Whisper dans resources/models - Définit le répertoire des modèles Ollama local - Optionnellement force l'hôte Ollama portable (localhost:11435 par défaut) Retourne base_dir normalisé. """ if base_dir is None: # Détection robuste du répertoire de base (compatible PyInstaller) if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): # Application packagée avec PyInstaller # sys.executable pointe vers BOB.exe dans le bon dossier base_dir = Path(sys.executable).parent.resolve() else: # Développement normal here = Path(__file__).resolve().parent base_dir = (here.parent).resolve() # Expo pour d'autres modules os.environ.setdefault("BOB_BASE_DIR", str(base_dir)) # 1) FFmpeg local ffmpeg_bin = base_dir / "vendor" / "ffmpeg" / "bin" if ffmpeg_bin.exists(): _prepend_path(ffmpeg_bin) # 2) Caches et modèles locaux models_root = base_dir / "resources" / "models" hf_cache = models_root / "huggingface" whisper_cache = models_root / "whisper" numba_cache = models_root / "numba_cache" for d in (hf_cache, whisper_cache, numba_cache): d.mkdir(parents=True, exist_ok=True) # Hugging Face caches os.environ.setdefault("HF_HOME", str(hf_cache)) os.environ.setdefault("TRANSFORMERS_CACHE", str(hf_cache)) os.environ.setdefault("HUGGINGFACE_HUB_CACHE", str(hf_cache)) # Whisper cache (openai-whisper regarde XDG_CACHE_HOME/WHISPER_CACHE_DIR) os.environ.setdefault("WHISPER_CACHE_DIR", str(whisper_cache)) os.environ.setdefault("XDG_CACHE_HOME", str(models_root)) # NumPy/Numba os.environ.setdefault("NUMBA_CACHE_DIR", str(numba_cache)) # 3) Dossiers d'E/S par défaut os.environ.setdefault("BOB_INPUT_DIR", str(base_dir / "input")) os.environ.setdefault("BOB_TRANSCRIPTIONS_DIR", str(base_dir / "output" / "transcriptions")) os.environ.setdefault("BOB_OUTPUT_FILE", str(base_dir / "output" / "resume_bob.txt")) # 4) Ollama portable (modèles + host) ollama_models = base_dir / "resources" / "ollama" / "models" ollama_models.mkdir(parents=True, exist_ok=True) # OLLAMA_MODELS est reconnu par Ollama pour localiser les modèles os.environ.setdefault("OLLAMA_MODELS", str(ollama_models)) # Forçage Ollama portable si demandé if force_ollama_portable is None: force_ollama_portable = os.environ.get("BOB_FORCE_PORTABLE_OLLAMA", "0") == "1" if force_ollama_portable: os.environ["BOB_FORCE_PORTABLE_OLLAMA"] = "1" # Permettre override externe, sinon 11434 (port standard Ollama) portable_host = os.environ.get("PORTABLE_OLLAMA_HOST", "http://localhost:11434") os.environ["OLLAMA_HOST"] = portable_host return base_dir __all__ = ["setup_portable_env"]