Skip to content

Commit 10a5e36

Browse files
fix: patch vulnerable python dependencies (#104)
* fix: patch vulnerable python dependencies * chore: refresh python dependency lockfile * fix: satisfy updated ty checks * style: apply ruff formatting
1 parent cc8f5bf commit 10a5e36

8 files changed

Lines changed: 401 additions & 308 deletions

File tree

macro_agents/pyproject.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,26 @@ dependencies = [
4747
"vadersentiment>=3.3.2",
4848
"sqlglot>=28.1.0,<29.0.0",
4949
"metaxy[dagster]>=0.1.10,<0.2.0",
50+
"aiohttp>=3.14.1",
51+
"cryptography>=48.0.1",
52+
"msgpack>=1.2.1",
53+
"pydantic-settings>=2.14.2",
54+
"pyjwt>=2.13.0",
55+
"starlette>=1.3.1",
5056
]
5157

5258
[project.optional-dependencies]
5359
dev = [
5460
"dagster-webserver",
55-
"pytest",
61+
"pytest>=9.0.3,<9.1.0",
5662
"pytest-cov",
5763
"pytest-xdist",
5864
"mypy",
5965
"ty",
6066
"duckdb>=1.0.0,<2.0.0",
6167
"ruff>=0.12.7,<1.0.0", # Move ruff here
62-
"sqlfluff>=3.4.2,<4.0.0", # Move sqlfluff here
63-
"sqlfluff-templater-dbt>=3.4.2,<4.0.0", # Move here
68+
"sqlfluff>=4.2.0,<5.0.0", # Move sqlfluff here
69+
"sqlfluff-templater-dbt>=4.2.0,<5.0.0", # Move here
6470
]
6571

6672
[build-system]

macro_agents/src/macro_agents/defs/analysis/data_points/interesting_data_points_assets.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,10 @@ def detect_interesting_data_points_weekly(
327327

328328
# 10. Return metadata
329329
finding_types = findings_df["finding_type"].unique().to_list()
330-
top_finding = (
330+
top_finding_value = (
331331
analyzed_findings[0]["significance_narrative"] if analyzed_findings else None
332332
)
333+
top_finding = top_finding_value if isinstance(top_finding_value, str) else None
333334

334335
context.log.info(
335336
f"Successfully completed weekly analysis with {len(analyzed_findings)} findings"

macro_agents/src/macro_agents/defs/backtesting/backtest_asset_class_relationship_analyzer.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from datetime import datetime
23

34
import dagster as dg
@@ -22,6 +23,14 @@
2223
from macro_agents.defs.resources.bigquery_warehouse import BigQueryWarehouseResource
2324

2425

26+
def _content_as_text(value: object) -> str:
27+
if value is None:
28+
return ""
29+
if isinstance(value, str):
30+
return value
31+
return json.dumps(value, default=str)
32+
33+
2534
def get_latest_backtest_economy_state_analysis(
2635
md_resource: BigQueryWarehouseResource,
2736
backtest_date: str,
@@ -454,7 +463,7 @@ def backtest_analyze_asset_class_relationships(
454463
)
455464

456465
first_result = all_results[0]
457-
analysis_content = first_result.get("analysis_content") or ""
466+
analysis_content = _content_as_text(first_result.get("analysis_content"))
458467
analysis_summary = (
459468
extract_relationship_summary(analysis_content) if analysis_content else {}
460469
)

macro_agents/src/macro_agents/defs/backtesting/backtest_economy_state_analyzer.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from datetime import datetime
23

34
import dagster as dg
@@ -15,6 +16,14 @@
1516
from macro_agents.defs.resources.bigquery_warehouse import BigQueryWarehouseResource
1617

1718

19+
def _content_as_text(value: object) -> str:
20+
if value is None:
21+
return ""
22+
if isinstance(value, str):
23+
return value
24+
return json.dumps(value, default=str)
25+
26+
1827
class BacktestConfig(dg.Config):
1928
"""Configuration for backtesting - can be specified at runtime."""
2029

@@ -522,7 +531,7 @@ def backtest_analyze_economy_state(
522531
)
523532

524533
first_result = all_results[0]
525-
analysis_content = first_result.get("analysis_content") or ""
534+
analysis_content = _content_as_text(first_result.get("analysis_content"))
526535
analysis_summary = (
527536
extract_economy_state_summary(analysis_content) if analysis_content else {}
528537
)

macro_agents/src/macro_agents/defs/backtesting/backtest_evaluator.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,32 @@ def recommendation_accuracy_metric(example, prediction, trace=None):
102102
return score
103103

104104

105+
def _period_result(evaluation_result: dict[str, object], period: str) -> dict | None:
106+
period_results = evaluation_result.get("period_results", {})
107+
if not isinstance(period_results, dict):
108+
return None
109+
110+
period_result = period_results.get(period)
111+
if not isinstance(period_result, dict):
112+
return None
113+
114+
return period_result
115+
116+
117+
def _period_outperformance(
118+
evaluation_result: dict[str, object], period: str
119+
) -> float | None:
120+
period_result = _period_result(evaluation_result, period)
121+
if period_result is None:
122+
return None
123+
124+
value = period_result.get("outperformance")
125+
if not isinstance(value, (int, float)):
126+
return None
127+
128+
return float(value)
129+
130+
105131
@dg.asset(
106132
kinds={"dspy", "duckdb"},
107133
group_name="backtesting",
@@ -228,7 +254,7 @@ def evaluate_backtest_recommendations(
228254
f"Running evaluation on {len(examples)} examples for {backtest_date}..."
229255
)
230256

231-
evaluation_results = []
257+
evaluation_results: list[dict[str, object]] = []
232258
for example in examples:
233259
prediction = module(
234260
recommendation=example.recommendation, outcomes=example.outcomes
@@ -238,7 +264,8 @@ def evaluate_backtest_recommendations(
238264

239265
if hasattr(example, "_metric_details") and example._metric_details:
240266
detail = list(example._metric_details.values())[0]
241-
evaluation_results.append(detail)
267+
if isinstance(detail, dict):
268+
evaluation_results.append(detail)
242269
else:
243270
recommendation = example.recommendation
244271
evaluation_results.append(
@@ -260,22 +287,23 @@ def evaluate_backtest_recommendations(
260287
misses_6m = 0
261288

262289
for r in evaluation_results:
263-
period_results = r.get("period_results", {})
264-
265-
if "1m" in period_results:
266-
if period_results["1m"].get("is_hit", False):
290+
period_result_1m = _period_result(r, "1m")
291+
if period_result_1m is not None:
292+
if period_result_1m.get("is_hit", False):
267293
hits_1m += 1
268294
else:
269295
misses_1m += 1
270296

271-
if "3m" in period_results:
272-
if period_results["3m"].get("is_hit", False):
297+
period_result_3m = _period_result(r, "3m")
298+
if period_result_3m is not None:
299+
if period_result_3m.get("is_hit", False):
273300
hits_3m += 1
274301
else:
275302
misses_3m += 1
276303

277-
if "6m" in period_results:
278-
if period_results["6m"].get("is_hit", False):
304+
period_result_6m = _period_result(r, "6m")
305+
if period_result_6m is not None:
306+
if period_result_6m.get("is_hit", False):
279307
hits_6m += 1
280308
else:
281309
misses_6m += 1
@@ -289,10 +317,9 @@ def evaluate_backtest_recommendations(
289317
accuracy_6m = hits_6m / total_6m if total_6m > 0 else 0.0
290318

291319
outperformance_1m = [
292-
r.get("period_results", {}).get("1m", {}).get("outperformance", 0.0)
320+
value
293321
for r in evaluation_results
294-
if r.get("period_results", {}).get("1m", {}).get("outperformance")
295-
is not None
322+
if (value := _period_outperformance(r, "1m")) is not None
296323
]
297324
avg_outperformance_1m = (
298325
sum(outperformance_1m) / len(outperformance_1m)
@@ -301,10 +328,9 @@ def evaluate_backtest_recommendations(
301328
)
302329

303330
outperformance_3m = [
304-
r.get("period_results", {}).get("3m", {}).get("outperformance", 0.0)
331+
value
305332
for r in evaluation_results
306-
if r.get("period_results", {}).get("3m", {}).get("outperformance")
307-
is not None
333+
if (value := _period_outperformance(r, "3m")) is not None
308334
]
309335
avg_outperformance_3m = (
310336
sum(outperformance_3m) / len(outperformance_3m)
@@ -313,10 +339,9 @@ def evaluate_backtest_recommendations(
313339
)
314340

315341
outperformance_6m = [
316-
r.get("period_results", {}).get("6m", {}).get("outperformance", 0.0)
342+
value
317343
for r in evaluation_results
318-
if r.get("period_results", {}).get("6m", {}).get("outperformance")
319-
is not None
344+
if (value := _period_outperformance(r, "6m")) is not None
320345
]
321346
avg_outperformance_6m = (
322347
sum(outperformance_6m) / len(outperformance_6m)

macro_agents/src/macro_agents/defs/backtesting/backtest_investment_recommendations.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
from datetime import datetime
23

34
import dagster as dg
@@ -23,6 +24,14 @@
2324
from macro_agents.defs.resources.bigquery_warehouse import BigQueryWarehouseResource
2425

2526

27+
def _content_as_text(value: object) -> str:
28+
if value is None:
29+
return ""
30+
if isinstance(value, str):
31+
return value
32+
return json.dumps(value, default=str)
33+
34+
2635
def get_latest_backtest_economy_state_analysis(
2736
md_resource: BigQueryWarehouseResource,
2837
backtest_date: str,
@@ -414,7 +423,9 @@ def backtest_generate_investment_recommendations(
414423
)
415424

416425
first_result = all_results[0]
417-
recommendations_content = first_result.get("recommendations_content") or ""
426+
recommendations_content = _content_as_text(
427+
first_result.get("recommendations_content")
428+
)
418429
recommendations_summary = (
419430
extract_recommendations_summary(recommendations_content)
420431
if recommendations_content

macro_agents/src/macro_agents/defs/utils/sec_text_extractor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,9 @@ def extract_sections(
265265
# TOC entries appear first in the document, actual section content appears later
266266
last_occurrence: dict[str, dict] = {}
267267
for pos in section_positions:
268-
last_occurrence[pos["key"]] = pos
268+
section_key = pos["key"]
269+
if isinstance(section_key, str):
270+
last_occurrence[section_key] = pos
269271

270272
# Convert back to list and sort by position
271273
unique_positions = sorted(last_occurrence.values(), key=lambda x: x["start"])

0 commit comments

Comments
 (0)