files.go

  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, &parameterMap)
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, &parameterMap)
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, &parameterMap)
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, &parameterMap)
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}