Coverage for orchestrant/paths.py: 93%

41 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-19 11:22 +0000

1"""Where an installed OrchestrANT finds its data and writes its logs.""" 

2 

3from __future__ import annotations 

4 

5import os 

6import sys 

7from pathlib import Path 

8 

9 

10MODEL_NAME = "deim_dfine_n_coco.onnx" 

11# A checkout has no model until this runs; the packages carry theirs. 

12FETCH_COMMAND = "python scripts/fetch_models.py" 

13 

14 

15def bundle_data_dir() -> Path | None: 

16 """The data directory of a packaged install; None in a checkout or a plain venv.""" 

17 env = os.getenv("ORCHESTRANT_DATA_DIR") 

18 if env: 

19 return Path(env) 

20 # A bundle keeps the interpreter in <root>/runtime and its data in <root>/share/orchestrant. 

21 candidate = Path(sys.prefix).parent / "share" / "orchestrant" 

22 return candidate if candidate.is_dir() else None 

23 

24 

25def model_search_paths(name: str = MODEL_NAME) -> list[Path]: 

26 """The places the default model is looked for, in order.""" 

27 paths: list[Path] = [] 

28 env = os.getenv("ORCHESTRANT_MODEL") 

29 if env: 

30 paths.append(Path(env)) 

31 data = bundle_data_dir() 

32 if data is not None: 

33 paths.append(data / "models" / name) 

34 paths.append(Path("resources") / "models" / name) 

35 # An editable install started from outside its checkout. 

36 paths.append(Path(__file__).resolve().parents[1] / "resources" / "models" / name) 

37 return paths 

38 

39 

40def default_model_path(name: str = MODEL_NAME) -> Path: 

41 """The first default model that exists, else the first candidate, so an error names it.""" 

42 paths = model_search_paths(name) 

43 return next((path for path in paths if path.is_file()), paths[0]) 

44 

45 

46def missing_model_message(model: Path | str) -> str: 

47 """The error for a model that is not there, naming how to fetch the default one.""" 

48 return f"model not found: {model}; fetch the default one with: {FETCH_COMMAND}" 

49 

50 

51def default_log_dir() -> Path: 

52 """A packaged install logs to the user's state dir, because its install dir may be read-only.""" 

53 env = os.getenv("ORCHESTRANT_LOG_DIR") 

54 if env: 

55 return Path(env) 

56 if bundle_data_dir() is None: 

57 return Path("logs") 

58 if sys.platform == "win32": 

59 local = os.getenv("LOCALAPPDATA") 

60 base = Path(local) if local else Path.home() / "AppData" / "Local" 

61 return base / "OrchestrANT" / "logs" 

62 state = os.getenv("XDG_STATE_HOME") 

63 base = Path(state) if state else Path.home() / ".local" / "state" 

64 return base / "orchestrant" / "logs"