| |
| """ |
| パス管理モジュール |
| PyInstaller対応とサーバー起動の両方に対応 |
| """ |
|
|
| import os |
| import sys |
| from pathlib import Path |
| from typing import Optional |
|
|
| class PathManager: |
| """パス管理クラス(シングルトン)""" |
| |
| _instance: Optional["PathManager"] = None |
| |
| def __new__(cls): |
| if cls._instance is None: |
| cls._instance = super().__new__(cls) |
| cls._instance._initialized = False |
| return cls._instance |
| |
| def __init__(self): |
| if self._initialized: |
| return |
| |
| self._initialized = True |
| self._setup_paths() |
| |
| def _setup_paths(self): |
| """パス設定を初期化""" |
| |
| if getattr(sys, 'frozen', False): |
| |
| self.is_pyinstaller = True |
| self.base_path = Path(sys._MEIPASS) |
| self.package_path = self.base_path / 'package' |
| self.python_executable = sys.executable |
| else: |
| |
| self.is_pyinstaller = False |
| self.base_path = Path(__file__).parent.parent |
| self.package_path = self.base_path / 'package' |
| self.python_executable = sys.executable |
| |
| |
| self.model_path = self._get_model_path() |
| |
| |
| print(f"[PATH] PyInstaller: {self.is_pyinstaller}") |
| print(f"[PATH] Base path: {self.base_path}") |
| print(f"[PATH] Package path: {self.package_path}") |
| print(f"[PATH] Model path: {self.model_path}") |
| |
| def _get_model_path(self) -> str: |
| """モデルファイルのパスを取得""" |
| |
| env_model_path = os.getenv('LLM_MODEL_PATH') |
| if env_model_path and os.path.exists(env_model_path): |
| return env_model_path |
| |
| |
| try: |
| |
| executable_dir = Path(os.path.dirname(sys.executable)) if getattr(sys, 'frozen', False) else Path(__file__).parent.parent |
| candidate_relative_paths = [ |
| |
| (executable_dir.parent / 'models' / 'llama-3.2-3b-instruct-q4_k_m.gguf'), |
| |
| (executable_dir / 'models' / 'llama-3.2-3b-instruct-q4_k_m.gguf'), |
| |
| (Path(getattr(sys, '_MEIPASS', str(self.base_path))) / 'models' / 'llama-3.2-3b-instruct-q4_k_m.gguf'), |
| ] |
| for rel in candidate_relative_paths: |
| rel_str = str(rel) |
| if os.path.exists(rel_str): |
| return rel_str |
| except Exception: |
| pass |
|
|
| |
| default_paths = [ |
| os.path.expanduser("~/Documents/GitHub/LLMV_app_frontend/src-tauri/python/models/llama-3.2-3b-instruct-q4_k_m.gguf"), |
| os.path.expanduser("~/Documents/models/llama-3.2-3b-instruct-q4_k_m.gguf"), |
| os.path.expanduser("~/models/llama-3.2-3b-instruct-q4_k_m.gguf"), |
| "/opt/models/llama-3.2-3b-instruct-q4_k_m.gguf" |
| ] |
| |
| for path in default_paths: |
| if os.path.exists(path): |
| return path |
| |
| |
| return default_paths[0] |
| |
| def get_package_path(self) -> str: |
| """パッケージパスを取得""" |
| return str(self.package_path) |
| |
| def get_model_path(self) -> str: |
| """モデルパスを取得""" |
| return self.model_path |
| |
| def get_python_executable(self) -> str: |
| """Python実行ファイルのパスを取得""" |
| return self.python_executable |
| |
| def setup_sys_path(self): |
| """sys.pathを設定""" |
| package_path_str = self.get_package_path() |
| |
| |
| if package_path_str not in sys.path: |
| sys.path.insert(0, package_path_str) |
| |
| |
| if not self.is_pyinstaller: |
| conda_package_path = '/Users/wataru/Documents/AppProject/LLMView_Server/package' |
| if os.path.exists(conda_package_path) and conda_package_path not in sys.path: |
| sys.path.insert(0, conda_package_path) |
| |
| print(f"[PATH] sys.path configured: {len(sys.path)} paths") |
| |
| def get_server_config(self) -> dict: |
| """サーバー設定を取得""" |
| return { |
| 'host': '127.0.0.1', |
| 'port': 5000, |
| 'debug': False, |
| 'use_reloader': False, |
| 'threaded': True |
| } |
| |
| def get_pyinstaller_spec_path(self) -> str: |
| """PyInstaller specファイルのパスを取得""" |
| return str(self.base_path / 'tauri_python_server.spec') |
| |
| def get_dist_path(self) -> str: |
| """ビルド出力ディレクトリのパスを取得""" |
| return str(self.base_path / 'dist') |
| |
| def get_executable_name(self) -> str: |
| """実行ファイル名を取得""" |
| return 'tauri_python_server' |
|
|
| |
| path_manager = PathManager() |
|
|
| def get_path_manager() -> PathManager: |
| """PathManagerインスタンスを取得""" |
| return path_manager |
|
|