google-genai 1.12.1__tar.gz → 1.14.0__tar.gz

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.
Files changed (36) hide show
  1. {google_genai-1.12.1/google_genai.egg-info → google_genai-1.14.0}/PKG-INFO +8 -6
  2. {google_genai-1.12.1 → google_genai-1.14.0}/README.md +7 -5
  3. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_api_client.py +59 -17
  4. google_genai-1.14.0/google/genai/_base_url.py +50 -0
  5. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_live_converters.py +231 -203
  6. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_transformers.py +2 -2
  7. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/batches.py +2 -2
  8. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/caches.py +236 -198
  9. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/chats.py +4 -4
  10. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/client.py +21 -9
  11. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/live.py +9 -6
  12. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/models.py +260 -230
  13. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/types.py +1380 -1045
  14. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/version.py +1 -1
  15. {google_genai-1.12.1 → google_genai-1.14.0/google_genai.egg-info}/PKG-INFO +8 -6
  16. {google_genai-1.12.1 → google_genai-1.14.0}/google_genai.egg-info/SOURCES.txt +1 -0
  17. {google_genai-1.12.1 → google_genai-1.14.0}/pyproject.toml +1 -1
  18. {google_genai-1.12.1 → google_genai-1.14.0}/LICENSE +0 -0
  19. {google_genai-1.12.1 → google_genai-1.14.0}/MANIFEST.in +0 -0
  20. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/__init__.py +0 -0
  21. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_api_module.py +0 -0
  22. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_automatic_function_calling_util.py +0 -0
  23. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_common.py +0 -0
  24. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_extra_utils.py +0 -0
  25. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_replay_api_client.py +0 -0
  26. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/_test_api_client.py +0 -0
  27. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/errors.py +0 -0
  28. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/files.py +0 -0
  29. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/operations.py +0 -0
  30. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/pagers.py +0 -0
  31. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/py.typed +0 -0
  32. {google_genai-1.12.1 → google_genai-1.14.0}/google/genai/tunings.py +0 -0
  33. {google_genai-1.12.1 → google_genai-1.14.0}/google_genai.egg-info/dependency_links.txt +0 -0
  34. {google_genai-1.12.1 → google_genai-1.14.0}/google_genai.egg-info/requires.txt +0 -0
  35. {google_genai-1.12.1 → google_genai-1.14.0}/google_genai.egg-info/top_level.txt +0 -0
  36. {google_genai-1.12.1 → google_genai-1.14.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-genai
3
- Version: 1.12.1
3
+ Version: 1.14.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License: Apache-2.0
@@ -32,6 +32,8 @@ Dynamic: license-file
32
32
  # Google Gen AI SDK
33
33
 
34
34
  [![PyPI version](https://img.shields.io/pypi/v/google-genai.svg)](https://pypi.org/project/google-genai/)
35
+ ![Python support](https://img.shields.io/pypi/pyversions/google-genai)
36
+ [![PyPI - Downloads](https://img.shields.io/pypi/dw/google-genai)](https://pypistats.org/packages/google-genai)
35
37
 
36
38
  --------
37
39
  **Documentation:** https://googleapis.github.io/python-genai/
@@ -1081,7 +1083,7 @@ else:
1081
1083
  file_uris = [file1.uri, file2.uri]
1082
1084
 
1083
1085
  cached_content = client.caches.create(
1084
- model='gemini-1.5-pro-002',
1086
+ model='gemini-2.0-flash-001',
1085
1087
  config=types.CreateCachedContentConfig(
1086
1088
  contents=[
1087
1089
  types.Content(
@@ -1114,7 +1116,7 @@ cached_content = client.caches.get(name=cached_content.name)
1114
1116
 
1115
1117
  ```python
1116
1118
  response = client.models.generate_content(
1117
- model='gemini-1.5-pro-002',
1119
+ model='gemini-2.0-flash-001',
1118
1120
  contents='Summarize the pdfs',
1119
1121
  config=types.GenerateContentConfig(
1120
1122
  cached_content=cached_content.name,
@@ -1135,12 +1137,12 @@ tuning through `tune`.
1135
1137
 
1136
1138
  ```python
1137
1139
  if client.vertexai:
1138
- model = 'gemini-1.5-pro-002'
1140
+ model = 'gemini-2.0-flash-001'
1139
1141
  training_dataset = types.TuningDataset(
1140
1142
  gcs_uri='gs://cloud-samples-data/ai-platform/generative_ai/gemini-1_5/text/sft_train_data.jsonl',
1141
1143
  )
1142
1144
  else:
1143
- model = 'models/gemini-1.0-pro-001'
1145
+ model = 'models/gemini-2.0-flash-001'
1144
1146
  training_dataset = types.TuningDataset(
1145
1147
  examples=[
1146
1148
  types.TuningExample(
@@ -1291,7 +1293,7 @@ Only supported in Vertex AI.
1291
1293
  ```python
1292
1294
  # Specify model and source file only, destination and job display name will be auto-populated
1293
1295
  job = client.batches.create(
1294
- model='gemini-1.5-flash-002',
1296
+ model='gemini-2.0-flash-001',
1295
1297
  src='bq://my-project.my-dataset.my-table',
1296
1298
  )
1297
1299
 
@@ -1,6 +1,8 @@
1
1
  # Google Gen AI SDK
2
2
 
3
3
  [![PyPI version](https://img.shields.io/pypi/v/google-genai.svg)](https://pypi.org/project/google-genai/)
4
+ ![Python support](https://img.shields.io/pypi/pyversions/google-genai)
5
+ [![PyPI - Downloads](https://img.shields.io/pypi/dw/google-genai)](https://pypistats.org/packages/google-genai)
4
6
 
5
7
  --------
6
8
  **Documentation:** https://googleapis.github.io/python-genai/
@@ -1050,7 +1052,7 @@ else:
1050
1052
  file_uris = [file1.uri, file2.uri]
1051
1053
 
1052
1054
  cached_content = client.caches.create(
1053
- model='gemini-1.5-pro-002',
1055
+ model='gemini-2.0-flash-001',
1054
1056
  config=types.CreateCachedContentConfig(
1055
1057
  contents=[
1056
1058
  types.Content(
@@ -1083,7 +1085,7 @@ cached_content = client.caches.get(name=cached_content.name)
1083
1085
 
1084
1086
  ```python
1085
1087
  response = client.models.generate_content(
1086
- model='gemini-1.5-pro-002',
1088
+ model='gemini-2.0-flash-001',
1087
1089
  contents='Summarize the pdfs',
1088
1090
  config=types.GenerateContentConfig(
1089
1091
  cached_content=cached_content.name,
@@ -1104,12 +1106,12 @@ tuning through `tune`.
1104
1106
 
1105
1107
  ```python
1106
1108
  if client.vertexai:
1107
- model = 'gemini-1.5-pro-002'
1109
+ model = 'gemini-2.0-flash-001'
1108
1110
  training_dataset = types.TuningDataset(
1109
1111
  gcs_uri='gs://cloud-samples-data/ai-platform/generative_ai/gemini-1_5/text/sft_train_data.jsonl',
1110
1112
  )
1111
1113
  else:
1112
- model = 'models/gemini-1.0-pro-001'
1114
+ model = 'models/gemini-2.0-flash-001'
1113
1115
  training_dataset = types.TuningDataset(
1114
1116
  examples=[
1115
1117
  types.TuningExample(
@@ -1260,7 +1262,7 @@ Only supported in Vertex AI.
1260
1262
  ```python
1261
1263
  # Specify model and source file only, destination and job display name will be auto-populated
1262
1264
  job = client.batches.create(
1263
- model='gemini-1.5-flash-002',
1265
+ model='gemini-2.0-flash-001',
1264
1266
  src='bq://my-project.my-dataset.my-table',
1265
1267
  )
1266
1268
 
@@ -58,7 +58,9 @@ from .types import HttpOptionsOrDict
58
58
 
59
59
  logger = logging.getLogger('google_genai._api_client')
60
60
  CHUNK_SIZE = 8 * 1024 * 1024 # 8 MB chunk size
61
-
61
+ MAX_RETRY_COUNT = 3
62
+ INITIAL_RETRY_DELAY = 1 # second
63
+ DELAY_MULTIPLIER = 2
62
64
 
63
65
  def _append_library_version_headers(headers: dict[str, str]) -> None:
64
66
  """Appends the telemetry header to the headers dict."""
@@ -283,6 +285,18 @@ class SyncHttpxClient(httpx.Client):
283
285
  kwargs.setdefault('follow_redirects', True)
284
286
  super().__init__(**kwargs)
285
287
 
288
+ def __del__(self) -> None:
289
+ """Closes the httpx client."""
290
+ try:
291
+ if self.is_closed:
292
+ return
293
+ except Exception:
294
+ pass
295
+ try:
296
+ self.close()
297
+ except Exception:
298
+ pass
299
+
286
300
 
287
301
  class AsyncHttpxClient(httpx.AsyncClient):
288
302
  """Async httpx client."""
@@ -292,6 +306,17 @@ class AsyncHttpxClient(httpx.AsyncClient):
292
306
  kwargs.setdefault('follow_redirects', True)
293
307
  super().__init__(**kwargs)
294
308
 
309
+ def __del__(self) -> None:
310
+ try:
311
+ if self.is_closed:
312
+ return
313
+ except Exception:
314
+ pass
315
+ try:
316
+ asyncio.get_running_loop().create_task(self.aclose())
317
+ except Exception:
318
+ pass
319
+
295
320
 
296
321
  class BaseApiClient:
297
322
  """Client for calling HTTP APIs sending and receiving JSON."""
@@ -865,15 +890,23 @@ class BaseApiClient:
865
890
  'Content-Length': str(chunk_size),
866
891
  }
867
892
  _populate_server_timeout_header(upload_headers, timeout_in_seconds)
868
- response = self._httpx_client.request(
869
- method='POST',
870
- url=upload_url,
871
- headers=upload_headers,
872
- content=file_chunk,
873
- timeout=timeout_in_seconds,
874
- )
893
+ retry_count = 0
894
+ while retry_count < MAX_RETRY_COUNT:
895
+ response = self._httpx_client.request(
896
+ method='POST',
897
+ url=upload_url,
898
+ headers=upload_headers,
899
+ content=file_chunk,
900
+ timeout=timeout_in_seconds,
901
+ )
902
+ if response.headers.get('x-goog-upload-status'):
903
+ break
904
+ delay_seconds = INITIAL_RETRY_DELAY * (DELAY_MULTIPLIER**retry_count)
905
+ retry_count += 1
906
+ time.sleep(delay_seconds)
907
+
875
908
  offset += chunk_size
876
- if response.headers['x-goog-upload-status'] != 'active':
909
+ if response.headers.get('x-goog-upload-status') != 'active':
877
910
  break # upload is complete or it has been interrupted.
878
911
  if upload_size <= offset: # Status is not finalized.
879
912
  raise ValueError(
@@ -881,7 +914,7 @@ class BaseApiClient:
881
914
  f' finalized.'
882
915
  )
883
916
 
884
- if response.headers['x-goog-upload-status'] != 'final':
917
+ if response.headers.get('x-goog-upload-status') != 'final':
885
918
  raise ValueError(
886
919
  'Failed to upload file: Upload status is not finalized.'
887
920
  )
@@ -1013,13 +1046,22 @@ class BaseApiClient:
1013
1046
  'Content-Length': str(chunk_size),
1014
1047
  }
1015
1048
  _populate_server_timeout_header(upload_headers, timeout_in_seconds)
1016
- response = await self._async_httpx_client.request(
1017
- method='POST',
1018
- url=upload_url,
1019
- content=file_chunk,
1020
- headers=upload_headers,
1021
- timeout=timeout_in_seconds,
1022
- )
1049
+
1050
+ retry_count = 0
1051
+ while retry_count < MAX_RETRY_COUNT:
1052
+ response = await self._async_httpx_client.request(
1053
+ method='POST',
1054
+ url=upload_url,
1055
+ content=file_chunk,
1056
+ headers=upload_headers,
1057
+ timeout=timeout_in_seconds,
1058
+ )
1059
+ if response.headers.get('x-goog-upload-status'):
1060
+ break
1061
+ delay_seconds = INITIAL_RETRY_DELAY * (DELAY_MULTIPLIER**retry_count)
1062
+ retry_count += 1
1063
+ time.sleep(delay_seconds)
1064
+
1023
1065
  offset += chunk_size
1024
1066
  if response.headers.get('x-goog-upload-status') != 'active':
1025
1067
  break # upload is complete or it has been interrupted.
@@ -0,0 +1,50 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ import os
17
+ from typing import Optional
18
+
19
+ from .types import HttpOptions
20
+
21
+ _default_base_gemini_url = None
22
+ _default_base_vertex_url = None
23
+
24
+
25
+ def set_default_base_urls(
26
+ gemini_url: Optional[str], vertex_url: Optional[str]
27
+ ) -> None:
28
+ """Overrides the base URLs for the Gemini API and Vertex AI API."""
29
+ global _default_base_gemini_url, _default_base_vertex_url
30
+ _default_base_gemini_url = gemini_url
31
+ _default_base_vertex_url = vertex_url
32
+
33
+
34
+ def get_base_url(
35
+ vertexai: bool,
36
+ http_options: Optional[HttpOptions] = None,
37
+ ) -> Optional[str]:
38
+ """Returns the default base URL based on the following priority.
39
+
40
+ 1. Base URLs set via HttpOptions.
41
+ 2. Base URLs set via the latest call to setDefaultBaseUrls.
42
+ 3. Base URLs set via environment variables.
43
+ """
44
+ if http_options and http_options.base_url:
45
+ return http_options.base_url
46
+
47
+ if vertexai:
48
+ return _default_base_vertex_url or os.getenv('GOOGLE_VERTEX_BASE_URL')
49
+ else:
50
+ return _default_base_gemini_url or os.getenv('GOOGLE_GEMINI_BASE_URL')