From 7ab7cd7591c9dfdb34c5290dc3227bc7bc9fa648 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 21 Mar 2026 08:32:52 +0000 Subject: [PATCH] perf: lazy load json parsing in PortfolioSnapshot This commit optimizes `PortfolioSnapshot` instantiation when loaded from the DB or JSON dictionaries by removing the immediate `json.loads(holdings_snapshot)` parsing inside the `from_dict` constructor. Instead, it overrides `__getattribute__` to implement a lazy-loading pattern, where the `holdings_snapshot` string is only parsed into a Python dictionary the very first time the field is accessed. This optimization ensures that parsing large JSON payloads doesn't block the instantiation of snapshots, which is particularly beneficial in workflows that load a large historical series of snapshots but never access their `holdings_snapshot` field. Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com> --- tradingagents/portfolio/models.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tradingagents/portfolio/models.py b/tradingagents/portfolio/models.py index f9989af4..ed3a379b 100644 --- a/tradingagents/portfolio/models.py +++ b/tradingagents/portfolio/models.py @@ -275,9 +275,18 @@ class PortfolioSnapshot: cash: float equity_value: float num_positions: int - holdings_snapshot: list[dict[str, Any]] = field(default_factory=list) + holdings_snapshot: list[dict[str, Any]] | str = field(default_factory=list) metadata: dict[str, Any] = field(default_factory=dict) + def __getattribute__(self, name: str) -> Any: + if name == "holdings_snapshot": + val = object.__getattribute__(self, "holdings_snapshot") + if isinstance(val, str): + val = json.loads(val) + object.__setattr__(self, "holdings_snapshot", val) + return val + return object.__getattribute__(self, name) + def to_dict(self) -> dict[str, Any]: """Serialise all fields. ``holdings_snapshot`` is already a list[dict].""" return { @@ -296,11 +305,8 @@ class PortfolioSnapshot: def from_dict(cls, data: dict[str, Any]) -> "PortfolioSnapshot": """Deserialise from DB row or JSON dict. - ``holdings_snapshot`` is parsed from a JSON string when needed. + ``holdings_snapshot`` is parsed lazily on first access. """ - holdings_snapshot = data.get("holdings_snapshot", []) - if isinstance(holdings_snapshot, str): - holdings_snapshot = json.loads(holdings_snapshot) return cls( snapshot_id=data["snapshot_id"], portfolio_id=data["portfolio_id"], @@ -309,6 +315,6 @@ class PortfolioSnapshot: cash=float(data["cash"]), equity_value=float(data["equity_value"]), num_positions=int(data["num_positions"]), - holdings_snapshot=holdings_snapshot, + holdings_snapshot=data.get("holdings_snapshot", []), metadata=data.get("metadata") or {}, )