From 9f1831005f50a7168a90a714c28828d97d335757 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 19 Aug 2026 11:26:41 +0000 Subject: [PATCH] Remove hardcoded API token for Fast.com Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com> --- src/netsleuth/config.py | 1 + src/netsleuth/speed.py | 4 +++- tests/test_speed_fastcom.py | 10 +++++----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/netsleuth/config.py b/src/netsleuth/config.py index 46e81c0..457ab1c 100644 --- a/src/netsleuth/config.py +++ b/src/netsleuth/config.py @@ -78,6 +78,7 @@ class Speedtest(BaseModel): upload_sizes_bytes: list[int] = Field(default_factory=lambda: [1_000_000, 5_000_000]) cloudflare_base_url: str = "https://speed.cloudflare.com" fastcom_api_url: str = "https://api.fast.com/netflix/speedtest/v2" + fastcom_api_token: str | None = None ndt7_locate_url: str = "https://locate.measurementlab.net/v2/nearest/ndt/ndt7" bufferbloat_probe_interval_seconds: float = 0.2 diff --git a/src/netsleuth/speed.py b/src/netsleuth/speed.py index 77f42f0..37730b9 100644 --- a/src/netsleuth/speed.py +++ b/src/netsleuth/speed.py @@ -174,9 +174,11 @@ async def tier_cloudflare(client: httpx.AsyncClient, cfg: Speedtest, timeout: fl async def tier_fastcom(client: httpx.AsyncClient, cfg: Speedtest, timeout: float) -> SpeedResult: + if not cfg.fastcom_api_token: + raise RuntimeError("Fast.com API token not configured") response = await client.get( cfg.fastcom_api_url, - params={"https": "true", "token": "YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm", "urlCount": "3"}, + params={"https": "true", "token": cfg.fastcom_api_token, "urlCount": "3"}, timeout=timeout, ) response.raise_for_status() diff --git a/tests/test_speed_fastcom.py b/tests/test_speed_fastcom.py index fe57022..38ebef0 100644 --- a/tests/test_speed_fastcom.py +++ b/tests/test_speed_fastcom.py @@ -6,7 +6,7 @@ from netsleuth.speed import tier_fastcom async def test_tier_fastcom_happy_path(httpx_mock): - config = Speedtest() + config = Speedtest(fastcom_api_token="YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm") api_url = config.fastcom_api_url httpx_mock.add_response( @@ -42,7 +42,7 @@ async def test_tier_fastcom_happy_path(httpx_mock): async def test_tier_fastcom_no_targets(httpx_mock): - config = Speedtest() + config = Speedtest(fastcom_api_token="YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm") api_url = config.fastcom_api_url httpx_mock.add_response( @@ -60,7 +60,7 @@ async def test_tier_fastcom_no_targets(httpx_mock): async def test_tier_fastcom_missing_urls(httpx_mock): - config = Speedtest() + config = Speedtest(fastcom_api_token="YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm") api_url = config.fastcom_api_url httpx_mock.add_response( @@ -89,7 +89,7 @@ async def test_tier_fastcom_missing_urls(httpx_mock): async def test_tier_fastcom_api_error(httpx_mock): - config = Speedtest() + config = Speedtest(fastcom_api_token="YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm") api_url = config.fastcom_api_url httpx_mock.add_response( @@ -105,7 +105,7 @@ async def test_tier_fastcom_api_error(httpx_mock): async def test_tier_fastcom_download_error(httpx_mock): - config = Speedtest() + config = Speedtest(fastcom_api_token="YXNkZmFzZGxmbnNkYWZoYXNkZmhrYWxm") api_url = config.fastcom_api_url httpx_mock.add_response(