config.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from __future__ import annotations
  2. import os
  3. from pathlib import Path
  4. from typing import Any
  5. import config as config_file
  6. from sweagent import REPO_ROOT
  7. from sweagent.utils.log import get_logger
  8. logger = get_logger("config")
  9. def convert_path_to_abspath(path: Path | str) -> Path:
  10. """If path is not absolute, convert it to an absolute path
  11. using the SWE_AGENT_CONFIG_ROOT environment variable (if set) or
  12. REPO_ROOT as base.
  13. """
  14. path = Path(path)
  15. root = Path(keys_config.get("SWE_AGENT_CONFIG_ROOT", REPO_ROOT))
  16. assert root.is_dir()
  17. if not path.is_absolute():
  18. path = root / path
  19. assert path.is_absolute()
  20. return path.resolve()
  21. def convert_paths_to_abspath(paths: list[Path | str]) -> list[Path]:
  22. return [convert_path_to_abspath(p) for p in paths]
  23. class Config:
  24. def __init__(self, *, keys_cfg_path: Path | None = None):
  25. """This wrapper class is used to load keys from environment variables or keys.cfg file.
  26. Whenever both are presents, the environment variable is used.
  27. """
  28. if keys_cfg_path is None:
  29. # Defer import to avoid circular import
  30. from sweagent import PACKAGE_DIR
  31. keys_cfg_path = PACKAGE_DIR.parent / "keys.cfg"
  32. self._keys_cfg = None
  33. if keys_cfg_path.exists():
  34. try:
  35. self._keys_cfg = config_file.Config(str(keys_cfg_path))
  36. except Exception as e:
  37. msg = f"Error loading keys.cfg from {keys_cfg_path}. Please check the file."
  38. raise RuntimeError(msg) from e
  39. else:
  40. logger.error(f"keys.cfg not found in {PACKAGE_DIR}")
  41. def get(self, key: str, default=None, choices: list[Any] | None = None) -> Any:
  42. """Get a key from environment variables or keys.cfg.
  43. Args:
  44. key: The key to retrieve.
  45. default: The default value to return if the key is not found.
  46. choices: If provided, the value must be one of the choices.
  47. """
  48. def check_choices(value):
  49. if choices is not None and value not in choices:
  50. msg = f"Value {value} for key {key} not in {choices}"
  51. raise ValueError(msg)
  52. return value
  53. if key in os.environ:
  54. return check_choices(os.environ[key])
  55. if self._keys_cfg is not None and key in self._keys_cfg:
  56. return check_choices(self._keys_cfg[key])
  57. return check_choices(default)
  58. def __getitem__(self, key: str) -> Any:
  59. if key in os.environ:
  60. return os.environ[key]
  61. if self._keys_cfg is not None and key in self._keys_cfg:
  62. return self._keys_cfg[key]
  63. msg = f"Key {key} not found in environment variables or keys.cfg (if existing)"
  64. raise KeyError(msg)
  65. def __contains__(self, key: str) -> bool:
  66. return key in os.environ or (self._keys_cfg is not None and key in self._keys_cfg)
  67. keys_config = Config()