google-genai 1.4.0__py3-none-any.whl → 1.5.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/types.py CHANGED
@@ -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
26
+ from typing import Any, Callable, Literal, Optional, Union, _UnionGenericAlias # type: ignore
27
27
  import pydantic
28
28
  from pydantic import Field
29
29
  from typing_extensions import TypedDict
@@ -56,6 +56,8 @@ else:
56
56
 
57
57
  logger = logging.getLogger('google_genai.types')
58
58
 
59
+ T = typing.TypeVar('T', bound='GenerateContentResponse')
60
+
59
61
 
60
62
  class Outcome(_common.CaseInSensitiveEnum):
61
63
  """Required. Outcome of the code execution."""
@@ -720,7 +722,7 @@ class UserContent(Content):
720
722
  def __init__(self, parts: Union['PartUnionDict', list['PartUnionDict']]):
721
723
  from . import _transformers as t
722
724
 
723
- super().__init__(parts=t.t_parts(None, parts=parts))
725
+ super().__init__(parts=t.t_parts(parts=parts))
724
726
 
725
727
 
726
728
  class ModelContent(Content):
@@ -748,7 +750,7 @@ class ModelContent(Content):
748
750
  def __init__(self, parts: Union['PartUnionDict', list['PartUnionDict']]):
749
751
  from . import _transformers as t
750
752
 
751
- super().__init__(parts=t.t_parts(None, parts=parts))
753
+ super().__init__(parts=t.t_parts(parts=parts))
752
754
 
753
755
 
754
756
  class ContentDict(TypedDict, total=False):
@@ -1736,7 +1738,7 @@ FileOrDict = Union[File, FileDict]
1736
1738
  if _is_pillow_image_imported:
1737
1739
  PartUnion = Union[File, Part, PIL_Image, str]
1738
1740
  else:
1739
- PartUnion = Union[File, Part, str]
1741
+ PartUnion = Union[File, Part, str] # type: ignore[misc]
1740
1742
 
1741
1743
 
1742
1744
  PartUnionDict = Union[PartUnion, PartDict]
@@ -3012,8 +3014,11 @@ class GenerateContentResponse(_common.BaseModel):
3012
3014
 
3013
3015
  @classmethod
3014
3016
  def _from_response(
3015
- cls, *, response: dict[str, object], kwargs: dict[str, object]
3016
- ) -> _common.BaseModel:
3017
+ cls: typing.Type[T],
3018
+ *,
3019
+ response: dict[str, object],
3020
+ kwargs: dict[str, object],
3021
+ ) -> T:
3017
3022
  result = super()._from_response(response=response, kwargs=kwargs)
3018
3023
 
3019
3024
  # Handles response schema.
@@ -3029,13 +3034,14 @@ class GenerateContentResponse(_common.BaseModel):
3029
3034
  ):
3030
3035
  # Pydantic schema.
3031
3036
  try:
3032
- result.parsed = response_schema.model_validate_json(result.text)
3037
+ if result.text is not None:
3038
+ result.parsed = response_schema.model_validate_json(result.text)
3033
3039
  # may not be a valid json per stream response
3034
3040
  except pydantic.ValidationError:
3035
3041
  pass
3036
3042
  except json.decoder.JSONDecodeError:
3037
3043
  pass
3038
- elif isinstance(response_schema, EnumMeta):
3044
+ elif isinstance(response_schema, EnumMeta) and result.text is not None:
3039
3045
  # Enum with "application/json" returns response in double quotes.
3040
3046
  enum_value = result.text.replace('"', '')
3041
3047
  try:
@@ -3044,7 +3050,7 @@ class GenerateContentResponse(_common.BaseModel):
3044
3050
  hasattr(response_schema, '__name__')
3045
3051
  and response_schema.__name__ == 'PlaceholderLiteralEnum'
3046
3052
  ):
3047
- result.parsed = str(response_schema(enum_value).name)
3053
+ result.parsed = str(response_schema(enum_value).name) # type: ignore
3048
3054
  except ValueError:
3049
3055
  pass
3050
3056
  elif isinstance(response_schema, builtin_types.GenericAlias) or isinstance(
@@ -3052,12 +3058,13 @@ class GenerateContentResponse(_common.BaseModel):
3052
3058
  ):
3053
3059
 
3054
3060
  class Placeholder(pydantic.BaseModel):
3055
- placeholder: response_schema
3061
+ placeholder: response_schema # type: ignore[valid-type]
3056
3062
 
3057
3063
  try:
3058
- parsed = {'placeholder': json.loads(result.text)}
3059
- placeholder = Placeholder.model_validate(parsed)
3060
- result.parsed = placeholder.placeholder
3064
+ if result.text is not None:
3065
+ parsed = {'placeholder': json.loads(result.text)}
3066
+ placeholder = Placeholder.model_validate(parsed)
3067
+ result.parsed = placeholder.placeholder
3061
3068
  except json.decoder.JSONDecodeError:
3062
3069
  pass
3063
3070
  except pydantic.ValidationError:
@@ -3070,7 +3077,8 @@ class GenerateContentResponse(_common.BaseModel):
3070
3077
  # want the result converted to. So just return json.
3071
3078
  # JSON schema.
3072
3079
  try:
3073
- result.parsed = json.loads(result.text)
3080
+ if result.text is not None:
3081
+ result.parsed = json.loads(result.text)
3074
3082
  # may not be a valid json per stream response
3075
3083
  except json.decoder.JSONDecodeError:
3076
3084
  pass
@@ -3080,20 +3088,22 @@ class GenerateContentResponse(_common.BaseModel):
3080
3088
  for union_type in union_types:
3081
3089
  if issubclass(union_type, pydantic.BaseModel):
3082
3090
  try:
3091
+ if result.text is not None:
3083
3092
 
3084
- class Placeholder(pydantic.BaseModel): # type: ignore[no-redef]
3085
- placeholder: response_schema
3093
+ class Placeholder(pydantic.BaseModel): # type: ignore[no-redef]
3094
+ placeholder: response_schema # type: ignore[valid-type]
3086
3095
 
3087
- parsed = {'placeholder': json.loads(result.text)}
3088
- placeholder = Placeholder.model_validate(parsed)
3089
- result.parsed = placeholder.placeholder
3096
+ parsed = {'placeholder': json.loads(result.text)}
3097
+ placeholder = Placeholder.model_validate(parsed)
3098
+ result.parsed = placeholder.placeholder
3090
3099
  except json.decoder.JSONDecodeError:
3091
3100
  pass
3092
3101
  except pydantic.ValidationError:
3093
3102
  pass
3094
3103
  else:
3095
3104
  try:
3096
- result.parsed = json.loads(result.text)
3105
+ if result.text is not None:
3106
+ result.parsed = json.loads(result.text)
3097
3107
  # may not be a valid json per stream response
3098
3108
  except json.decoder.JSONDecodeError:
3099
3109
  pass
@@ -3602,18 +3612,23 @@ class Image(_common.BaseModel):
3602
3612
  """Image."""
3603
3613
 
3604
3614
  @classmethod
3605
- def from_file(cls, *, location: str) -> 'Image':
3615
+ def from_file(
3616
+ cls, *, location: str, mime_type: Optional[str] = None
3617
+ ) -> 'Image':
3606
3618
  """Lazy-loads an image from a local file or Google Cloud Storage.
3607
3619
 
3608
3620
  Args:
3609
3621
  location: The local path or Google Cloud Storage URI from which to load
3610
3622
  the image.
3623
+ mime_type: The MIME type of the image. If not provided, the MIME type
3624
+ will be automatically determined.
3611
3625
 
3612
3626
  Returns:
3613
3627
  A loaded image as an `Image` object.
3614
3628
  """
3615
3629
  import urllib
3616
3630
  import pathlib
3631
+ import mimetypes
3617
3632
 
3618
3633
  parsed_url = urllib.parse.urlparse(location)
3619
3634
  if (
@@ -3632,7 +3647,10 @@ class Image(_common.BaseModel):
3632
3647
 
3633
3648
  # Load image from local path
3634
3649
  image_bytes = pathlib.Path(location).read_bytes()
3635
- image = cls(image_bytes=image_bytes)
3650
+
3651
+ if not mime_type:
3652
+ mime_type, _ = mimetypes.guess_type(location)
3653
+ image = cls(image_bytes=image_bytes, mime_type=mime_type)
3636
3654
  return image
3637
3655
 
3638
3656
  def show(self):
@@ -3663,6 +3681,8 @@ class Image(_common.BaseModel):
3663
3681
  'The PIL module is not available. Please install the Pillow'
3664
3682
  ' package. `pip install pillow`'
3665
3683
  )
3684
+ if self.image_bytes is None:
3685
+ raise ValueError('The image bytes are not set.')
3666
3686
  self._loaded_image = PIL_Image.open(io.BytesIO(self.image_bytes))
3667
3687
  return self._loaded_image
3668
3688
 
@@ -3674,6 +3694,8 @@ class Image(_common.BaseModel):
3674
3694
  """
3675
3695
  import pathlib
3676
3696
 
3697
+ if self.image_bytes is None:
3698
+ raise ValueError('The image bytes are not set.')
3677
3699
  pathlib.Path(location).write_bytes(self.image_bytes)
3678
3700
 
3679
3701
 
@@ -5074,6 +5096,11 @@ class _GenerateVideosParameters(_common.BaseModel):
5074
5096
  default=None,
5075
5097
  description="""The text prompt for generating the videos. Optional for image to video use cases.""",
5076
5098
  )
5099
+ image: Optional[Image] = Field(
5100
+ default=None,
5101
+ description="""The input image for generating the videos.
5102
+ Optional if prompt is provided.""",
5103
+ )
5077
5104
  config: Optional[GenerateVideosConfig] = Field(
5078
5105
  default=None, description="""Configuration for generating videos."""
5079
5106
  )
@@ -5089,6 +5116,10 @@ class _GenerateVideosParametersDict(TypedDict, total=False):
5089
5116
  prompt: Optional[str]
5090
5117
  """The text prompt for generating the videos. Optional for image to video use cases."""
5091
5118
 
5119
+ image: Optional[ImageDict]
5120
+ """The input image for generating the videos.
5121
+ Optional if prompt is provided."""
5122
+
5092
5123
  config: Optional[GenerateVideosConfigDict]
5093
5124
  """Configuration for generating videos."""
5094
5125
 
@@ -5130,14 +5161,16 @@ class Video(_common.BaseModel):
5130
5161
  def show(self):
5131
5162
  """Shows the video.
5132
5163
 
5164
+ If the video has no mime_type, it is assumed to be video/mp4.
5165
+
5133
5166
  This method only works in a notebook environment.
5134
5167
  """
5135
- if self.uri:
5168
+ if self.uri and not self.video_bytes:
5136
5169
  return ValueError('Showing remote videos is not supported.')
5137
5170
  if not self.video_bytes:
5138
5171
  return ValueError('Video has no bytes.')
5139
- if not self.mime_type:
5140
- return ValueError('Mime type must be provided to display video.')
5172
+
5173
+ mime_type = self.mime_type or 'video/mp4'
5141
5174
 
5142
5175
  try:
5143
5176
  from IPython import display as IPython_display
@@ -5146,7 +5179,7 @@ class Video(_common.BaseModel):
5146
5179
 
5147
5180
  if IPython_display:
5148
5181
  return IPython_display.Video(
5149
- data=self.video_bytes, mimetype=self.mime_type, embed=True
5182
+ data=self.video_bytes, mimetype=mime_type, embed=True
5150
5183
  )
5151
5184
 
5152
5185
  def __repr__(self):
google/genai/version.py CHANGED
@@ -13,4 +13,4 @@
13
13
  # limitations under the License.
14
14
  #
15
15
 
16
- __version__ = '1.4.0' # x-release-please-version
16
+ __version__ = '1.5.0' # x-release-please-version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: google-genai
3
- Version: 1.4.0
3
+ Version: 1.5.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License: Apache-2.0
@@ -20,6 +20,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
20
  Requires-Python: >=3.9
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
+ Requires-Dist: anyio<5.0.0dev,>=4.8.0
23
24
  Requires-Dist: google-auth<3.0.0dev,>=2.14.1
24
25
  Requires-Dist: httpx<1.0.0dev,>=0.28.1
25
26
  Requires-Dist: pydantic<3.0.0dev,>=2.0.0
@@ -0,0 +1,27 @@
1
+ google/genai/__init__.py,sha256=IYw-PcsdgjSpS1mU_ZcYkTfPocsJ4aVmrDxP7vX7c6Y,709
2
+ google/genai/_api_client.py,sha256=5VOAFiVe3nSwoMy4QmSPKRzxtVY-lJ8yDEO6SdN267Y,29726
3
+ google/genai/_api_module.py,sha256=66FsFq9N8PdTegDyx3am3NHpI0Bw7HBmifUMCrZsx_Q,902
4
+ google/genai/_automatic_function_calling_util.py,sha256=AmFRhGdA6QFdUi9V73Fj4Z4R1dg3-y5b-7YxWUdRNk4,11087
5
+ google/genai/_common.py,sha256=u0qX3Uli_7qaYmoTZm9JnVzoMihD4ASPksmqmsjGSBs,10071
6
+ google/genai/_extra_utils.py,sha256=l9U0uaq4TWdfY7fOpGR3LcsA6-TMEblfQlEXdC0IGPY,12462
7
+ google/genai/_replay_api_client.py,sha256=OxZIAyyyI4D9uj0avNO0QGf4DPWJ4Pqf_MCbUs5pvYc,18459
8
+ google/genai/_test_api_client.py,sha256=XNOWq8AkYbqInv1aljNGlFXsv8slQIWTYy_hdcCetD0,4797
9
+ google/genai/_transformers.py,sha256=sq4rZPY808LbZpvkx-tvhWrKl9s0eoDenhc8nfTnYA0,29017
10
+ google/genai/batches.py,sha256=R4ptSnxTn1ADskGo3_arKP1FaWKsVo9oam6GFou9Mv0,41413
11
+ google/genai/caches.py,sha256=yj8ASOpYt3lYNc0-lni_BEASZ7SUk-qRz2ZD3jjqW9U,57806
12
+ google/genai/chats.py,sha256=ds5iF4hqvyHbHE4OlP1b5s93SwD0hlMNpWxT7db2E48,13493
13
+ google/genai/client.py,sha256=uhX1MhEHepqe6biU-ix_d4wsv5xG8NevT7gFEva0XEM,9785
14
+ google/genai/errors.py,sha256=BMEANEl_EK1ZIIZsO1FxgX1szvsdaEIaqhu4NpnBLow,4213
15
+ google/genai/files.py,sha256=jPK2B8pLw4Vh9zn8yuC0e30qHarmbZxc1bRPNpMwnfM,45363
16
+ google/genai/live.py,sha256=z_Y7LSZcPVkfInjLT9J8LWNIXD5E3e6TPDXZeadOcn0,24710
17
+ google/genai/models.py,sha256=sQT2OEcOYoacfpjF-Bu3-cp5ejOoaNiVm8e_v1j--RM,208476
18
+ google/genai/operations.py,sha256=YABHc75FvF3XAKjxgDgINEhuNLdUyNaMPKuDZWHglkM,19599
19
+ google/genai/pagers.py,sha256=-Ge5vQnBGbbScCGTlaZKuSTBcgTCDP4NuyS3vjixlC8,6869
20
+ google/genai/tunings.py,sha256=e8KrNDDQVbVZHsuFVuDuvpSNdsA33L-R68ulb2p3vEA,47751
21
+ google/genai/types.py,sha256=K_UU4zX_SM2oPN3xfRyVR10dV1A9td47fMHQvYBwqck,298284
22
+ google/genai/version.py,sha256=xEXL7YjPjoHY7XhGUYbNRRLHxqn4NKGHgH0_mXO-SN0,626
23
+ google_genai-1.5.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
24
+ google_genai-1.5.0.dist-info/METADATA,sha256=_OZODJs7oHaP1Veht5rLlNvg_pVq3AIUIdV6YFm5g1k,29190
25
+ google_genai-1.5.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
26
+ google_genai-1.5.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
27
+ google_genai-1.5.0.dist-info/RECORD,,
@@ -1,27 +0,0 @@
1
- google/genai/__init__.py,sha256=IYw-PcsdgjSpS1mU_ZcYkTfPocsJ4aVmrDxP7vX7c6Y,709
2
- google/genai/_api_client.py,sha256=_dbVVtxTzO9ZiTgp3gLSc8C6_198Z8Maay9fUa-mi4M,27078
3
- google/genai/_api_module.py,sha256=66FsFq9N8PdTegDyx3am3NHpI0Bw7HBmifUMCrZsx_Q,902
4
- google/genai/_automatic_function_calling_util.py,sha256=OcmWb6RLYCMRxiEZu4Q1B9aVXg_Q1qqZvMlVaAwdKWI,11062
5
- google/genai/_common.py,sha256=uPDZ_HdZvWz7teUln36nCcRYbHbYTiT5HAmTuB_eCqA,9983
6
- google/genai/_extra_utils.py,sha256=UrmiGxOkXXBIThwu8A0QAkKZiv39whmlqGSXoP0oHDk,11807
7
- google/genai/_replay_api_client.py,sha256=rPu73PCijydo7cGdDS0B75Us3exopPBiXmRZmGSytzI,16199
8
- google/genai/_test_api_client.py,sha256=XNOWq8AkYbqInv1aljNGlFXsv8slQIWTYy_hdcCetD0,4797
9
- google/genai/_transformers.py,sha256=mEowhaTeH7l2pUevr7YB6DphN_D2-iPiyKnF6d41-bo,28340
10
- google/genai/batches.py,sha256=QgZlVDSNzOvtTUWnMR5f7fAALOLDyi5X022P0fkMvuc,41183
11
- google/genai/caches.py,sha256=7n0_7SeHa3nohJ0DFsOrIghE8AaVTLVLpYyiRemKf_I,57576
12
- google/genai/chats.py,sha256=ds5iF4hqvyHbHE4OlP1b5s93SwD0hlMNpWxT7db2E48,13493
13
- google/genai/client.py,sha256=uhX1MhEHepqe6biU-ix_d4wsv5xG8NevT7gFEva0XEM,9785
14
- google/genai/errors.py,sha256=BMEANEl_EK1ZIIZsO1FxgX1szvsdaEIaqhu4NpnBLow,4213
15
- google/genai/files.py,sha256=-IdlddbpwNK5ToA00vtOij_DMU2ugEZRQkBp3x7cCoM,44668
16
- google/genai/live.py,sha256=z_Y7LSZcPVkfInjLT9J8LWNIXD5E3e6TPDXZeadOcn0,24710
17
- google/genai/models.py,sha256=ra6j8-_PVy0LqTBHpK80pHwws9aPiY-5uTHQ_3t86RI,206985
18
- google/genai/operations.py,sha256=6zxvDBIJAH38Ga23Wf6msoEGzJWhfOscGnbHY_tdCrE,19451
19
- google/genai/pagers.py,sha256=xC0LEgR8E4z9XNZUnZnNwSsAUCJPlMFUpJ7eXr4nuDM,6645
20
- google/genai/tunings.py,sha256=Prt3bI5fKUoDWtz6A6pxSWQwP0_ecGXa1rPOvfzGKSM,47568
21
- google/genai/types.py,sha256=z8tX1THcR2dTMKZYwsOZWR_OGBHvdpkmCNFBSft55zE,297091
22
- google/genai/version.py,sha256=mOyGG-hAwdvxg1_wBKMm2uMprTFFYHVKz6j0htJ9Irs,626
23
- google_genai-1.4.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
24
- google_genai-1.4.0.dist-info/METADATA,sha256=y4Jij7zMfosWDeq44MoSPBuZQ4x3xctqOnqha4IMqcA,29152
25
- google_genai-1.4.0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
26
- google_genai-1.4.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
27
- google_genai-1.4.0.dist-info/RECORD,,