google-genai 1.47.0__py3-none-any.whl → 1.48.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.
@@ -15,6 +15,7 @@
15
15
 
16
16
  """Extra utils depending on types that are shared between sync and async modules."""
17
17
 
18
+ import asyncio
18
19
  import inspect
19
20
  import io
20
21
  import logging
@@ -117,6 +118,35 @@ def format_destination(
117
118
  return config
118
119
 
119
120
 
121
+ def find_afc_incompatible_tool_indexes(
122
+ config: Optional[types.GenerateContentConfigOrDict] = None,
123
+ ) -> list[int]:
124
+ """Checks if the config contains any AFC incompatible tools.
125
+
126
+ A `types.Tool` object that contains `function_declarations` is considered a
127
+ non-AFC tool for this execution path.
128
+
129
+ Args:
130
+ config: The GenerateContentConfig to check for incompatible tools.
131
+
132
+ Returns:
133
+ A list of indexes of the incompatible tools in the config.
134
+ """
135
+ if not config:
136
+ return []
137
+ config_model = _create_generate_content_config_model(config)
138
+ incompatible_tools_indexes: list[int] = []
139
+
140
+ if not config_model or not config_model.tools:
141
+ return incompatible_tools_indexes
142
+
143
+ for index, tool in enumerate(config_model.tools):
144
+ if isinstance(tool, types.Tool) and tool.function_declarations:
145
+ incompatible_tools_indexes.append(index)
146
+
147
+ return incompatible_tools_indexes
148
+
149
+
120
150
  def get_function_map(
121
151
  config: Optional[types.GenerateContentConfigOrDict] = None,
122
152
  mcp_to_genai_tool_adapters: Optional[
@@ -371,7 +401,9 @@ async def get_function_response_parts_async(
371
401
  }
372
402
  else:
373
403
  func_response = {
374
- 'result': invoke_function_from_dict_args(args, func)
404
+ 'result': await asyncio.to_thread(
405
+ invoke_function_from_dict_args, args, func
406
+ )
375
407
  }
376
408
  except Exception as e: # pylint: disable=broad-except
377
409
  func_response = {'error': str(e)}
@@ -536,13 +568,14 @@ async def parse_config_for_mcp_sessions(
536
568
  def append_chunk_contents(
537
569
  contents: Union[types.ContentListUnion, types.ContentListUnionDict],
538
570
  chunk: types.GenerateContentResponse,
539
- ) -> None:
540
- """Appends the contents of the chunk to the contents list."""
571
+ ) -> Union[types.ContentListUnion, types.ContentListUnionDict]:
572
+ """Appends the contents of the chunk to the contents list and returns it."""
541
573
  if chunk is not None and chunk.candidates is not None:
542
574
  chunk_content = chunk.candidates[0].content
543
575
  contents = t.t_contents(contents) # type: ignore[assignment]
544
576
  if isinstance(contents, list) and chunk_content is not None:
545
577
  contents.append(chunk_content) # type: ignore[arg-type]
578
+ return contents
546
579
 
547
580
 
548
581
  def prepare_resumable_upload(
@@ -258,6 +258,11 @@ def _GoogleSearch_to_mldev(
258
258
  'exclude_domains parameter is not supported in Gemini API.'
259
259
  )
260
260
 
261
+ if getv(from_object, ['blocking_confidence']) is not None:
262
+ raise ValueError(
263
+ 'blocking_confidence parameter is not supported in Gemini API.'
264
+ )
265
+
261
266
  if getv(from_object, ['time_range_filter']) is not None:
262
267
  setv(
263
268
  to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
@@ -172,6 +172,11 @@ def _GoogleSearch_to_mldev(
172
172
  'exclude_domains parameter is not supported in Gemini API.'
173
173
  )
174
174
 
175
+ if getv(from_object, ['blocking_confidence']) is not None:
176
+ raise ValueError(
177
+ 'blocking_confidence parameter is not supported in Gemini API.'
178
+ )
179
+
175
180
  if getv(from_object, ['time_range_filter']) is not None:
176
181
  setv(
177
182
  to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
google/genai/batches.py CHANGED
@@ -1040,6 +1040,11 @@ def _GoogleSearch_to_mldev(
1040
1040
  'exclude_domains parameter is not supported in Gemini API.'
1041
1041
  )
1042
1042
 
1043
+ if getv(from_object, ['blocking_confidence']) is not None:
1044
+ raise ValueError(
1045
+ 'blocking_confidence parameter is not supported in Gemini API.'
1046
+ )
1047
+
1043
1048
  if getv(from_object, ['time_range_filter']) is not None:
1044
1049
  setv(
1045
1050
  to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
google/genai/caches.py CHANGED
@@ -386,6 +386,11 @@ def _GoogleSearch_to_mldev(
386
386
  'exclude_domains parameter is not supported in Gemini API.'
387
387
  )
388
388
 
389
+ if getv(from_object, ['blocking_confidence']) is not None:
390
+ raise ValueError(
391
+ 'blocking_confidence parameter is not supported in Gemini API.'
392
+ )
393
+
389
394
  if getv(from_object, ['time_range_filter']) is not None:
390
395
  setv(
391
396
  to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
google/genai/models.py CHANGED
@@ -2462,6 +2462,11 @@ def _GoogleSearch_to_mldev(
2462
2462
  'exclude_domains parameter is not supported in Gemini API.'
2463
2463
  )
2464
2464
 
2465
+ if getv(from_object, ['blocking_confidence']) is not None:
2466
+ raise ValueError(
2467
+ 'blocking_confidence parameter is not supported in Gemini API.'
2468
+ )
2469
+
2465
2470
  if getv(from_object, ['time_range_filter']) is not None:
2466
2471
  setv(
2467
2472
  to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
@@ -4993,6 +4998,9 @@ class Models(_api_module.BaseModule):
4993
4998
  # scones.
4994
4999
  """
4995
5000
 
5001
+ incompatible_tools_indexes = (
5002
+ _extra_utils.find_afc_incompatible_tool_indexes(config)
5003
+ )
4996
5004
  parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
4997
5005
  if (
4998
5006
  parsed_config
@@ -5006,6 +5014,28 @@ class Models(_api_module.BaseModule):
5006
5014
  return self._generate_content(
5007
5015
  model=model, contents=contents, config=parsed_config
5008
5016
  )
5017
+ if incompatible_tools_indexes:
5018
+ original_tools_length = 0
5019
+ if isinstance(config, types.GenerateContentConfig):
5020
+ if config.tools:
5021
+ original_tools_length = len(config.tools)
5022
+ elif isinstance(config, dict):
5023
+ tools = config.get('tools', [])
5024
+ if tools:
5025
+ original_tools_length = len(tools)
5026
+ if len(incompatible_tools_indexes) != original_tools_length:
5027
+ indices_str = ', '.join(map(str, incompatible_tools_indexes))
5028
+ logger.warning(
5029
+ 'Tools at indices [%s] are not compatible with automatic function '
5030
+ 'calling (AFC). AFC is disabled. If AFC is intended, please '
5031
+ 'include python callables in the tool list, and do not include '
5032
+ 'function declaration in the tool list.',
5033
+ indices_str,
5034
+ )
5035
+ return self._generate_content(
5036
+ model=model, contents=contents, config=parsed_config
5037
+ )
5038
+
5009
5039
  remaining_remote_calls_afc = _extra_utils.get_max_remote_calls_afc(
5010
5040
  parsed_config
5011
5041
  )
@@ -5129,6 +5159,9 @@ class Models(_api_module.BaseModule):
5129
5159
  # scones.
5130
5160
  """
5131
5161
 
5162
+ incompatible_tools_indexes = (
5163
+ _extra_utils.find_afc_incompatible_tool_indexes(config)
5164
+ )
5132
5165
  parsed_config = _extra_utils.parse_config_for_mcp_usage(config)
5133
5166
  if (
5134
5167
  parsed_config
@@ -5144,6 +5177,27 @@ class Models(_api_module.BaseModule):
5144
5177
  )
5145
5178
  return
5146
5179
 
5180
+ if incompatible_tools_indexes:
5181
+ original_tools_length = 0
5182
+ if isinstance(config, types.GenerateContentConfig):
5183
+ if config.tools:
5184
+ original_tools_length = len(config.tools)
5185
+ elif isinstance(config, dict):
5186
+ tools = config.get('tools', [])
5187
+ if tools:
5188
+ original_tools_length = len(tools)
5189
+ if len(incompatible_tools_indexes) != original_tools_length:
5190
+ indices_str = ', '.join(map(str, incompatible_tools_indexes))
5191
+ logger.warning(
5192
+ 'Tools at indices [%s] are not compatible with automatic function '
5193
+ 'calling. AFC will be disabled.',
5194
+ indices_str,
5195
+ )
5196
+ yield from self._generate_content_stream(
5197
+ model=model, contents=contents, config=parsed_config
5198
+ )
5199
+ return
5200
+
5147
5201
  remaining_remote_calls_afc = _extra_utils.get_max_remote_calls_afc(
5148
5202
  parsed_config
5149
5203
  )
@@ -5168,7 +5222,7 @@ class Models(_api_module.BaseModule):
5168
5222
  # Yield chunks only if there's no function response parts.
5169
5223
  for chunk in response:
5170
5224
  if not function_map:
5171
- _extra_utils.append_chunk_contents(contents, chunk)
5225
+ contents = _extra_utils.append_chunk_contents(contents, chunk) # type: ignore[assignment]
5172
5226
  yield chunk
5173
5227
  else:
5174
5228
  if (
@@ -5181,7 +5235,7 @@ class Models(_api_module.BaseModule):
5181
5235
  chunk, function_map
5182
5236
  )
5183
5237
  if not func_response_parts:
5184
- _extra_utils.append_chunk_contents(contents, chunk)
5238
+ contents = _extra_utils.append_chunk_contents(contents, chunk) # type: ignore[assignment]
5185
5239
  yield chunk
5186
5240
 
5187
5241
  else:
@@ -5191,7 +5245,7 @@ class Models(_api_module.BaseModule):
5191
5245
  chunk.automatic_function_calling_history = (
5192
5246
  automatic_function_calling_history
5193
5247
  )
5194
- _extra_utils.append_chunk_contents(contents, chunk)
5248
+ contents = _extra_utils.append_chunk_contents(contents, chunk) # type: ignore[assignment]
5195
5249
  yield chunk
5196
5250
  if (
5197
5251
  chunk is None
@@ -6759,6 +6813,9 @@ class AsyncModels(_api_module.BaseModule):
6759
6813
  # J'aime les bagels.
6760
6814
  """
6761
6815
  # Retrieve and cache any MCP sessions if provided.
6816
+ incompatible_tools_indexes = (
6817
+ _extra_utils.find_afc_incompatible_tool_indexes(config)
6818
+ )
6762
6819
  parsed_config, mcp_to_genai_tool_adapters = (
6763
6820
  await _extra_utils.parse_config_for_mcp_sessions(config)
6764
6821
  )
@@ -6766,6 +6823,27 @@ class AsyncModels(_api_module.BaseModule):
6766
6823
  return await self._generate_content(
6767
6824
  model=model, contents=contents, config=parsed_config
6768
6825
  )
6826
+ if incompatible_tools_indexes:
6827
+ original_tools_length = 0
6828
+ if isinstance(config, types.GenerateContentConfig):
6829
+ if config.tools:
6830
+ original_tools_length = len(config.tools)
6831
+ elif isinstance(config, dict):
6832
+ tools = config.get('tools', [])
6833
+ if tools:
6834
+ original_tools_length = len(tools)
6835
+ if len(incompatible_tools_indexes) != original_tools_length:
6836
+ indices_str = ', '.join(map(str, incompatible_tools_indexes))
6837
+ logger.warning(
6838
+ 'Tools at indices [%s] are not compatible with automatic function '
6839
+ 'calling (AFC). AFC is disabled. If AFC is intended, please '
6840
+ 'include python callables in the tool list, and do not include '
6841
+ 'function declaration in the tool list.',
6842
+ indices_str,
6843
+ )
6844
+ return await self._generate_content(
6845
+ model=model, contents=contents, config=parsed_config
6846
+ )
6769
6847
  remaining_remote_calls_afc = _extra_utils.get_max_remote_calls_afc(
6770
6848
  parsed_config
6771
6849
  )
@@ -6890,6 +6968,10 @@ class AsyncModels(_api_module.BaseModule):
6890
6968
  # scones.
6891
6969
  """
6892
6970
 
6971
+ # Retrieve and cache any MCP sessions if provided.
6972
+ incompatible_tools_indexes = (
6973
+ _extra_utils.find_afc_incompatible_tool_indexes(config)
6974
+ )
6893
6975
  # Retrieve and cache any MCP sessions if provided.
6894
6976
  parsed_config, mcp_to_genai_tool_adapters = (
6895
6977
  await _extra_utils.parse_config_for_mcp_sessions(config)
@@ -6905,6 +6987,34 @@ class AsyncModels(_api_module.BaseModule):
6905
6987
 
6906
6988
  return base_async_generator(model, contents, parsed_config) # type: ignore[no-untyped-call, no-any-return]
6907
6989
 
6990
+ if incompatible_tools_indexes:
6991
+ original_tools_length = 0
6992
+ if isinstance(config, types.GenerateContentConfig):
6993
+ if config.tools:
6994
+ original_tools_length = len(config.tools)
6995
+ elif isinstance(config, dict):
6996
+ tools = config.get('tools', [])
6997
+ if tools:
6998
+ original_tools_length = len(tools)
6999
+ if len(incompatible_tools_indexes) != original_tools_length:
7000
+ indices_str = ', '.join(map(str, incompatible_tools_indexes))
7001
+ logger.warning(
7002
+ 'Tools at indices [%s] are not compatible with automatic function '
7003
+ 'calling (AFC). AFC is disabled. If AFC is intended, please '
7004
+ 'include python callables in the tool list, and do not include '
7005
+ 'function declaration in the tool list.',
7006
+ indices_str,
7007
+ )
7008
+ response = await self._generate_content_stream(
7009
+ model=model, contents=contents, config=parsed_config
7010
+ )
7011
+
7012
+ async def base_async_generator(model, contents, config): # type: ignore[no-untyped-def]
7013
+ async for chunk in response: # type: ignore[attr-defined]
7014
+ yield chunk
7015
+
7016
+ return base_async_generator(model, contents, parsed_config) # type: ignore[no-untyped-call, no-any-return]
7017
+
6908
7018
  async def async_generator(model, contents, config): # type: ignore[no-untyped-def]
6909
7019
  remaining_remote_calls_afc = _extra_utils.get_max_remote_calls_afc(config)
6910
7020
  logger.info(
@@ -6938,7 +7048,7 @@ class AsyncModels(_api_module.BaseModule):
6938
7048
  # Yield chunks only if there's no function response parts.
6939
7049
  async for chunk in response: # type: ignore[attr-defined]
6940
7050
  if not function_map:
6941
- _extra_utils.append_chunk_contents(contents, chunk)
7051
+ contents = _extra_utils.append_chunk_contents(contents, chunk)
6942
7052
  yield chunk
6943
7053
  else:
6944
7054
  if (
@@ -6953,7 +7063,7 @@ class AsyncModels(_api_module.BaseModule):
6953
7063
  )
6954
7064
  )
6955
7065
  if not func_response_parts:
6956
- _extra_utils.append_chunk_contents(contents, chunk)
7066
+ contents = _extra_utils.append_chunk_contents(contents, chunk)
6957
7067
  yield chunk
6958
7068
 
6959
7069
  else:
@@ -6964,7 +7074,7 @@ class AsyncModels(_api_module.BaseModule):
6964
7074
  chunk.automatic_function_calling_history = (
6965
7075
  automatic_function_calling_history
6966
7076
  )
6967
- _extra_utils.append_chunk_contents(contents, chunk)
7077
+ contents = _extra_utils.append_chunk_contents(contents, chunk)
6968
7078
  yield chunk
6969
7079
  if (
6970
7080
  chunk is None
google/genai/types.py CHANGED
@@ -214,6 +214,28 @@ class ApiSpec(_common.CaseInSensitiveEnum):
214
214
  """Elastic search API spec."""
215
215
 
216
216
 
217
+ class PhishBlockThreshold(_common.CaseInSensitiveEnum):
218
+ """Sites with confidence level chosen & above this value will be blocked from the search results.
219
+
220
+ This enum is not supported in Gemini API.
221
+ """
222
+
223
+ PHISH_BLOCK_THRESHOLD_UNSPECIFIED = 'PHISH_BLOCK_THRESHOLD_UNSPECIFIED'
224
+ """Defaults to unspecified."""
225
+ BLOCK_LOW_AND_ABOVE = 'BLOCK_LOW_AND_ABOVE'
226
+ """Blocks Low and above confidence URL that is risky."""
227
+ BLOCK_MEDIUM_AND_ABOVE = 'BLOCK_MEDIUM_AND_ABOVE'
228
+ """Blocks Medium and above confidence URL that is risky."""
229
+ BLOCK_HIGH_AND_ABOVE = 'BLOCK_HIGH_AND_ABOVE'
230
+ """Blocks High and above confidence URL that is risky."""
231
+ BLOCK_HIGHER_AND_ABOVE = 'BLOCK_HIGHER_AND_ABOVE'
232
+ """Blocks Higher and above confidence URL that is risky."""
233
+ BLOCK_VERY_HIGH_AND_ABOVE = 'BLOCK_VERY_HIGH_AND_ABOVE'
234
+ """Blocks Very high and above confidence URL that is risky."""
235
+ BLOCK_ONLY_EXTREMELY_HIGH = 'BLOCK_ONLY_EXTREMELY_HIGH'
236
+ """Blocks Extremely high confidence URL that is risky."""
237
+
238
+
217
239
  class HarmCategory(_common.CaseInSensitiveEnum):
218
240
  """Harm category."""
219
241
 
@@ -3554,6 +3576,10 @@ class EnterpriseWebSearch(_common.BaseModel):
3554
3576
  default=None,
3555
3577
  description="""Optional. List of domains to be excluded from the search results. The default limit is 2000 domains.""",
3556
3578
  )
3579
+ blocking_confidence: Optional[PhishBlockThreshold] = Field(
3580
+ default=None,
3581
+ description="""Optional. Sites with confidence level chosen & above this value will be blocked from the search results.""",
3582
+ )
3557
3583
 
3558
3584
 
3559
3585
  class EnterpriseWebSearchDict(TypedDict, total=False):
@@ -3565,6 +3591,9 @@ class EnterpriseWebSearchDict(TypedDict, total=False):
3565
3591
  exclude_domains: Optional[list[str]]
3566
3592
  """Optional. List of domains to be excluded from the search results. The default limit is 2000 domains."""
3567
3593
 
3594
+ blocking_confidence: Optional[PhishBlockThreshold]
3595
+ """Optional. Sites with confidence level chosen & above this value will be blocked from the search results."""
3596
+
3568
3597
 
3569
3598
  EnterpriseWebSearchOrDict = Union[EnterpriseWebSearch, EnterpriseWebSearchDict]
3570
3599
 
@@ -3615,6 +3644,10 @@ class GoogleSearch(_common.BaseModel):
3615
3644
  default=None,
3616
3645
  description="""Optional. List of domains to be excluded from the search results. The default limit is 2000 domains. Example: ["amazon.com", "facebook.com"]. This field is not supported in Gemini API.""",
3617
3646
  )
3647
+ blocking_confidence: Optional[PhishBlockThreshold] = Field(
3648
+ default=None,
3649
+ description="""Optional. Sites with confidence level chosen & above this value will be blocked from the search results. This field is not supported in Gemini API.""",
3650
+ )
3618
3651
  time_range_filter: Optional[Interval] = Field(
3619
3652
  default=None,
3620
3653
  description="""Optional. Filter search results to a specific time range. If customers set a start time, they must set an end time (and vice versa). This field is not supported in Vertex AI.""",
@@ -3630,6 +3663,9 @@ class GoogleSearchDict(TypedDict, total=False):
3630
3663
  exclude_domains: Optional[list[str]]
3631
3664
  """Optional. List of domains to be excluded from the search results. The default limit is 2000 domains. Example: ["amazon.com", "facebook.com"]. This field is not supported in Gemini API."""
3632
3665
 
3666
+ blocking_confidence: Optional[PhishBlockThreshold]
3667
+ """Optional. Sites with confidence level chosen & above this value will be blocked from the search results. This field is not supported in Gemini API."""
3668
+
3633
3669
  time_range_filter: Optional[IntervalDict]
3634
3670
  """Optional. Filter search results to a specific time range. If customers set a start time, they must set an end time (and vice versa). This field is not supported in Vertex AI."""
3635
3671
 
@@ -5993,10 +6029,18 @@ class GenerateContentResponse(_common.BaseModel):
5993
6029
  description="""First candidate from the parsed response if response_schema is provided. Not available for streaming.""",
5994
6030
  )
5995
6031
 
5996
- def _get_text(self, warn_property: str = 'text') -> Optional[str]:
6032
+ def _get_text(self, warn_property: Optional[str] = None) -> Optional[str]:
5997
6033
  """Returns the concatenation of all text parts in the response.
5998
6034
 
5999
- This is an internal method that allows customizing the warning message.
6035
+ This is an internal method that allows customizing or disabling the warning
6036
+ message.
6037
+
6038
+ Args:
6039
+ warn_property: The property name that is being accessed. This is used to
6040
+ customize the warning message. If None, no warning will be logged.
6041
+
6042
+ Returns:
6043
+ The concatenation of all text parts in the response.
6000
6044
  """
6001
6045
  if (
6002
6046
  not self.candidates
@@ -6004,7 +6048,7 @@ class GenerateContentResponse(_common.BaseModel):
6004
6048
  or not self.candidates[0].content.parts
6005
6049
  ):
6006
6050
  return None
6007
- if len(self.candidates) > 1:
6051
+ if len(self.candidates) > 1 and warn_property:
6008
6052
  logger.warning(
6009
6053
  f'there are {len(self.candidates)} candidates, returning'
6010
6054
  f' {warn_property} result from the first candidate. Access'
@@ -6025,7 +6069,7 @@ class GenerateContentResponse(_common.BaseModel):
6025
6069
  continue
6026
6070
  any_text_part_text = True
6027
6071
  text += part.text
6028
- if non_text_parts:
6072
+ if non_text_parts and warn_property:
6029
6073
  logger.warning(
6030
6074
  'Warning: there are non-text parts in the response:'
6031
6075
  f' {non_text_parts}, returning concatenated {warn_property} result'
@@ -6054,7 +6098,10 @@ class GenerateContentResponse(_common.BaseModel):
6054
6098
 
6055
6099
  @property
6056
6100
  def text(self) -> Optional[str]:
6057
- """Returns the concatenation of all text parts in the response."""
6101
+ """Returns the concatenation of all text parts in the response.
6102
+
6103
+ If there are multiple candidates, returns the text from only the first one.
6104
+ """
6058
6105
  return self._get_text(warn_property='text')
6059
6106
 
6060
6107
  @property
@@ -6145,7 +6192,7 @@ class GenerateContentResponse(_common.BaseModel):
6145
6192
  ):
6146
6193
  # Pydantic schema.
6147
6194
  try:
6148
- result_text = result._get_text(warn_property='parsed')
6195
+ result_text = result._get_text()
6149
6196
  if result_text is not None:
6150
6197
  result.parsed = response_schema.model_validate_json(result_text)
6151
6198
  # may not be a valid json per stream response
@@ -6154,11 +6201,10 @@ class GenerateContentResponse(_common.BaseModel):
6154
6201
  except json.decoder.JSONDecodeError:
6155
6202
  pass
6156
6203
  elif (
6157
- isinstance(response_schema, EnumMeta)
6158
- and result._get_text(warn_property='parsed') is not None
6204
+ isinstance(response_schema, EnumMeta) and result._get_text() is not None
6159
6205
  ):
6160
6206
  # Enum with "application/json" returns response in double quotes.
6161
- result_text = result._get_text(warn_property='parsed')
6207
+ result_text = result._get_text()
6162
6208
  if result_text is None:
6163
6209
  raise ValueError('Response is empty.')
6164
6210
  enum_value = result_text.replace('"', '')
@@ -6179,7 +6225,7 @@ class GenerateContentResponse(_common.BaseModel):
6179
6225
  placeholder: response_schema # type: ignore[valid-type]
6180
6226
 
6181
6227
  try:
6182
- result_text = result._get_text(warn_property='parsed')
6228
+ result_text = result._get_text()
6183
6229
  if result_text is not None:
6184
6230
  parsed = {'placeholder': json.loads(result_text)}
6185
6231
  placeholder = Placeholder.model_validate(parsed)
@@ -6196,7 +6242,7 @@ class GenerateContentResponse(_common.BaseModel):
6196
6242
  # want the result converted to. So just return json.
6197
6243
  # JSON schema.
6198
6244
  try:
6199
- result_text = result._get_text(warn_property='parsed')
6245
+ result_text = result._get_text()
6200
6246
  if result_text is not None:
6201
6247
  result.parsed = json.loads(result_text)
6202
6248
  # may not be a valid json per stream response
@@ -6208,7 +6254,7 @@ class GenerateContentResponse(_common.BaseModel):
6208
6254
  for union_type in union_types:
6209
6255
  if issubclass(union_type, pydantic.BaseModel):
6210
6256
  try:
6211
- result_text = result._get_text(warn_property='parsed')
6257
+ result_text = result._get_text()
6212
6258
  if result_text is not None:
6213
6259
 
6214
6260
  class Placeholder(pydantic.BaseModel): # type: ignore[no-redef]
@@ -6223,7 +6269,7 @@ class GenerateContentResponse(_common.BaseModel):
6223
6269
  pass
6224
6270
  else:
6225
6271
  try:
6226
- result_text = result._get_text(warn_property='parsed')
6272
+ result_text = result._get_text()
6227
6273
  if result_text is not None:
6228
6274
  result.parsed = json.loads(result_text)
6229
6275
  # may not be a valid json per stream response
google/genai/version.py CHANGED
@@ -13,4 +13,4 @@
13
13
  # limitations under the License.
14
14
  #
15
15
 
16
- __version__ = '1.47.0' # x-release-please-version
16
+ __version__ = '1.48.0' # x-release-please-version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-genai
3
- Version: 1.47.0
3
+ Version: 1.48.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License-Expression: Apache-2.0
@@ -9,7 +9,6 @@ Classifier: Intended Audience :: Developers
9
9
  Classifier: Operating System :: OS Independent
10
10
  Classifier: Programming Language :: Python
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
15
14
  Classifier: Programming Language :: Python :: 3.12
@@ -17,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.13
17
16
  Classifier: Programming Language :: Python :: 3.14
18
17
  Classifier: Topic :: Internet
19
18
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
- Requires-Python: >=3.9
19
+ Requires-Python: >=3.10
21
20
  Description-Content-Type: text/markdown
22
21
  License-File: LICENSE
23
22
  Requires-Dist: anyio<5.0.0,>=4.8.0
@@ -6,17 +6,17 @@ google/genai/_automatic_function_calling_util.py,sha256=xXNkJR-pzSMkeSXMz3Jw-kMH
6
6
  google/genai/_base_transformers.py,sha256=wljA6m4tLl4XLGlBC2DNOls5N9-X9tffBq0M7i8jgpw,1034
7
7
  google/genai/_base_url.py,sha256=E5H4dew14Y16qfnB3XRnjSCi19cJVlkaMNoM_8ip-PM,1597
8
8
  google/genai/_common.py,sha256=6_psdFl0iBRwgyIKOuGtugpTCHPGB2zZzsJCVcI_2oI,24114
9
- google/genai/_extra_utils.py,sha256=ld4W5t38QMdx-FOvQYycUM6ejSmEnyHvt2HBCB1pwAg,23202
10
- google/genai/_live_converters.py,sha256=e7TZxmdc9eCMThXKzV5pHtYMTtESei7cJeU4ok9r1Bg,42296
9
+ google/genai/_extra_utils.py,sha256=dqSB1XHO1TLlGqtZz9sShtFnJc2UZgDlG89-dNAAgD0,24263
10
+ google/genai/_live_converters.py,sha256=zJ8ZbFWA2vhO0_fbOtWQo7Zp82nViEisYfFupMyZokc,42458
11
11
  google/genai/_local_tokenizer_loader.py,sha256=cGN1F0f7hNjRIGCGTLeox7IGAZf_YcvZjSp2rCyhUak,7465
12
12
  google/genai/_mcp_utils.py,sha256=HuWJ8FUjquv40Mf_QjcL5r5yXWrS-JjINsjlOSbbyAc,3870
13
13
  google/genai/_operations_converters.py,sha256=8w4WSeA_KSyc56JcL1MTknZHIds0gF3E8YdriluUJfY,8708
14
14
  google/genai/_replay_api_client.py,sha256=oCPZULWpmjahOn5pvY7KkCB_cksNwm7pc4nuTnqqqV8,22956
15
15
  google/genai/_test_api_client.py,sha256=4ruFIy5_1qcbKqqIBu3HSQbpSOBrxiecBtDZaTGFR1s,4797
16
- google/genai/_tokens_converters.py,sha256=vPsx-o5y6CgQx0HqEhHggPQ0YrvmRXg6l3hM0XprA8I,14137
16
+ google/genai/_tokens_converters.py,sha256=oDnzbQRA1abHBV9JLFV_5G7Pzm1cRPDUe_MVNTxI6LQ,14299
17
17
  google/genai/_transformers.py,sha256=h2VV2AnKdvHQtEwiiLV3vJFezYBYSfacvPmF5kcocEE,43165
18
- google/genai/batches.py,sha256=WZSxcaQd64CsZ016Mg5U2mcaMigq9ffzqVO3pOfag6o,74986
19
- google/genai/caches.py,sha256=bWgXf1_6v1-a4m7gx7Y8mALrMLFCyvS5yd3XGmP04DY,44788
18
+ google/genai/batches.py,sha256=FCfGgcueOI3_yTRUXp2XccpnWeNlH1ex5OKbbNESL3Y,75148
19
+ google/genai/caches.py,sha256=CAJyiBHcSuaDimxTfd5y9-iVRHGvmOfcuNnWEfktXzQ,44950
20
20
  google/genai/chats.py,sha256=pIBw8d13llupLn4a7vP6vnpbzDcvCCrZZ-Q2r8Cvo7g,16652
21
21
  google/genai/client.py,sha256=_2B9w4cyah1kepMYwaaCpEDtbL3JWSt0Qx7k1IJXCFU,13110
22
22
  google/genai/errors.py,sha256=dLH0Bo8-Y0K7zKASU5O0y_0FSKpSFJn8JPcnwIUvtIM,6089
@@ -24,16 +24,16 @@ google/genai/files.py,sha256=2TkcZo7iviHA48OEjc9YnyirZ-umBUN7Z4Gdr4nHyJI,31551
24
24
  google/genai/live.py,sha256=IzBIHjjasfHivDxhi4HvMru0G8LlkFsM_e6QCgSL1cQ,41278
25
25
  google/genai/live_music.py,sha256=Y7I7jh5SAKgyjBIMLboH0oTnZJ18uOT2SpRDKURvp94,6783
26
26
  google/genai/local_tokenizer.py,sha256=EKZ72cV2Zfutlo_efMOPnLRNZN4WQe57rD3G80cF340,14109
27
- google/genai/models.py,sha256=6XScrBzv9Wtruf9gQV4x8Uden1Wdw87OEDMJVlHH1F0,228216
27
+ google/genai/models.py,sha256=7PR9QXjDqQ9j6xHoLFqvwx9_E9E88gPuebk0BafZmqc,232918
28
28
  google/genai/operations.py,sha256=KgM5vsagUnAMGk9wKxuQYBUh_6bwrPQ9BzZvydiumQA,16208
29
29
  google/genai/pagers.py,sha256=m0SfWWn1EJs2k1On3DZx371qb8g2BRm_188ExsicIRc,7098
30
30
  google/genai/py.typed,sha256=RsMFoLwBkAvY05t6izop4UHZtqOPLiKp3GkIEizzmQY,40
31
31
  google/genai/tokens.py,sha256=4BPW0gGWFeFVk3INkuY2tfREnsrvzQDhouvRI6_F9Q8,12235
32
32
  google/genai/tunings.py,sha256=qCkvzZsqlfJL-KPUtZtjTp4rQeLYTc5LCYJfJgKyJhM,63586
33
- google/genai/types.py,sha256=pEJ8R9OmWxzFgEd9rZ-CDvw6vClpqnhoq_BdU87UJ3I,582585
34
- google/genai/version.py,sha256=KI452uyiQJlyNkY4COWWobH2eHDIBQtP1914F70h9Pk,627
35
- google_genai-1.47.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
36
- google_genai-1.47.0.dist-info/METADATA,sha256=haiWzFF16ZcBtMhrZObgZpLbdmBlTxZ407mfHChCxCU,46781
37
- google_genai-1.47.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
- google_genai-1.47.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
39
- google_genai-1.47.0.dist-info/RECORD,,
33
+ google/genai/types.py,sha256=QVdMdjrgtZjkN4EinSnAgOc9tKeJ7xWjpztVq8tTrHQ,584659
34
+ google/genai/version.py,sha256=uVriLvLljZ_EUwzUyeuTH0mIiXjfBiPSFoXMwP29l6E,627
35
+ google_genai-1.48.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
36
+ google_genai-1.48.0.dist-info/METADATA,sha256=lnyEk6qDliPNImLJjxz99V---_l4F3PK7P_v_d79Xjk,46732
37
+ google_genai-1.48.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
+ google_genai-1.48.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
39
+ google_genai-1.48.0.dist-info/RECORD,,