diff --git a/haystack/components/generators/openai_image_generator.py b/haystack/components/generators/openai_image_generator.py index 6605f991524..de690416b88 100644 --- a/haystack/components/generators/openai_image_generator.py +++ b/haystack/components/generators/openai_image_generator.py @@ -230,6 +230,8 @@ def to_dict(self) -> dict[str, Any]: api_key=self.api_key, api_base_url=self.api_base_url, organization=self.organization, + timeout=self.timeout, + max_retries=self.max_retries, http_client_kwargs=self.http_client_kwargs, ) diff --git a/releasenotes/notes/openai-image-generator-serialize-client-settings-3d7c1a9e5b40f286.yaml b/releasenotes/notes/openai-image-generator-serialize-client-settings-3d7c1a9e5b40f286.yaml new file mode 100644 index 00000000000..93062054133 --- /dev/null +++ b/releasenotes/notes/openai-image-generator-serialize-client-settings-3d7c1a9e5b40f286.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + ``OpenAIImageGenerator.to_dict()`` now serializes ``timeout`` and ``max_retries``, like the other OpenAI-backed + components already do. Previously both were dropped, so a pipeline that was serialized and loaded back silently + fell back to the ``OPENAI_TIMEOUT``/``OPENAI_MAX_RETRIES`` environment variables or to the 30 seconds and 5 + retries defaults. diff --git a/test/components/generators/test_openai_image_generator.py b/test/components/generators/test_openai_image_generator.py index 65abe223da6..769c5fdf8d4 100644 --- a/test/components/generators/test_openai_image_generator.py +++ b/test/components/generators/test_openai_image_generator.py @@ -88,6 +88,8 @@ def test_to_dict(self): "api_key": {"type": "env_var", "env_vars": ["OPENAI_API_KEY"], "strict": True}, "api_base_url": None, "organization": None, + "timeout": None, + "max_retries": None, "http_client_kwargs": None, }, } @@ -114,6 +116,8 @@ def test_to_dict_with_params(self): "api_key": {"type": "env_var", "env_vars": ["EXAMPLE_API_KEY"], "strict": True}, "api_base_url": "https://api.openai.com", "organization": "test-org", + "timeout": 60.0, + "max_retries": 10, "http_client_kwargs": {"proxy": "http://localhost:8080"}, }, } @@ -128,6 +132,8 @@ def test_from_dict(self): "api_key": {"type": "env_var", "env_vars": ["OPENAI_API_KEY"], "strict": True}, "api_base_url": None, "organization": None, + "timeout": 60.0, + "max_retries": 10, "http_client_kwargs": None, }, } @@ -136,6 +142,8 @@ def test_from_dict(self): assert generator.quality == "auto" assert generator.size == "1024x1024" assert generator.api_key.to_dict() == {"type": "env_var", "env_vars": ["OPENAI_API_KEY"], "strict": True} + assert pytest.approx(generator.timeout) == 60.0 + assert generator.max_retries == 10 assert generator.http_client_kwargs is None def test_from_dict_default_params(self): @@ -163,6 +171,12 @@ def test_run(self, mock_image_response): assert response["images"] == ["test-b64-json"] assert response["revised_prompt"] == "test-prompt" + def test_to_dict_from_dict_roundtrip_keeps_client_kwargs(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("OPENAI_API_KEY", "test-api-key") + generator = OpenAIImageGenerator(timeout=60.0, max_retries=10) + deserialized = OpenAIImageGenerator.from_dict(generator.to_dict()) + assert deserialized._client_kwargs() == generator._client_kwargs() + @pytest.mark.skipif( not os.environ.get("OPENAI_API_KEY", None), reason="Export an env var called OPENAI_API_KEY containing the OpenAI API key to run this test.",