diff --git a/src/tradegraph_financial_advisor/agents/financial_agent.py b/src/tradegraph_financial_advisor/agents/financial_agent.py index b6c26ed..aeae9ec 100644 --- a/src/tradegraph_financial_advisor/agents/financial_agent.py +++ b/src/tradegraph_financial_advisor/agents/financial_agent.py @@ -62,7 +62,7 @@ async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]: else: market_data = await self._get_equity_market_data(symbol) symbol_data["market_data"] = ( - market_data.dict() if market_data else None + market_data.model_dump() if market_data else None ) if include_financials: @@ -73,7 +73,7 @@ async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]: symbol, market_data ) symbol_data["financials"] = ( - financials.dict() if financials else None + financials.model_dump() if financials else None ) if include_technical: @@ -82,7 +82,7 @@ async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]: else: technical = await self._get_equity_technical_indicators(symbol) symbol_data["technical_indicators"] = ( - technical.dict() if technical else None + technical.model_dump() if technical else None ) results[symbol] = symbol_data diff --git a/src/tradegraph_financial_advisor/agents/news_agent.py b/src/tradegraph_financial_advisor/agents/news_agent.py index ebd1d15..7de2f48 100644 --- a/src/tradegraph_financial_advisor/agents/news_agent.py +++ b/src/tradegraph_financial_advisor/agents/news_agent.py @@ -54,7 +54,7 @@ async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]: analyzed_articles = await self._analyze_articles(all_articles, symbols) return { - "articles": [article.dict() for article in analyzed_articles], + "articles": [article.model_dump() for article in analyzed_articles], "total_count": len(analyzed_articles), "sources": settings.news_sources, "analysis_timestamp": datetime.now().isoformat(), diff --git a/src/tradegraph_financial_advisor/agents/recommendation_engine.py b/src/tradegraph_financial_advisor/agents/recommendation_engine.py index dde60f8..8a3c734 100644 --- a/src/tradegraph_financial_advisor/agents/recommendation_engine.py +++ b/src/tradegraph_financial_advisor/agents/recommendation_engine.py @@ -62,11 +62,13 @@ async def execute(self, input_data: Dict[str, Any]) -> Dict[str, Any]: ) return { - "individual_recommendations": [rec.dict() for rec in recommendations], + "individual_recommendations": [rec.model_dump() for rec in recommendations], "portfolio_recommendation": ( - portfolio_recommendation.dict() if portfolio_recommendation else None + portfolio_recommendation.model_dump() + if portfolio_recommendation + else None ), - "alerts": [alert.dict() for alert in alerts], + "alerts": [alert.model_dump() for alert in alerts], "generation_timestamp": datetime.now().isoformat(), } diff --git a/src/tradegraph_financial_advisor/config/settings.py b/src/tradegraph_financial_advisor/config/settings.py index 1f3c0fa..6311879 100644 --- a/src/tradegraph_financial_advisor/config/settings.py +++ b/src/tradegraph_financial_advisor/config/settings.py @@ -3,20 +3,24 @@ from dotenv import load_dotenv from pydantic import Field -from pydantic_settings import BaseSettings +from pydantic_settings import BaseSettings, SettingsConfigDict load_dotenv() class Settings(BaseSettings): - openai_api_key: str = Field("", env="OPENAI_API_KEY") - finnhub_api_key: str = Field("", env="FINNHUB_API_KEY") - alpha_vantage_api_key: Optional[str] = Field(None, env="ALPHA_VANTAGE_API_KEY") - financial_data_api_key: Optional[str] = Field(None, env="FINANCIAL_DATA_API_KEY") + model_config = SettingsConfigDict( + env_file=".env", case_sensitive=False, extra="ignore" + ) + + openai_api_key: str = Field(default="") + finnhub_api_key: str = Field(default="") + alpha_vantage_api_key: Optional[str] = Field(default=None) + financial_data_api_key: Optional[str] = Field(default=None) - log_level: str = Field("INFO", env="LOG_LEVEL") - max_concurrent_agents: int = Field(5, env="MAX_CONCURRENT_AGENTS") - analysis_timeout_seconds: int = Field(30, env="ANALYSIS_TIMEOUT_SECONDS") + log_level: str = Field(default="INFO") + max_concurrent_agents: int = Field(default=5) + analysis_timeout_seconds: int = Field(default=30) news_sources: List[str] = Field( default_factory=lambda: [ @@ -25,8 +29,7 @@ class Settings(BaseSettings): "yahoo-finance", "marketwatch", "cnbc", - ], - env="NEWS_SOURCES", + ] ) analysis_depth: str = Field("detailed", env="ANALYSIS_DEPTH") default_portfolio_size: float = Field(100000.0, env="DEFAULT_PORTFOLIO_SIZE") diff --git a/src/tradegraph_financial_advisor/main.py b/src/tradegraph_financial_advisor/main.py index 4588d8b..2397a8b 100644 --- a/src/tradegraph_financial_advisor/main.py +++ b/src/tradegraph_financial_advisor/main.py @@ -194,11 +194,21 @@ async def quick_analysis( workflow_results, "sentiment_analysis", {} ) + portfolio_recommendation_payload = ( + portfolio_recommendation.dict() + if hasattr(portfolio_recommendation, "dict") + else portfolio_recommendation + ) + return { "analysis_type": "basic", "symbols": symbols, "recommendations": recommendations, - "portfolio_recommendation": portfolio_recommendation, + "portfolio_recommendation": ( + portfolio_recommendation_payload + if portfolio_recommendation_payload + else None + ), "sentiment_analysis": sentiment_analysis, "analysis_timestamp": datetime.now().isoformat(), } diff --git a/tests/unit/test_models.py b/tests/unit/test_models.py index 56e0945..5ad6f43 100644 --- a/tests/unit/test_models.py +++ b/tests/unit/test_models.py @@ -312,7 +312,7 @@ def test_model_serialization(self): ) # Test dict conversion - rec_dict = recommendation.dict() + rec_dict = recommendation.model_dump() assert rec_dict["symbol"] == "AAPL" assert rec_dict["recommendation"] == "buy" assert rec_dict["risk_level"] == "medium" @@ -320,7 +320,7 @@ def test_model_serialization(self): # Test JSON serialization import json - json_str = recommendation.json() + json_str = recommendation.model_dump_json() parsed = json.loads(json_str) assert parsed["symbol"] == "AAPL"