google-genai 1.51.0__py3-none-any.whl → 1.52.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,6 +37,7 @@ import time
37
37
  from typing import Any, AsyncIterator, Iterator, Optional, Tuple, TYPE_CHECKING, Union
38
38
  from urllib.parse import urlparse
39
39
  from urllib.parse import urlunparse
40
+ import warnings
40
41
 
41
42
  import anyio
42
43
  import certifi
@@ -55,6 +56,7 @@ from .types import HttpOptions
55
56
  from .types import HttpOptionsOrDict
56
57
  from .types import HttpResponse as SdkHttpResponse
57
58
  from .types import HttpRetryOptions
59
+ from .types import ResourceScope
58
60
 
59
61
 
60
62
  try:
@@ -578,6 +580,12 @@ class BaseApiClient:
578
580
  elif isinstance(http_options, HttpOptions):
579
581
  validated_http_options = http_options
580
582
 
583
+ if validated_http_options.base_url_resource_scope and not validated_http_options.base_url:
584
+ # base_url_resource_scope is only valid when base_url is set.
585
+ raise ValueError(
586
+ 'base_url must be set when base_url_resource_scope is set.'
587
+ )
588
+
581
589
  # Retrieve implicitly set values from the environment.
582
590
  env_project = os.environ.get('GOOGLE_CLOUD_PROJECT', None)
583
591
  env_location = os.environ.get('GOOGLE_CLOUD_LOCATION', None)
@@ -727,10 +735,44 @@ class BaseApiClient:
727
735
 
728
736
  async def _get_aiohttp_session(self) -> 'aiohttp.ClientSession':
729
737
  """Returns the aiohttp client session."""
730
- if self._aiohttp_session is None or self._aiohttp_session.closed:
738
+ if (
739
+ self._aiohttp_session is None
740
+ or self._aiohttp_session.closed
741
+ or self._aiohttp_session._loop.is_closed() # pylint: disable=protected-access
742
+ ):
731
743
  # Initialize the aiohttp client session if it's not set up or closed.
732
- self._aiohttp_session = aiohttp.ClientSession(
733
- connector=aiohttp.TCPConnector(limit=0),
744
+ class AiohttpClientSession(aiohttp.ClientSession): # type: ignore[misc]
745
+
746
+ def __del__(self, _warnings: Any = warnings) -> None:
747
+ if not self.closed:
748
+ context = {
749
+ 'client_session': self,
750
+ 'message': 'Unclosed client session',
751
+ }
752
+ if self._source_traceback is not None:
753
+ context['source_traceback'] = self._source_traceback
754
+ # Remove this self._loop.call_exception_handler(context)
755
+
756
+ class AiohttpTCPConnector(aiohttp.TCPConnector): # type: ignore[misc]
757
+
758
+ def __del__(self, _warnings: Any = warnings) -> None:
759
+ if self._closed:
760
+ return
761
+ if not self._conns:
762
+ return
763
+ conns = [repr(c) for c in self._conns.values()]
764
+ # After v3.13.2, it may change to self._close_immediately()
765
+ self._close()
766
+ context = {
767
+ 'connector': self,
768
+ 'connections': conns,
769
+ 'message': 'Unclosed connector',
770
+ }
771
+ if self._source_traceback is not None:
772
+ context['source_traceback'] = self._source_traceback
773
+ # Remove this self._loop.call_exception_handler(context)
774
+ self._aiohttp_session = AiohttpClientSession(
775
+ connector=AiohttpTCPConnector(limit=0),
734
776
  trust_env=True,
735
777
  read_bufsize=READ_BUFFER_SIZE,
736
778
  )
@@ -1044,6 +1086,11 @@ class BaseApiClient:
1044
1086
  and not path.startswith('projects/')
1045
1087
  and not query_vertex_base_models
1046
1088
  and (self.project or self.location)
1089
+ and not (
1090
+ self.custom_base_url
1091
+ and patched_http_options.base_url_resource_scope
1092
+ == ResourceScope.COLLECTION
1093
+ )
1047
1094
  ):
1048
1095
  path = f'projects/{self.project}/locations/{self.location}/' + path
1049
1096
 
@@ -1073,10 +1120,21 @@ class BaseApiClient:
1073
1120
  or (self.project and self.location)
1074
1121
  or self.api_key
1075
1122
  ):
1076
- url = join_url_path(
1077
- base_url,
1078
- versioned_path,
1079
- )
1123
+ if (
1124
+ patched_http_options.base_url_resource_scope
1125
+ == ResourceScope.COLLECTION
1126
+ ):
1127
+ url = join_url_path(base_url, path)
1128
+ else:
1129
+ url = join_url_path(
1130
+ base_url,
1131
+ versioned_path,
1132
+ )
1133
+ elif(
1134
+ self.custom_base_url
1135
+ and patched_http_options.base_url_resource_scope == ResourceScope.COLLECTION
1136
+ ):
1137
+ url = join_url_path(base_url, path)
1080
1138
 
1081
1139
  if self.api_key and self.api_key.startswith('auth_tokens/'):
1082
1140
  raise EphemeralTokenAPIKeyError(
google/genai/_common.py CHANGED
@@ -588,6 +588,7 @@ class BaseModel(pydantic.BaseModel):
588
588
  expected_type = non_none_types[0]
589
589
 
590
590
  if (isinstance(expected_type, type) and
591
+ get_origin(expected_type) is None and
591
592
  issubclass(expected_type, pydantic.BaseModel) and
592
593
  isinstance(value, pydantic.BaseModel) and
593
594
  not isinstance(value, expected_type)):
google/genai/types.py CHANGED
@@ -575,6 +575,17 @@ class PartMediaResolutionLevel(_common.CaseInSensitiveEnum):
575
575
  """Media resolution set to high."""
576
576
 
577
577
 
578
+ class ResourceScope(_common.CaseInSensitiveEnum):
579
+ """Resource scope."""
580
+
581
+ COLLECTION = 'COLLECTION'
582
+ """When setting base_url, this value configures resource scope to be the collection.
583
+ The resource name will not include api version, project, or location.
584
+ For example, if base_url is set to "https://aiplatform.googleapis.com",
585
+ then the resource name for a Model would be
586
+ "https://aiplatform.googleapis.com/publishers/google/models/gemini-3-pro-preview"""
587
+
588
+
578
589
  class JSONSchemaType(Enum):
579
590
  """The type of the data supported by JSON Schema.
580
591
 
@@ -1863,6 +1874,10 @@ class HttpOptions(_common.BaseModel):
1863
1874
  default=None,
1864
1875
  description="""The base URL for the AI platform service endpoint.""",
1865
1876
  )
1877
+ base_url_resource_scope: Optional[ResourceScope] = Field(
1878
+ default=None,
1879
+ description="""The resource scope used to constructing the resource name when base_url is set""",
1880
+ )
1866
1881
  api_version: Optional[str] = Field(
1867
1882
  default=None, description="""Specifies the version of the API to use."""
1868
1883
  )
@@ -1906,6 +1921,9 @@ class HttpOptionsDict(TypedDict, total=False):
1906
1921
  base_url: Optional[str]
1907
1922
  """The base URL for the AI platform service endpoint."""
1908
1923
 
1924
+ base_url_resource_scope: Optional[ResourceScope]
1925
+ """The resource scope used to constructing the resource name when base_url is set"""
1926
+
1909
1927
  api_version: Optional[str]
1910
1928
  """Specifies the version of the API to use."""
1911
1929
 
google/genai/version.py CHANGED
@@ -13,4 +13,4 @@
13
13
  # limitations under the License.
14
14
  #
15
15
 
16
- __version__ = '1.51.0' # x-release-please-version
16
+ __version__ = '1.52.0' # x-release-please-version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-genai
3
- Version: 1.51.0
3
+ Version: 1.52.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License-Expression: Apache-2.0
@@ -28,7 +28,7 @@ Requires-Dist: tenacity<9.2.0,>=8.2.3
28
28
  Requires-Dist: websockets<15.1.0,>=13.0.0
29
29
  Requires-Dist: typing-extensions<5.0.0,>=4.11.0
30
30
  Provides-Extra: aiohttp
31
- Requires-Dist: aiohttp<4.0.0; extra == "aiohttp"
31
+ Requires-Dist: aiohttp<3.13.3; extra == "aiohttp"
32
32
  Provides-Extra: local-tokenizer
33
33
  Requires-Dist: sentencepiece>=0.2.0; extra == "local-tokenizer"
34
34
  Requires-Dist: protobuf; extra == "local-tokenizer"
@@ -1,11 +1,11 @@
1
1
  google/genai/__init__.py,sha256=SKz_9WQKA3R4OpJIDJlgssVfizLNDG2tuWtOD9pxrPE,729
2
2
  google/genai/_adapters.py,sha256=Kok38miNYJff2n--l0zEK_hbq0y2rWOH7k75J7SMYbQ,1744
3
- google/genai/_api_client.py,sha256=HB7TPN_H-rGnpy3Ainz91To7SaGr0lr0hlYZopJ8ZXc,65082
3
+ google/genai/_api_client.py,sha256=xZTh53LjzEnNLvGRjSm8FgEq0Sgg4Dy3Iuc-EejpQeg,67228
4
4
  google/genai/_api_module.py,sha256=lj8eUWx8_LBGBz-49qz6_ywWm3GYp3d8Bg5JoOHbtbI,902
5
5
  google/genai/_automatic_function_calling_util.py,sha256=xXNkJR-pzSMkeSXMz3Jw-kMHFbTJEiRJ3wocuwtWW4I,11627
6
6
  google/genai/_base_transformers.py,sha256=wljA6m4tLl4XLGlBC2DNOls5N9-X9tffBq0M7i8jgpw,1034
7
7
  google/genai/_base_url.py,sha256=E5H4dew14Y16qfnB3XRnjSCi19cJVlkaMNoM_8ip-PM,1597
8
- google/genai/_common.py,sha256=eq3mvCbq_XZvMbIRwONU_VgfTdNdBDP-5l9ZJtFZZAg,25373
8
+ google/genai/_common.py,sha256=9HOP8GtEnTGTF-5A92hQdcPWeaCS6ig3vgnmm-8jiTY,25421
9
9
  google/genai/_extra_utils.py,sha256=GXsUfyKAPZaW9_ySvdzSAXThvuzaKwXcAmdHW_hoHpY,25309
10
10
  google/genai/_live_converters.py,sha256=sn18ntVlaWsM8sRVXE5oLLnHNY3LjJyStXHFCxFokAE,43721
11
11
  google/genai/_local_tokenizer_loader.py,sha256=7yvJfEkWIpw2ueY4ZmoOAamJD-G7bm_9g44glD6bVwM,7147
@@ -32,10 +32,10 @@ google/genai/pagers.py,sha256=1i8NXDuKuQznFin5H5-I0hmj6H5YMTYsEJP7S0ITSbY,7158
32
32
  google/genai/py.typed,sha256=RsMFoLwBkAvY05t6izop4UHZtqOPLiKp3GkIEizzmQY,40
33
33
  google/genai/tokens.py,sha256=4BPW0gGWFeFVk3INkuY2tfREnsrvzQDhouvRI6_F9Q8,12235
34
34
  google/genai/tunings.py,sha256=8JTTXCwrmzS6gGorMhOmgXJKy8VjEw83gtrymPpPYkQ,73623
35
- google/genai/types.py,sha256=7dy5x4yiaT_1pjkWp89NUkhkji-NXe2mO3TmJLTt6OA,642865
36
- google/genai/version.py,sha256=T6wmItNBkQEhP7HT6ii4ENcN1_4rr9ShX8OU57PDzDs,627
37
- google_genai-1.51.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
38
- google_genai-1.51.0.dist-info/METADATA,sha256=yVW7WChOLpIYKnf2EmKGZxnkSz0WyzvR5w2KzLxISrU,46808
39
- google_genai-1.51.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
- google_genai-1.51.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
41
- google_genai-1.51.0.dist-info/RECORD,,
35
+ google/genai/types.py,sha256=5vGYQvYYDkFDLTVv07g2bowv9K9X_A-3btO_XEZgjeI,643678
36
+ google/genai/version.py,sha256=JH1tQnbCVjInbmLbF5ZTx2SPw1T8BXZF1T6Uo547tpE,627
37
+ google_genai-1.52.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
38
+ google_genai-1.52.0.dist-info/METADATA,sha256=EXGEv-8tXP-UfLMpjfMU3vI2ykqVzmKxOIIX5dpg4lQ,46809
39
+ google_genai-1.52.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ google_genai-1.52.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
41
+ google_genai-1.52.0.dist-info/RECORD,,