From b88bd8b327b5f1ce3b9ebb76b53c3798fd927531 Mon Sep 17 00:00:00 2001 From: 0x7d0 Date: Fri, 10 Oct 2025 13:56:45 +0200 Subject: [PATCH] fix: Add .env loading to test and fix PDF text parsing in portfolio reports --- cli/portfolio_pdf_generator.py | 34 ++++++++++++++++++++++++++++++++-- test_portfolio_analysis.py | 6 ++++++ 2 files changed, 38 insertions(+), 2 deletions(-) mode change 100644 => 100755 test_portfolio_analysis.py diff --git a/cli/portfolio_pdf_generator.py b/cli/portfolio_pdf_generator.py index 776bbc18..4f2aab88 100644 --- a/cli/portfolio_pdf_generator.py +++ b/cli/portfolio_pdf_generator.py @@ -1,6 +1,7 @@ """PDF report generator for portfolio analysis results.""" import datetime import io +import re from pathlib import Path from typing import Dict, Any @@ -291,6 +292,25 @@ def generate_portfolio_pdf_report( elements.append(t) elements.append(Spacer(1, 30)) + # Helper function to clean text for PDF + def clean_text(text: str) -> str: + """Clean text and properly escape for reportlab.""" + # Escape special XML/HTML characters first + text = text.replace('&', '&') + text = text.replace('<', '<') + text = text.replace('>', '>') + + # Convert markdown bold (**text**) to HTML bold + text = re.sub(r'\*\*(.+?)\*\*', r'\1', text) + + # Convert markdown italic (*text*) to HTML italic + text = re.sub(r'(?\1', text) + + # Remove markdown headers + text = re.sub(r'^#{1,6}\s+', '', text, flags=re.MULTILINE) + + return text + # Generate charts print("Generating portfolio charts...") charts = generate_portfolio_charts(result) @@ -329,7 +349,12 @@ def generate_portfolio_pdf_report( elements.append(Spacer(1, 12)) for line in result.portfolio_recommendation.split('\n'): if line.strip(): - elements.append(Paragraph(line.replace('#', '').replace('**', '').replace('**', ''), styles['CustomBody'])) + cleaned_line = clean_text(line) + try: + elements.append(Paragraph(cleaned_line, styles['CustomBody'])) + except Exception as e: + print(f"Warning: Could not parse line, adding as plain text: {e}") + elements.append(Paragraph(cleaned_line.replace('<', '<').replace('>', '>'), styles['CustomBody'])) # Risk Assessment elements.append(PageBreak()) @@ -338,7 +363,12 @@ def generate_portfolio_pdf_report( elements.append(Spacer(1, 12)) for line in result.risk_assessment.split('\n'): if line.strip(): - elements.append(Paragraph(line.replace('#', '').replace('**', '').replace('**', ''), styles['CustomBody'])) + cleaned_line = clean_text(line) + try: + elements.append(Paragraph(cleaned_line, styles['CustomBody'])) + except Exception as e: + print(f"Warning: Could not parse line, adding as plain text: {e}") + elements.append(Paragraph(cleaned_line.replace('<', '<').replace('>', '>'), styles['CustomBody'])) # Rebalancing Suggestions if result.rebalancing_suggestions: diff --git a/test_portfolio_analysis.py b/test_portfolio_analysis.py old mode 100644 new mode 100755 index 56cd0d3b..008fbb12 --- a/test_portfolio_analysis.py +++ b/test_portfolio_analysis.py @@ -1,5 +1,11 @@ +#!/usr/bin/env python3 """Test portfolio analysis functionality.""" from pathlib import Path +from dotenv import load_dotenv + +# Load environment variables +load_dotenv() + from tradingagents.portfolio.models import Portfolio, Position from tradingagents.portfolio.portfolio_graph import PortfolioAnalysisGraph from tradingagents.default_config import DEFAULT_CONFIG