mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-26 22:42:40 +03:00
style: normalise blank lines between definitions
- two between top-level definitions, one between methods, none doubled inside a body
This commit is contained in:
@@ -309,6 +309,7 @@ def select_deep_thinking_agent(provider, default=None) -> str:
|
||||
"""Select deep thinking llm engine using an interactive selection."""
|
||||
return _select_model(provider, "deep", default)
|
||||
|
||||
|
||||
def _llm_provider_table() -> list[tuple[str, str, str | None]]:
|
||||
"""(display_name, provider_key, base_url) for every supported provider.
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ def test_existing_key_file_is_tightened_before_writing(monkeypatch, prompts, tmp
|
||||
assert "OTHER=1" in env.read_text()
|
||||
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name == "nt", reason="POSIX file modes")
|
||||
def test_read_only_key_file_is_still_updated(monkeypatch, prompts, tmp_path):
|
||||
env = tmp_path / ".env"
|
||||
|
||||
@@ -58,8 +58,6 @@ def _bare_graph(tmpdir, *, enabled=True):
|
||||
return g
|
||||
|
||||
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_disabled_is_a_noop():
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
|
||||
@@ -103,7 +103,6 @@ class TestCheckpointResume(unittest.TestCase):
|
||||
|
||||
self.assertEqual(result["count"], 11)
|
||||
|
||||
|
||||
def test_different_date_starts_fresh(self):
|
||||
"""A different date must NOT resume from an existing checkpoint."""
|
||||
global _should_crash
|
||||
|
||||
@@ -15,6 +15,7 @@ from tradingagents.llm_clients.factory import _coerce_max_retries, build_llm_kwa
|
||||
|
||||
# --- coercion / validation -------------------------------------------------
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize("value,expected", [(0, 0), (2, 2), (10, 10), ("6", 6)])
|
||||
def test_coerce_accepts_non_negative_ints_and_numeric_strings(value, expected):
|
||||
|
||||
@@ -17,6 +17,7 @@ from tradingagents.llm_clients.factory import _coerce_max_tokens, build_llm_kwar
|
||||
|
||||
# --- coercion / validation -------------------------------------------------
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize("value,expected", [(1, 1), (8192, 8192), ("4096", 4096)])
|
||||
def test_coerce_accepts_positive_ints_and_numeric_strings(value, expected):
|
||||
|
||||
@@ -106,7 +106,6 @@ def test_global_news_empty_after_filter_is_informative(monkeypatch):
|
||||
assert "unavailable" in out and "not an absence" in out
|
||||
|
||||
|
||||
|
||||
def _ticker_with(articles, monkeypatch):
|
||||
class FakeTicker:
|
||||
def __init__(self, *a, **k):
|
||||
@@ -162,7 +161,6 @@ def test_coverage_gap_boundaries(dates, expect_gap):
|
||||
assert "unavailable for 2026-05-01..2026-05-08" in out and "not an absence" in out
|
||||
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_ticker_news_empty_feed_for_a_past_window_is_unavailable(monkeypatch):
|
||||
_ticker_with([], monkeypatch)
|
||||
|
||||
@@ -30,6 +30,7 @@ def _stamp(path, ts):
|
||||
|
||||
# --- date normalization -----------------------------------------------------
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_normalize_dates_strips_tz_and_normalizes_to_midnight():
|
||||
aware = pd.Series(pd.to_datetime(
|
||||
|
||||
@@ -251,7 +251,6 @@ def test_posts_from_an_unrequested_or_unnamed_subreddit_are_not_dropped():
|
||||
assert "NO LABEL" in out
|
||||
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_each_subreddit_keeps_its_own_quota():
|
||||
busy = [{"title": f"A{i}", "created_utc": None, "selftext": "", "subreddit": "a"} for i in range(9)]
|
||||
|
||||
@@ -172,7 +172,6 @@ def test_reddit_live_empty_feed_is_a_real_absence(monkeypatch):
|
||||
assert "unavailable" not in out
|
||||
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch):
|
||||
monkeypatch.setattr(stocktwits, "urlopen", lambda *a, **k: _JsonResp({"messages": []}))
|
||||
@@ -180,7 +179,6 @@ def test_stocktwits_empty_stream_for_a_past_window_is_unavailable(monkeypatch):
|
||||
assert "unavailable" in out and "not an absence" in out
|
||||
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_reddit_window_straddling_the_lookback_is_unavailable(monkeypatch):
|
||||
# Ten days ago through five days ago: the week-long search never reaches the
|
||||
|
||||
@@ -156,6 +156,7 @@ VENDOR_METHODS = {
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_category_for_method(method: str) -> str:
|
||||
"""Get the category that contains the specified method."""
|
||||
for category, info in TOOLS_CATEGORIES.items():
|
||||
@@ -163,6 +164,7 @@ def get_category_for_method(method: str) -> str:
|
||||
return category
|
||||
raise ValueError(f"Method '{method}' not found in any category")
|
||||
|
||||
|
||||
def get_vendor(category: str, method: str = None) -> str:
|
||||
"""Get the configured vendor for a data category or specific tool method.
|
||||
Tool-level configuration takes precedence over category-level.
|
||||
@@ -178,6 +180,7 @@ def get_vendor(category: str, method: str = None) -> str:
|
||||
# Fall back to category-level configuration
|
||||
return config.get("data_vendors", {}).get(category, "default")
|
||||
|
||||
|
||||
def route_to_vendor(method: str, *args, **kwargs):
|
||||
"""Route method calls to appropriate vendor implementation with fallback support."""
|
||||
category = get_category_for_method(method)
|
||||
|
||||
+3
-1
@@ -34,6 +34,7 @@ def get_api_key() -> str:
|
||||
)
|
||||
return api_key
|
||||
|
||||
|
||||
def format_datetime_for_api(date_input, end_of_day: bool = False) -> str:
|
||||
"""Convert various date formats to the YYYYMMDDTHHMM Alpha Vantage expects.
|
||||
|
||||
@@ -60,10 +61,12 @@ def format_datetime_for_api(date_input, end_of_day: bool = False) -> str:
|
||||
else:
|
||||
raise ValueError(f"Date must be string or datetime object, got {type(date_input)}")
|
||||
|
||||
|
||||
class AlphaVantageRateLimitError(VendorRateLimitError):
|
||||
"""Raised when the Alpha Vantage API rate limit is exceeded."""
|
||||
pass
|
||||
|
||||
|
||||
def _make_api_request(function_name: str, params: dict) -> dict | str:
|
||||
"""Helper function to make API requests and handle responses.
|
||||
|
||||
@@ -119,7 +122,6 @@ def _make_api_request(function_name: str, params: dict) -> dict | str:
|
||||
return response_text
|
||||
|
||||
|
||||
|
||||
def _filter_csv_by_date_range(csv_data: str, start_date: str, end_date: str) -> str:
|
||||
"""
|
||||
Filter CSV data to include only rows within the specified date range.
|
||||
|
||||
@@ -32,6 +32,7 @@ def get_news(ticker, start_date, end_date) -> dict[str, str] | str:
|
||||
|
||||
return _make_api_request("NEWS_SENTIMENT", params)
|
||||
|
||||
|
||||
def get_global_news(curr_date, look_back_days: int | None = None, limit: int | None = None) -> dict[str, str] | str:
|
||||
"""Returns global market news & sentiment data without ticker-specific filtering.
|
||||
|
||||
|
||||
+1
@@ -64,6 +64,7 @@ def _coverage_dates(posts) -> list:
|
||||
dates.append(datetime.now(timezone.utc) - _SEARCH_LOOKBACK)
|
||||
return dates
|
||||
|
||||
|
||||
_RSS = "https://www.reddit.com/r/{sub}/search.rss?{qs}"
|
||||
# A descriptive, identified User-Agent (per Reddit's API etiquette). Reddit
|
||||
# blocks generic/anonymous tokens like bare "Mozilla/5.0" or "curl/…" but
|
||||
|
||||
+1
-1
@@ -69,6 +69,7 @@ def get_YFin_data_online(
|
||||
|
||||
return header + csv_string
|
||||
|
||||
|
||||
def get_stock_stats_indicators_window(
|
||||
symbol: Annotated[str, "ticker symbol of the company"],
|
||||
indicator: Annotated[str, "technical indicator to get the analysis and report of"],
|
||||
@@ -269,7 +270,6 @@ def get_stockstats_indicator(
|
||||
return str(indicator_value)
|
||||
|
||||
|
||||
|
||||
def get_closes(symbol: str, start_date: str, end_date: str) -> pd.Series:
|
||||
"""Daily closes from ``start_date`` up to, not including, ``end_date``."""
|
||||
canonical = normalize_symbol(symbol)
|
||||
|
||||
Reference in New Issue
Block a user