diff --git a/tests/tools/test_pixabay_per_page_clamp.py b/tests/tools/test_pixabay_per_page_clamp.py new file mode 100644 index 00000000..a05a496e --- /dev/null +++ b/tests/tools/test_pixabay_per_page_clamp.py @@ -0,0 +1,62 @@ +"""Pixabay rejects per_page outside 3-200 with HTTP 400, so every +Pixabay caller must clamp before building the request.""" + +import requests + +from tools.graphics.pixabay_image import PixabayImage +from tools.video.pixabay_video import PixabayVideo +from tools.video.stock_sources.base import SearchFilters +from tools.video.stock_sources.pixabay_video import PixabayVideoSource + + +class _FakeResponse: + def raise_for_status(self): + pass + + def json(self): + return {"hits": [], "total": 0} + + +def _capture_get(captured): + def fake_get(url, params=None, timeout=None, **kwargs): + captured["params"] = params + return _FakeResponse() + + return fake_get + + +def test_pixabay_video_tool_clamps_per_page(monkeypatch): + monkeypatch.setenv("PIXABAY_API_KEY", "test-key") + captured = {} + monkeypatch.setattr(requests, "get", _capture_get(captured)) + + PixabayVideo().execute({"query": "sky", "per_page": 1}) + assert captured["params"]["per_page"] == 3 + + PixabayVideo().execute({"query": "sky", "per_page": 500}) + assert captured["params"]["per_page"] == 200 + + +def test_pixabay_image_tool_clamps_per_page(monkeypatch): + monkeypatch.setenv("PIXABAY_API_KEY", "test-key") + captured = {} + monkeypatch.setattr(requests, "get", _capture_get(captured)) + + PixabayImage().execute({"query": "sky", "per_page": 1}) + assert captured["params"]["per_page"] == 3 + + PixabayImage().execute({"query": "sky", "per_page": 500}) + assert captured["params"]["per_page"] == 200 + + +def test_pixabay_stock_source_clamps_per_page(monkeypatch): + monkeypatch.setenv("PIXABAY_API_KEY", "test-key") + captured = {} + monkeypatch.setattr(requests, "get", _capture_get(captured)) + + source = PixabayVideoSource() + source.search("sky", SearchFilters(per_page=1)) + assert captured["params"]["per_page"] == 3 + + source.search("sky", SearchFilters(per_page=500)) + assert captured["params"]["per_page"] == 200 diff --git a/tools/graphics/pixabay_image.py b/tools/graphics/pixabay_image.py index cba51aab..b2e2da98 100644 --- a/tools/graphics/pixabay_image.py +++ b/tools/graphics/pixabay_image.py @@ -127,7 +127,8 @@ class PixabayImage(BaseTool): params: dict[str, Any] = { "key": api_key, "q": query, - "per_page": inputs.get("per_page", 5), + # Pixabay rejects per_page outside 3-200 with HTTP 400 + "per_page": max(3, min(inputs.get("per_page", 5), 200)), "page": inputs.get("page", 1), "safesearch": str(inputs.get("safesearch", True)).lower(), } diff --git a/tools/video/pixabay_video.py b/tools/video/pixabay_video.py index 75963374..a8a8da20 100644 --- a/tools/video/pixabay_video.py +++ b/tools/video/pixabay_video.py @@ -130,7 +130,8 @@ class PixabayVideo(BaseTool): params: dict[str, Any] = { "key": api_key, "q": query, - "per_page": inputs.get("per_page", 5), + # Pixabay rejects per_page outside 3-200 with HTTP 400 + "per_page": max(3, min(inputs.get("per_page", 5), 200)), "page": inputs.get("page", 1), "safesearch": str(inputs.get("safesearch", True)).lower(), }