google-genai 0.6.0__py3-none-any.whl → 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/genai/_api_client.py +74 -82
- google/genai/_api_module.py +24 -0
- google/genai/_automatic_function_calling_util.py +43 -22
- google/genai/_common.py +11 -8
- google/genai/_extra_utils.py +22 -16
- google/genai/_operations.py +365 -0
- google/genai/_replay_api_client.py +7 -2
- google/genai/_test_api_client.py +1 -1
- google/genai/_transformers.py +218 -97
- google/genai/batches.py +194 -155
- google/genai/caches.py +117 -134
- google/genai/chats.py +22 -18
- google/genai/client.py +31 -37
- google/genai/files.py +154 -183
- google/genai/live.py +11 -5
- google/genai/models.py +506 -254
- google/genai/tunings.py +85 -422
- google/genai/types.py +647 -458
- google/genai/version.py +1 -1
- {google_genai-0.6.0.dist-info → google_genai-0.8.0.dist-info}/METADATA +119 -70
- google_genai-0.8.0.dist-info/RECORD +27 -0
- google_genai-0.6.0.dist-info/RECORD +0 -25
- {google_genai-0.6.0.dist-info → google_genai-0.8.0.dist-info}/LICENSE +0 -0
- {google_genai-0.6.0.dist-info → google_genai-0.8.0.dist-info}/WHEEL +0 -0
- {google_genai-0.6.0.dist-info → google_genai-0.8.0.dist-info}/top_level.txt +0 -0
google/genai/files.py
CHANGED
@@ -21,6 +21,7 @@ import os
|
|
21
21
|
import pathlib
|
22
22
|
from typing import Optional, Union
|
23
23
|
from urllib.parse import urlencode
|
24
|
+
from . import _api_module
|
24
25
|
from . import _common
|
25
26
|
from . import _transformers as t
|
26
27
|
from . import types
|
@@ -36,8 +37,6 @@ def _ListFilesConfig_to_mldev(
|
|
36
37
|
parent_object: dict = None,
|
37
38
|
) -> dict:
|
38
39
|
to_object = {}
|
39
|
-
if getv(from_object, ['http_options']) is not None:
|
40
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
41
40
|
|
42
41
|
if getv(from_object, ['page_size']) is not None:
|
43
42
|
setv(
|
@@ -60,8 +59,6 @@ def _ListFilesConfig_to_vertex(
|
|
60
59
|
parent_object: dict = None,
|
61
60
|
) -> dict:
|
62
61
|
to_object = {}
|
63
|
-
if getv(from_object, ['http_options']) is not None:
|
64
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
65
62
|
|
66
63
|
if getv(from_object, ['page_size']) is not None:
|
67
64
|
setv(
|
@@ -252,30 +249,6 @@ def _File_to_vertex(
|
|
252
249
|
return to_object
|
253
250
|
|
254
251
|
|
255
|
-
def _CreateFileConfig_to_mldev(
|
256
|
-
api_client: ApiClient,
|
257
|
-
from_object: Union[dict, object],
|
258
|
-
parent_object: dict = None,
|
259
|
-
) -> dict:
|
260
|
-
to_object = {}
|
261
|
-
if getv(from_object, ['http_options']) is not None:
|
262
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
263
|
-
|
264
|
-
return to_object
|
265
|
-
|
266
|
-
|
267
|
-
def _CreateFileConfig_to_vertex(
|
268
|
-
api_client: ApiClient,
|
269
|
-
from_object: Union[dict, object],
|
270
|
-
parent_object: dict = None,
|
271
|
-
) -> dict:
|
272
|
-
to_object = {}
|
273
|
-
if getv(from_object, ['http_options']) is not None:
|
274
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
275
|
-
|
276
|
-
return to_object
|
277
|
-
|
278
|
-
|
279
252
|
def _CreateFileParameters_to_mldev(
|
280
253
|
api_client: ApiClient,
|
281
254
|
from_object: Union[dict, object],
|
@@ -290,13 +263,7 @@ def _CreateFileParameters_to_mldev(
|
|
290
263
|
)
|
291
264
|
|
292
265
|
if getv(from_object, ['config']) is not None:
|
293
|
-
setv(
|
294
|
-
to_object,
|
295
|
-
['config'],
|
296
|
-
_CreateFileConfig_to_mldev(
|
297
|
-
api_client, getv(from_object, ['config']), to_object
|
298
|
-
),
|
299
|
-
)
|
266
|
+
setv(to_object, ['config'], getv(from_object, ['config']))
|
300
267
|
|
301
268
|
return to_object
|
302
269
|
|
@@ -316,30 +283,6 @@ def _CreateFileParameters_to_vertex(
|
|
316
283
|
return to_object
|
317
284
|
|
318
285
|
|
319
|
-
def _GetFileConfig_to_mldev(
|
320
|
-
api_client: ApiClient,
|
321
|
-
from_object: Union[dict, object],
|
322
|
-
parent_object: dict = None,
|
323
|
-
) -> dict:
|
324
|
-
to_object = {}
|
325
|
-
if getv(from_object, ['http_options']) is not None:
|
326
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
327
|
-
|
328
|
-
return to_object
|
329
|
-
|
330
|
-
|
331
|
-
def _GetFileConfig_to_vertex(
|
332
|
-
api_client: ApiClient,
|
333
|
-
from_object: Union[dict, object],
|
334
|
-
parent_object: dict = None,
|
335
|
-
) -> dict:
|
336
|
-
to_object = {}
|
337
|
-
if getv(from_object, ['http_options']) is not None:
|
338
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
339
|
-
|
340
|
-
return to_object
|
341
|
-
|
342
|
-
|
343
286
|
def _GetFileParameters_to_mldev(
|
344
287
|
api_client: ApiClient,
|
345
288
|
from_object: Union[dict, object],
|
@@ -354,13 +297,7 @@ def _GetFileParameters_to_mldev(
|
|
354
297
|
)
|
355
298
|
|
356
299
|
if getv(from_object, ['config']) is not None:
|
357
|
-
setv(
|
358
|
-
to_object,
|
359
|
-
['config'],
|
360
|
-
_GetFileConfig_to_mldev(
|
361
|
-
api_client, getv(from_object, ['config']), to_object
|
362
|
-
),
|
363
|
-
)
|
300
|
+
setv(to_object, ['config'], getv(from_object, ['config']))
|
364
301
|
|
365
302
|
return to_object
|
366
303
|
|
@@ -380,30 +317,6 @@ def _GetFileParameters_to_vertex(
|
|
380
317
|
return to_object
|
381
318
|
|
382
319
|
|
383
|
-
def _DeleteFileConfig_to_mldev(
|
384
|
-
api_client: ApiClient,
|
385
|
-
from_object: Union[dict, object],
|
386
|
-
parent_object: dict = None,
|
387
|
-
) -> dict:
|
388
|
-
to_object = {}
|
389
|
-
if getv(from_object, ['http_options']) is not None:
|
390
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
391
|
-
|
392
|
-
return to_object
|
393
|
-
|
394
|
-
|
395
|
-
def _DeleteFileConfig_to_vertex(
|
396
|
-
api_client: ApiClient,
|
397
|
-
from_object: Union[dict, object],
|
398
|
-
parent_object: dict = None,
|
399
|
-
) -> dict:
|
400
|
-
to_object = {}
|
401
|
-
if getv(from_object, ['http_options']) is not None:
|
402
|
-
setv(to_object, ['httpOptions'], getv(from_object, ['http_options']))
|
403
|
-
|
404
|
-
return to_object
|
405
|
-
|
406
|
-
|
407
320
|
def _DeleteFileParameters_to_mldev(
|
408
321
|
api_client: ApiClient,
|
409
322
|
from_object: Union[dict, object],
|
@@ -418,13 +331,7 @@ def _DeleteFileParameters_to_mldev(
|
|
418
331
|
)
|
419
332
|
|
420
333
|
if getv(from_object, ['config']) is not None:
|
421
|
-
setv(
|
422
|
-
to_object,
|
423
|
-
['config'],
|
424
|
-
_DeleteFileConfig_to_mldev(
|
425
|
-
api_client, getv(from_object, ['config']), to_object
|
426
|
-
),
|
427
|
-
)
|
334
|
+
setv(to_object, ['config'], getv(from_object, ['config']))
|
428
335
|
|
429
336
|
return to_object
|
430
337
|
|
@@ -444,6 +351,16 @@ def _DeleteFileParameters_to_vertex(
|
|
444
351
|
return to_object
|
445
352
|
|
446
353
|
|
354
|
+
def _FileState_to_vertex_enum_validate(enum_value: any):
|
355
|
+
if enum_value in set(['STATE_UNSPECIFIED', 'PROCESSING', 'ACTIVE', 'FAILED']):
|
356
|
+
raise ValueError(f'{enum_value} enum value is not supported in Vertex AI.')
|
357
|
+
|
358
|
+
|
359
|
+
def _FileSource_to_vertex_enum_validate(enum_value: any):
|
360
|
+
if enum_value in set(['SOURCE_UNSPECIFIED', 'UPLOADED', 'GENERATED']):
|
361
|
+
raise ValueError(f'{enum_value} enum value is not supported in Vertex AI.')
|
362
|
+
|
363
|
+
|
447
364
|
def _FileStatus_from_mldev(
|
448
365
|
api_client: ApiClient,
|
449
366
|
from_object: Union[dict, object],
|
@@ -611,7 +528,7 @@ def _DeleteFileResponse_from_vertex(
|
|
611
528
|
return to_object
|
612
529
|
|
613
530
|
|
614
|
-
class Files(
|
531
|
+
class Files(_api_module.BaseModule):
|
615
532
|
|
616
533
|
def _list(
|
617
534
|
self, *, config: Optional[types.ListFilesConfigOrDict] = None
|
@@ -649,8 +566,14 @@ class Files(_common.BaseModule):
|
|
649
566
|
if query_params:
|
650
567
|
path = f'{path}?{urlencode(query_params)}'
|
651
568
|
# TODO: remove the hack that pops config.
|
652
|
-
|
653
|
-
|
569
|
+
request_dict.pop('config', None)
|
570
|
+
|
571
|
+
http_options = None
|
572
|
+
if isinstance(config, dict):
|
573
|
+
http_options = config.get('http_options', None)
|
574
|
+
elif hasattr(config, 'http_options'):
|
575
|
+
http_options = config.http_options
|
576
|
+
|
654
577
|
request_dict = _common.convert_to_dict(request_dict)
|
655
578
|
request_dict = _common.encode_unserializable_types(request_dict)
|
656
579
|
|
@@ -668,7 +591,7 @@ class Files(_common.BaseModule):
|
|
668
591
|
)
|
669
592
|
|
670
593
|
return_value = types.ListFilesResponse._from_response(
|
671
|
-
response_dict, parameter_model
|
594
|
+
response=response_dict, kwargs=parameter_model
|
672
595
|
)
|
673
596
|
self._api_client._verify_response(return_value)
|
674
597
|
return return_value
|
@@ -696,8 +619,14 @@ class Files(_common.BaseModule):
|
|
696
619
|
if query_params:
|
697
620
|
path = f'{path}?{urlencode(query_params)}'
|
698
621
|
# TODO: remove the hack that pops config.
|
699
|
-
|
700
|
-
|
622
|
+
request_dict.pop('config', None)
|
623
|
+
|
624
|
+
http_options = None
|
625
|
+
if isinstance(config, dict):
|
626
|
+
http_options = config.get('http_options', None)
|
627
|
+
elif hasattr(config, 'http_options'):
|
628
|
+
http_options = config.http_options
|
629
|
+
|
701
630
|
request_dict = _common.convert_to_dict(request_dict)
|
702
631
|
request_dict = _common.encode_unserializable_types(request_dict)
|
703
632
|
|
@@ -715,7 +644,7 @@ class Files(_common.BaseModule):
|
|
715
644
|
)
|
716
645
|
|
717
646
|
return_value = types.CreateFileResponse._from_response(
|
718
|
-
response_dict, parameter_model
|
647
|
+
response=response_dict, kwargs=parameter_model
|
719
648
|
)
|
720
649
|
self._api_client._verify_response(return_value)
|
721
650
|
return return_value
|
@@ -757,8 +686,14 @@ class Files(_common.BaseModule):
|
|
757
686
|
if query_params:
|
758
687
|
path = f'{path}?{urlencode(query_params)}'
|
759
688
|
# TODO: remove the hack that pops config.
|
760
|
-
|
761
|
-
|
689
|
+
request_dict.pop('config', None)
|
690
|
+
|
691
|
+
http_options = None
|
692
|
+
if isinstance(config, dict):
|
693
|
+
http_options = config.get('http_options', None)
|
694
|
+
elif hasattr(config, 'http_options'):
|
695
|
+
http_options = config.http_options
|
696
|
+
|
762
697
|
request_dict = _common.convert_to_dict(request_dict)
|
763
698
|
request_dict = _common.encode_unserializable_types(request_dict)
|
764
699
|
|
@@ -771,7 +706,9 @@ class Files(_common.BaseModule):
|
|
771
706
|
else:
|
772
707
|
response_dict = _File_from_mldev(self._api_client, response_dict)
|
773
708
|
|
774
|
-
return_value = types.File._from_response(
|
709
|
+
return_value = types.File._from_response(
|
710
|
+
response=response_dict, kwargs=parameter_model
|
711
|
+
)
|
775
712
|
self._api_client._verify_response(return_value)
|
776
713
|
return return_value
|
777
714
|
|
@@ -811,8 +748,14 @@ class Files(_common.BaseModule):
|
|
811
748
|
if query_params:
|
812
749
|
path = f'{path}?{urlencode(query_params)}'
|
813
750
|
# TODO: remove the hack that pops config.
|
814
|
-
|
815
|
-
|
751
|
+
request_dict.pop('config', None)
|
752
|
+
|
753
|
+
http_options = None
|
754
|
+
if isinstance(config, dict):
|
755
|
+
http_options = config.get('http_options', None)
|
756
|
+
elif hasattr(config, 'http_options'):
|
757
|
+
http_options = config.http_options
|
758
|
+
|
816
759
|
request_dict = _common.convert_to_dict(request_dict)
|
817
760
|
request_dict = _common.encode_unserializable_types(request_dict)
|
818
761
|
|
@@ -830,7 +773,7 @@ class Files(_common.BaseModule):
|
|
830
773
|
)
|
831
774
|
|
832
775
|
return_value = types.DeleteFileResponse._from_response(
|
833
|
-
response_dict, parameter_model
|
776
|
+
response=response_dict, kwargs=parameter_model
|
834
777
|
)
|
835
778
|
self._api_client._verify_response(return_value)
|
836
779
|
return return_value
|
@@ -838,16 +781,17 @@ class Files(_common.BaseModule):
|
|
838
781
|
def upload(
|
839
782
|
self,
|
840
783
|
*,
|
841
|
-
|
784
|
+
file: Union[str, pathlib.Path, os.PathLike, io.IOBase],
|
842
785
|
config: Optional[types.UploadFileConfigOrDict] = None,
|
843
786
|
) -> types.File:
|
844
787
|
"""Calls the API to upload a file using a supported file service.
|
845
788
|
|
846
789
|
Args:
|
847
|
-
|
848
|
-
|
849
|
-
other words, do not use non-blocking mode or text mode.
|
850
|
-
must be seekable, that is, it must be able to call
|
790
|
+
file: A path to the file or an `IOBase` object to be uploaded. If it's an
|
791
|
+
IOBase object, it must be opened in blocking (the default) mode and
|
792
|
+
binary mode. In other words, do not use non-blocking mode or text mode.
|
793
|
+
The given stream must be seekable, that is, it must be able to call
|
794
|
+
`seek()` on 'path'.
|
851
795
|
config: Optional parameters to set `diplay_name`, `mime_type`, and `name`.
|
852
796
|
"""
|
853
797
|
if self._api_client.vertexai:
|
@@ -861,37 +805,37 @@ class Files(_common.BaseModule):
|
|
861
805
|
config_model = types.UploadFileConfig(**config)
|
862
806
|
else:
|
863
807
|
config_model = config
|
864
|
-
|
808
|
+
file_obj = types.File(
|
865
809
|
mime_type=config_model.mime_type,
|
866
810
|
name=config_model.name,
|
867
811
|
display_name=config_model.display_name,
|
868
812
|
)
|
869
813
|
else: # if not config
|
870
|
-
|
871
|
-
if
|
872
|
-
|
814
|
+
file_obj = types.File()
|
815
|
+
if file_obj.name is not None and not file_obj.name.startswith('files/'):
|
816
|
+
file_obj.name = f'files/{file_obj.name}'
|
873
817
|
|
874
|
-
if isinstance(
|
875
|
-
if
|
818
|
+
if isinstance(file, io.IOBase):
|
819
|
+
if file_obj.mime_type is None:
|
876
820
|
raise ValueError(
|
877
821
|
'Unknown mime type: Could not determine the mimetype for your'
|
878
822
|
' file\n please set the `mime_type` argument'
|
879
823
|
)
|
880
|
-
if hasattr(
|
881
|
-
if 'b' not in
|
824
|
+
if hasattr(file, 'mode'):
|
825
|
+
if 'b' not in file.mode:
|
882
826
|
raise ValueError('The file must be opened in binary mode.')
|
883
|
-
offset =
|
884
|
-
|
885
|
-
|
886
|
-
|
827
|
+
offset = file.tell()
|
828
|
+
file.seek(0, os.SEEK_END)
|
829
|
+
file_obj.size_bytes = file.tell() - offset
|
830
|
+
file.seek(offset, os.SEEK_SET)
|
887
831
|
else:
|
888
|
-
fs_path = os.fspath(
|
832
|
+
fs_path = os.fspath(file)
|
889
833
|
if not fs_path or not os.path.isfile(fs_path):
|
890
|
-
raise FileNotFoundError(f'{
|
891
|
-
|
892
|
-
if
|
893
|
-
|
894
|
-
if
|
834
|
+
raise FileNotFoundError(f'{file} is not a valid file path.')
|
835
|
+
file_obj.size_bytes = os.path.getsize(fs_path)
|
836
|
+
if file_obj.mime_type is None:
|
837
|
+
file_obj.mime_type, _ = mimetypes.guess_type(fs_path)
|
838
|
+
if file_obj.mime_type is None:
|
895
839
|
raise ValueError(
|
896
840
|
'Unknown mime type: Could not determine the mimetype for your'
|
897
841
|
' file\n please set the `mime_type` argument'
|
@@ -906,12 +850,12 @@ class Files(_common.BaseModule):
|
|
906
850
|
'Content-Type': 'application/json',
|
907
851
|
'X-Goog-Upload-Protocol': 'resumable',
|
908
852
|
'X-Goog-Upload-Command': 'start',
|
909
|
-
'X-Goog-Upload-Header-Content-Length': f'{
|
910
|
-
'X-Goog-Upload-Header-Content-Type': f'{
|
853
|
+
'X-Goog-Upload-Header-Content-Length': f'{file_obj.size_bytes}',
|
854
|
+
'X-Goog-Upload-Header-Content-Type': f'{file_obj.mime_type}',
|
911
855
|
},
|
912
|
-
'
|
856
|
+
'deprecated_response_payload': response,
|
913
857
|
}
|
914
|
-
self._create(file=
|
858
|
+
self._create(file=file_obj, config={'http_options': http_options})
|
915
859
|
|
916
860
|
if (
|
917
861
|
'headers' not in response
|
@@ -923,13 +867,13 @@ class Files(_common.BaseModule):
|
|
923
867
|
)
|
924
868
|
upload_url = response['headers']['X-Goog-Upload-URL']
|
925
869
|
|
926
|
-
if isinstance(
|
870
|
+
if isinstance(file, io.IOBase):
|
927
871
|
return_file = self._api_client.upload_file(
|
928
|
-
|
872
|
+
file, upload_url, file_obj.size_bytes
|
929
873
|
)
|
930
874
|
else:
|
931
875
|
return_file = self._api_client.upload_file(
|
932
|
-
fs_path, upload_url,
|
876
|
+
fs_path, upload_url, file_obj.size_bytes
|
933
877
|
)
|
934
878
|
|
935
879
|
return types.File._from_response(
|
@@ -1015,7 +959,7 @@ class Files(_common.BaseModule):
|
|
1015
959
|
return data
|
1016
960
|
|
1017
961
|
|
1018
|
-
class AsyncFiles(
|
962
|
+
class AsyncFiles(_api_module.BaseModule):
|
1019
963
|
|
1020
964
|
async def _list(
|
1021
965
|
self, *, config: Optional[types.ListFilesConfigOrDict] = None
|
@@ -1053,8 +997,14 @@ class AsyncFiles(_common.BaseModule):
|
|
1053
997
|
if query_params:
|
1054
998
|
path = f'{path}?{urlencode(query_params)}'
|
1055
999
|
# TODO: remove the hack that pops config.
|
1056
|
-
|
1057
|
-
|
1000
|
+
request_dict.pop('config', None)
|
1001
|
+
|
1002
|
+
http_options = None
|
1003
|
+
if isinstance(config, dict):
|
1004
|
+
http_options = config.get('http_options', None)
|
1005
|
+
elif hasattr(config, 'http_options'):
|
1006
|
+
http_options = config.http_options
|
1007
|
+
|
1058
1008
|
request_dict = _common.convert_to_dict(request_dict)
|
1059
1009
|
request_dict = _common.encode_unserializable_types(request_dict)
|
1060
1010
|
|
@@ -1072,7 +1022,7 @@ class AsyncFiles(_common.BaseModule):
|
|
1072
1022
|
)
|
1073
1023
|
|
1074
1024
|
return_value = types.ListFilesResponse._from_response(
|
1075
|
-
response_dict, parameter_model
|
1025
|
+
response=response_dict, kwargs=parameter_model
|
1076
1026
|
)
|
1077
1027
|
self._api_client._verify_response(return_value)
|
1078
1028
|
return return_value
|
@@ -1100,8 +1050,14 @@ class AsyncFiles(_common.BaseModule):
|
|
1100
1050
|
if query_params:
|
1101
1051
|
path = f'{path}?{urlencode(query_params)}'
|
1102
1052
|
# TODO: remove the hack that pops config.
|
1103
|
-
|
1104
|
-
|
1053
|
+
request_dict.pop('config', None)
|
1054
|
+
|
1055
|
+
http_options = None
|
1056
|
+
if isinstance(config, dict):
|
1057
|
+
http_options = config.get('http_options', None)
|
1058
|
+
elif hasattr(config, 'http_options'):
|
1059
|
+
http_options = config.http_options
|
1060
|
+
|
1105
1061
|
request_dict = _common.convert_to_dict(request_dict)
|
1106
1062
|
request_dict = _common.encode_unserializable_types(request_dict)
|
1107
1063
|
|
@@ -1119,7 +1075,7 @@ class AsyncFiles(_common.BaseModule):
|
|
1119
1075
|
)
|
1120
1076
|
|
1121
1077
|
return_value = types.CreateFileResponse._from_response(
|
1122
|
-
response_dict, parameter_model
|
1078
|
+
response=response_dict, kwargs=parameter_model
|
1123
1079
|
)
|
1124
1080
|
self._api_client._verify_response(return_value)
|
1125
1081
|
return return_value
|
@@ -1161,8 +1117,14 @@ class AsyncFiles(_common.BaseModule):
|
|
1161
1117
|
if query_params:
|
1162
1118
|
path = f'{path}?{urlencode(query_params)}'
|
1163
1119
|
# TODO: remove the hack that pops config.
|
1164
|
-
|
1165
|
-
|
1120
|
+
request_dict.pop('config', None)
|
1121
|
+
|
1122
|
+
http_options = None
|
1123
|
+
if isinstance(config, dict):
|
1124
|
+
http_options = config.get('http_options', None)
|
1125
|
+
elif hasattr(config, 'http_options'):
|
1126
|
+
http_options = config.http_options
|
1127
|
+
|
1166
1128
|
request_dict = _common.convert_to_dict(request_dict)
|
1167
1129
|
request_dict = _common.encode_unserializable_types(request_dict)
|
1168
1130
|
|
@@ -1175,7 +1137,9 @@ class AsyncFiles(_common.BaseModule):
|
|
1175
1137
|
else:
|
1176
1138
|
response_dict = _File_from_mldev(self._api_client, response_dict)
|
1177
1139
|
|
1178
|
-
return_value = types.File._from_response(
|
1140
|
+
return_value = types.File._from_response(
|
1141
|
+
response=response_dict, kwargs=parameter_model
|
1142
|
+
)
|
1179
1143
|
self._api_client._verify_response(return_value)
|
1180
1144
|
return return_value
|
1181
1145
|
|
@@ -1215,8 +1179,14 @@ class AsyncFiles(_common.BaseModule):
|
|
1215
1179
|
if query_params:
|
1216
1180
|
path = f'{path}?{urlencode(query_params)}'
|
1217
1181
|
# TODO: remove the hack that pops config.
|
1218
|
-
|
1219
|
-
|
1182
|
+
request_dict.pop('config', None)
|
1183
|
+
|
1184
|
+
http_options = None
|
1185
|
+
if isinstance(config, dict):
|
1186
|
+
http_options = config.get('http_options', None)
|
1187
|
+
elif hasattr(config, 'http_options'):
|
1188
|
+
http_options = config.http_options
|
1189
|
+
|
1220
1190
|
request_dict = _common.convert_to_dict(request_dict)
|
1221
1191
|
request_dict = _common.encode_unserializable_types(request_dict)
|
1222
1192
|
|
@@ -1234,7 +1204,7 @@ class AsyncFiles(_common.BaseModule):
|
|
1234
1204
|
)
|
1235
1205
|
|
1236
1206
|
return_value = types.DeleteFileResponse._from_response(
|
1237
|
-
response_dict, parameter_model
|
1207
|
+
response=response_dict, kwargs=parameter_model
|
1238
1208
|
)
|
1239
1209
|
self._api_client._verify_response(return_value)
|
1240
1210
|
return return_value
|
@@ -1242,16 +1212,17 @@ class AsyncFiles(_common.BaseModule):
|
|
1242
1212
|
async def upload(
|
1243
1213
|
self,
|
1244
1214
|
*,
|
1245
|
-
|
1215
|
+
file: Union[str, pathlib.Path, os.PathLike, io.IOBase],
|
1246
1216
|
config: Optional[types.UploadFileConfigOrDict] = None,
|
1247
1217
|
) -> types.File:
|
1248
1218
|
"""Calls the API to upload a file asynchronously using a supported file service.
|
1249
1219
|
|
1250
1220
|
Args:
|
1251
|
-
|
1252
|
-
|
1253
|
-
other words, do not use non-blocking mode or text mode.
|
1254
|
-
must be seekable, that is, it must be able to call
|
1221
|
+
file: A path to the file or an `IOBase` object to be uploaded. If it's an
|
1222
|
+
IOBase object, it must be opened in blocking (the default) mode and
|
1223
|
+
binary mode. In other words, do not use non-blocking mode or text mode.
|
1224
|
+
The given stream must be seekable, that is, it must be able to call
|
1225
|
+
`seek()` on 'path'.
|
1255
1226
|
config: Optional parameters to set `diplay_name`, `mime_type`, and `name`.
|
1256
1227
|
"""
|
1257
1228
|
if self._api_client.vertexai:
|
@@ -1265,37 +1236,37 @@ class AsyncFiles(_common.BaseModule):
|
|
1265
1236
|
config_model = types.UploadFileConfig(**config)
|
1266
1237
|
else:
|
1267
1238
|
config_model = config
|
1268
|
-
|
1239
|
+
file_obj = types.File(
|
1269
1240
|
mime_type=config_model.mime_type,
|
1270
1241
|
name=config_model.name,
|
1271
1242
|
display_name=config_model.display_name,
|
1272
1243
|
)
|
1273
1244
|
else: # if not config
|
1274
|
-
|
1275
|
-
if
|
1276
|
-
|
1245
|
+
file_obj = types.File()
|
1246
|
+
if file_obj.name is not None and not file_obj.name.startswith('files/'):
|
1247
|
+
file_obj.name = f'files/{file_obj.name}'
|
1277
1248
|
|
1278
|
-
if isinstance(
|
1279
|
-
if
|
1249
|
+
if isinstance(file, io.IOBase):
|
1250
|
+
if file_obj.mime_type is None:
|
1280
1251
|
raise ValueError(
|
1281
1252
|
'Unknown mime type: Could not determine the mimetype for your'
|
1282
1253
|
' file\n please set the `mime_type` argument'
|
1283
1254
|
)
|
1284
|
-
if hasattr(
|
1285
|
-
if 'b' not in
|
1255
|
+
if hasattr(file, 'mode'):
|
1256
|
+
if 'b' not in file.mode:
|
1286
1257
|
raise ValueError('The file must be opened in binary mode.')
|
1287
|
-
offset =
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1258
|
+
offset = file.tell()
|
1259
|
+
file.seek(0, os.SEEK_END)
|
1260
|
+
file_obj.size_bytes = file.tell() - offset
|
1261
|
+
file.seek(offset, os.SEEK_SET)
|
1291
1262
|
else:
|
1292
|
-
fs_path = os.fspath(
|
1263
|
+
fs_path = os.fspath(file)
|
1293
1264
|
if not fs_path or not os.path.isfile(fs_path):
|
1294
|
-
raise FileNotFoundError(f'{
|
1295
|
-
|
1296
|
-
if
|
1297
|
-
|
1298
|
-
if
|
1265
|
+
raise FileNotFoundError(f'{file} is not a valid file path.')
|
1266
|
+
file_obj.size_bytes = os.path.getsize(fs_path)
|
1267
|
+
if file_obj.mime_type is None:
|
1268
|
+
file_obj.mime_type, _ = mimetypes.guess_type(fs_path)
|
1269
|
+
if file_obj.mime_type is None:
|
1299
1270
|
raise ValueError(
|
1300
1271
|
'Unknown mime type: Could not determine the mimetype for your'
|
1301
1272
|
' file\n please set the `mime_type` argument'
|
@@ -1311,12 +1282,12 @@ class AsyncFiles(_common.BaseModule):
|
|
1311
1282
|
'Content-Type': 'application/json',
|
1312
1283
|
'X-Goog-Upload-Protocol': 'resumable',
|
1313
1284
|
'X-Goog-Upload-Command': 'start',
|
1314
|
-
'X-Goog-Upload-Header-Content-Length': f'{
|
1315
|
-
'X-Goog-Upload-Header-Content-Type': f'{
|
1285
|
+
'X-Goog-Upload-Header-Content-Length': f'{file_obj.size_bytes}',
|
1286
|
+
'X-Goog-Upload-Header-Content-Type': f'{file_obj.mime_type}',
|
1316
1287
|
},
|
1317
|
-
'
|
1288
|
+
'deprecated_response_payload': response,
|
1318
1289
|
}
|
1319
|
-
await self._create(file=
|
1290
|
+
await self._create(file=file_obj, config={'http_options': http_options})
|
1320
1291
|
if (
|
1321
1292
|
'headers' not in response
|
1322
1293
|
or 'X-Goog-Upload-URL' not in response['headers']
|
@@ -1327,13 +1298,13 @@ class AsyncFiles(_common.BaseModule):
|
|
1327
1298
|
)
|
1328
1299
|
upload_url = response['headers']['X-Goog-Upload-URL']
|
1329
1300
|
|
1330
|
-
if isinstance(
|
1301
|
+
if isinstance(file, io.IOBase):
|
1331
1302
|
return_file = await self._api_client.async_upload_file(
|
1332
|
-
|
1303
|
+
file, upload_url, file_obj.size_bytes
|
1333
1304
|
)
|
1334
1305
|
else:
|
1335
1306
|
return_file = await self._api_client.async_upload_file(
|
1336
|
-
fs_path, upload_url,
|
1307
|
+
fs_path, upload_url, file_obj.size_bytes
|
1337
1308
|
)
|
1338
1309
|
|
1339
1310
|
return types.File._from_response(
|