Coverage for src/usaspending/models/lazy_record.py: 100%
29 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 17:15 -0700
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-03 17:15 -0700
1# usaspendingapi/models/lazy.py
2from .base_model import ClientAwareModel
3from typing import Dict, Any, Optional, TYPE_CHECKING
5if TYPE_CHECKING:
6 from usaspending.client import USASpending
9class LazyRecord(ClientAwareModel):
10 """Enhanced LazyRecord that maintains client reference."""
12 def __init__(self, data: Dict[str, Any], client: "USASpending"):
13 super().__init__(data, client)
14 self._details_fetched = False
16 def _ensure_details(self) -> None:
17 """Fetch full details using the client."""
18 if self._details_fetched:
19 return
21 new_data = self._fetch_details()
22 if new_data:
23 self._data.update(new_data)
24 self._details_fetched = True
26 def _fetch_details(self) -> Optional[Dict[str, Any]]:
27 """Override in subclasses."""
28 raise NotImplementedError
30 def _lazy_get(self, *keys: str, default: Any = None) -> Any:
31 """Get value, triggering lazy load if needed."""
33 keys = list(keys)
35 # If we've already lazy-loaded details, return whatever
36 # values are present in the data
38 if self._details_fetched:
39 return self.get_value(keys, default=default)
40 else:
41 # Try loading the value directly
42 # If returned value is None, than try fetching
43 # the source data
44 value = None
46 for key in keys:
47 if key in self._data:
48 value = self._data[key]
49 break
51 if value is None:
52 # Load full resource data from source
53 self._ensure_details()
55 # Set flag
56 self._details_fetched = True
58 # Attempt to return the value again
59 value = self.get_value(keys, default=default)
60 return value