google-genai 0.7.0__py3-none-any.whl → 0.8.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.
@@ -255,7 +255,7 @@ class ApiClient:
255
255
  'Project and location or API key must be set when using the Vertex '
256
256
  'AI API.'
257
257
  )
258
- if self.api_key:
258
+ if self.api_key or self.location == 'global':
259
259
  self._http_options['base_url'] = (
260
260
  f'https://aiplatform.googleapis.com/'
261
261
  )
@@ -273,7 +273,7 @@ class ApiClient:
273
273
  self._http_options['api_version'] = 'v1beta'
274
274
  # Default options for both clients.
275
275
  self._http_options['headers'] = {'Content-Type': 'application/json'}
276
- if self.api_key and not self.vertexai:
276
+ if self.api_key:
277
277
  self._http_options['headers']['x-goog-api-key'] = self.api_key
278
278
  # Update the http options with the user provided http options.
279
279
  if http_options:
@@ -323,8 +323,6 @@ class ApiClient:
323
323
  and not self.api_key
324
324
  ):
325
325
  path = f'projects/{self.project}/locations/{self.location}/' + path
326
- elif self.vertexai and self.api_key:
327
- path = f'{path}?key={self.api_key}'
328
326
  url = _join_url_path(
329
327
  patched_http_options['base_url'],
330
328
  patched_http_options['api_version'] + '/' + path,
google/genai/_common.py CHANGED
@@ -21,6 +21,7 @@ import enum
21
21
  import typing
22
22
  from typing import Union
23
23
  import uuid
24
+ import warnings
24
25
 
25
26
  import pydantic
26
27
  from pydantic import alias_generators
@@ -213,8 +214,16 @@ class CaseInSensitiveEnum(str, enum.Enum):
213
214
  except KeyError:
214
215
  try:
215
216
  return cls[value.lower()] # Try to access directly with lowercase
216
- except KeyError as e:
217
- raise ValueError(f"{value} is not a valid {cls.__name__}") from e
217
+ except KeyError:
218
+ warnings.warn(f"{value} is not a valid {cls.__name__}")
219
+ try:
220
+ # Creating a enum instance based on the value
221
+ unknown_enum_val = cls._new_member_(cls) # pylint: disable=protected-access,attribute-error
222
+ unknown_enum_val._name_ = str(value) # pylint: disable=protected-access
223
+ unknown_enum_val._value_ = value # pylint: disable=protected-access
224
+ return unknown_enum_val
225
+ except:
226
+ return None
218
227
 
219
228
 
220
229
  def timestamped_unique_name() -> str:
@@ -0,0 +1,365 @@
1
+ # Copyright 2024 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
+ # Code generated by the Google Gen AI SDK generator DO NOT EDIT.
17
+
18
+ from typing import Optional, Union
19
+ from urllib.parse import urlencode
20
+ from . import _api_module
21
+ from . import _common
22
+ from . import types
23
+ from ._api_client import ApiClient
24
+ from ._common import get_value_by_path as getv
25
+ from ._common import set_value_by_path as setv
26
+
27
+
28
+ def _GetOperationParameters_to_mldev(
29
+ api_client: ApiClient,
30
+ from_object: Union[dict, object],
31
+ parent_object: dict = None,
32
+ ) -> dict:
33
+ to_object = {}
34
+ if getv(from_object, ['operation_name']) is not None:
35
+ setv(
36
+ to_object,
37
+ ['_url', 'operationName'],
38
+ getv(from_object, ['operation_name']),
39
+ )
40
+
41
+ if getv(from_object, ['config']) is not None:
42
+ setv(to_object, ['config'], getv(from_object, ['config']))
43
+
44
+ return to_object
45
+
46
+
47
+ def _GetOperationParameters_to_vertex(
48
+ api_client: ApiClient,
49
+ from_object: Union[dict, object],
50
+ parent_object: dict = None,
51
+ ) -> dict:
52
+ to_object = {}
53
+ if getv(from_object, ['operation_name']) is not None:
54
+ setv(
55
+ to_object,
56
+ ['_url', 'operationName'],
57
+ getv(from_object, ['operation_name']),
58
+ )
59
+
60
+ if getv(from_object, ['config']) is not None:
61
+ setv(to_object, ['config'], getv(from_object, ['config']))
62
+
63
+ return to_object
64
+
65
+
66
+ def _FetchPredictOperationParameters_to_mldev(
67
+ api_client: ApiClient,
68
+ from_object: Union[dict, object],
69
+ parent_object: dict = None,
70
+ ) -> dict:
71
+ to_object = {}
72
+ if getv(from_object, ['operation_name']) is not None:
73
+ raise ValueError('operation_name parameter is not supported in Gemini API.')
74
+
75
+ if getv(from_object, ['resource_name']) is not None:
76
+ raise ValueError('resource_name parameter is not supported in Gemini API.')
77
+
78
+ if getv(from_object, ['config']) is not None:
79
+ raise ValueError('config parameter is not supported in Gemini API.')
80
+
81
+ return to_object
82
+
83
+
84
+ def _FetchPredictOperationParameters_to_vertex(
85
+ api_client: ApiClient,
86
+ from_object: Union[dict, object],
87
+ parent_object: dict = None,
88
+ ) -> dict:
89
+ to_object = {}
90
+ if getv(from_object, ['operation_name']) is not None:
91
+ setv(to_object, ['operationName'], getv(from_object, ['operation_name']))
92
+
93
+ if getv(from_object, ['resource_name']) is not None:
94
+ setv(
95
+ to_object,
96
+ ['_url', 'resourceName'],
97
+ getv(from_object, ['resource_name']),
98
+ )
99
+
100
+ if getv(from_object, ['config']) is not None:
101
+ setv(to_object, ['config'], getv(from_object, ['config']))
102
+
103
+ return to_object
104
+
105
+
106
+ def _Operation_from_mldev(
107
+ api_client: ApiClient,
108
+ from_object: Union[dict, object],
109
+ parent_object: dict = None,
110
+ ) -> dict:
111
+ to_object = {}
112
+ if getv(from_object, ['name']) is not None:
113
+ setv(to_object, ['name'], getv(from_object, ['name']))
114
+
115
+ if getv(from_object, ['metadata']) is not None:
116
+ setv(to_object, ['metadata'], getv(from_object, ['metadata']))
117
+
118
+ if getv(from_object, ['done']) is not None:
119
+ setv(to_object, ['done'], getv(from_object, ['done']))
120
+
121
+ if getv(from_object, ['error']) is not None:
122
+ setv(to_object, ['error'], getv(from_object, ['error']))
123
+
124
+ if getv(from_object, ['response']) is not None:
125
+ setv(to_object, ['response'], getv(from_object, ['response']))
126
+
127
+ return to_object
128
+
129
+
130
+ def _Operation_from_vertex(
131
+ api_client: ApiClient,
132
+ from_object: Union[dict, object],
133
+ parent_object: dict = None,
134
+ ) -> dict:
135
+ to_object = {}
136
+ if getv(from_object, ['name']) is not None:
137
+ setv(to_object, ['name'], getv(from_object, ['name']))
138
+
139
+ if getv(from_object, ['metadata']) is not None:
140
+ setv(to_object, ['metadata'], getv(from_object, ['metadata']))
141
+
142
+ if getv(from_object, ['done']) is not None:
143
+ setv(to_object, ['done'], getv(from_object, ['done']))
144
+
145
+ if getv(from_object, ['error']) is not None:
146
+ setv(to_object, ['error'], getv(from_object, ['error']))
147
+
148
+ if getv(from_object, ['response']) is not None:
149
+ setv(to_object, ['response'], getv(from_object, ['response']))
150
+
151
+ return to_object
152
+
153
+
154
+ class _operations(_api_module.BaseModule):
155
+
156
+ def _get_operation(
157
+ self,
158
+ *,
159
+ operation_name: str,
160
+ config: Optional[types.GetOperationConfigOrDict] = None,
161
+ ) -> types.Operation:
162
+ parameter_model = types._GetOperationParameters(
163
+ operation_name=operation_name,
164
+ config=config,
165
+ )
166
+
167
+ if self._api_client.vertexai:
168
+ request_dict = _GetOperationParameters_to_vertex(
169
+ self._api_client, parameter_model
170
+ )
171
+ path = '{operationName}'.format_map(request_dict.get('_url'))
172
+ else:
173
+ request_dict = _GetOperationParameters_to_mldev(
174
+ self._api_client, parameter_model
175
+ )
176
+ path = '{operationName}'.format_map(request_dict.get('_url'))
177
+ query_params = request_dict.get('_query')
178
+ if query_params:
179
+ path = f'{path}?{urlencode(query_params)}'
180
+ # TODO: remove the hack that pops config.
181
+ request_dict.pop('config', None)
182
+
183
+ http_options = None
184
+ if isinstance(config, dict):
185
+ http_options = config.get('http_options', None)
186
+ elif hasattr(config, 'http_options'):
187
+ http_options = config.http_options
188
+
189
+ request_dict = _common.convert_to_dict(request_dict)
190
+ request_dict = _common.encode_unserializable_types(request_dict)
191
+
192
+ response_dict = self._api_client.request(
193
+ 'get', path, request_dict, http_options
194
+ )
195
+
196
+ if self._api_client.vertexai:
197
+ response_dict = _Operation_from_vertex(self._api_client, response_dict)
198
+ else:
199
+ response_dict = _Operation_from_mldev(self._api_client, response_dict)
200
+
201
+ return_value = types.Operation._from_response(
202
+ response=response_dict, kwargs=parameter_model
203
+ )
204
+ self._api_client._verify_response(return_value)
205
+ return return_value
206
+
207
+ def _fetch_predict_operation(
208
+ self,
209
+ *,
210
+ operation_name: str,
211
+ resource_name: str,
212
+ config: Optional[types.FetchPredictOperationConfigOrDict] = None,
213
+ ) -> types.Operation:
214
+ parameter_model = types._FetchPredictOperationParameters(
215
+ operation_name=operation_name,
216
+ resource_name=resource_name,
217
+ config=config,
218
+ )
219
+
220
+ if not self._api_client.vertexai:
221
+ raise ValueError('This method is only supported in the Vertex AI client.')
222
+ else:
223
+ request_dict = _FetchPredictOperationParameters_to_vertex(
224
+ self._api_client, parameter_model
225
+ )
226
+ path = '{resourceName}:fetchPredictOperation'.format_map(
227
+ request_dict.get('_url')
228
+ )
229
+
230
+ query_params = request_dict.get('_query')
231
+ if query_params:
232
+ path = f'{path}?{urlencode(query_params)}'
233
+ # TODO: remove the hack that pops config.
234
+ request_dict.pop('config', None)
235
+
236
+ http_options = None
237
+ if isinstance(config, dict):
238
+ http_options = config.get('http_options', None)
239
+ elif hasattr(config, 'http_options'):
240
+ http_options = config.http_options
241
+
242
+ request_dict = _common.convert_to_dict(request_dict)
243
+ request_dict = _common.encode_unserializable_types(request_dict)
244
+
245
+ response_dict = self._api_client.request(
246
+ 'post', path, request_dict, http_options
247
+ )
248
+
249
+ if self._api_client.vertexai:
250
+ response_dict = _Operation_from_vertex(self._api_client, response_dict)
251
+ else:
252
+ response_dict = _Operation_from_mldev(self._api_client, response_dict)
253
+
254
+ return_value = types.Operation._from_response(
255
+ response=response_dict, kwargs=parameter_model
256
+ )
257
+ self._api_client._verify_response(return_value)
258
+ return return_value
259
+
260
+
261
+ class Async_operations(_api_module.BaseModule):
262
+
263
+ async def _get_operation(
264
+ self,
265
+ *,
266
+ operation_name: str,
267
+ config: Optional[types.GetOperationConfigOrDict] = None,
268
+ ) -> types.Operation:
269
+ parameter_model = types._GetOperationParameters(
270
+ operation_name=operation_name,
271
+ config=config,
272
+ )
273
+
274
+ if self._api_client.vertexai:
275
+ request_dict = _GetOperationParameters_to_vertex(
276
+ self._api_client, parameter_model
277
+ )
278
+ path = '{operationName}'.format_map(request_dict.get('_url'))
279
+ else:
280
+ request_dict = _GetOperationParameters_to_mldev(
281
+ self._api_client, parameter_model
282
+ )
283
+ path = '{operationName}'.format_map(request_dict.get('_url'))
284
+ query_params = request_dict.get('_query')
285
+ if query_params:
286
+ path = f'{path}?{urlencode(query_params)}'
287
+ # TODO: remove the hack that pops config.
288
+ request_dict.pop('config', None)
289
+
290
+ http_options = None
291
+ if isinstance(config, dict):
292
+ http_options = config.get('http_options', None)
293
+ elif hasattr(config, 'http_options'):
294
+ http_options = config.http_options
295
+
296
+ request_dict = _common.convert_to_dict(request_dict)
297
+ request_dict = _common.encode_unserializable_types(request_dict)
298
+
299
+ response_dict = await self._api_client.async_request(
300
+ 'get', path, request_dict, http_options
301
+ )
302
+
303
+ if self._api_client.vertexai:
304
+ response_dict = _Operation_from_vertex(self._api_client, response_dict)
305
+ else:
306
+ response_dict = _Operation_from_mldev(self._api_client, response_dict)
307
+
308
+ return_value = types.Operation._from_response(
309
+ response=response_dict, kwargs=parameter_model
310
+ )
311
+ self._api_client._verify_response(return_value)
312
+ return return_value
313
+
314
+ async def _fetch_predict_operation(
315
+ self,
316
+ *,
317
+ operation_name: str,
318
+ resource_name: str,
319
+ config: Optional[types.FetchPredictOperationConfigOrDict] = None,
320
+ ) -> types.Operation:
321
+ parameter_model = types._FetchPredictOperationParameters(
322
+ operation_name=operation_name,
323
+ resource_name=resource_name,
324
+ config=config,
325
+ )
326
+
327
+ if not self._api_client.vertexai:
328
+ raise ValueError('This method is only supported in the Vertex AI client.')
329
+ else:
330
+ request_dict = _FetchPredictOperationParameters_to_vertex(
331
+ self._api_client, parameter_model
332
+ )
333
+ path = '{resourceName}:fetchPredictOperation'.format_map(
334
+ request_dict.get('_url')
335
+ )
336
+
337
+ query_params = request_dict.get('_query')
338
+ if query_params:
339
+ path = f'{path}?{urlencode(query_params)}'
340
+ # TODO: remove the hack that pops config.
341
+ request_dict.pop('config', None)
342
+
343
+ http_options = None
344
+ if isinstance(config, dict):
345
+ http_options = config.get('http_options', None)
346
+ elif hasattr(config, 'http_options'):
347
+ http_options = config.http_options
348
+
349
+ request_dict = _common.convert_to_dict(request_dict)
350
+ request_dict = _common.encode_unserializable_types(request_dict)
351
+
352
+ response_dict = await self._api_client.async_request(
353
+ 'post', path, request_dict, http_options
354
+ )
355
+
356
+ if self._api_client.vertexai:
357
+ response_dict = _Operation_from_vertex(self._api_client, response_dict)
358
+ else:
359
+ response_dict = _Operation_from_mldev(self._api_client, response_dict)
360
+
361
+ return_value = types.Operation._from_response(
362
+ response=response_dict, kwargs=parameter_model
363
+ )
364
+ self._api_client._verify_response(return_value)
365
+ return return_value
@@ -78,6 +78,11 @@ def _redact_request_url(url: str) -> str:
78
78
  '{VERTEX_URL_PREFIX}/',
79
79
  result,
80
80
  )
81
+ result = re.sub(
82
+ r'.*aiplatform.googleapis.com/[^/]+/',
83
+ '{VERTEX_URL_PREFIX}/',
84
+ result,
85
+ )
81
86
  result = re.sub(
82
87
  r'https://generativelanguage.googleapis.com/[^/]+',
83
88
  '{MLDEV_URL_PREFIX}',
google/genai/files.py CHANGED
@@ -781,16 +781,17 @@ class Files(_api_module.BaseModule):
781
781
  def upload(
782
782
  self,
783
783
  *,
784
- path: Union[str, pathlib.Path, os.PathLike, io.IOBase],
784
+ file: Union[str, pathlib.Path, os.PathLike, io.IOBase],
785
785
  config: Optional[types.UploadFileConfigOrDict] = None,
786
786
  ) -> types.File:
787
787
  """Calls the API to upload a file using a supported file service.
788
788
 
789
789
  Args:
790
- path: The path to the file or an `IOBase` object to be uploaded. If it's
791
- an IOBase object, it must be opened in blocking mode and binary mode. In
792
- other words, do not use non-blocking mode or text mode. The given stream
793
- must be seekable, that is, it must be able to call seek() on 'path'.
790
+ file: A path to the file or an `IOBase` object to be uploaded. If it's an
791
+ IOBase object, it must be opened in blocking (the default) mode and
792
+ binary mode. In other words, do not use non-blocking mode or text mode.
793
+ The given stream must be seekable, that is, it must be able to call
794
+ `seek()` on 'path'.
794
795
  config: Optional parameters to set `diplay_name`, `mime_type`, and `name`.
795
796
  """
796
797
  if self._api_client.vertexai:
@@ -804,37 +805,37 @@ class Files(_api_module.BaseModule):
804
805
  config_model = types.UploadFileConfig(**config)
805
806
  else:
806
807
  config_model = config
807
- file = types.File(
808
+ file_obj = types.File(
808
809
  mime_type=config_model.mime_type,
809
810
  name=config_model.name,
810
811
  display_name=config_model.display_name,
811
812
  )
812
813
  else: # if not config
813
- file = types.File()
814
- if file.name is not None and not file.name.startswith('files/'):
815
- file.name = f'files/{file.name}'
814
+ file_obj = types.File()
815
+ if file_obj.name is not None and not file_obj.name.startswith('files/'):
816
+ file_obj.name = f'files/{file_obj.name}'
816
817
 
817
- if isinstance(path, io.IOBase):
818
- if file.mime_type is None:
818
+ if isinstance(file, io.IOBase):
819
+ if file_obj.mime_type is None:
819
820
  raise ValueError(
820
821
  'Unknown mime type: Could not determine the mimetype for your'
821
822
  ' file\n please set the `mime_type` argument'
822
823
  )
823
- if hasattr(path, 'mode'):
824
- if 'b' not in path.mode:
824
+ if hasattr(file, 'mode'):
825
+ if 'b' not in file.mode:
825
826
  raise ValueError('The file must be opened in binary mode.')
826
- offset = path.tell()
827
- path.seek(0, os.SEEK_END)
828
- file.size_bytes = path.tell() - offset
829
- path.seek(offset, os.SEEK_SET)
827
+ offset = file.tell()
828
+ file.seek(0, os.SEEK_END)
829
+ file_obj.size_bytes = file.tell() - offset
830
+ file.seek(offset, os.SEEK_SET)
830
831
  else:
831
- fs_path = os.fspath(path)
832
+ fs_path = os.fspath(file)
832
833
  if not fs_path or not os.path.isfile(fs_path):
833
- raise FileNotFoundError(f'{path} is not a valid file path.')
834
- file.size_bytes = os.path.getsize(fs_path)
835
- if file.mime_type is None:
836
- file.mime_type, _ = mimetypes.guess_type(fs_path)
837
- if file.mime_type is None:
834
+ raise FileNotFoundError(f'{file} is not a valid file path.')
835
+ file_obj.size_bytes = os.path.getsize(fs_path)
836
+ if file_obj.mime_type is None:
837
+ file_obj.mime_type, _ = mimetypes.guess_type(fs_path)
838
+ if file_obj.mime_type is None:
838
839
  raise ValueError(
839
840
  'Unknown mime type: Could not determine the mimetype for your'
840
841
  ' file\n please set the `mime_type` argument'
@@ -849,12 +850,12 @@ class Files(_api_module.BaseModule):
849
850
  'Content-Type': 'application/json',
850
851
  'X-Goog-Upload-Protocol': 'resumable',
851
852
  'X-Goog-Upload-Command': 'start',
852
- 'X-Goog-Upload-Header-Content-Length': f'{file.size_bytes}',
853
- 'X-Goog-Upload-Header-Content-Type': f'{file.mime_type}',
853
+ 'X-Goog-Upload-Header-Content-Length': f'{file_obj.size_bytes}',
854
+ 'X-Goog-Upload-Header-Content-Type': f'{file_obj.mime_type}',
854
855
  },
855
856
  'deprecated_response_payload': response,
856
857
  }
857
- self._create(file=file, config={'http_options': http_options})
858
+ self._create(file=file_obj, config={'http_options': http_options})
858
859
 
859
860
  if (
860
861
  'headers' not in response
@@ -866,13 +867,13 @@ class Files(_api_module.BaseModule):
866
867
  )
867
868
  upload_url = response['headers']['X-Goog-Upload-URL']
868
869
 
869
- if isinstance(path, io.IOBase):
870
+ if isinstance(file, io.IOBase):
870
871
  return_file = self._api_client.upload_file(
871
- path, upload_url, file.size_bytes
872
+ file, upload_url, file_obj.size_bytes
872
873
  )
873
874
  else:
874
875
  return_file = self._api_client.upload_file(
875
- fs_path, upload_url, file.size_bytes
876
+ fs_path, upload_url, file_obj.size_bytes
876
877
  )
877
878
 
878
879
  return types.File._from_response(
@@ -1211,16 +1212,17 @@ class AsyncFiles(_api_module.BaseModule):
1211
1212
  async def upload(
1212
1213
  self,
1213
1214
  *,
1214
- path: Union[str, pathlib.Path, os.PathLike, io.IOBase],
1215
+ file: Union[str, pathlib.Path, os.PathLike, io.IOBase],
1215
1216
  config: Optional[types.UploadFileConfigOrDict] = None,
1216
1217
  ) -> types.File:
1217
1218
  """Calls the API to upload a file asynchronously using a supported file service.
1218
1219
 
1219
1220
  Args:
1220
- path: The path to the file or an `IOBase` object to be uploaded. If it's
1221
- an IOBase object, it must be opened in blocking mode and binary mode. In
1222
- other words, do not use non-blocking mode or text mode. The given stream
1223
- must be seekable, that is, it must be able to call seek() on 'path'.
1221
+ file: A path to the file or an `IOBase` object to be uploaded. If it's an
1222
+ IOBase object, it must be opened in blocking (the default) mode and
1223
+ binary mode. In other words, do not use non-blocking mode or text mode.
1224
+ The given stream must be seekable, that is, it must be able to call
1225
+ `seek()` on 'path'.
1224
1226
  config: Optional parameters to set `diplay_name`, `mime_type`, and `name`.
1225
1227
  """
1226
1228
  if self._api_client.vertexai:
@@ -1234,37 +1236,37 @@ class AsyncFiles(_api_module.BaseModule):
1234
1236
  config_model = types.UploadFileConfig(**config)
1235
1237
  else:
1236
1238
  config_model = config
1237
- file = types.File(
1239
+ file_obj = types.File(
1238
1240
  mime_type=config_model.mime_type,
1239
1241
  name=config_model.name,
1240
1242
  display_name=config_model.display_name,
1241
1243
  )
1242
1244
  else: # if not config
1243
- file = types.File()
1244
- if file.name is not None and not file.name.startswith('files/'):
1245
- file.name = f'files/{file.name}'
1245
+ file_obj = types.File()
1246
+ if file_obj.name is not None and not file_obj.name.startswith('files/'):
1247
+ file_obj.name = f'files/{file_obj.name}'
1246
1248
 
1247
- if isinstance(path, io.IOBase):
1248
- if file.mime_type is None:
1249
+ if isinstance(file, io.IOBase):
1250
+ if file_obj.mime_type is None:
1249
1251
  raise ValueError(
1250
1252
  'Unknown mime type: Could not determine the mimetype for your'
1251
1253
  ' file\n please set the `mime_type` argument'
1252
1254
  )
1253
- if hasattr(path, 'mode'):
1254
- if 'b' not in path.mode:
1255
+ if hasattr(file, 'mode'):
1256
+ if 'b' not in file.mode:
1255
1257
  raise ValueError('The file must be opened in binary mode.')
1256
- offset = path.tell()
1257
- path.seek(0, os.SEEK_END)
1258
- file.size_bytes = path.tell() - offset
1259
- path.seek(offset, os.SEEK_SET)
1258
+ offset = file.tell()
1259
+ file.seek(0, os.SEEK_END)
1260
+ file_obj.size_bytes = file.tell() - offset
1261
+ file.seek(offset, os.SEEK_SET)
1260
1262
  else:
1261
- fs_path = os.fspath(path)
1263
+ fs_path = os.fspath(file)
1262
1264
  if not fs_path or not os.path.isfile(fs_path):
1263
- raise FileNotFoundError(f'{path} is not a valid file path.')
1264
- file.size_bytes = os.path.getsize(fs_path)
1265
- if file.mime_type is None:
1266
- file.mime_type, _ = mimetypes.guess_type(fs_path)
1267
- if file.mime_type is None:
1265
+ raise FileNotFoundError(f'{file} is not a valid file path.')
1266
+ file_obj.size_bytes = os.path.getsize(fs_path)
1267
+ if file_obj.mime_type is None:
1268
+ file_obj.mime_type, _ = mimetypes.guess_type(fs_path)
1269
+ if file_obj.mime_type is None:
1268
1270
  raise ValueError(
1269
1271
  'Unknown mime type: Could not determine the mimetype for your'
1270
1272
  ' file\n please set the `mime_type` argument'
@@ -1280,12 +1282,12 @@ class AsyncFiles(_api_module.BaseModule):
1280
1282
  'Content-Type': 'application/json',
1281
1283
  'X-Goog-Upload-Protocol': 'resumable',
1282
1284
  'X-Goog-Upload-Command': 'start',
1283
- 'X-Goog-Upload-Header-Content-Length': f'{file.size_bytes}',
1284
- 'X-Goog-Upload-Header-Content-Type': f'{file.mime_type}',
1285
+ 'X-Goog-Upload-Header-Content-Length': f'{file_obj.size_bytes}',
1286
+ 'X-Goog-Upload-Header-Content-Type': f'{file_obj.mime_type}',
1285
1287
  },
1286
1288
  'deprecated_response_payload': response,
1287
1289
  }
1288
- await self._create(file=file, config={'http_options': http_options})
1290
+ await self._create(file=file_obj, config={'http_options': http_options})
1289
1291
  if (
1290
1292
  'headers' not in response
1291
1293
  or 'X-Goog-Upload-URL' not in response['headers']
@@ -1296,13 +1298,13 @@ class AsyncFiles(_api_module.BaseModule):
1296
1298
  )
1297
1299
  upload_url = response['headers']['X-Goog-Upload-URL']
1298
1300
 
1299
- if isinstance(path, io.IOBase):
1301
+ if isinstance(file, io.IOBase):
1300
1302
  return_file = await self._api_client.async_upload_file(
1301
- path, upload_url, file.size_bytes
1303
+ file, upload_url, file_obj.size_bytes
1302
1304
  )
1303
1305
  else:
1304
1306
  return_file = await self._api_client.async_upload_file(
1305
- fs_path, upload_url, file.size_bytes
1307
+ fs_path, upload_url, file_obj.size_bytes
1306
1308
  )
1307
1309
 
1308
1310
  return types.File._from_response(
google/genai/models.py CHANGED
@@ -3366,6 +3366,9 @@ def _GeneratedImage_from_mldev(
3366
3366
  getv(from_object, ['raiFilteredReason']),
3367
3367
  )
3368
3368
 
3369
+ if getv(from_object, ['prompt']) is not None:
3370
+ setv(to_object, ['enhanced_prompt'], getv(from_object, ['prompt']))
3371
+
3369
3372
  return to_object
3370
3373
 
3371
3374
 
@@ -3389,6 +3392,9 @@ def _GeneratedImage_from_vertex(
3389
3392
  getv(from_object, ['raiFilteredReason']),
3390
3393
  )
3391
3394
 
3395
+ if getv(from_object, ['prompt']) is not None:
3396
+ setv(to_object, ['enhanced_prompt'], getv(from_object, ['prompt']))
3397
+
3392
3398
  return to_object
3393
3399
 
3394
3400
 
google/genai/types.py CHANGED
@@ -3533,6 +3533,12 @@ class GeneratedImage(_common.BaseModel):
3533
3533
  response.
3534
3534
  """,
3535
3535
  )
3536
+ enhanced_prompt: Optional[str] = Field(
3537
+ default=None,
3538
+ description="""The rewritten prompt used for the image generation if the prompt
3539
+ enhancer is enabled.
3540
+ """,
3541
+ )
3536
3542
 
3537
3543
 
3538
3544
  class GeneratedImageDict(TypedDict, total=False):
@@ -3547,6 +3553,11 @@ class GeneratedImageDict(TypedDict, total=False):
3547
3553
  response.
3548
3554
  """
3549
3555
 
3556
+ enhanced_prompt: Optional[str]
3557
+ """The rewritten prompt used for the image generation if the prompt
3558
+ enhancer is enabled.
3559
+ """
3560
+
3550
3561
 
3551
3562
  GeneratedImageOrDict = Union[GeneratedImage, GeneratedImageDict]
3552
3563
 
@@ -7190,6 +7201,147 @@ class DeleteResourceJobDict(TypedDict, total=False):
7190
7201
  DeleteResourceJobOrDict = Union[DeleteResourceJob, DeleteResourceJobDict]
7191
7202
 
7192
7203
 
7204
+ class GetOperationConfig(_common.BaseModel):
7205
+
7206
+ http_options: Optional[HttpOptions] = Field(
7207
+ default=None, description="""Used to override HTTP request options."""
7208
+ )
7209
+
7210
+
7211
+ class GetOperationConfigDict(TypedDict, total=False):
7212
+
7213
+ http_options: Optional[HttpOptionsDict]
7214
+ """Used to override HTTP request options."""
7215
+
7216
+
7217
+ GetOperationConfigOrDict = Union[GetOperationConfig, GetOperationConfigDict]
7218
+
7219
+
7220
+ class _GetOperationParameters(_common.BaseModel):
7221
+ """Parameters for the GET method."""
7222
+
7223
+ operation_name: Optional[str] = Field(
7224
+ default=None,
7225
+ description="""The server-assigned name for the operation.""",
7226
+ )
7227
+ config: Optional[GetOperationConfig] = Field(
7228
+ default=None,
7229
+ description="""Used to override the default configuration.""",
7230
+ )
7231
+
7232
+
7233
+ class _GetOperationParametersDict(TypedDict, total=False):
7234
+ """Parameters for the GET method."""
7235
+
7236
+ operation_name: Optional[str]
7237
+ """The server-assigned name for the operation."""
7238
+
7239
+ config: Optional[GetOperationConfigDict]
7240
+ """Used to override the default configuration."""
7241
+
7242
+
7243
+ _GetOperationParametersOrDict = Union[
7244
+ _GetOperationParameters, _GetOperationParametersDict
7245
+ ]
7246
+
7247
+
7248
+ class Operation(_common.BaseModel):
7249
+ """A long-running operation."""
7250
+
7251
+ name: Optional[str] = Field(
7252
+ default=None,
7253
+ description="""The server-assigned name, which is only unique within the same service that originally returns it. If you use the default HTTP mapping, the `name` should be a resource name ending with `operations/{unique_id}`.""",
7254
+ )
7255
+ metadata: Optional[dict[str, Any]] = Field(
7256
+ default=None,
7257
+ description="""Service-specific metadata associated with the operation. It typically contains progress information and common metadata such as create time. Some services might not provide such metadata. Any method that returns a long-running operation should document the metadata type, if any.""",
7258
+ )
7259
+ done: Optional[bool] = Field(
7260
+ default=None,
7261
+ description="""If the value is `false`, it means the operation is still in progress. If `true`, the operation is completed, and either `error` or `response` is available.""",
7262
+ )
7263
+ error: Optional[dict[str, Any]] = Field(
7264
+ default=None,
7265
+ description="""The error result of the operation in case of failure or cancellation.""",
7266
+ )
7267
+ response: Optional[dict[str, Any]] = Field(
7268
+ default=None,
7269
+ description="""The normal response of the operation in case of success.""",
7270
+ )
7271
+
7272
+
7273
+ class OperationDict(TypedDict, total=False):
7274
+ """A long-running operation."""
7275
+
7276
+ name: Optional[str]
7277
+ """The server-assigned name, which is only unique within the same service that originally returns it. If you use the default HTTP mapping, the `name` should be a resource name ending with `operations/{unique_id}`."""
7278
+
7279
+ metadata: Optional[dict[str, Any]]
7280
+ """Service-specific metadata associated with the operation. It typically contains progress information and common metadata such as create time. Some services might not provide such metadata. Any method that returns a long-running operation should document the metadata type, if any."""
7281
+
7282
+ done: Optional[bool]
7283
+ """If the value is `false`, it means the operation is still in progress. If `true`, the operation is completed, and either `error` or `response` is available."""
7284
+
7285
+ error: Optional[dict[str, Any]]
7286
+ """The error result of the operation in case of failure or cancellation."""
7287
+
7288
+ response: Optional[dict[str, Any]]
7289
+ """The normal response of the operation in case of success."""
7290
+
7291
+
7292
+ OperationOrDict = Union[Operation, OperationDict]
7293
+
7294
+
7295
+ class FetchPredictOperationConfig(_common.BaseModel):
7296
+
7297
+ http_options: Optional[HttpOptions] = Field(
7298
+ default=None, description="""Used to override HTTP request options."""
7299
+ )
7300
+
7301
+
7302
+ class FetchPredictOperationConfigDict(TypedDict, total=False):
7303
+
7304
+ http_options: Optional[HttpOptionsDict]
7305
+ """Used to override HTTP request options."""
7306
+
7307
+
7308
+ FetchPredictOperationConfigOrDict = Union[
7309
+ FetchPredictOperationConfig, FetchPredictOperationConfigDict
7310
+ ]
7311
+
7312
+
7313
+ class _FetchPredictOperationParameters(_common.BaseModel):
7314
+ """Parameters for the fetchPredictOperation method."""
7315
+
7316
+ operation_name: Optional[str] = Field(
7317
+ default=None,
7318
+ description="""The server-assigned name for the operation.""",
7319
+ )
7320
+ resource_name: Optional[str] = Field(default=None, description="""""")
7321
+ config: Optional[FetchPredictOperationConfig] = Field(
7322
+ default=None,
7323
+ description="""Used to override the default configuration.""",
7324
+ )
7325
+
7326
+
7327
+ class _FetchPredictOperationParametersDict(TypedDict, total=False):
7328
+ """Parameters for the fetchPredictOperation method."""
7329
+
7330
+ operation_name: Optional[str]
7331
+ """The server-assigned name for the operation."""
7332
+
7333
+ resource_name: Optional[str]
7334
+ """"""
7335
+
7336
+ config: Optional[FetchPredictOperationConfigDict]
7337
+ """Used to override the default configuration."""
7338
+
7339
+
7340
+ _FetchPredictOperationParametersOrDict = Union[
7341
+ _FetchPredictOperationParameters, _FetchPredictOperationParametersDict
7342
+ ]
7343
+
7344
+
7193
7345
  class TestTableItem(_common.BaseModel):
7194
7346
 
7195
7347
  name: Optional[str] = Field(
google/genai/version.py CHANGED
@@ -13,4 +13,4 @@
13
13
  # limitations under the License.
14
14
  #
15
15
 
16
- __version__ = '0.7.0' # x-release-please-version
16
+ __version__ = '0.8.0' # x-release-please-version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: google-genai
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License: Apache-2.0
@@ -97,9 +97,10 @@ download the file in console.
97
97
  python code.
98
98
 
99
99
  ```python
100
- file = client.files.upload(path="a11.text")
100
+ file = client.files.upload(path="a11.txt")
101
101
  response = client.models.generate_content(
102
- model="gemini-2.0-flash-exp", contents=["Summarize this file", file]
102
+ model="gemini-2.0-flash-exp",
103
+ contents=["Could you summarize this file?", file]
103
104
  )
104
105
  print(response.text)
105
106
  ```
@@ -1,10 +1,11 @@
1
1
  google/genai/__init__.py,sha256=IYw-PcsdgjSpS1mU_ZcYkTfPocsJ4aVmrDxP7vX7c6Y,709
2
- google/genai/_api_client.py,sha256=JPCynlSCc_yPEV4-rdV2-BPv-OHoBvotxXbI0VLA3Q4,22882
2
+ google/genai/_api_client.py,sha256=ZXiLrTI0wWVZaGEC1BHU9fLVp1MZKpnY8J3wV59VOk4,22806
3
3
  google/genai/_api_module.py,sha256=9bxmtcSTpT8Ht6VwJyw7fQqiR0jJXz7350dWGl-bC5E,780
4
4
  google/genai/_automatic_function_calling_util.py,sha256=sEaDAeHjv-H71o1L3_P8sqOslK4TK0Rybn4WPymeEBk,10665
5
- google/genai/_common.py,sha256=aAtTQeGYn8WeiQD2lbjYiHZXWzBdj59wKiqAyQeaByc,8610
5
+ google/genai/_common.py,sha256=Q-3n5U7GCDDfOU_7uBkGYkEcEH2VcMa_NuLcyNzWExM,9017
6
6
  google/genai/_extra_utils.py,sha256=y-6Jr2GN2BKZV67I6fTgDtwfsOTQs7QlLDBQdmW_jKk,11258
7
- google/genai/_replay_api_client.py,sha256=8KMjwjah52Mgf0rURK-CO10MqtULh8vkRSOT4-AqPpU,14722
7
+ google/genai/_operations.py,sha256=KaDgwqG5g6Odd1P6ftvIUT9gF3ov08drm01jE1CjB_s,11490
8
+ google/genai/_replay_api_client.py,sha256=yV2vJJk5Nvdqyi0QmNhupMdm2jrzdYoHVFnVMAx-l0M,14834
8
9
  google/genai/_test_api_client.py,sha256=2PvDcW3h01U4UOSoj7TUo6TwdBHSEN_lO2tXjBoh5Fw,4765
9
10
  google/genai/_transformers.py,sha256=AiSVoQML3MK6AP5xTStIiJUOlrZO4m_qBULOjgdZHC0,21963
10
11
  google/genai/batches.py,sha256=jv8pW_g_cZee6ol5ER5bQRUkXsj4IUcZC5cMo-YAnt0,38033
@@ -12,15 +13,15 @@ google/genai/caches.py,sha256=jsiclHO71kIa2CNrds3O8PL2fCNr_dlhUSPjhiRsjNE,53152
12
13
  google/genai/chats.py,sha256=GyufXQPtyP_v4L3943xaKXMpo1Us9sBTdMSTUV4P6s8,7827
13
14
  google/genai/client.py,sha256=MTZ3DOXk1_xgljaHlvF16jr_SKVPRfU8lZ1eH_dfDeQ,9334
14
15
  google/genai/errors.py,sha256=DtpDZT5UDqumk2cTRUlg3k4ypmO_0tkMNzJgA3qzCmc,3666
15
- google/genai/files.py,sha256=FQLGv-at7T_AZiVkhTsreIaLK_U1acufx-zt8coOjkc,41706
16
+ google/genai/files.py,sha256=arkka0MaNKjfKyVXdQ6-Llnr9W6J4NQYgxHdN69yAwQ,41885
16
17
  google/genai/live.py,sha256=wxz8ebqcPR6JJs39OOVz8zPzfAf31Zol7sGE7byQEyI,23302
17
- google/genai/models.py,sha256=mitGmy1myd6-zmmV8BEDkdc88cbp8ZF9SyZTNeWnBfk,166628
18
+ google/genai/models.py,sha256=GP80VHjWRizW8fypNDUvMIWsObmQMDYuqIHEhLKB0lk,166870
18
19
  google/genai/pagers.py,sha256=hSHd-gLvEzYWwK85i8EcFNWUMKtszUs7Nw2r3L7d6_U,6686
19
20
  google/genai/tunings.py,sha256=iJJYn1O_wjFKTIL8VS2zpIRqpfCNRrO2REP2ztgFW6M,39144
20
- google/genai/types.py,sha256=vOP1JkluVGFhmNFBJk6Z1BoOv4zzwysjIUiU7GFPXwg,273187
21
- google/genai/version.py,sha256=nKmMytxBOALBA2ILryXEQSQpZZJxtfZwKkJcznog9Lw,626
22
- google_genai-0.7.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
23
- google_genai-0.7.0.dist-info/METADATA,sha256=eUcx3JIC0OOIh3_hT-pfkYvkyP2ZWrUXU5JoCZqTDwg,23948
24
- google_genai-0.7.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
25
- google_genai-0.7.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
26
- google_genai-0.7.0.dist-info/RECORD,,
21
+ google/genai/types.py,sha256=1xYY4hxaoi86aoc9n2J8CcoQcAg8HQE1m8Idq9nYbDQ,278477
22
+ google/genai/version.py,sha256=0XfCLnUKjoi5AZ_PK2-LMgByDDmYvGy8YPU9SF8C5Bo,626
23
+ google_genai-0.8.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
24
+ google_genai-0.8.0.dist-info/METADATA,sha256=M_NzvfnF5Oaeuf06FISINgAbXOgEYVhD2UjJK3nSeMU,23962
25
+ google_genai-0.8.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
26
+ google_genai-0.8.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
27
+ google_genai-0.8.0.dist-info/RECORD,,