Coverage for arclith / adapters / output / yaml / secret_adapter.py: 100%

23 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-25 15:02 +0100

1from __future__ import annotations 

2 

3from pathlib import Path 

4 

5import yaml 

6 

7from arclith.domain.ports.secret_resolver import SecretResolver 

8 

9 

10class YamlSecretAdapter(SecretResolver): 

11 """Reads secrets from a gitignored YAML file (local dev fallback). 

12 

13 The file mirrors the config.yaml structure — only secret fields need to appear. 

14 

15 Example secrets.yaml: 

16 adapters: 

17 mongodb: 

18 uri: mongodb://localhost:5971 

19 lm: 

20 planner: 

21 api_key: sk-ant-xxxx 

22 """ 

23 

24 def __init__(self, path: str | Path) -> None: 

25 self._path = Path(path) 

26 self._data: dict | None = None 

27 

28 def _load(self) -> dict: 

29 if self._data is None: 

30 if self._path.exists(): 

31 with self._path.open() as f: 

32 self._data = yaml.safe_load(f) or {} 

33 else: 

34 self._data = {} 

35 return self._data 

36 

37 def get(self, field_path: str, secret_key: str) -> str | None: 

38 data = self._load() 

39 current: object = data 

40 for key in field_path.split("."): 

41 if not isinstance(current, dict) or key not in current: 

42 return None 

43 current = current[key] 

44 return str(current) if current is not None else None 

45