Skip to content

Commit de4e7b9

Browse files
anakin87davidsbatista
authored andcommitted
chore!: google_genai - drop Python 3.9 and use X|Y typing (#2706)
1 parent 482fbd6 commit de4e7b9

6 files changed

Lines changed: 40 additions & 46 deletions

File tree

integrations/google_genai/pyproject.toml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "google-genai-haystack"
77
dynamic = ["version"]
88
description = 'Use models like Gemini via Google Gen AI SDK'
99
readme = "README.md"
10-
requires-python = ">=3.9"
10+
requires-python = ">=3.10"
1111
license = "Apache-2.0"
1212
keywords = []
1313
authors = [
@@ -18,15 +18,14 @@ classifiers = [
1818
"License :: OSI Approved :: Apache Software License",
1919
"Development Status :: 4 - Beta",
2020
"Programming Language :: Python",
21-
"Programming Language :: Python :: 3.9",
2221
"Programming Language :: Python :: 3.10",
2322
"Programming Language :: Python :: 3.11",
2423
"Programming Language :: Python :: 3.12",
2524
"Programming Language :: Python :: 3.13",
2625
"Programming Language :: Python :: Implementation :: CPython",
2726
"Programming Language :: Python :: Implementation :: PyPy",
2827
]
29-
dependencies = ["haystack-ai>=2.19.0", "google-genai[aiohttp]>=1.18.0", "jsonref>=1.0.0"]
28+
dependencies = ["haystack-ai>=2.22.0", "google-genai[aiohttp]>=1.18.0", "jsonref>=1.0.0"]
3029

3130
[project.urls]
3231
Documentation = "https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/google_genai#readme"
@@ -87,7 +86,6 @@ module = [
8786
ignore_missing_imports = true
8887

8988
[tool.ruff]
90-
target-version = "py39"
9189
line-length = 120
9290

9391
[tool.ruff.lint]
@@ -140,10 +138,6 @@ ignore = [
140138
# Allow function call argument defaults e.g. `Secret.from_env_var`
141139
"B008",
142140
]
143-
unfixable = [
144-
# Don't touch unused imports
145-
"F401",
146-
]
147141

148142
[tool.ruff.lint.isort]
149143
known-first-party = ["haystack_integrations"]

integrations/google_genai/src/haystack_integrations/components/common/google_genai/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
from typing import Literal, Optional
5+
from typing import Literal
66

77
from google.genai import Client
88
from haystack import logging
@@ -14,8 +14,8 @@
1414
def _get_client(
1515
api_key: Secret,
1616
api: Literal["gemini", "vertex"],
17-
vertex_ai_project: Optional[str],
18-
vertex_ai_location: Optional[str],
17+
vertex_ai_project: str | None,
18+
vertex_ai_location: str | None,
1919
) -> Client:
2020
"""
2121
Internal utility function to get a Google GenAI client.

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
from typing import Any, Literal, Optional, Union
5+
from typing import Any, Literal
66

77
from google.genai import types
88
from haystack import Document, component, default_from_dict, default_to_dict, logging
@@ -75,16 +75,16 @@ def __init__(
7575
*,
7676
api_key: Secret = Secret.from_env_var(["GOOGLE_API_KEY", "GEMINI_API_KEY"], strict=False),
7777
api: Literal["gemini", "vertex"] = "gemini",
78-
vertex_ai_project: Optional[str] = None,
79-
vertex_ai_location: Optional[str] = None,
78+
vertex_ai_project: str | None = None,
79+
vertex_ai_location: str | None = None,
8080
model: str = "text-embedding-004",
8181
prefix: str = "",
8282
suffix: str = "",
8383
batch_size: int = 32,
8484
progress_bar: bool = True,
85-
meta_fields_to_embed: Optional[list[str]] = None,
85+
meta_fields_to_embed: list[str] | None = None,
8686
embedding_separator: str = "\n",
87-
config: Optional[dict[str, Any]] = None,
87+
config: dict[str, Any] | None = None,
8888
) -> None:
8989
"""
9090
Creates an GoogleGenAIDocumentEmbedder component.
@@ -195,7 +195,7 @@ def _prepare_texts_to_embed(self, documents: list[Document]) -> list[str]:
195195

196196
def _embed_batch(
197197
self, texts_to_embed: list[str], batch_size: int
198-
) -> tuple[list[Optional[list[float]]], dict[str, Any]]:
198+
) -> tuple[list[list[float] | None], dict[str, Any]]:
199199
"""
200200
Embed a list of texts in batches.
201201
"""
@@ -227,7 +227,7 @@ def _embed_batch(
227227

228228
async def _embed_batch_async(
229229
self, texts_to_embed: list[str], batch_size: int
230-
) -> tuple[list[Optional[list[float]]], dict[str, Any]]:
230+
) -> tuple[list[list[float] | None], dict[str, Any]]:
231231
"""
232232
Embed a list of texts in batches asynchronously.
233233
"""
@@ -257,7 +257,7 @@ async def _embed_batch_async(
257257
return all_embeddings, meta
258258

259259
@component.output_types(documents=list[Document], meta=dict[str, Any])
260-
def run(self, documents: list[Document]) -> Union[dict[str, list[Document]], dict[str, Any]]:
260+
def run(self, documents: list[Document]) -> dict[str, list[Document]] | dict[str, Any]:
261261
"""
262262
Embeds a list of documents.
263263
@@ -281,13 +281,13 @@ def run(self, documents: list[Document]) -> Union[dict[str, list[Document]], dic
281281
meta: dict[str, Any]
282282
embeddings, meta = self._embed_batch(texts_to_embed=texts_to_embed, batch_size=self._batch_size)
283283

284-
for doc, emb in zip(documents, embeddings):
284+
for doc, emb in zip(documents, embeddings, strict=True):
285285
doc.embedding = emb
286286

287287
return {"documents": documents, "meta": meta}
288288

289289
@component.output_types(documents=list[Document], meta=dict[str, Any])
290-
async def run_async(self, documents: list[Document]) -> Union[dict[str, list[Document]], dict[str, Any]]:
290+
async def run_async(self, documents: list[Document]) -> dict[str, list[Document]] | dict[str, Any]:
291291
"""
292292
Embeds a list of documents asynchronously.
293293
@@ -310,7 +310,7 @@ async def run_async(self, documents: list[Document]) -> Union[dict[str, list[Doc
310310

311311
embeddings, meta = await self._embed_batch_async(texts_to_embed=texts_to_embed, batch_size=self._batch_size)
312312

313-
for doc, emb in zip(documents, embeddings):
313+
for doc, emb in zip(documents, embeddings, strict=True):
314314
doc.embedding = emb
315315

316316
return {"documents": documents, "meta": meta}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
from typing import Any, Literal, Optional, Union
5+
from typing import Any, Literal
66

77
from google.genai import types
88
from haystack import component, default_from_dict, default_to_dict, logging
@@ -76,12 +76,12 @@ def __init__(
7676
*,
7777
api_key: Secret = Secret.from_env_var(["GOOGLE_API_KEY", "GEMINI_API_KEY"], strict=False),
7878
api: Literal["gemini", "vertex"] = "gemini",
79-
vertex_ai_project: Optional[str] = None,
80-
vertex_ai_location: Optional[str] = None,
79+
vertex_ai_project: str | None = None,
80+
vertex_ai_location: str | None = None,
8181
model: str = "text-embedding-004",
8282
prefix: str = "",
8383
suffix: str = "",
84-
config: Optional[dict[str, Any]] = None,
84+
config: dict[str, Any] | None = None,
8585
) -> None:
8686
"""
8787
Creates an GoogleGenAITextEmbedder component.
@@ -177,7 +177,7 @@ def _prepare_output(self, result: types.EmbedContentResponse) -> dict[str, Any]:
177177
return {"embedding": embedding, "meta": {"model": self._model_name}}
178178

179179
@component.output_types(embedding=list[float], meta=dict[str, Any])
180-
def run(self, text: str) -> Union[dict[str, list[float]], dict[str, Any]]:
180+
def run(self, text: str) -> dict[str, list[float]] | dict[str, Any]:
181181
"""
182182
Embeds a single string.
183183
@@ -194,7 +194,7 @@ def run(self, text: str) -> Union[dict[str, list[float]], dict[str, Any]]:
194194
return self._prepare_output(result=response)
195195

196196
@component.output_types(embedding=list[float], meta=dict[str, Any])
197-
async def run_async(self, text: str) -> Union[dict[str, list[float]], dict[str, Any]]:
197+
async def run_async(self, text: str) -> dict[str, list[float]] | dict[str, Any]:
198198
"""
199199
Asynchronously embed a single string.
200200

integrations/google_genai/src/haystack_integrations/components/generators/google_genai/chat/chat_generator.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import json
77
from collections.abc import AsyncIterator, Iterator
88
from datetime import datetime, timezone
9-
from typing import Any, Literal, Optional
9+
from typing import Any, Literal
1010

1111
from google.genai import types
1212
from haystack import logging
@@ -456,13 +456,13 @@ def __init__(
456456
*,
457457
api_key: Secret = Secret.from_env_var(["GOOGLE_API_KEY", "GEMINI_API_KEY"], strict=False),
458458
api: Literal["gemini", "vertex"] = "gemini",
459-
vertex_ai_project: Optional[str] = None,
460-
vertex_ai_location: Optional[str] = None,
459+
vertex_ai_project: str | None = None,
460+
vertex_ai_location: str | None = None,
461461
model: str = "gemini-2.5-flash",
462-
generation_kwargs: Optional[dict[str, Any]] = None,
463-
safety_settings: Optional[list[dict[str, Any]]] = None,
464-
streaming_callback: Optional[StreamingCallbackT] = None,
465-
tools: Optional[ToolsType] = None,
462+
generation_kwargs: dict[str, Any] | None = None,
463+
safety_settings: list[dict[str, Any]] | None = None,
464+
streaming_callback: StreamingCallbackT | None = None,
465+
tools: ToolsType | None = None,
466466
):
467467
"""
468468
Initialize a GoogleGenAIChatGenerator instance.
@@ -801,10 +801,10 @@ def _process_thinking_config(self, generation_kwargs: dict[str, Any]) -> dict[st
801801
def run(
802802
self,
803803
messages: list[ChatMessage],
804-
generation_kwargs: Optional[dict[str, Any]] = None,
805-
safety_settings: Optional[list[dict[str, Any]]] = None,
806-
streaming_callback: Optional[StreamingCallbackT] = None,
807-
tools: Optional[ToolsType] = None,
804+
generation_kwargs: dict[str, Any] | None = None,
805+
safety_settings: list[dict[str, Any]] | None = None,
806+
streaming_callback: StreamingCallbackT | None = None,
807+
tools: ToolsType | None = None,
808808
) -> dict[str, Any]:
809809
"""
810810
Run the Google Gen AI chat generator on the given input data.
@@ -909,10 +909,10 @@ def run(
909909
async def run_async(
910910
self,
911911
messages: list[ChatMessage],
912-
generation_kwargs: Optional[dict[str, Any]] = None,
913-
safety_settings: Optional[list[dict[str, Any]]] = None,
914-
streaming_callback: Optional[StreamingCallbackT] = None,
915-
tools: Optional[ToolsType] = None,
912+
generation_kwargs: dict[str, Any] | None = None,
913+
safety_settings: list[dict[str, Any]] | None = None,
914+
streaming_callback: StreamingCallbackT | None = None,
915+
tools: ToolsType | None = None,
916916
) -> dict[str, Any]:
917917
"""
918918
Async version of the run method. Run the Google Gen AI chat generator on the given input data.

integrations/google_genai/src/haystack_integrations/components/generators/google_genai/chat/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
from typing import Any, Union
5+
from typing import Any
66

77

88
def remove_key_from_schema(
9-
schema: Union[dict[str, Any], list[Any], Any], target_key: str
10-
) -> Union[dict[str, Any], list[Any], Any]:
9+
schema: dict[str, Any] | list[Any] | Any, target_key: str
10+
) -> dict[str, Any] | list[Any] | Any:
1111
"""
1212
Recursively traverse a schema and remove all occurrences of the target key.
1313

0 commit comments

Comments
 (0)