Skip to content

Commit 22ac91c

Browse files
julian-rischclaude
andauthored
refactor!: remove from_dict overrides that only call default_from_dict from 14 components (#4059)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent e41fa35 commit 22ac91c

26 files changed

Lines changed: 65 additions & 337 deletions

File tree

‎integrations/amazon_textract/src/haystack_integrations/components/converters/amazon_textract/converter.py‎

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import boto3
99
from botocore.config import Config
1010
from botocore.exceptions import BotoCoreError, ClientError
11-
from haystack import Document, component, default_from_dict, default_to_dict, logging
11+
from haystack import Document, component, default_to_dict, logging
1212
from haystack.components.converters.utils import get_bytestream_from_source, normalize_metadata
1313
from haystack.dataclasses import ByteStream
14-
from haystack.utils import Secret, deserialize_secrets_inplace
14+
from haystack.utils import Secret
1515

1616
from .errors import AmazonTextractConfigurationError
1717

@@ -253,25 +253,3 @@ def to_dict(self) -> dict[str, Any]:
253253
store_full_path=self.store_full_path,
254254
boto3_config=self.boto3_config,
255255
)
256-
257-
@classmethod
258-
def from_dict(cls, data: dict[str, Any]) -> "AmazonTextractConverter":
259-
"""
260-
Deserializes the component from a dictionary.
261-
262-
:param data:
263-
The dictionary to deserialize from.
264-
:returns:
265-
The deserialized component.
266-
"""
267-
deserialize_secrets_inplace(
268-
data["init_parameters"],
269-
keys=[
270-
"aws_access_key_id",
271-
"aws_secret_access_key",
272-
"aws_session_token",
273-
"aws_region_name",
274-
"aws_profile_name",
275-
],
276-
)
277-
return default_from_dict(cls, data)

‎integrations/amazon_textract/tests/test_amazon_textract_converter.py‎

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import pytest
1010
from botocore.exceptions import BotoCoreError, ClientError
11+
from haystack.core.serialization import component_from_dict
1112
from haystack.dataclasses import ByteStream
1213
from haystack.utils import Secret
1314

@@ -116,28 +117,6 @@ def test_to_dict_default_params(self):
116117
assert data["init_parameters"]["store_full_path"] is False
117118
assert data["init_parameters"]["boto3_config"] is None
118119

119-
def test_from_dict(self):
120-
expected_type = "haystack_integrations.components.converters.amazon_textract.converter.AmazonTextractConverter"
121-
data = {
122-
"type": expected_type,
123-
"init_parameters": {
124-
"aws_access_key_id": {"type": "env_var", "env_vars": ["AWS_ACCESS_KEY_ID"], "strict": False},
125-
"aws_secret_access_key": {"type": "env_var", "env_vars": ["AWS_SECRET_ACCESS_KEY"], "strict": False},
126-
"aws_session_token": {"type": "env_var", "env_vars": ["AWS_SESSION_TOKEN"], "strict": False},
127-
"aws_region_name": {"type": "env_var", "env_vars": ["AWS_DEFAULT_REGION"], "strict": False},
128-
"aws_profile_name": {"type": "env_var", "env_vars": ["AWS_PROFILE"], "strict": False},
129-
"feature_types": ["TABLES", "FORMS"],
130-
"store_full_path": False,
131-
"boto3_config": None,
132-
},
133-
}
134-
135-
converter = AmazonTextractConverter.from_dict(data)
136-
137-
assert converter.feature_types == ["TABLES", "FORMS"]
138-
assert converter.store_full_path is False
139-
assert converter.boto3_config is None
140-
141120
def test_from_dict_roundtrip(self):
142121
converter = AmazonTextractConverter(
143122
aws_access_key_id=Secret.from_env_var("AWS_ACCESS_KEY_ID", strict=False),
@@ -147,11 +126,16 @@ def test_from_dict_roundtrip(self):
147126
)
148127

149128
data = converter.to_dict()
150-
restored = AmazonTextractConverter.from_dict(data)
129+
restored = component_from_dict(AmazonTextractConverter, data, name="restored")
151130

152131
assert restored.feature_types == converter.feature_types
153132
assert restored.store_full_path == converter.store_full_path
154133
assert restored.boto3_config == converter.boto3_config
134+
assert restored.aws_access_key_id == converter.aws_access_key_id
135+
assert restored.aws_secret_access_key == converter.aws_secret_access_key
136+
assert restored.aws_session_token == converter.aws_session_token
137+
assert restored.aws_region_name == converter.aws_region_name
138+
assert restored.aws_profile_name == converter.aws_profile_name
155139

156140

157141
class TestComponentLifecycle:

‎integrations/azure_form_recognizer/src/haystack_integrations/components/converters/azure_form_recognizer/converter.py‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
import networkx as nx
1212
from azure.ai.formrecognizer import AnalyzeResult, DocumentAnalysisClient, DocumentLine, DocumentParagraph
1313
from azure.core.credentials import AzureKeyCredential
14-
from haystack import Document, component, default_from_dict, default_to_dict, logging
14+
from haystack import Document, component, default_to_dict, logging
1515
from haystack.components.converters.utils import get_bytestream_from_source, normalize_metadata
1616
from haystack.dataclasses import ByteStream
17-
from haystack.utils import Secret, deserialize_secrets_inplace
17+
from haystack.utils import Secret
1818
from pandas import DataFrame
1919

2020
logger = logging.getLogger(__name__)
@@ -186,19 +186,6 @@ def to_dict(self) -> dict[str, Any]:
186186
store_full_path=self.store_full_path,
187187
)
188188

189-
@classmethod
190-
def from_dict(cls, data: dict[str, Any]) -> "AzureOCRDocumentConverter":
191-
"""
192-
Deserializes the component from a dictionary.
193-
194-
:param data:
195-
The dictionary to deserialize from.
196-
:returns:
197-
The deserialized component.
198-
"""
199-
deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
200-
return default_from_dict(cls, data)
201-
202189
def _convert_tables_and_text(self, result: AnalyzeResult, meta: dict[str, Any] | None) -> list[Document]:
203190
"""
204191
Converts the tables and text extracted by Azure's Document Intelligence service into Haystack Documents.

‎integrations/azure_form_recognizer/tests/test_azure_ocr_doc_converter.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import pytest
1414
from azure.ai.formrecognizer import AnalyzeResult
15+
from haystack.core.serialization import component_from_dict
1516
from haystack.dataclasses.byte_stream import ByteStream
1617
from haystack.utils import Secret
1718

@@ -143,7 +144,7 @@ def test_from_dict(self):
143144
"store_full_path": False,
144145
},
145146
}
146-
component = AzureOCRDocumentConverter.from_dict(data)
147+
component = component_from_dict(AzureOCRDocumentConverter, data, name="component")
147148
assert component.endpoint == "test_endpoint"
148149
assert component.model_id == "prebuilt-read"
149150
assert component.api_key == Secret.from_env_var("AZURE_AI_API_KEY")

‎integrations/google_genai/src/haystack_integrations/components/embedders/google_genai/document_embedder.py‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
from google.genai import Client, types
99
from google.genai.client import AsyncClient
10-
from haystack import Document, component, default_from_dict, default_to_dict, logging
11-
from haystack.utils import Secret, deserialize_secrets_inplace
10+
from haystack import Document, component, default_to_dict, logging
11+
from haystack.utils import Secret
1212
from tqdm import tqdm
1313

1414
from haystack_integrations.common.google_genai.utils import _get_client
@@ -211,19 +211,6 @@ def to_dict(self) -> dict[str, Any]:
211211
max_retries=self._max_retries,
212212
)
213213

214-
@classmethod
215-
def from_dict(cls, data: dict[str, Any]) -> "GoogleGenAIDocumentEmbedder":
216-
"""
217-
Deserializes the component from a dictionary.
218-
219-
:param data:
220-
Dictionary to deserialize from.
221-
:returns:
222-
Deserialized component.
223-
"""
224-
deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
225-
return default_from_dict(cls, data)
226-
227214
def _prepare_texts_to_embed(self, documents: list[Document]) -> list[str]:
228215
"""
229216
Prepare the texts to embed by concatenating the Document text with the metadata fields to embed.

‎integrations/google_genai/src/haystack_integrations/components/embedders/google_genai/multimodal_document_embedder.py‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
from google.genai import Client
1212
from google.genai.client import AsyncClient
1313
from google.genai.types import Content, EmbedContentConfig, Part
14-
from haystack import Document, component, default_from_dict, default_to_dict, logging
14+
from haystack import Document, component, default_to_dict, logging
1515
from haystack.components.converters.image.image_utils import (
1616
_batch_convert_pdf_pages_to_images,
1717
_encode_image_to_base64,
1818
_PDFPageInfo,
1919
)
2020
from haystack.dataclasses import ByteStream
21-
from haystack.utils import Secret, deserialize_secrets_inplace
21+
from haystack.utils import Secret
2222
from tqdm import tqdm
2323
from tqdm.asyncio import tqdm as async_tqdm
2424
from typing_extensions import NotRequired, TypedDict
@@ -321,19 +321,6 @@ def to_dict(self) -> dict[str, Any]:
321321
max_retries=self._max_retries,
322322
)
323323

324-
@classmethod
325-
def from_dict(cls, data: dict[str, Any]) -> "GoogleGenAIMultimodalDocumentEmbedder":
326-
"""
327-
Deserializes the component from a dictionary.
328-
329-
:param data:
330-
Dictionary to deserialize from.
331-
:returns:
332-
Deserialized component.
333-
"""
334-
deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
335-
return default_from_dict(cls, data)
336-
337324
def _extract_parts_to_embed(self, documents: list[Document]) -> list[Part]:
338325
"""
339326
Validates the input documents and extracts the files to embed in the format expected by the Google AI API.

‎integrations/google_genai/src/haystack_integrations/components/embedders/google_genai/text_embedder.py‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
from google.genai import Client, types
88
from google.genai.client import AsyncClient
9-
from haystack import component, default_from_dict, default_to_dict, logging
10-
from haystack.utils import Secret, deserialize_secrets_inplace
9+
from haystack import component, default_to_dict, logging
10+
from haystack.utils import Secret
1111

1212
from haystack_integrations.common.google_genai.utils import _get_client
1313

@@ -191,19 +191,6 @@ def to_dict(self) -> dict[str, Any]:
191191
max_retries=self._max_retries,
192192
)
193193

194-
@classmethod
195-
def from_dict(cls, data: dict[str, Any]) -> "GoogleGenAITextEmbedder":
196-
"""
197-
Deserializes the component from a dictionary.
198-
199-
:param data:
200-
Dictionary to deserialize from.
201-
:returns:
202-
Deserialized component.
203-
"""
204-
deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
205-
return default_from_dict(cls, data)
206-
207194
def _prepare_input(self, text: str) -> dict[str, Any]:
208195
if not isinstance(text, str):
209196
error_message_text = (

‎integrations/google_genai/tests/test_document_embedder.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import numpy as np
1010
import pytest
1111
from haystack import Document
12+
from haystack.core.serialization import component_from_dict
1213
from haystack.utils.auth import Secret
1314

1415
from haystack_integrations.components.embedders.google_genai import GoogleGenAIDocumentEmbedder, GoogleGenAITextEmbedder
@@ -156,7 +157,7 @@ def test_from_dict(self, monkeypatch):
156157
},
157158
}
158159
monkeypatch.setenv("GOOGLE_API_KEY", "fake-api-key")
159-
embedder = GoogleGenAIDocumentEmbedder.from_dict(data)
160+
embedder = component_from_dict(GoogleGenAIDocumentEmbedder, data, name="embedder")
160161
assert embedder._api_key.resolve_value() == "fake-api-key"
161162
assert embedder._model == "gemini-embedding-001"
162163
assert embedder._prefix == ""

‎integrations/google_genai/tests/test_text_embedder.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import pytest
99
from google.genai.types import ContentEmbedding, EmbedContentResponse
10+
from haystack.core.serialization import component_from_dict
1011
from haystack.utils.auth import Secret
1112

1213
from haystack_integrations.components.embedders.google_genai import GoogleGenAITextEmbedder
@@ -111,7 +112,7 @@ def test_from_dict(self, monkeypatch):
111112
"max_retries": 3,
112113
},
113114
}
114-
component = GoogleGenAITextEmbedder.from_dict(data)
115+
component = component_from_dict(GoogleGenAITextEmbedder, data, name="component")
115116
assert component._api_key.resolve_value() == "fake-api-key"
116117
assert component._model_name == "gemini-embedding-001"
117118
assert component._prefix == ""

‎integrations/mistral/src/haystack_integrations/components/converters/mistral/ocr_document_converter.py‎

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
from pathlib import Path
88
from typing import Any, ClassVar
99

10-
from haystack import Document, component, default_from_dict, default_to_dict, logging
10+
from haystack import Document, component, default_to_dict, logging
1111
from haystack.components.converters.utils import (
1212
get_bytestream_from_source,
1313
normalize_metadata,
1414
)
1515
from haystack.dataclasses import ByteStream
16-
from haystack.utils import Secret, deserialize_secrets_inplace
16+
from haystack.utils import Secret
1717
from mistralai.client import Mistral
1818
from mistralai.client.models import (
1919
DocumentURLChunk,
@@ -186,19 +186,6 @@ def to_dict(self) -> dict[str, Any]:
186186
cleanup_uploaded_files=self.cleanup_uploaded_files,
187187
)
188188

189-
@classmethod
190-
def from_dict(cls, data: dict[str, Any]) -> "MistralOCRDocumentConverter":
191-
"""
192-
Deserializes the component from a dictionary.
193-
194-
:param data:
195-
Dictionary to deserialize from.
196-
:returns:
197-
Deserialized component.
198-
"""
199-
deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
200-
return default_from_dict(cls, data)
201-
202189
@component.output_types(documents=list[Document], raw_mistral_response=list[dict[str, Any]])
203190
def run(
204191
self,

0 commit comments

Comments
 (0)