Repository: deepset-ai/haystack

Issue:
Add `max_retries` and `timeout` params to all `AzureOpenAI` classes
**Is your feature request related to a problem? Please describe.**

Currently all `OpenAI` related classes (e.g. `OpenAIDocumentEmbedder`, `OpenAIChatGenerator`) can be initialised by setting `max_retries` and `timeout` params.

The corresponding `AzureOpenAI` don't always have the same params.

**Describe the solution you'd like**

It would be nice to have these params in the `AzureOpenAI` classes

**Describe alternatives you've considered**

Subclass `AzureOpenAI` and create custom components.

**Additional context**

cc @anakin87 :)

Discussion:
coveralls: ## Pull Request Test Coverage Report for [Build 9839157221](https://coveralls.io/builds/68510940)

### Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

- For more information on this, see <a target="_blank" href="https://docs.coveralls.io/build-types#tracking-coverage-changes-with-pull_request-builds">Tracking coverage changes with pull request builds</a>.
- To avoid this issue with future PRs, see these <a target="_blank" href="https://docs.coveralls.io/build-types#recommended-ci-configurations">Recommended CI Configurations</a>.
- For a quick fix, <a target="_blank" href="https://github.blog/changelog/2022-02-03-more-ways-to-keep-your-pull-request-branch-up-to-date/#update-your-pull-request-branch-by-rebasing">rebase this PR at GitHub</a>. Your next report should be accurate.

### Details

* **0** of **0**   changed or added relevant lines in **0** files are covered.
* **6** unchanged lines in **2** files lost coverage.
* Overall coverage increased (+**0.005%**) to **90.008%**

---


|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [components/generators/azure.py](https://coveralls.io/builds/68510940/source?filename=components%2Fgenerators%2Fazure.py#L115) | 3 | 92.5% |
| [components/generators/chat/azure.py](https://coveralls.io/builds/68510940/source?filename=components%2Fgenerators%2Fchat%2Fazure.py#L132) | 3 | 92.31% |
<!-- | **Total:** | **6** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/68510940/badge)](https://coveralls.io/builds/68510940) |
| :-- | --: |
| Change from base [Build 9804009410](https://coveralls.io/builds/68478044): |  0.005% |
| Covered Lines: | 6774 |
| Relevant Lines: | 7526 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/haystack/components/generators/chat/azure.py b/haystack/components/generators/chat/azure.py
index 06da6095..9ef4311e 100644
--- a/haystack/components/generators/chat/azure.py
+++ b/haystack/components/generators/chat/azure.py
@@ -81,6 +81,7 @@ class AzureOpenAIChatGenerator(OpenAIChatGenerator):
         organization: Optional[str] = None,
         streaming_callback: Optional[Callable[[StreamingChunk], None]] = None,
         timeout: Optional[float] = None,
+        max_retries: Optional[int] = None,
         generation_kwargs: Optional[Dict[str, Any]] = None,
     ):
         """
@@ -95,6 +96,10 @@ class AzureOpenAIChatGenerator(OpenAIChatGenerator):
         [production best practices](https://platform.openai.com/docs/guides/production-best-practices/setting-up-your-organization).
         :param streaming_callback: A callback function that is called when a new token is received from the stream.
             The callback function accepts StreamingChunk as an argument.
+        :param timeout: The timeout in seconds to be passed to the underlying `AzureOpenAI` client, if not set it is
+            inferred from the `OPENAI_TIMEOUT` environment variable or set to 30.
+        :param max_retries: Maximum retries to establish a connection with AzureOpenAI if it returns an internal error,
+            if not set it is inferred from the `OPENAI_MAX_RETRIES` environment variable or set to 5.
         :param generation_kwargs: Other parameters to use for the model. These parameters are all sent directly to
             the OpenAI endpoint. See OpenAI [documentation](https://platform.openai.com/docs/api-reference/chat) for
             more details.
@@ -140,7 +145,8 @@ class AzureOpenAIChatGenerator(OpenAIChatGenerator):
         self.azure_deployment = azure_deployment
         self.organization = organization
         self.model = azure_deployment or "gpt-35-turbo"
-        self.timeout = timeout
+        self.timeout = timeout or float(os.environ.get("OPENAI_TIMEOUT", 30.0))
+        self.max_retries = max_retries or int(os.environ.get("OPENAI_MAX_RETRIES", 5))
 
         self.client = AzureOpenAI(
             api_version=api_version,
@@ -149,6 +155,8 @@ class AzureOpenAIChatGenerator(OpenAIChatGenerator):
             api_key=api_key.resolve_value() if api_key is not None else None,
             azure_ad_token=azure_ad_token.resolve_value() if azure_ad_token is not None else None,
             organization=organization,
+            timeout=self.timeout,
+            max_retries=self.max_retries,
         )
 
     def to_dict(self) -> Dict[str, Any]:
@@ -168,6 +176,7 @@ class AzureOpenAIChatGenerator(OpenAIChatGenerator):
             streaming_callback=callback_name,
             generation_kwargs=self.generation_kwargs,
             timeout=self.timeout,
+            max_retries=self.max_retries,
             api_key=self.api_key.to_dict() if self.api_key is not None else None,
             azure_ad_token=self.azure_ad_token.to_dict() if self.azure_ad_token is not None else None,
         )
diff --git a/releasenotes/notes/max_retries-for-AzureOpenAIChatGenerator-9e49b4c7bec5c72b.yaml b/releasenotes/notes/max_retries-for-AzureOpenAIChatGenerator-9e49b4c7bec5c72b.yaml
new file mode 100644
index 00000000..888a53a8
--- /dev/null
+++ b/releasenotes/notes/max_retries-for-AzureOpenAIChatGenerator-9e49b4c7bec5c72b.yaml
@@ -0,0 +1,4 @@
+---
+enhancements:
+  - |
+    Add `max_retries` and `timeout` parameters to the AzureOpenAIChatGenerator initializations.


Test patch:
diff --git a/test/components/generators/chat/test_azure.py b/test/components/generators/chat/test_azure.py
index 80ffb956..80a290a6 100644
--- a/test/components/generators/chat/test_azure.py
+++ b/test/components/generators/chat/test_azure.py
@@ -55,7 +55,8 @@ class TestOpenAIChatGenerator:
                 "organization": None,
                 "streaming_callback": None,
                 "generation_kwargs": {},
-                "timeout": None,
+                "timeout": 30.0,
+                "max_retries": 5,
             },
         }
 
@@ -66,6 +67,7 @@ class TestOpenAIChatGenerator:
             azure_ad_token=Secret.from_env_var("ENV_VAR1", strict=False),
             azure_endpoint="some-non-existing-endpoint",
             timeout=2.5,
+            max_retries=10,
             generation_kwargs={"max_tokens": 10, "some_test_param": "test-params"},
         )
         data = component.to_dict()
@@ -80,6 +82,7 @@ class TestOpenAIChatGenerator:
                 "organization": None,
                 "streaming_callback": None,
                 "timeout": 2.5,
+                "max_retries": 10,
                 "generation_kwargs": {"max_tokens": 10, "some_test_param": "test-params"},
             },
         }