google-genai 1.11.0__py3-none-any.whl → 1.12.1__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 +25 -41
- google/genai/_automatic_function_calling_util.py +4 -24
- google/genai/_common.py +40 -37
- google/genai/_extra_utils.py +7 -7
- google/genai/_live_converters.py +2487 -0
- google/genai/_replay_api_client.py +32 -26
- google/genai/_transformers.py +46 -81
- google/genai/batches.py +45 -45
- google/genai/caches.py +126 -126
- google/genai/chats.py +13 -9
- google/genai/client.py +3 -2
- google/genai/errors.py +6 -6
- google/genai/files.py +38 -38
- google/genai/live.py +69 -17
- google/genai/models.py +388 -388
- google/genai/operations.py +33 -33
- google/genai/pagers.py +2 -2
- google/genai/py.typed +1 -0
- google/genai/tunings.py +70 -70
- google/genai/types.py +456 -24
- google/genai/version.py +1 -1
- {google_genai-1.11.0.dist-info → google_genai-1.12.1.dist-info}/METADATA +1 -1
- google_genai-1.12.1.dist-info/RECORD +29 -0
- {google_genai-1.11.0.dist-info → google_genai-1.12.1.dist-info}/WHEEL +1 -1
- google/genai/live_converters.py +0 -1298
- google_genai-1.11.0.dist-info/RECORD +0 -28
- {google_genai-1.11.0.dist-info → google_genai-1.12.1.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.11.0.dist-info → google_genai-1.12.1.dist-info}/top_level.txt +0 -0
google/genai/types.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 Google LLC
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -23,7 +23,7 @@ import logging
|
|
23
23
|
import sys
|
24
24
|
import types as builtin_types
|
25
25
|
import typing
|
26
|
-
from typing import Any, Callable, Literal, Optional, Union, _UnionGenericAlias # type: ignore
|
26
|
+
from typing import Any, Callable, Literal, Optional, Sequence, Union, _UnionGenericAlias # type: ignore
|
27
27
|
import pydantic
|
28
28
|
from pydantic import Field
|
29
29
|
from typing_extensions import TypedDict
|
@@ -40,6 +40,7 @@ else:
|
|
40
40
|
|
41
41
|
_is_pillow_image_imported = False
|
42
42
|
if typing.TYPE_CHECKING:
|
43
|
+
from ._api_client import BaseApiClient
|
43
44
|
import PIL.Image
|
44
45
|
|
45
46
|
PIL_Image = PIL.Image.Image
|
@@ -139,6 +140,7 @@ class FinishReason(_common.CaseInSensitiveEnum):
|
|
139
140
|
MAX_TOKENS = 'MAX_TOKENS'
|
140
141
|
SAFETY = 'SAFETY'
|
141
142
|
RECITATION = 'RECITATION'
|
143
|
+
LANGUAGE = 'LANGUAGE'
|
142
144
|
OTHER = 'OTHER'
|
143
145
|
BLOCKLIST = 'BLOCKLIST'
|
144
146
|
PROHIBITED_CONTENT = 'PROHIBITED_CONTENT'
|
@@ -641,7 +643,22 @@ class Part(_common.BaseModel):
|
|
641
643
|
)
|
642
644
|
|
643
645
|
@classmethod
|
644
|
-
def from_uri(
|
646
|
+
def from_uri(
|
647
|
+
cls, *, file_uri: str, mime_type: Optional[str] = None
|
648
|
+
) -> 'Part':
|
649
|
+
"""Creates a Part from a file uri.
|
650
|
+
|
651
|
+
Args:
|
652
|
+
file_uri (str): The uri of the file
|
653
|
+
mime_type (str): mime_type: The MIME type of the image. If not provided,
|
654
|
+
the MIME type will be automatically determined.
|
655
|
+
"""
|
656
|
+
if mime_type is None:
|
657
|
+
import mimetypes
|
658
|
+
|
659
|
+
mime_type, _ = mimetypes.guess_type(file_uri)
|
660
|
+
if not mime_type:
|
661
|
+
raise ValueError(f'Failed to determine mime type for file: {file_uri}')
|
645
662
|
file_data = FileData(file_uri=file_uri, mime_type=mime_type)
|
646
663
|
return cls(file_data=file_data)
|
647
664
|
|
@@ -1172,6 +1189,288 @@ class Schema(_common.BaseModel):
|
|
1172
1189
|
|
1173
1190
|
return convert_schema(self)
|
1174
1191
|
|
1192
|
+
@classmethod
|
1193
|
+
def from_json_schema(
|
1194
|
+
cls,
|
1195
|
+
*,
|
1196
|
+
json_schema: JSONSchema,
|
1197
|
+
api_option: Literal['VERTEX_AI', 'GEMINI_API'] = 'GEMINI_API',
|
1198
|
+
raise_error_on_unsupported_field: bool = False,
|
1199
|
+
) -> 'Schema':
|
1200
|
+
"""Converts a JSONSchema object to a Schema object.
|
1201
|
+
|
1202
|
+
The JSONSchema is compatible with 2020-12 JSON Schema draft, specified by
|
1203
|
+
OpenAPI 3.1.
|
1204
|
+
|
1205
|
+
Args:
|
1206
|
+
json_schema: JSONSchema object to be converted.
|
1207
|
+
api_option: API option to be used. If set to 'VERTEX_AI', the JSONSchema
|
1208
|
+
will be converted to a Schema object that is compatible with Vertex AI
|
1209
|
+
API. If set to 'GEMINI_API', the JSONSchema will be converted to a
|
1210
|
+
Schema object that is compatible with Gemini API. Default is
|
1211
|
+
'GEMINI_API'.
|
1212
|
+
raise_error_on_unsupported_field: If set to True, an error will be
|
1213
|
+
raised if the JSONSchema contains any unsupported fields. Default is
|
1214
|
+
False.
|
1215
|
+
|
1216
|
+
Returns:
|
1217
|
+
Schema object that is compatible with the specified API option.
|
1218
|
+
Raises:
|
1219
|
+
ValueError: If the JSONSchema contains any unsupported fields and
|
1220
|
+
raise_error_on_unsupported_field is set to True. Or if the JSONSchema
|
1221
|
+
is not compatible with the specified API option.
|
1222
|
+
"""
|
1223
|
+
google_schema_field_names: set[str] = set(cls.model_fields.keys())
|
1224
|
+
schema_field_names: tuple[str, ...] = (
|
1225
|
+
'items',
|
1226
|
+
) # 'additional_properties' to come
|
1227
|
+
list_schema_field_names: tuple[str, ...] = (
|
1228
|
+
'any_of', # 'one_of', 'all_of', 'not' to come
|
1229
|
+
)
|
1230
|
+
dict_schema_field_names: tuple[str, ...] = ('properties',) # 'defs' to come
|
1231
|
+
|
1232
|
+
number_integer_related_field_names: tuple[str, ...] = (
|
1233
|
+
'description',
|
1234
|
+
'enum',
|
1235
|
+
'format',
|
1236
|
+
'maximum',
|
1237
|
+
'minimum',
|
1238
|
+
'title',
|
1239
|
+
)
|
1240
|
+
string_related_field_names: tuple[str, ...] = (
|
1241
|
+
'description',
|
1242
|
+
'enum',
|
1243
|
+
'format',
|
1244
|
+
'max_length',
|
1245
|
+
'min_length',
|
1246
|
+
'pattern',
|
1247
|
+
'title',
|
1248
|
+
)
|
1249
|
+
object_related_field_names: tuple[str, ...] = (
|
1250
|
+
'any_of',
|
1251
|
+
'description',
|
1252
|
+
'max_properties',
|
1253
|
+
'min_properties',
|
1254
|
+
'properties',
|
1255
|
+
'required',
|
1256
|
+
'title',
|
1257
|
+
)
|
1258
|
+
array_related_field_names: tuple[str, ...] = (
|
1259
|
+
'description',
|
1260
|
+
'items',
|
1261
|
+
'max_items',
|
1262
|
+
'min_items',
|
1263
|
+
'title',
|
1264
|
+
)
|
1265
|
+
boolean_related_field_names: tuple[str, ...] = (
|
1266
|
+
'description',
|
1267
|
+
'title',
|
1268
|
+
)
|
1269
|
+
# placeholder for potential gemini api unsupported fields
|
1270
|
+
gemini_api_unsupported_field_names: tuple[str, ...] = ()
|
1271
|
+
|
1272
|
+
def normalize_json_schema_type(
|
1273
|
+
json_schema_type: Optional[
|
1274
|
+
Union[JSONSchemaType, Sequence[JSONSchemaType], str, Sequence[str]]
|
1275
|
+
],
|
1276
|
+
) -> tuple[list[str], bool]:
|
1277
|
+
"""Returns (non_null_types, nullable)"""
|
1278
|
+
if json_schema_type is None:
|
1279
|
+
return [], False
|
1280
|
+
if isinstance(json_schema_type, str):
|
1281
|
+
if json_schema_type == JSONSchemaType.NULL.value:
|
1282
|
+
return [], True
|
1283
|
+
return [json_schema_type], False
|
1284
|
+
if isinstance(json_schema_type, JSONSchemaType):
|
1285
|
+
if json_schema_type == JSONSchemaType.NULL:
|
1286
|
+
return [], True
|
1287
|
+
return [json_schema_type.value], False
|
1288
|
+
non_null_types = []
|
1289
|
+
nullable = False
|
1290
|
+
for type_value in json_schema_type:
|
1291
|
+
if isinstance(type_value, JSONSchemaType):
|
1292
|
+
type_value = type_value.value
|
1293
|
+
if type_value == JSONSchemaType.NULL.value:
|
1294
|
+
nullable = True
|
1295
|
+
else:
|
1296
|
+
non_null_types.append(type_value)
|
1297
|
+
return non_null_types, nullable
|
1298
|
+
|
1299
|
+
def raise_error_if_cannot_convert(
|
1300
|
+
json_schema_dict: dict[str, Any],
|
1301
|
+
api_option: Literal['VERTEX_AI', 'GEMINI_API'],
|
1302
|
+
raise_error_on_unsupported_field: bool,
|
1303
|
+
) -> None:
|
1304
|
+
"""Raises an error if the JSONSchema cannot be converted to the specified Schema object."""
|
1305
|
+
if not raise_error_on_unsupported_field:
|
1306
|
+
return
|
1307
|
+
for field_name, field_value in json_schema_dict.items():
|
1308
|
+
if field_value is None:
|
1309
|
+
continue
|
1310
|
+
if field_name not in google_schema_field_names:
|
1311
|
+
raise ValueError((
|
1312
|
+
f'JSONSchema field "{field_name}" is not supported by the '
|
1313
|
+
'Schema object. And the "raise_error_on_unsupported_field" '
|
1314
|
+
'argument is set to True. If you still want to convert '
|
1315
|
+
'it into the Schema object, please either remove the field '
|
1316
|
+
f'"{field_name}" from the JSONSchema object, or leave the '
|
1317
|
+
'"raise_error_on_unsupported_field" unset.'
|
1318
|
+
))
|
1319
|
+
if (
|
1320
|
+
field_name in gemini_api_unsupported_field_names
|
1321
|
+
and api_option == 'GEMINI_API'
|
1322
|
+
):
|
1323
|
+
raise ValueError((
|
1324
|
+
f'The "{field_name}" field is not supported by the Schema '
|
1325
|
+
'object for GEMINI_API.'
|
1326
|
+
))
|
1327
|
+
|
1328
|
+
def copy_schema_fields(
|
1329
|
+
json_schema_dict: dict[str, Any],
|
1330
|
+
related_fields_to_copy: tuple[str, ...],
|
1331
|
+
sub_schema_in_any_of: dict[str, Any],
|
1332
|
+
) -> None:
|
1333
|
+
"""Copies the fields from json_schema_dict to sub_schema_in_any_of."""
|
1334
|
+
for field_name in related_fields_to_copy:
|
1335
|
+
sub_schema_in_any_of[field_name] = json_schema_dict.get(
|
1336
|
+
field_name, None
|
1337
|
+
)
|
1338
|
+
|
1339
|
+
def convert_json_schema(
|
1340
|
+
json_schema: JSONSchema,
|
1341
|
+
api_option: Literal['VERTEX_AI', 'GEMINI_API'],
|
1342
|
+
raise_error_on_unsupported_field: bool,
|
1343
|
+
) -> 'Schema':
|
1344
|
+
schema = Schema()
|
1345
|
+
json_schema_dict = json_schema.model_dump()
|
1346
|
+
raise_error_if_cannot_convert(
|
1347
|
+
json_schema_dict=json_schema_dict,
|
1348
|
+
api_option=api_option,
|
1349
|
+
raise_error_on_unsupported_field=raise_error_on_unsupported_field,
|
1350
|
+
)
|
1351
|
+
|
1352
|
+
# At the highest level of the logic, there are two passes:
|
1353
|
+
# Pass 1: the JSONSchema.type is union-like,
|
1354
|
+
# e.g. ['null', 'string', 'array'].
|
1355
|
+
# for this case, we need to split the JSONSchema into multiple
|
1356
|
+
# sub-schemas, and copy them into the any_of field of the Schema.
|
1357
|
+
# And when we copy the non-type fields into any_of field,
|
1358
|
+
# we only copy the fields related to the specific type.
|
1359
|
+
# Detailed logic is commented below with `Pass 1` keyword tag.
|
1360
|
+
# Pass 2: the JSONSchema.type is not union-like,
|
1361
|
+
# e.g. 'string', ['string'], ['null', 'string'].
|
1362
|
+
# for this case, no splitting is needed. Detailed
|
1363
|
+
# logic is commented below with `Pass 2` keyword tag.
|
1364
|
+
#
|
1365
|
+
#
|
1366
|
+
# Pass 1: the JSONSchema.type is union-like
|
1367
|
+
# e.g. ['null', 'string', 'array'].
|
1368
|
+
non_null_types, nullable = normalize_json_schema_type(
|
1369
|
+
json_schema_dict.get('type', None)
|
1370
|
+
)
|
1371
|
+
if len(non_null_types) > 1:
|
1372
|
+
logger.warning(
|
1373
|
+
'JSONSchema type is union-like, e.g. ["null", "string", "array"]. '
|
1374
|
+
'Converting it into multiple sub-schemas, and copying them into '
|
1375
|
+
'the any_of field of the Schema. The value of `default` field is '
|
1376
|
+
'ignored because it is ambiguous to tell which sub-schema it '
|
1377
|
+
'belongs to.'
|
1378
|
+
)
|
1379
|
+
reformed_json_schema = JSONSchema()
|
1380
|
+
# start splitting the JSONSchema into multiple sub-schemas
|
1381
|
+
any_of = []
|
1382
|
+
if nullable:
|
1383
|
+
schema.nullable = True
|
1384
|
+
for normalized_type in non_null_types:
|
1385
|
+
sub_schema_in_any_of = {'type': normalized_type}
|
1386
|
+
if normalized_type == JSONSchemaType.BOOLEAN.value:
|
1387
|
+
copy_schema_fields(
|
1388
|
+
json_schema_dict=json_schema_dict,
|
1389
|
+
related_fields_to_copy=boolean_related_field_names,
|
1390
|
+
sub_schema_in_any_of=sub_schema_in_any_of,
|
1391
|
+
)
|
1392
|
+
elif normalized_type in (
|
1393
|
+
JSONSchemaType.NUMBER.value,
|
1394
|
+
JSONSchemaType.INTEGER.value,
|
1395
|
+
):
|
1396
|
+
copy_schema_fields(
|
1397
|
+
json_schema_dict=json_schema_dict,
|
1398
|
+
related_fields_to_copy=number_integer_related_field_names,
|
1399
|
+
sub_schema_in_any_of=sub_schema_in_any_of,
|
1400
|
+
)
|
1401
|
+
elif normalized_type == JSONSchemaType.STRING.value:
|
1402
|
+
copy_schema_fields(
|
1403
|
+
json_schema_dict=json_schema_dict,
|
1404
|
+
related_fields_to_copy=string_related_field_names,
|
1405
|
+
sub_schema_in_any_of=sub_schema_in_any_of,
|
1406
|
+
)
|
1407
|
+
elif normalized_type == JSONSchemaType.ARRAY.value:
|
1408
|
+
copy_schema_fields(
|
1409
|
+
json_schema_dict=json_schema_dict,
|
1410
|
+
related_fields_to_copy=array_related_field_names,
|
1411
|
+
sub_schema_in_any_of=sub_schema_in_any_of,
|
1412
|
+
)
|
1413
|
+
elif normalized_type == JSONSchemaType.OBJECT.value:
|
1414
|
+
copy_schema_fields(
|
1415
|
+
json_schema_dict=json_schema_dict,
|
1416
|
+
related_fields_to_copy=object_related_field_names,
|
1417
|
+
sub_schema_in_any_of=sub_schema_in_any_of,
|
1418
|
+
)
|
1419
|
+
any_of.append(JSONSchema(**sub_schema_in_any_of))
|
1420
|
+
reformed_json_schema.any_of = any_of
|
1421
|
+
json_schema_dict = reformed_json_schema.model_dump()
|
1422
|
+
|
1423
|
+
# Pass 2: the JSONSchema.type is not union-like,
|
1424
|
+
# e.g. 'string', ['string'], ['null', 'string'].
|
1425
|
+
for field_name, field_value in json_schema_dict.items():
|
1426
|
+
if field_value is None:
|
1427
|
+
continue
|
1428
|
+
if field_name in schema_field_names:
|
1429
|
+
schema_field_value: 'Schema' = convert_json_schema(
|
1430
|
+
json_schema=JSONSchema(**field_value),
|
1431
|
+
api_option=api_option,
|
1432
|
+
raise_error_on_unsupported_field=raise_error_on_unsupported_field,
|
1433
|
+
)
|
1434
|
+
setattr(schema, field_name, schema_field_value)
|
1435
|
+
elif field_name in list_schema_field_names:
|
1436
|
+
list_schema_field_value: list['Schema'] = [
|
1437
|
+
convert_json_schema(
|
1438
|
+
json_schema=JSONSchema(**this_field_value),
|
1439
|
+
api_option=api_option,
|
1440
|
+
raise_error_on_unsupported_field=raise_error_on_unsupported_field,
|
1441
|
+
)
|
1442
|
+
for this_field_value in field_value
|
1443
|
+
]
|
1444
|
+
setattr(schema, field_name, list_schema_field_value)
|
1445
|
+
elif field_name in dict_schema_field_names:
|
1446
|
+
dict_schema_field_value: dict[str, 'Schema'] = {
|
1447
|
+
key: convert_json_schema(
|
1448
|
+
json_schema=JSONSchema(**value),
|
1449
|
+
api_option=api_option,
|
1450
|
+
raise_error_on_unsupported_field=raise_error_on_unsupported_field,
|
1451
|
+
)
|
1452
|
+
for key, value in field_value.items()
|
1453
|
+
}
|
1454
|
+
setattr(schema, field_name, dict_schema_field_value)
|
1455
|
+
elif field_name == 'type':
|
1456
|
+
# non_null_types can only be empty or have one element.
|
1457
|
+
# because already handled union-like case above.
|
1458
|
+
non_null_types, nullable = normalize_json_schema_type(field_value)
|
1459
|
+
if nullable:
|
1460
|
+
schema.nullable = True
|
1461
|
+
if non_null_types:
|
1462
|
+
schema.type = Type(non_null_types[0])
|
1463
|
+
else:
|
1464
|
+
setattr(schema, field_name, field_value)
|
1465
|
+
|
1466
|
+
return schema
|
1467
|
+
|
1468
|
+
return convert_json_schema(
|
1469
|
+
json_schema=json_schema,
|
1470
|
+
api_option=api_option,
|
1471
|
+
raise_error_on_unsupported_field=raise_error_on_unsupported_field,
|
1472
|
+
)
|
1473
|
+
|
1175
1474
|
|
1176
1475
|
class SchemaDict(TypedDict, total=False):
|
1177
1476
|
"""Schema that defines the format of input and output data.
|
@@ -1331,7 +1630,7 @@ class FunctionDeclaration(_common.BaseModel):
|
|
1331
1630
|
def from_callable_with_api_option(
|
1332
1631
|
cls,
|
1333
1632
|
*,
|
1334
|
-
callable: Callable,
|
1633
|
+
callable: Callable[..., Any],
|
1335
1634
|
api_option: Literal['VERTEX_AI', 'GEMINI_API'] = 'GEMINI_API',
|
1336
1635
|
) -> 'FunctionDeclaration':
|
1337
1636
|
"""Converts a Callable to a FunctionDeclaration based on the API option.
|
@@ -1397,8 +1696,8 @@ class FunctionDeclaration(_common.BaseModel):
|
|
1397
1696
|
def from_callable(
|
1398
1697
|
cls,
|
1399
1698
|
*,
|
1400
|
-
client,
|
1401
|
-
callable: Callable,
|
1699
|
+
client: 'BaseApiClient',
|
1700
|
+
callable: Callable[..., Any],
|
1402
1701
|
) -> 'FunctionDeclaration':
|
1403
1702
|
"""Converts a Callable to a FunctionDeclaration based on the client."""
|
1404
1703
|
if client.vertexai:
|
@@ -1873,11 +2172,11 @@ class ToolDict(TypedDict, total=False):
|
|
1873
2172
|
|
1874
2173
|
|
1875
2174
|
ToolOrDict = Union[Tool, ToolDict]
|
1876
|
-
ToolListUnion = list[Union[Tool, Callable]]
|
1877
|
-
ToolListUnionDict = list[Union[ToolDict, Callable]]
|
2175
|
+
ToolListUnion = list[Union[Tool, Callable[..., Any]]]
|
2176
|
+
ToolListUnionDict = list[Union[ToolDict, Callable[..., Any]]]
|
1878
2177
|
|
1879
2178
|
SchemaUnion = Union[
|
1880
|
-
dict, type, Schema, builtin_types.GenericAlias, VersionedUnionType # type: ignore[valid-type]
|
2179
|
+
dict[Any, Any], type, Schema, builtin_types.GenericAlias, VersionedUnionType # type: ignore[valid-type]
|
1881
2180
|
]
|
1882
2181
|
SchemaUnionDict = Union[SchemaUnion, SchemaDict]
|
1883
2182
|
|
@@ -2497,7 +2796,7 @@ class GenerateContentConfig(_common.BaseModel):
|
|
2497
2796
|
|
2498
2797
|
@pydantic.field_validator('response_schema', mode='before')
|
2499
2798
|
@classmethod
|
2500
|
-
def _convert_literal_to_enum(cls, value):
|
2799
|
+
def _convert_literal_to_enum(cls, value: Any) -> Union[Any, EnumMeta]:
|
2501
2800
|
if typing.get_origin(value) is typing.Literal:
|
2502
2801
|
enum_vals = typing.get_args(value)
|
2503
2802
|
if not all(isinstance(arg, str) for arg in enum_vals):
|
@@ -3490,7 +3789,7 @@ class GenerateContentResponse(_common.BaseModel):
|
|
3490
3789
|
default=None, description="""Usage metadata about the response(s)."""
|
3491
3790
|
)
|
3492
3791
|
automatic_function_calling_history: Optional[list[Content]] = None
|
3493
|
-
parsed: Optional[Union[pydantic.BaseModel, dict, Enum]] = Field(
|
3792
|
+
parsed: Optional[Union[pydantic.BaseModel, dict[Any, Any], Enum]] = Field(
|
3494
3793
|
default=None,
|
3495
3794
|
description="""First candidate from the parsed response if response_schema is provided. Not available for streaming.""",
|
3496
3795
|
)
|
@@ -4210,7 +4509,7 @@ class Image(_common.BaseModel):
|
|
4210
4509
|
default=None, description="""The MIME type of the image."""
|
4211
4510
|
)
|
4212
4511
|
|
4213
|
-
_loaded_image = None
|
4512
|
+
_loaded_image: Optional['PIL_Image'] = None
|
4214
4513
|
|
4215
4514
|
"""Image."""
|
4216
4515
|
|
@@ -4256,7 +4555,7 @@ class Image(_common.BaseModel):
|
|
4256
4555
|
image = cls(image_bytes=image_bytes, mime_type=mime_type)
|
4257
4556
|
return image
|
4258
4557
|
|
4259
|
-
def show(self):
|
4558
|
+
def show(self) -> None:
|
4260
4559
|
"""Shows the image.
|
4261
4560
|
|
4262
4561
|
This method only works in a notebook environment.
|
@@ -4270,7 +4569,7 @@ class Image(_common.BaseModel):
|
|
4270
4569
|
IPython_display.display(self._pil_image)
|
4271
4570
|
|
4272
4571
|
@property
|
4273
|
-
def _pil_image(self) -> 'PIL_Image':
|
4572
|
+
def _pil_image(self) -> Optional['PIL_Image']:
|
4274
4573
|
PIL_Image: Optional[builtin_types.ModuleType]
|
4275
4574
|
try:
|
4276
4575
|
from PIL import Image as PIL_Image
|
@@ -4289,7 +4588,7 @@ class Image(_common.BaseModel):
|
|
4289
4588
|
self._loaded_image = PIL_Image.open(io.BytesIO(self.image_bytes))
|
4290
4589
|
return self._loaded_image
|
4291
4590
|
|
4292
|
-
def save(self, location: str):
|
4591
|
+
def save(self, location: str) -> None:
|
4293
4592
|
"""Saves the image to a file.
|
4294
4593
|
|
4295
4594
|
Args:
|
@@ -5840,7 +6139,7 @@ class Video(_common.BaseModel):
|
|
5840
6139
|
|
5841
6140
|
pathlib.Path(path).write_bytes(self.video_bytes)
|
5842
6141
|
|
5843
|
-
def show(self):
|
6142
|
+
def show(self) -> None:
|
5844
6143
|
"""Shows the video.
|
5845
6144
|
|
5846
6145
|
If the video has no mime_type, it is assumed to be video/mp4.
|
@@ -5848,9 +6147,9 @@ class Video(_common.BaseModel):
|
|
5848
6147
|
This method only works in a notebook environment.
|
5849
6148
|
"""
|
5850
6149
|
if self.uri and not self.video_bytes:
|
5851
|
-
|
6150
|
+
raise ValueError('Showing remote videos is not supported.')
|
5852
6151
|
if not self.video_bytes:
|
5853
|
-
|
6152
|
+
raise ValueError('Video has no bytes.')
|
5854
6153
|
|
5855
6154
|
mime_type = self.mime_type or 'video/mp4'
|
5856
6155
|
|
@@ -5866,7 +6165,7 @@ class Video(_common.BaseModel):
|
|
5866
6165
|
)
|
5867
6166
|
)
|
5868
6167
|
|
5869
|
-
def __repr__(self):
|
6168
|
+
def __repr__(self) -> str:
|
5870
6169
|
video_bytes = '<video_bytes>' if self.video_bytes else 'None'
|
5871
6170
|
return (
|
5872
6171
|
f'Video(uri={self.uri}, video_bytes={video_bytes},'
|
@@ -8930,7 +9229,7 @@ class RawReferenceImage(_common.BaseModel):
|
|
8930
9229
|
|
8931
9230
|
@pydantic.model_validator(mode='before')
|
8932
9231
|
@classmethod
|
8933
|
-
def _validate_mask_image_config(self, values):
|
9232
|
+
def _validate_mask_image_config(self, values: Any) -> Any:
|
8934
9233
|
if 'reference_type' in values:
|
8935
9234
|
raise ValueError('Cannot set internal reference_type field directly.')
|
8936
9235
|
values['reference_type'] = 'REFERENCE_TYPE_RAW'
|
@@ -8992,7 +9291,7 @@ class MaskReferenceImage(_common.BaseModel):
|
|
8992
9291
|
|
8993
9292
|
@pydantic.model_validator(mode='before')
|
8994
9293
|
@classmethod
|
8995
|
-
def _validate_mask_image_config(self, values):
|
9294
|
+
def _validate_mask_image_config(self, values: Any) -> Any:
|
8996
9295
|
config = values.get('config', None)
|
8997
9296
|
values['mask_image_config'] = config
|
8998
9297
|
if 'reference_type' in values:
|
@@ -9063,7 +9362,7 @@ class ControlReferenceImage(_common.BaseModel):
|
|
9063
9362
|
|
9064
9363
|
@pydantic.model_validator(mode='before')
|
9065
9364
|
@classmethod
|
9066
|
-
def _validate_mask_image_config(self, values):
|
9365
|
+
def _validate_mask_image_config(self, values: Any) -> Any:
|
9067
9366
|
config = values.get('config', None)
|
9068
9367
|
values['control_image_config'] = config
|
9069
9368
|
if 'reference_type' in values:
|
@@ -9134,7 +9433,7 @@ class StyleReferenceImage(_common.BaseModel):
|
|
9134
9433
|
|
9135
9434
|
@pydantic.model_validator(mode='before')
|
9136
9435
|
@classmethod
|
9137
|
-
def _validate_mask_image_config(self, values):
|
9436
|
+
def _validate_mask_image_config(self, values: Any) -> Any:
|
9138
9437
|
config = values.get('config', None)
|
9139
9438
|
values['style_image_config'] = config
|
9140
9439
|
if 'reference_type' in values:
|
@@ -9201,7 +9500,7 @@ class SubjectReferenceImage(_common.BaseModel):
|
|
9201
9500
|
|
9202
9501
|
@pydantic.model_validator(mode='before')
|
9203
9502
|
@classmethod
|
9204
|
-
def _validate_mask_image_config(self, values):
|
9503
|
+
def _validate_mask_image_config(self, values: Any) -> Any:
|
9205
9504
|
config = values.get('config', None)
|
9206
9505
|
values['subject_image_config'] = config
|
9207
9506
|
if 'reference_type' in values:
|
@@ -10079,6 +10378,33 @@ class LiveClientRealtimeInput(_common.BaseModel):
|
|
10079
10378
|
media_chunks: Optional[list[Blob]] = Field(
|
10080
10379
|
default=None, description="""Inlined bytes data for media input."""
|
10081
10380
|
)
|
10381
|
+
audio: Optional[Blob] = Field(
|
10382
|
+
default=None, description="""The realtime audio input stream."""
|
10383
|
+
)
|
10384
|
+
audio_stream_end: Optional[bool] = Field(
|
10385
|
+
default=None,
|
10386
|
+
description="""
|
10387
|
+
Indicates that the audio stream has ended, e.g. because the microphone was
|
10388
|
+
turned off.
|
10389
|
+
|
10390
|
+
This should only be sent when automatic activity detection is enabled
|
10391
|
+
(which is the default).
|
10392
|
+
|
10393
|
+
The client can reopen the stream by sending an audio message.
|
10394
|
+
""",
|
10395
|
+
)
|
10396
|
+
video: Optional[Blob] = Field(
|
10397
|
+
default=None, description="""The realtime video input stream."""
|
10398
|
+
)
|
10399
|
+
text: Optional[str] = Field(
|
10400
|
+
default=None, description="""The realtime text input stream."""
|
10401
|
+
)
|
10402
|
+
activity_start: Optional[ActivityStart] = Field(
|
10403
|
+
default=None, description="""Marks the start of user activity."""
|
10404
|
+
)
|
10405
|
+
activity_end: Optional[ActivityEnd] = Field(
|
10406
|
+
default=None, description="""Marks the end of user activity."""
|
10407
|
+
)
|
10082
10408
|
|
10083
10409
|
|
10084
10410
|
class LiveClientRealtimeInputDict(TypedDict, total=False):
|
@@ -10101,6 +10427,32 @@ class LiveClientRealtimeInputDict(TypedDict, total=False):
|
|
10101
10427
|
media_chunks: Optional[list[BlobDict]]
|
10102
10428
|
"""Inlined bytes data for media input."""
|
10103
10429
|
|
10430
|
+
audio: Optional[BlobDict]
|
10431
|
+
"""The realtime audio input stream."""
|
10432
|
+
|
10433
|
+
audio_stream_end: Optional[bool]
|
10434
|
+
"""
|
10435
|
+
Indicates that the audio stream has ended, e.g. because the microphone was
|
10436
|
+
turned off.
|
10437
|
+
|
10438
|
+
This should only be sent when automatic activity detection is enabled
|
10439
|
+
(which is the default).
|
10440
|
+
|
10441
|
+
The client can reopen the stream by sending an audio message.
|
10442
|
+
"""
|
10443
|
+
|
10444
|
+
video: Optional[BlobDict]
|
10445
|
+
"""The realtime video input stream."""
|
10446
|
+
|
10447
|
+
text: Optional[str]
|
10448
|
+
"""The realtime text input stream."""
|
10449
|
+
|
10450
|
+
activity_start: Optional[ActivityStartDict]
|
10451
|
+
"""Marks the start of user activity."""
|
10452
|
+
|
10453
|
+
activity_end: Optional[ActivityEndDict]
|
10454
|
+
"""Marks the end of user activity."""
|
10455
|
+
|
10104
10456
|
|
10105
10457
|
LiveClientRealtimeInputOrDict = Union[
|
10106
10458
|
LiveClientRealtimeInput, LiveClientRealtimeInputDict
|
@@ -10404,3 +10756,83 @@ class LiveConnectParametersDict(TypedDict, total=False):
|
|
10404
10756
|
LiveConnectParametersOrDict = Union[
|
10405
10757
|
LiveConnectParameters, LiveConnectParametersDict
|
10406
10758
|
]
|
10759
|
+
|
10760
|
+
if _is_pillow_image_imported:
|
10761
|
+
BlobImageUnion = Union[Blob, PIL_Image]
|
10762
|
+
else:
|
10763
|
+
BlobImageUnion = Blob # type: ignore[misc]
|
10764
|
+
|
10765
|
+
BlobImageUnionDict = Union[BlobImageUnion, BlobDict]
|
10766
|
+
|
10767
|
+
|
10768
|
+
class LiveSendRealtimeInputParameters(_common.BaseModel):
|
10769
|
+
"""Parameters for sending realtime input to the live API."""
|
10770
|
+
|
10771
|
+
media: Optional[BlobImageUnion] = Field(
|
10772
|
+
default=None, description="""Realtime input to send to the session."""
|
10773
|
+
)
|
10774
|
+
audio: Optional[Blob] = Field(
|
10775
|
+
default=None, description="""The realtime audio input stream."""
|
10776
|
+
)
|
10777
|
+
audio_stream_end: Optional[bool] = Field(
|
10778
|
+
default=None,
|
10779
|
+
description="""
|
10780
|
+
Indicates that the audio stream has ended, e.g. because the microphone was
|
10781
|
+
turned off.
|
10782
|
+
|
10783
|
+
This should only be sent when automatic activity detection is enabled
|
10784
|
+
(which is the default).
|
10785
|
+
|
10786
|
+
The client can reopen the stream by sending an audio message.
|
10787
|
+
""",
|
10788
|
+
)
|
10789
|
+
video: Optional[BlobImageUnion] = Field(
|
10790
|
+
default=None, description="""The realtime video input stream."""
|
10791
|
+
)
|
10792
|
+
text: Optional[str] = Field(
|
10793
|
+
default=None, description="""The realtime text input stream."""
|
10794
|
+
)
|
10795
|
+
activity_start: Optional[ActivityStart] = Field(
|
10796
|
+
default=None, description="""Marks the start of user activity."""
|
10797
|
+
)
|
10798
|
+
activity_end: Optional[ActivityEnd] = Field(
|
10799
|
+
default=None, description="""Marks the end of user activity."""
|
10800
|
+
)
|
10801
|
+
|
10802
|
+
|
10803
|
+
class LiveSendRealtimeInputParametersDict(TypedDict, total=False):
|
10804
|
+
"""Parameters for sending realtime input to the live API."""
|
10805
|
+
|
10806
|
+
media: Optional[BlobImageUnionDict]
|
10807
|
+
"""Realtime input to send to the session."""
|
10808
|
+
|
10809
|
+
audio: Optional[BlobDict]
|
10810
|
+
"""The realtime audio input stream."""
|
10811
|
+
|
10812
|
+
audio_stream_end: Optional[bool]
|
10813
|
+
"""
|
10814
|
+
Indicates that the audio stream has ended, e.g. because the microphone was
|
10815
|
+
turned off.
|
10816
|
+
|
10817
|
+
This should only be sent when automatic activity detection is enabled
|
10818
|
+
(which is the default).
|
10819
|
+
|
10820
|
+
The client can reopen the stream by sending an audio message.
|
10821
|
+
"""
|
10822
|
+
|
10823
|
+
video: Optional[BlobImageUnionDict]
|
10824
|
+
"""The realtime video input stream."""
|
10825
|
+
|
10826
|
+
text: Optional[str]
|
10827
|
+
"""The realtime text input stream."""
|
10828
|
+
|
10829
|
+
activity_start: Optional[ActivityStartDict]
|
10830
|
+
"""Marks the start of user activity."""
|
10831
|
+
|
10832
|
+
activity_end: Optional[ActivityEndDict]
|
10833
|
+
"""Marks the end of user activity."""
|
10834
|
+
|
10835
|
+
|
10836
|
+
LiveSendRealtimeInputParametersOrDict = Union[
|
10837
|
+
LiveSendRealtimeInputParameters, LiveSendRealtimeInputParametersDict
|
10838
|
+
]
|
google/genai/version.py
CHANGED