From fe600f49f365a9a78225deb37669ed4d892ab167 Mon Sep 17 00:00:00 2001 From: Abderrahmane El Aoudi <220033760+A2ELAOUDI@users.noreply.github.com> Date: Fri, 30 Oct 2026 10:34:47 +0000 Subject: [PATCH] chore: enforce ruff docstring rules in remaining integrations Adds D102, D103, D205, D209, D213, D417, D419 to the ruff config of amazon_sagemaker, arcadedb, azure_doc_intelligence, azure_form_recognizer and litellm, and fixes the resulting docstring violations. Part of #2947 --- integrations/amazon_sagemaker/pyproject.toml | 9 ++++++++- .../generators/amazon_sagemaker/sagemaker.py | 1 + integrations/arcadedb/pyproject.toml | 3 ++- .../document_stores/arcadedb/document_store.py | 11 ++++++++--- .../azure_doc_intelligence/pyproject.toml | 7 +++++++ integrations/azure_form_recognizer/pyproject.toml | 7 +++++++ integrations/litellm/pyproject.toml | 5 ++++- .../generators/litellm/chat/chat_generator.py | 15 ++++++++++----- 8 files changed, 47 insertions(+), 11 deletions(-) diff --git a/integrations/amazon_sagemaker/pyproject.toml b/integrations/amazon_sagemaker/pyproject.toml index 73cae9ae0b..2171c92994 100644 --- a/integrations/amazon_sagemaker/pyproject.toml +++ b/integrations/amazon_sagemaker/pyproject.toml @@ -93,6 +93,13 @@ select = [ "ARG", "B", "C", + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D205", # 1 blank line required between summary line and description + "D209", # Closing triple quotes go to new line + "D213", # summary lines must be positioned on the second physical line of the docstring + "D417", # Missing argument descriptions in the docstring + "D419", # Docstring is empty "DTZ", "E", "EM", @@ -143,7 +150,7 @@ ban-relative-imports = "parents" [tool.ruff.lint.per-file-ignores] # Tests can use magic values, assertions, and relative imports -"tests/**/*" = ["PLR2004", "S101", "TID252", "ANN"] +"tests/**/*" = ["PLR2004", "S101", "TID252", "D", "ANN"] [tool.coverage.run] source = ["haystack_integrations"] diff --git a/integrations/amazon_sagemaker/src/haystack_integrations/components/generators/amazon_sagemaker/sagemaker.py b/integrations/amazon_sagemaker/src/haystack_integrations/components/generators/amazon_sagemaker/sagemaker.py index 966ee4b78d..c174834998 100644 --- a/integrations/amazon_sagemaker/src/haystack_integrations/components/generators/amazon_sagemaker/sagemaker.py +++ b/integrations/amazon_sagemaker/src/haystack_integrations/components/generators/amazon_sagemaker/sagemaker.py @@ -117,6 +117,7 @@ def resolve_secret(secret: Secret | None) -> str | None: def _get_telemetry_data(self) -> dict[str, Any]: """ Returns data that is sent to Posthog for usage analytics. + :returns: A dictionary with the following keys: - `model`: The name of the model. """ diff --git a/integrations/arcadedb/pyproject.toml b/integrations/arcadedb/pyproject.toml index ce826b420d..5698e116be 100644 --- a/integrations/arcadedb/pyproject.toml +++ b/integrations/arcadedb/pyproject.toml @@ -85,7 +85,8 @@ line-length = 120 [tool.ruff.lint] select = [ - "A", "ANN", "ARG", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", + "A", "ANN", "ARG", "B", "C", "D102", "D103", "D205", "D209", "D213", "D417", "D419", + "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N", "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "T", "TID", "UP", "W", "YTT", ] diff --git a/integrations/arcadedb/src/haystack_integrations/document_stores/arcadedb/document_store.py b/integrations/arcadedb/src/haystack_integrations/document_stores/arcadedb/document_store.py index 103c3fabb1..10d1b43f4c 100644 --- a/integrations/arcadedb/src/haystack_integrations/document_stores/arcadedb/document_store.py +++ b/integrations/arcadedb/src/haystack_integrations/document_stores/arcadedb/document_store.py @@ -308,6 +308,7 @@ def sort_key(value: Any) -> tuple[Any, str]: def _get_metadata_projection_documents(self) -> list[dict[str, Any]]: """ Private helper to fetch sample documents for schema inference. + Note: Does not `_ensure_initialized()`. To avoid redundant initialization checks during internal calls, the caller is responsible for ensuring the document store is initialized before invoking this method. @@ -319,6 +320,7 @@ def _get_metadata_projection_documents(self) -> list[dict[str, Any]]: def _infer_metadata_field_type(values: list[Any]) -> str: """ Infers the metadata field type from a list of sampled values. + :param values: A list of raw Python values sampled from the field. :returns: A type string — one of ``"boolean"``, ``"double"``, ``"long"``, or ``"keyword"``. Returns ``"keyword"`` if values are empty or of mixed types. @@ -523,7 +525,8 @@ def update_by_filter(self, filters: dict[str, Any], meta: dict[str, Any]) -> int def count_documents_by_filter(self, filters: dict[str, Any]) -> int: """ - Counts the number of documents matching the provided filter + Counts the number of documents matching the provided filter. + :param filters: The filters to apply to the documents :returns: The number of documents that match the filter """ @@ -545,6 +548,7 @@ def count_documents_by_filter(self, filters: dict[str, Any]) -> int: def count_unique_metadata_by_filter(self, filters: dict[str, Any], metadata_fields: list[str]) -> dict[str, int]: """ Counts unique values for each metadata field in documents matching the provided filters. + :param filters: The filters to apply to the document list. :param metadata_fields: Metadata fields for which to count unique values. :returns: A dictionary where keys are metadata field names and values are the @@ -576,6 +580,7 @@ def count_unique_metadata_by_filter(self, filters: dict[str, Any], metadata_fiel def get_metadata_fields_info(self) -> dict[str, dict[str, str]]: """ Returns the metadata fields and their corresponding types based on sampled documents. + :returns: A dictionary mapping field names to dictionaries with a `type` key. """ self._ensure_initialized() @@ -602,6 +607,7 @@ def get_metadata_fields_info(self) -> dict[str, dict[str, str]]: def get_metadata_field_min_max(self, metadata_field: str) -> dict[str, Any]: """ For a given metadata field, finds its min and max values. + :param metadata_field: The metadata field to inspect. :returns: A dictionary with `min` and `max` keys and their corresponding values. """ @@ -626,8 +632,7 @@ def get_metadata_field_unique_values( filters: dict[str, Any] | None = None, ) -> tuple[list[Any], int]: """ - Retrieves unique values for a field matching a search term or all possible values - if no search term is given. + Retrieves unique values for a field matching a search term, or all values if no search term is given. **Note**: values of different types are kept distinct even when they compare equal in Python, so the int `1`, the float `1.0`, the bool `True` and the str `"1"` are returned as four separate diff --git a/integrations/azure_doc_intelligence/pyproject.toml b/integrations/azure_doc_intelligence/pyproject.toml index fe68535867..cbca4197b4 100644 --- a/integrations/azure_doc_intelligence/pyproject.toml +++ b/integrations/azure_doc_intelligence/pyproject.toml @@ -96,6 +96,13 @@ select = [ "ARG", "B", "C", + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D205", # 1 blank line required between summary line and description + "D209", # Closing triple quotes go to new line + "D213", # summary lines must be positioned on the second physical line of the docstring + "D417", # Missing argument descriptions in the docstring + "D419", # Docstring is empty "DTZ", "E", "EM", diff --git a/integrations/azure_form_recognizer/pyproject.toml b/integrations/azure_form_recognizer/pyproject.toml index a87dda13d2..12a40deb9a 100644 --- a/integrations/azure_form_recognizer/pyproject.toml +++ b/integrations/azure_form_recognizer/pyproject.toml @@ -101,6 +101,13 @@ select = [ "ARG", "B", "C", + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D205", # 1 blank line required between summary line and description + "D209", # Closing triple quotes go to new line + "D213", # summary lines must be positioned on the second physical line of the docstring + "D417", # Missing argument descriptions in the docstring + "D419", # Docstring is empty "DTZ", "E", "EM", diff --git a/integrations/litellm/pyproject.toml b/integrations/litellm/pyproject.toml index 4b3f7b1940..864c2ed3dd 100644 --- a/integrations/litellm/pyproject.toml +++ b/integrations/litellm/pyproject.toml @@ -78,7 +78,10 @@ disallow_incomplete_defs = true line-length = 120 [tool.ruff.lint] -select = ["A", "B", "E", "F", "I", "N", "Q", "RUF", "S", "T", "UP", "W"] +select = [ + "A", "B", "D102", "D103", "D205", "D209", "D213", "D417", "D419", + "E", "F", "I", "N", "Q", "RUF", "S", "T", "UP", "W", +] ignore = ["T201", "B027", "S105", "S106", "S107"] [tool.ruff.lint.isort] diff --git a/integrations/litellm/src/haystack_integrations/components/generators/litellm/chat/chat_generator.py b/integrations/litellm/src/haystack_integrations/components/generators/litellm/chat/chat_generator.py index 03c41f00e0..7c68c4fbb5 100644 --- a/integrations/litellm/src/haystack_integrations/components/generators/litellm/chat/chat_generator.py +++ b/integrations/litellm/src/haystack_integrations/components/generators/litellm/chat/chat_generator.py @@ -33,7 +33,8 @@ @component class LiteLLMChatGenerator: - """Completes chats using any of 100+ LLM providers via LiteLLM. + """ + Completes chats using any of 100+ LLM providers via LiteLLM. LiteLLM routes to OpenAI, Anthropic, Google, AWS Bedrock, Azure, Cohere, Mistral, Groq, and many more through a single unified interface. @@ -74,7 +75,8 @@ def __init__( generation_kwargs: dict[str, Any] | None = None, tools: ToolsType | None = None, ) -> None: - """Create a LiteLLMChatGenerator instance. + """ + Create a LiteLLMChatGenerator instance. :param api_key: The API key for the provider. Optional: when not set, LiteLLM resolves @@ -144,7 +146,8 @@ def run( *, tools: ToolsType | None = None, ) -> dict[str, list[ChatMessage]]: - """Invoke chat completion via LiteLLM. + """ + Invoke chat completion via LiteLLM. :param messages: Input messages as ChatMessage instances. If a string is provided, it is converted to a list containing a ChatMessage with user role. @@ -183,7 +186,8 @@ async def run_async( *, tools: ToolsType | None = None, ) -> dict[str, list[ChatMessage]]: - """Async version of run(). Invoke chat completion via LiteLLM. + """ + Async version of run(). Invoke chat completion via LiteLLM. :param messages: Input messages as ChatMessage instances. If a string is provided, it is converted to a list containing a ChatMessage with user role. @@ -316,7 +320,8 @@ def _build_chat_message(response: Any, choice: Any) -> ChatMessage: def _convert_litellm_chunk_to_streaming_chunk( chunk: Any, previous_chunks: list[StreamingChunk], component_info: ComponentInfo ) -> StreamingChunk: - """Convert a single litellm streaming chunk into a Haystack ``StreamingChunk``. + """ + Convert a single litellm streaming chunk into a Haystack ``StreamingChunk``. The structured fields (``tool_calls``, ``finish_reason``, ``index``) are populated so that ``_convert_streaming_chunks_to_chat_message`` can reconstruct tool calls and metadata; it reads