1// Copyright 2025 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Code generated by the Google Gen AI SDK generator DO NOT EDIT.
16
17package genai
18
19import (
20 "context"
21 "fmt"
22 "io"
23 "iter"
24 "mime"
25 "net/http"
26 "os"
27 "path/filepath"
28 "strconv"
29 "strings"
30)
31
32func listFilesConfigToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
33 toObject = make(map[string]any)
34
35 fromPageSize := getValueByPath(fromObject, []string{"pageSize"})
36 if fromPageSize != nil {
37 setValueByPath(parentObject, []string{"_query", "pageSize"}, fromPageSize)
38 }
39
40 fromPageToken := getValueByPath(fromObject, []string{"pageToken"})
41 if fromPageToken != nil {
42 setValueByPath(parentObject, []string{"_query", "pageToken"}, fromPageToken)
43 }
44
45 return toObject, nil
46}
47
48func listFilesParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
49 toObject = make(map[string]any)
50
51 fromConfig := getValueByPath(fromObject, []string{"config"})
52 if fromConfig != nil {
53 fromConfig, err = listFilesConfigToMldev(ac, fromConfig.(map[string]any), toObject)
54 if err != nil {
55 return nil, err
56 }
57
58 setValueByPath(toObject, []string{"config"}, fromConfig)
59 }
60
61 return toObject, nil
62}
63
64func fileStatusToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
65 toObject = make(map[string]any)
66
67 fromDetails := getValueByPath(fromObject, []string{"details"})
68 if fromDetails != nil {
69 setValueByPath(toObject, []string{"details"}, fromDetails)
70 }
71
72 fromMessage := getValueByPath(fromObject, []string{"message"})
73 if fromMessage != nil {
74 setValueByPath(toObject, []string{"message"}, fromMessage)
75 }
76
77 fromCode := getValueByPath(fromObject, []string{"code"})
78 if fromCode != nil {
79 setValueByPath(toObject, []string{"code"}, fromCode)
80 }
81
82 return toObject, nil
83}
84
85func fileToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
86 toObject = make(map[string]any)
87
88 fromName := getValueByPath(fromObject, []string{"name"})
89 if fromName != nil {
90 setValueByPath(toObject, []string{"name"}, fromName)
91 }
92
93 fromDisplayName := getValueByPath(fromObject, []string{"displayName"})
94 if fromDisplayName != nil {
95 setValueByPath(toObject, []string{"displayName"}, fromDisplayName)
96 }
97
98 fromMimeType := getValueByPath(fromObject, []string{"mimeType"})
99 if fromMimeType != nil {
100 setValueByPath(toObject, []string{"mimeType"}, fromMimeType)
101 }
102
103 fromSizeBytes := getValueByPath(fromObject, []string{"sizeBytes"})
104 if fromSizeBytes != nil {
105 setValueByPath(toObject, []string{"sizeBytes"}, fromSizeBytes)
106 }
107
108 fromCreateTime := getValueByPath(fromObject, []string{"createTime"})
109 if fromCreateTime != nil {
110 setValueByPath(toObject, []string{"createTime"}, fromCreateTime)
111 }
112
113 fromExpirationTime := getValueByPath(fromObject, []string{"expirationTime"})
114 if fromExpirationTime != nil {
115 setValueByPath(toObject, []string{"expirationTime"}, fromExpirationTime)
116 }
117
118 fromUpdateTime := getValueByPath(fromObject, []string{"updateTime"})
119 if fromUpdateTime != nil {
120 setValueByPath(toObject, []string{"updateTime"}, fromUpdateTime)
121 }
122
123 fromSha256Hash := getValueByPath(fromObject, []string{"sha256Hash"})
124 if fromSha256Hash != nil {
125 setValueByPath(toObject, []string{"sha256Hash"}, fromSha256Hash)
126 }
127
128 fromUri := getValueByPath(fromObject, []string{"uri"})
129 if fromUri != nil {
130 setValueByPath(toObject, []string{"uri"}, fromUri)
131 }
132
133 fromDownloadUri := getValueByPath(fromObject, []string{"downloadUri"})
134 if fromDownloadUri != nil {
135 setValueByPath(toObject, []string{"downloadUri"}, fromDownloadUri)
136 }
137
138 fromState := getValueByPath(fromObject, []string{"state"})
139 if fromState != nil {
140 setValueByPath(toObject, []string{"state"}, fromState)
141 }
142
143 fromSource := getValueByPath(fromObject, []string{"source"})
144 if fromSource != nil {
145 setValueByPath(toObject, []string{"source"}, fromSource)
146 }
147
148 fromVideoMetadata := getValueByPath(fromObject, []string{"videoMetadata"})
149 if fromVideoMetadata != nil {
150 setValueByPath(toObject, []string{"videoMetadata"}, fromVideoMetadata)
151 }
152
153 fromError := getValueByPath(fromObject, []string{"error"})
154 if fromError != nil {
155 fromError, err = fileStatusToMldev(ac, fromError.(map[string]any), toObject)
156 if err != nil {
157 return nil, err
158 }
159
160 setValueByPath(toObject, []string{"error"}, fromError)
161 }
162
163 return toObject, nil
164}
165
166func createFileParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
167 toObject = make(map[string]any)
168
169 fromFile := getValueByPath(fromObject, []string{"file"})
170 if fromFile != nil {
171 fromFile, err = fileToMldev(ac, fromFile.(map[string]any), toObject)
172 if err != nil {
173 return nil, err
174 }
175
176 setValueByPath(toObject, []string{"file"}, fromFile)
177 }
178
179 fromConfig := getValueByPath(fromObject, []string{"config"})
180 if fromConfig != nil {
181 setValueByPath(toObject, []string{"config"}, fromConfig)
182 }
183
184 return toObject, nil
185}
186
187func getFileParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
188 toObject = make(map[string]any)
189
190 fromName := getValueByPath(fromObject, []string{"name"})
191 if fromName != nil {
192 fromName, err = tFileName(ac, fromName)
193 if err != nil {
194 return nil, err
195 }
196
197 setValueByPath(toObject, []string{"_url", "file"}, fromName)
198 }
199
200 fromConfig := getValueByPath(fromObject, []string{"config"})
201 if fromConfig != nil {
202 setValueByPath(toObject, []string{"config"}, fromConfig)
203 }
204
205 return toObject, nil
206}
207
208func deleteFileParametersToMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
209 toObject = make(map[string]any)
210
211 fromName := getValueByPath(fromObject, []string{"name"})
212 if fromName != nil {
213 fromName, err = tFileName(ac, fromName)
214 if err != nil {
215 return nil, err
216 }
217
218 setValueByPath(toObject, []string{"_url", "file"}, fromName)
219 }
220
221 fromConfig := getValueByPath(fromObject, []string{"config"})
222 if fromConfig != nil {
223 setValueByPath(toObject, []string{"config"}, fromConfig)
224 }
225
226 return toObject, nil
227}
228
229func fileStatusFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
230 toObject = make(map[string]any)
231
232 fromDetails := getValueByPath(fromObject, []string{"details"})
233 if fromDetails != nil {
234 setValueByPath(toObject, []string{"details"}, fromDetails)
235 }
236
237 fromMessage := getValueByPath(fromObject, []string{"message"})
238 if fromMessage != nil {
239 setValueByPath(toObject, []string{"message"}, fromMessage)
240 }
241
242 fromCode := getValueByPath(fromObject, []string{"code"})
243 if fromCode != nil {
244 setValueByPath(toObject, []string{"code"}, fromCode)
245 }
246
247 return toObject, nil
248}
249
250func fileFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
251 toObject = make(map[string]any)
252
253 fromName := getValueByPath(fromObject, []string{"name"})
254 if fromName != nil {
255 setValueByPath(toObject, []string{"name"}, fromName)
256 }
257
258 fromDisplayName := getValueByPath(fromObject, []string{"displayName"})
259 if fromDisplayName != nil {
260 setValueByPath(toObject, []string{"displayName"}, fromDisplayName)
261 }
262
263 fromMimeType := getValueByPath(fromObject, []string{"mimeType"})
264 if fromMimeType != nil {
265 setValueByPath(toObject, []string{"mimeType"}, fromMimeType)
266 }
267
268 fromSizeBytes := getValueByPath(fromObject, []string{"sizeBytes"})
269 if fromSizeBytes != nil {
270 setValueByPath(toObject, []string{"sizeBytes"}, fromSizeBytes)
271 }
272
273 fromCreateTime := getValueByPath(fromObject, []string{"createTime"})
274 if fromCreateTime != nil {
275 setValueByPath(toObject, []string{"createTime"}, fromCreateTime)
276 }
277
278 fromExpirationTime := getValueByPath(fromObject, []string{"expirationTime"})
279 if fromExpirationTime != nil {
280 setValueByPath(toObject, []string{"expirationTime"}, fromExpirationTime)
281 }
282
283 fromUpdateTime := getValueByPath(fromObject, []string{"updateTime"})
284 if fromUpdateTime != nil {
285 setValueByPath(toObject, []string{"updateTime"}, fromUpdateTime)
286 }
287
288 fromSha256Hash := getValueByPath(fromObject, []string{"sha256Hash"})
289 if fromSha256Hash != nil {
290 setValueByPath(toObject, []string{"sha256Hash"}, fromSha256Hash)
291 }
292
293 fromUri := getValueByPath(fromObject, []string{"uri"})
294 if fromUri != nil {
295 setValueByPath(toObject, []string{"uri"}, fromUri)
296 }
297
298 fromDownloadUri := getValueByPath(fromObject, []string{"downloadUri"})
299 if fromDownloadUri != nil {
300 setValueByPath(toObject, []string{"downloadUri"}, fromDownloadUri)
301 }
302
303 fromState := getValueByPath(fromObject, []string{"state"})
304 if fromState != nil {
305 setValueByPath(toObject, []string{"state"}, fromState)
306 }
307
308 fromSource := getValueByPath(fromObject, []string{"source"})
309 if fromSource != nil {
310 setValueByPath(toObject, []string{"source"}, fromSource)
311 }
312
313 fromVideoMetadata := getValueByPath(fromObject, []string{"videoMetadata"})
314 if fromVideoMetadata != nil {
315 setValueByPath(toObject, []string{"videoMetadata"}, fromVideoMetadata)
316 }
317
318 fromError := getValueByPath(fromObject, []string{"error"})
319 if fromError != nil {
320 fromError, err = fileStatusFromMldev(ac, fromError.(map[string]any), toObject)
321 if err != nil {
322 return nil, err
323 }
324
325 setValueByPath(toObject, []string{"error"}, fromError)
326 }
327
328 return toObject, nil
329}
330
331func listFilesResponseFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
332 toObject = make(map[string]any)
333
334 fromNextPageToken := getValueByPath(fromObject, []string{"nextPageToken"})
335 if fromNextPageToken != nil {
336 setValueByPath(toObject, []string{"nextPageToken"}, fromNextPageToken)
337 }
338
339 fromFiles := getValueByPath(fromObject, []string{"files"})
340 if fromFiles != nil {
341 fromFiles, err = applyConverterToSlice(ac, fromFiles.([]any), fileFromMldev)
342 if err != nil {
343 return nil, err
344 }
345
346 setValueByPath(toObject, []string{"files"}, fromFiles)
347 }
348
349 return toObject, nil
350}
351
352func createFileResponseFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
353 toObject = make(map[string]any)
354
355 fromHttpHeaders := getValueByPath(fromObject, []string{"httpHeaders"})
356 if fromHttpHeaders != nil {
357 setValueByPath(toObject, []string{"httpHeaders"}, fromHttpHeaders)
358 }
359
360 return toObject, nil
361}
362
363func deleteFileResponseFromMldev(ac *apiClient, fromObject map[string]any, parentObject map[string]any) (toObject map[string]any, err error) {
364 toObject = make(map[string]any)
365
366 return toObject, nil
367}
368
369type Files struct {
370 apiClient *apiClient
371}
372
373func (m Files) list(ctx context.Context, config *ListFilesConfig) (*ListFilesResponse, error) {
374 parameterMap := make(map[string]any)
375
376 kwargs := map[string]any{"config": config}
377 deepMarshal(kwargs, ¶meterMap)
378
379 var httpOptions *HTTPOptions
380 if config == nil {
381 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
382 } else {
383 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
384 config.HTTPOptions = nil
385 }
386 var response = new(ListFilesResponse)
387 var responseMap map[string]any
388 var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
389 var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
390 if m.apiClient.clientConfig.Backend == BackendVertexAI {
391
392 return nil, fmt.Errorf("method List is only supported in the Gemini Developer client. You can choose to use Gemini Developer client by setting ClientConfig.Backend to BackendGeminiAPI.")
393
394 } else {
395 toConverter = listFilesParametersToMldev
396 fromConverter = listFilesResponseFromMldev
397 }
398
399 body, err := toConverter(m.apiClient, parameterMap, nil)
400 if err != nil {
401 return nil, err
402 }
403 var path string
404 var urlParams map[string]any
405 if _, ok := body["_url"]; ok {
406 urlParams = body["_url"].(map[string]any)
407 delete(body, "_url")
408 }
409 if m.apiClient.clientConfig.Backend == BackendVertexAI {
410 path, err = formatMap("None", urlParams)
411 } else {
412 path, err = formatMap("files", urlParams)
413 }
414 if err != nil {
415 return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
416 }
417 if _, ok := body["_query"]; ok {
418 query, err := createURLQuery(body["_query"].(map[string]any))
419 if err != nil {
420 return nil, err
421 }
422 path += "?" + query
423 delete(body, "_query")
424 }
425
426 if _, ok := body["config"]; ok {
427 delete(body, "config")
428 }
429 responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodGet, body, httpOptions)
430 if err != nil {
431 return nil, err
432 }
433 responseMap, err = fromConverter(m.apiClient, responseMap, nil)
434 if err != nil {
435 return nil, err
436 }
437 err = mapToStruct(responseMap, response)
438 if err != nil {
439 return nil, err
440 }
441 return response, nil
442}
443
444func (m Files) create(ctx context.Context, file *File, config *CreateFileConfig) (*CreateFileResponse, error) {
445 parameterMap := make(map[string]any)
446
447 kwargs := map[string]any{"file": file, "config": config}
448 deepMarshal(kwargs, ¶meterMap)
449
450 var httpOptions *HTTPOptions
451 if config == nil {
452 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
453 } else {
454 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
455 config.HTTPOptions = nil
456 }
457 var response = new(CreateFileResponse)
458 var responseMap map[string]any
459 var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
460 var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
461 if m.apiClient.clientConfig.Backend == BackendVertexAI {
462
463 return nil, fmt.Errorf("method Create is only supported in the Gemini Developer client. You can choose to use Gemini Developer client by setting ClientConfig.Backend to BackendGeminiAPI.")
464
465 } else {
466 toConverter = createFileParametersToMldev
467 fromConverter = createFileResponseFromMldev
468 }
469
470 body, err := toConverter(m.apiClient, parameterMap, nil)
471 if err != nil {
472 return nil, err
473 }
474 var path string
475 var urlParams map[string]any
476 if _, ok := body["_url"]; ok {
477 urlParams = body["_url"].(map[string]any)
478 delete(body, "_url")
479 }
480 if m.apiClient.clientConfig.Backend == BackendVertexAI {
481 path, err = formatMap("None", urlParams)
482 } else {
483 path, err = formatMap("upload/v1beta/files", urlParams)
484 }
485 if err != nil {
486 return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
487 }
488 if _, ok := body["_query"]; ok {
489 query, err := createURLQuery(body["_query"].(map[string]any))
490 if err != nil {
491 return nil, err
492 }
493 path += "?" + query
494 delete(body, "_query")
495 }
496
497 if _, ok := body["config"]; ok {
498 delete(body, "config")
499 }
500 responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodPost, body, httpOptions)
501 if err != nil {
502 return nil, err
503 }
504 responseMap, err = fromConverter(m.apiClient, responseMap, nil)
505 if err != nil {
506 return nil, err
507 }
508 err = mapToStruct(responseMap, response)
509 if err != nil {
510 return nil, err
511 }
512 return response, nil
513}
514
515func (m Files) Get(ctx context.Context, name string, config *GetFileConfig) (*File, error) {
516 parameterMap := make(map[string]any)
517
518 kwargs := map[string]any{"name": name, "config": config}
519 deepMarshal(kwargs, ¶meterMap)
520
521 var httpOptions *HTTPOptions
522 if config == nil {
523 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
524 } else {
525 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
526 config.HTTPOptions = nil
527 }
528 var response = new(File)
529 var responseMap map[string]any
530 var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
531 var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
532 if m.apiClient.clientConfig.Backend == BackendVertexAI {
533
534 return nil, fmt.Errorf("method Get is only supported in the Gemini Developer client. You can choose to use Gemini Developer client by setting ClientConfig.Backend to BackendGeminiAPI.")
535
536 } else {
537 toConverter = getFileParametersToMldev
538 fromConverter = fileFromMldev
539 }
540
541 body, err := toConverter(m.apiClient, parameterMap, nil)
542 if err != nil {
543 return nil, err
544 }
545 var path string
546 var urlParams map[string]any
547 if _, ok := body["_url"]; ok {
548 urlParams = body["_url"].(map[string]any)
549 delete(body, "_url")
550 }
551 if m.apiClient.clientConfig.Backend == BackendVertexAI {
552 path, err = formatMap("None", urlParams)
553 } else {
554 path, err = formatMap("files/{file}", urlParams)
555 }
556 if err != nil {
557 return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
558 }
559 if _, ok := body["_query"]; ok {
560 query, err := createURLQuery(body["_query"].(map[string]any))
561 if err != nil {
562 return nil, err
563 }
564 path += "?" + query
565 delete(body, "_query")
566 }
567
568 if _, ok := body["config"]; ok {
569 delete(body, "config")
570 }
571 responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodGet, body, httpOptions)
572 if err != nil {
573 return nil, err
574 }
575 responseMap, err = fromConverter(m.apiClient, responseMap, nil)
576 if err != nil {
577 return nil, err
578 }
579 err = mapToStruct(responseMap, response)
580 if err != nil {
581 return nil, err
582 }
583 return response, nil
584}
585
586func (m Files) Delete(ctx context.Context, name string, config *DeleteFileConfig) (*DeleteFileResponse, error) {
587 parameterMap := make(map[string]any)
588
589 kwargs := map[string]any{"name": name, "config": config}
590 deepMarshal(kwargs, ¶meterMap)
591
592 var httpOptions *HTTPOptions
593 if config == nil {
594 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
595 } else {
596 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
597 config.HTTPOptions = nil
598 }
599 var response = new(DeleteFileResponse)
600 var responseMap map[string]any
601 var fromConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
602 var toConverter func(*apiClient, map[string]any, map[string]any) (map[string]any, error)
603 if m.apiClient.clientConfig.Backend == BackendVertexAI {
604
605 return nil, fmt.Errorf("method Delete is only supported in the Gemini Developer client. You can choose to use Gemini Developer client by setting ClientConfig.Backend to BackendGeminiAPI.")
606
607 } else {
608 toConverter = deleteFileParametersToMldev
609 fromConverter = deleteFileResponseFromMldev
610 }
611
612 body, err := toConverter(m.apiClient, parameterMap, nil)
613 if err != nil {
614 return nil, err
615 }
616 var path string
617 var urlParams map[string]any
618 if _, ok := body["_url"]; ok {
619 urlParams = body["_url"].(map[string]any)
620 delete(body, "_url")
621 }
622 if m.apiClient.clientConfig.Backend == BackendVertexAI {
623 path, err = formatMap("None", urlParams)
624 } else {
625 path, err = formatMap("files/{file}", urlParams)
626 }
627 if err != nil {
628 return nil, fmt.Errorf("invalid url params: %#v.\n%w", urlParams, err)
629 }
630 if _, ok := body["_query"]; ok {
631 query, err := createURLQuery(body["_query"].(map[string]any))
632 if err != nil {
633 return nil, err
634 }
635 path += "?" + query
636 delete(body, "_query")
637 }
638
639 if _, ok := body["config"]; ok {
640 delete(body, "config")
641 }
642 responseMap, err = sendRequest(ctx, m.apiClient, path, http.MethodDelete, body, httpOptions)
643 if err != nil {
644 return nil, err
645 }
646 responseMap, err = fromConverter(m.apiClient, responseMap, nil)
647 if err != nil {
648 return nil, err
649 }
650 err = mapToStruct(responseMap, response)
651 if err != nil {
652 return nil, err
653 }
654 return response, nil
655}
656
657// List retrieves a paginated list of files resources.
658func (m Files) List(ctx context.Context, config *ListFilesConfig) (Page[File], error) {
659 listFunc := func(ctx context.Context, config map[string]any) ([]*File, string, error) {
660 var c ListFilesConfig
661 if err := mapToStruct(config, &c); err != nil {
662 return nil, "", err
663 }
664 resp, err := m.list(ctx, &c)
665 if err != nil {
666 return nil, "", err
667 }
668 return resp.Files, resp.NextPageToken, nil
669 }
670 c := make(map[string]any)
671 deepMarshal(config, &c)
672 return newPage(ctx, "files", c, listFunc)
673}
674
675// All retrieves all files resources.
676//
677// This method handles pagination internally, making multiple API calls as needed
678// to fetch all entries. It returns an iterator that yields each file
679// entry one by one. You do not need to manage pagination
680// tokens or make multiple calls to retrieve all data.
681func (m Files) All(ctx context.Context) iter.Seq2[*File, error] {
682 listFunc := func(ctx context.Context, config map[string]any) ([]*File, string, error) {
683 var c ListFilesConfig
684 if err := mapToStruct(config, &c); err != nil {
685 return nil, "", err
686 }
687 resp, err := m.list(ctx, &c)
688 if err != nil {
689 return nil, "", err
690 }
691 return resp.Files, resp.NextPageToken, nil
692 }
693 p, err := newPage(ctx, "files", map[string]any{}, listFunc)
694 if err != nil {
695 return yieldErrorAndEndIterator[File](err)
696 }
697 return p.all(ctx)
698}
699
700// Download function downloads a file from the specified URI.
701// If the URI refers to a video([Video], [GeneratedVideo]), the video bytes will be populated to the video's VideoBytes field.
702func (m Files) Download(ctx context.Context, uri DownloadURI, config *DownloadFileConfig) ([]byte, error) {
703 if m.apiClient.clientConfig.Backend == BackendVertexAI {
704 return nil, fmt.Errorf("method Download is only supported in the Gemini Developer client. You can choose to use Gemini Developer client by setting ClientConfig.Backend to BackendGeminiAPI.")
705 }
706 if uri.uri() == "" {
707 return nil, fmt.Errorf("the resource doesn't support download")
708 }
709 fileName, err := tFileName(m.apiClient, uri.uri())
710 if err != nil {
711 return nil, err
712 }
713 path := fmt.Sprintf("files/%s:download?alt=media", fileName)
714
715 var httpOptions *HTTPOptions
716 if config == nil {
717 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, nil)
718 } else {
719 httpOptions = mergeHTTPOptions(m.apiClient.clientConfig, config.HTTPOptions)
720 config.HTTPOptions = nil
721 }
722
723 data, err := downloadFile(ctx, m.apiClient, path, httpOptions)
724 if err != nil {
725 return nil, err
726 }
727 _ = uri.setVideoBytes(data)
728 return data, nil
729}
730
731// Upload copies the contents of the given io.Reader to file storage associated
732// with the service, and returns information about the resulting file.
733func (m Files) Upload(ctx context.Context, r io.Reader, config *UploadFileConfig) (*File, error) {
734 if m.apiClient.clientConfig.Backend == BackendVertexAI {
735 return nil, fmt.Errorf("This method is only supported in the Gemini Developer client.")
736 }
737
738 var fileToUpload File
739 if config != nil {
740 fileToUpload.MIMEType = config.MIMEType
741 fileToUpload.Name = config.Name
742 fileToUpload.DisplayName = config.DisplayName
743 }
744
745 if fileToUpload.Name != "" && !strings.HasPrefix(fileToUpload.Name, "files/") {
746 fileToUpload.Name = "files/" + fileToUpload.Name
747 }
748
749 httpOptions := HTTPOptions{Headers: http.Header{}}
750 if config != nil && config.HTTPOptions != nil {
751 deepCopy(*config.HTTPOptions, &httpOptions)
752 }
753 if httpOptions.Headers == nil {
754 httpOptions.Headers = http.Header{}
755 }
756
757 httpOptions.APIVersion = ""
758 httpOptions.Headers.Add("Content-Type", "application/json")
759 httpOptions.Headers.Add("X-Goog-Upload-Protocol", "resumable")
760 httpOptions.Headers.Add("X-Goog-Upload-Command", "start")
761 httpOptions.Headers.Add("X-Goog-Upload-Header-Content-Type", fileToUpload.MIMEType)
762
763 var createFileConfig CreateFileConfig
764 createFileConfig.HTTPOptions = &httpOptions
765
766 resp, err := m.create(ctx, &fileToUpload, &createFileConfig)
767 if err != nil {
768 return nil, fmt.Errorf("Failed to create file. Ran into an error: %s", err)
769 }
770 if resp.HTTPHeaders == nil || resp.HTTPHeaders.Get("x-goog-upload-url") == "" {
771 return nil, fmt.Errorf("Failed to create file. Upload URL was not returned from the create file request.")
772 }
773
774 uploadURL := resp.HTTPHeaders.Get("x-goog-upload-url")
775 return m.apiClient.uploadFile(ctx, r, uploadURL, &httpOptions)
776}
777
778// UploadFromPath uploads a file from the specified path and returns information
779// about the resulting file.
780func (m Files) UploadFromPath(ctx context.Context, path string, config *UploadFileConfig) (*File, error) {
781 fileInfo, err := os.Stat(path)
782 if err != nil || fileInfo.IsDir() {
783 return nil, fmt.Errorf("%s is not a valid file path.", path)
784 }
785
786 osf, err := os.Open(path)
787 if err != nil {
788 return nil, err
789 }
790 defer osf.Close()
791
792 if config == nil {
793 config = &UploadFileConfig{}
794 }
795
796 var copiedCfg UploadFileConfig
797 deepCopy(*config, &copiedCfg)
798
799 if copiedCfg.MIMEType == "" {
800 copiedCfg.MIMEType = mime.TypeByExtension(filepath.Ext(path))
801 if copiedCfg.MIMEType == "" {
802 return nil, fmt.Errorf("Unknown mime type: Could not determine the mimetype for your file please set the `MIMEType` argument")
803 }
804 }
805
806 if copiedCfg.HTTPOptions == nil {
807 copiedCfg.HTTPOptions = &HTTPOptions{Headers: http.Header{}}
808 }
809 if copiedCfg.HTTPOptions.Headers == nil {
810 copiedCfg.HTTPOptions.Headers = http.Header{}
811 }
812 copiedCfg.HTTPOptions.Headers.Add("X-Goog-Upload-Header-Content-Length", strconv.FormatInt(fileInfo.Size(), 10))
813
814 return m.Upload(ctx, osf, &copiedCfg)
815}