google-genai 1.32.0__py3-none-any.whl → 1.33.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.
- google/genai/_api_client.py +32 -9
- google/genai/_replay_api_client.py +15 -0
- google/genai/files.py +2 -0
- google/genai/models.py +27 -179
- google/genai/types.py +165 -236
- google/genai/version.py +1 -1
- {google_genai-1.32.0.dist-info → google_genai-1.33.0.dist-info}/METADATA +1 -1
- {google_genai-1.32.0.dist-info → google_genai-1.33.0.dist-info}/RECORD +11 -11
- {google_genai-1.32.0.dist-info → google_genai-1.33.0.dist-info}/WHEEL +0 -0
- {google_genai-1.32.0.dist-info → google_genai-1.33.0.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.32.0.dist-info → google_genai-1.33.0.dist-info}/top_level.txt +0 -0
google/genai/_api_client.py
CHANGED
@@ -584,13 +584,9 @@ class BaseApiClient:
|
|
584
584
|
# Initialize the lock. This lock will be used to protect access to the
|
585
585
|
# credentials. This is crucial for thread safety when multiple coroutines
|
586
586
|
# might be accessing the credentials at the same time.
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
except RuntimeError:
|
591
|
-
asyncio.set_event_loop(asyncio.new_event_loop())
|
592
|
-
self._sync_auth_lock = threading.Lock()
|
593
|
-
self._async_auth_lock = asyncio.Lock()
|
587
|
+
self._sync_auth_lock = threading.Lock()
|
588
|
+
self._async_auth_lock: Optional[asyncio.Lock] = None
|
589
|
+
self._async_auth_lock_creation_lock: Optional[asyncio.Lock] = None
|
594
590
|
|
595
591
|
# Handle when to use Vertex AI in express mode (api key).
|
596
592
|
# Explicit initializer arguments are already validated above.
|
@@ -903,10 +899,36 @@ class BaseApiClient:
|
|
903
899
|
else:
|
904
900
|
raise RuntimeError('Could not resolve API token from the environment')
|
905
901
|
|
902
|
+
async def _get_async_auth_lock(self) -> asyncio.Lock:
|
903
|
+
"""Lazily initializes and returns an asyncio.Lock for async authentication.
|
904
|
+
|
905
|
+
This method ensures that a single `asyncio.Lock` instance is created and
|
906
|
+
shared among all asynchronous operations that require authentication,
|
907
|
+
preventing race conditions when accessing or refreshing credentials.
|
908
|
+
|
909
|
+
The lock is created on the first call to this method. An internal async lock
|
910
|
+
is used to protect the creation of the main authentication lock to ensure
|
911
|
+
it's a singleton within the client instance.
|
912
|
+
|
913
|
+
Returns:
|
914
|
+
The asyncio.Lock instance for asynchronous authentication operations.
|
915
|
+
"""
|
916
|
+
if self._async_auth_lock is None:
|
917
|
+
# Create async creation lock if needed
|
918
|
+
if self._async_auth_lock_creation_lock is None:
|
919
|
+
self._async_auth_lock_creation_lock = asyncio.Lock()
|
920
|
+
|
921
|
+
async with self._async_auth_lock_creation_lock:
|
922
|
+
if self._async_auth_lock is None:
|
923
|
+
self._async_auth_lock = asyncio.Lock()
|
924
|
+
|
925
|
+
return self._async_auth_lock
|
926
|
+
|
906
927
|
async def _async_access_token(self) -> Union[str, Any]:
|
907
928
|
"""Retrieves the access token for the credentials asynchronously."""
|
908
929
|
if not self._credentials:
|
909
|
-
|
930
|
+
async_auth_lock = await self._get_async_auth_lock()
|
931
|
+
async with async_auth_lock:
|
910
932
|
# This ensures that only one coroutine can execute the auth logic at a
|
911
933
|
# time for thread safety.
|
912
934
|
if not self._credentials:
|
@@ -920,7 +942,8 @@ class BaseApiClient:
|
|
920
942
|
if self._credentials:
|
921
943
|
if self._credentials.expired or not self._credentials.token:
|
922
944
|
# Only refresh when it needs to. Default expiration is 3600 seconds.
|
923
|
-
|
945
|
+
async_auth_lock = await self._get_async_auth_lock()
|
946
|
+
async with async_auth_lock:
|
924
947
|
if self._credentials.expired or not self._credentials.token:
|
925
948
|
# Double check that the credentials expired before refreshing.
|
926
949
|
await asyncio.to_thread(refresh_auth, self._credentials)
|
@@ -471,6 +471,21 @@ class ReplayApiClient(BaseApiClient):
|
|
471
471
|
expected = interaction.response.sdk_response_segments[
|
472
472
|
self._sdk_response_index
|
473
473
|
]
|
474
|
+
# The sdk_http_response.body has format in the string, need to get rid of
|
475
|
+
# the format information before comparing.
|
476
|
+
if isinstance(expected, dict):
|
477
|
+
if 'sdk_http_response' in expected and isinstance(
|
478
|
+
expected['sdk_http_response'], dict
|
479
|
+
):
|
480
|
+
if 'body' in expected['sdk_http_response']:
|
481
|
+
raw_body = expected['sdk_http_response']['body']
|
482
|
+
print('raw_body length: ', len(raw_body))
|
483
|
+
print('raw_body: ', raw_body)
|
484
|
+
if isinstance(raw_body, str) and raw_body != '':
|
485
|
+
raw_body = json.loads(raw_body)
|
486
|
+
raw_body = json.dumps(raw_body)
|
487
|
+
expected['sdk_http_response']['body'] = raw_body
|
488
|
+
|
474
489
|
assert (
|
475
490
|
actual == expected
|
476
491
|
), f'SDK response mismatch:\nActual: {actual}\nExpected: {expected}'
|
google/genai/files.py
CHANGED
@@ -434,6 +434,7 @@ class Files(_api_module.BaseModule):
|
|
434
434
|
config, 'should_return_http_response', None
|
435
435
|
):
|
436
436
|
return_value = types.CreateFileResponse(sdk_http_response=response)
|
437
|
+
self._api_client._verify_response(return_value)
|
437
438
|
return return_value
|
438
439
|
|
439
440
|
response_dict = '' if not response.body else json.loads(response.body)
|
@@ -916,6 +917,7 @@ class AsyncFiles(_api_module.BaseModule):
|
|
916
917
|
config, 'should_return_http_response', None
|
917
918
|
):
|
918
919
|
return_value = types.CreateFileResponse(sdk_http_response=response)
|
920
|
+
self._api_client._verify_response(return_value)
|
919
921
|
return return_value
|
920
922
|
|
921
923
|
response_dict = '' if not response.body else json.loads(response.body)
|
google/genai/models.py
CHANGED
@@ -1330,7 +1330,11 @@ def _GenerateVideosConfig_to_mldev(
|
|
1330
1330
|
)
|
1331
1331
|
|
1332
1332
|
if getv(from_object, ['resolution']) is not None:
|
1333
|
-
|
1333
|
+
setv(
|
1334
|
+
parent_object,
|
1335
|
+
['parameters', 'resolution'],
|
1336
|
+
getv(from_object, ['resolution']),
|
1337
|
+
)
|
1334
1338
|
|
1335
1339
|
if getv(from_object, ['person_generation']) is not None:
|
1336
1340
|
setv(
|
@@ -5256,6 +5260,13 @@ class Models(_api_module.BaseModule):
|
|
5256
5260
|
'post', path, request_dict, http_options
|
5257
5261
|
)
|
5258
5262
|
|
5263
|
+
if config is not None and getattr(
|
5264
|
+
config, 'should_return_http_response', None
|
5265
|
+
):
|
5266
|
+
return_value = types.GenerateContentResponse(sdk_http_response=response)
|
5267
|
+
self._api_client._verify_response(return_value)
|
5268
|
+
return return_value
|
5269
|
+
|
5259
5270
|
response_dict = '' if not response.body else json.loads(response.body)
|
5260
5271
|
|
5261
5272
|
if self._api_client.vertexai:
|
@@ -5455,13 +5466,7 @@ class Models(_api_module.BaseModule):
|
|
5455
5466
|
prompt: str,
|
5456
5467
|
config: Optional[types.GenerateImagesConfigOrDict] = None,
|
5457
5468
|
) -> types.GenerateImagesResponse:
|
5458
|
-
"""
|
5459
|
-
|
5460
|
-
Args:
|
5461
|
-
model (str): The model to use.
|
5462
|
-
prompt (str): A text description of the images to generate.
|
5463
|
-
config (GenerateImagesConfig): Configuration for generation.
|
5464
|
-
"""
|
5469
|
+
"""Private method for generating images."""
|
5465
5470
|
|
5466
5471
|
parameter_model = types._GenerateImagesParameters(
|
5467
5472
|
model=model,
|
@@ -5534,47 +5539,7 @@ class Models(_api_module.BaseModule):
|
|
5534
5539
|
reference_images: list[types._ReferenceImageAPIOrDict],
|
5535
5540
|
config: Optional[types.EditImageConfigOrDict] = None,
|
5536
5541
|
) -> types.EditImageResponse:
|
5537
|
-
"""
|
5538
|
-
|
5539
|
-
Args:
|
5540
|
-
model (str): The model to use.
|
5541
|
-
prompt (str): A text description of the edit to apply to the image.
|
5542
|
-
reference_images (list[Union[RawReferenceImage, MaskReferenceImage,
|
5543
|
-
ControlReferenceImage, StyleReferenceImage, SubjectReferenceImage]): The
|
5544
|
-
reference images for editing.
|
5545
|
-
config (EditImageConfig): Configuration for editing.
|
5546
|
-
|
5547
|
-
Usage:
|
5548
|
-
|
5549
|
-
.. code-block:: python
|
5550
|
-
|
5551
|
-
from google.genai.types import RawReferenceImage, MaskReferenceImage
|
5552
|
-
|
5553
|
-
raw_ref_image = RawReferenceImage(
|
5554
|
-
reference_id=1,
|
5555
|
-
reference_image=types.Image.from_file(IMAGE_FILE_PATH),
|
5556
|
-
)
|
5557
|
-
|
5558
|
-
mask_ref_image = MaskReferenceImage(
|
5559
|
-
reference_id=2,
|
5560
|
-
config=types.MaskReferenceConfig(
|
5561
|
-
mask_mode='MASK_MODE_FOREGROUND',
|
5562
|
-
mask_dilation=0.06,
|
5563
|
-
),
|
5564
|
-
)
|
5565
|
-
response = client.models.edit_image(
|
5566
|
-
model='imagen-3.0-capability-001',
|
5567
|
-
prompt='man with dog',
|
5568
|
-
reference_images=[raw_ref_image, mask_ref_image],
|
5569
|
-
config=types.EditImageConfig(
|
5570
|
-
edit_mode= "EDIT_MODE_INPAINT_INSERTION",
|
5571
|
-
number_of_images= 1,
|
5572
|
-
include_rai_reason= True,
|
5573
|
-
)
|
5574
|
-
)
|
5575
|
-
response.generated_images[0].image.show()
|
5576
|
-
# Shows a man with a dog instead of a cat.
|
5577
|
-
"""
|
5542
|
+
"""Private method for editing an image."""
|
5578
5543
|
|
5579
5544
|
parameter_model = types._EditImageParameters(
|
5580
5545
|
model=model,
|
@@ -5638,14 +5603,7 @@ class Models(_api_module.BaseModule):
|
|
5638
5603
|
upscale_factor: str,
|
5639
5604
|
config: Optional[types._UpscaleImageAPIConfigOrDict] = None,
|
5640
5605
|
) -> types.UpscaleImageResponse:
|
5641
|
-
"""
|
5642
|
-
|
5643
|
-
Args:
|
5644
|
-
model (str): The model to use.
|
5645
|
-
image (Image): The input image for upscaling.
|
5646
|
-
upscale_factor (str): The factor to upscale the image (x2 or x4).
|
5647
|
-
config (_UpscaleImageAPIConfig): Configuration for upscaling.
|
5648
|
-
"""
|
5606
|
+
"""Private method for upscaling an image."""
|
5649
5607
|
|
5650
5608
|
parameter_model = types._UpscaleImageAPIParameters(
|
5651
5609
|
model=model,
|
@@ -6331,39 +6289,7 @@ class Models(_api_module.BaseModule):
|
|
6331
6289
|
source: Optional[types.GenerateVideosSourceOrDict] = None,
|
6332
6290
|
config: Optional[types.GenerateVideosConfigOrDict] = None,
|
6333
6291
|
) -> types.GenerateVideosOperation:
|
6334
|
-
"""
|
6335
|
-
|
6336
|
-
The following use cases are supported:
|
6337
|
-
1. Text to video generation.
|
6338
|
-
2a. Image to video generation (additional text prompt is optional).
|
6339
|
-
2b. Image to video generation with frame interpolation (specify last_frame
|
6340
|
-
in config).
|
6341
|
-
3. Video extension (additional text prompt is optional)
|
6342
|
-
|
6343
|
-
Args:
|
6344
|
-
model: The model to use.
|
6345
|
-
prompt: The text prompt for generating the videos. Optional for image to
|
6346
|
-
video and video extension use cases.
|
6347
|
-
image: The input image for generating the videos. Optional if prompt is
|
6348
|
-
provided.
|
6349
|
-
video: The input video for video extension use cases. Optional if prompt
|
6350
|
-
or image is provided.
|
6351
|
-
config: Configuration for generation.
|
6352
|
-
|
6353
|
-
Usage:
|
6354
|
-
|
6355
|
-
```
|
6356
|
-
operation = client.models.generate_videos(
|
6357
|
-
model="veo-2.0-generate-001",
|
6358
|
-
prompt="A neon hologram of a cat driving at top speed",
|
6359
|
-
)
|
6360
|
-
while not operation.done:
|
6361
|
-
time.sleep(10)
|
6362
|
-
operation = client.operations.get(operation)
|
6363
|
-
|
6364
|
-
operation.result.generated_videos[0].video.uri
|
6365
|
-
```
|
6366
|
-
"""
|
6292
|
+
"""Private method for generating videos."""
|
6367
6293
|
|
6368
6294
|
parameter_model = types._GenerateVideosParameters(
|
6369
6295
|
model=model,
|
@@ -7081,6 +7007,13 @@ class AsyncModels(_api_module.BaseModule):
|
|
7081
7007
|
'post', path, request_dict, http_options
|
7082
7008
|
)
|
7083
7009
|
|
7010
|
+
if config is not None and getattr(
|
7011
|
+
config, 'should_return_http_response', None
|
7012
|
+
):
|
7013
|
+
return_value = types.GenerateContentResponse(sdk_http_response=response)
|
7014
|
+
self._api_client._verify_response(return_value)
|
7015
|
+
return return_value
|
7016
|
+
|
7084
7017
|
response_dict = '' if not response.body else json.loads(response.body)
|
7085
7018
|
|
7086
7019
|
if self._api_client.vertexai:
|
@@ -7285,13 +7218,7 @@ class AsyncModels(_api_module.BaseModule):
|
|
7285
7218
|
prompt: str,
|
7286
7219
|
config: Optional[types.GenerateImagesConfigOrDict] = None,
|
7287
7220
|
) -> types.GenerateImagesResponse:
|
7288
|
-
"""
|
7289
|
-
|
7290
|
-
Args:
|
7291
|
-
model (str): The model to use.
|
7292
|
-
prompt (str): A text description of the images to generate.
|
7293
|
-
config (GenerateImagesConfig): Configuration for generation.
|
7294
|
-
"""
|
7221
|
+
"""Private method for generating images asynchronously."""
|
7295
7222
|
|
7296
7223
|
parameter_model = types._GenerateImagesParameters(
|
7297
7224
|
model=model,
|
@@ -7364,47 +7291,7 @@ class AsyncModels(_api_module.BaseModule):
|
|
7364
7291
|
reference_images: list[types._ReferenceImageAPIOrDict],
|
7365
7292
|
config: Optional[types.EditImageConfigOrDict] = None,
|
7366
7293
|
) -> types.EditImageResponse:
|
7367
|
-
"""
|
7368
|
-
|
7369
|
-
Args:
|
7370
|
-
model (str): The model to use.
|
7371
|
-
prompt (str): A text description of the edit to apply to the image.
|
7372
|
-
reference_images (list[Union[RawReferenceImage, MaskReferenceImage,
|
7373
|
-
ControlReferenceImage, StyleReferenceImage, SubjectReferenceImage]): The
|
7374
|
-
reference images for editing.
|
7375
|
-
config (EditImageConfig): Configuration for editing.
|
7376
|
-
|
7377
|
-
Usage:
|
7378
|
-
|
7379
|
-
.. code-block:: python
|
7380
|
-
|
7381
|
-
from google.genai.types import RawReferenceImage, MaskReferenceImage
|
7382
|
-
|
7383
|
-
raw_ref_image = RawReferenceImage(
|
7384
|
-
reference_id=1,
|
7385
|
-
reference_image=types.Image.from_file(IMAGE_FILE_PATH),
|
7386
|
-
)
|
7387
|
-
|
7388
|
-
mask_ref_image = MaskReferenceImage(
|
7389
|
-
reference_id=2,
|
7390
|
-
config=types.MaskReferenceConfig(
|
7391
|
-
mask_mode='MASK_MODE_FOREGROUND',
|
7392
|
-
mask_dilation=0.06,
|
7393
|
-
),
|
7394
|
-
)
|
7395
|
-
response = await client.aio.models.edit_image(
|
7396
|
-
model='imagen-3.0-capability-001',
|
7397
|
-
prompt='man with dog',
|
7398
|
-
reference_images=[raw_ref_image, mask_ref_image],
|
7399
|
-
config=types.EditImageConfig(
|
7400
|
-
edit_mode= "EDIT_MODE_INPAINT_INSERTION",
|
7401
|
-
number_of_images= 1,
|
7402
|
-
include_rai_reason= True,
|
7403
|
-
)
|
7404
|
-
)
|
7405
|
-
response.generated_images[0].image.show()
|
7406
|
-
# Shows a man with a dog instead of a cat.
|
7407
|
-
"""
|
7294
|
+
"""Private method for editing an image asynchronously."""
|
7408
7295
|
|
7409
7296
|
parameter_model = types._EditImageParameters(
|
7410
7297
|
model=model,
|
@@ -7468,14 +7355,7 @@ class AsyncModels(_api_module.BaseModule):
|
|
7468
7355
|
upscale_factor: str,
|
7469
7356
|
config: Optional[types._UpscaleImageAPIConfigOrDict] = None,
|
7470
7357
|
) -> types.UpscaleImageResponse:
|
7471
|
-
"""
|
7472
|
-
|
7473
|
-
Args:
|
7474
|
-
model (str): The model to use.
|
7475
|
-
image (Image): The input image for upscaling.
|
7476
|
-
upscale_factor (str): The factor to upscale the image (x2 or x4).
|
7477
|
-
config (_UpscaleImageAPIConfig): Configuration for upscaling.
|
7478
|
-
"""
|
7358
|
+
"""Private method for upscaling an image asynchronously."""
|
7479
7359
|
|
7480
7360
|
parameter_model = types._UpscaleImageAPIParameters(
|
7481
7361
|
model=model,
|
@@ -8167,39 +8047,7 @@ class AsyncModels(_api_module.BaseModule):
|
|
8167
8047
|
source: Optional[types.GenerateVideosSourceOrDict] = None,
|
8168
8048
|
config: Optional[types.GenerateVideosConfigOrDict] = None,
|
8169
8049
|
) -> types.GenerateVideosOperation:
|
8170
|
-
"""
|
8171
|
-
|
8172
|
-
The following use cases are supported:
|
8173
|
-
1. Text to video generation.
|
8174
|
-
2a. Image to video generation (additional text prompt is optional).
|
8175
|
-
2b. Image to video generation with frame interpolation (specify last_frame
|
8176
|
-
in config).
|
8177
|
-
3. Video extension (additional text prompt is optional)
|
8178
|
-
|
8179
|
-
Args:
|
8180
|
-
model: The model to use.
|
8181
|
-
prompt: The text prompt for generating the videos. Optional for image to
|
8182
|
-
video and video extension use cases.
|
8183
|
-
image: The input image for generating the videos. Optional if prompt is
|
8184
|
-
provided.
|
8185
|
-
video: The input video for video extension use cases. Optional if prompt
|
8186
|
-
or image is provided.
|
8187
|
-
config: Configuration for generation.
|
8188
|
-
|
8189
|
-
Usage:
|
8190
|
-
|
8191
|
-
```
|
8192
|
-
operation = client.models.generate_videos(
|
8193
|
-
model="veo-2.0-generate-001",
|
8194
|
-
prompt="A neon hologram of a cat driving at top speed",
|
8195
|
-
)
|
8196
|
-
while not operation.done:
|
8197
|
-
time.sleep(10)
|
8198
|
-
operation = client.operations.get(operation)
|
8199
|
-
|
8200
|
-
operation.result.generated_videos[0].video.uri
|
8201
|
-
```
|
8202
|
-
"""
|
8050
|
+
"""Private method for generating videos asynchronously."""
|
8203
8051
|
|
8204
8052
|
parameter_model = types._GenerateVideosParameters(
|
8205
8053
|
model=model,
|