google-gemini / generative-ai-python

The official Python library for the Google Gemini API
https://pypi.org/project/google-generativeai/
Apache License 2.0
1.39k stars 270 forks source link

I can't upload file with a credential #510

Open Gekko0114 opened 3 weeks ago

Gekko0114 commented 3 weeks ago

Description of the bug:

I can't run the method upload_file with a google cloud credential. I would like to upload file using json key. However, I can't upload file with that credential. To upload file, I need API Key for google cloud.

Actual vs expected behavior:

I am not sure this behavior is intentional or not, but I prefer uploading file with a credential instead of API key.

Any other information you'd like to share?

If this is just a bug, I can contribute to fix it.

gmKeshari commented 3 weeks ago

Hi @Gekko0114,

In order to expedite the trouble-shooting process, please provide a minimum code snippet or screenshot to reproduce the issue reported here. Thanks!

Gekko0114 commented 3 weeks ago

@gmKeshari Sure. Thanks. This is not exactly same as my code, but like this.

from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file('service-account.json')
genai.configure(credentials=credentials)
file = genai.upload_file(path=output_path)

Then got an error that API_KEY is required to upload the file.

gmKeshari commented 3 weeks ago

The error message indicating that an API key is required to upload the file suggests that the genai.upload_file method expects an API key as one of the necessary parameters. This is likely because the method is designed to interact with a Google Cloud service that requires API key authentication. This could be due to security reasons, limitations of the underlying service, or design choices made by the genai library.

To resolve this issue without using an API key, you might need to consider the following options:

  1. Check Documentation: Verify the genai library documentation to confirm whether the upload_file method supports authentication using service account credentials or if it strictly requires an API key. The documentation should outline the supported authentication methods for different operations.

  2. Explore Other Methods: If the upload_file method doesn't support service account credentials, you might need to explore other methods of uploading files, such as using the Google Cloud Storage API directly or using a different library that supports service account authentication for file uploads.

Here is an example Using Google Cloud Storage : If you decide to use Google Cloud Storage for uploading files, here’s an example of how you can use service account credentials to upload files:

Here is an example Using Google Cloud Storage : If you decide to use Google Cloud Storage for uploading files, here’s an example of how you can use service account credentials to upload files:

"""

from google.cloud import storage

Initialize a client using service account credentials

client = storage.Client.from_service_account_json('service-account.json')

Define the bucket and blob (file)

bucket_name = 'your-bucket-name' file_path = 'path/to/your/file' destination_blob_name = 'destination/path/in/bucket/file'

Get the bucket and blob

bucket = client.bucket(bucket_name) blob = bucket.blob(destination_blob_name)

Upload the file

blob.upload_from_filename(file_path)

print(f"File {file_path} uploaded to {destination_blob_name}.")

"""

MarkDaoust commented 3 weeks ago

Yeah, so uploads go through a different channel compared to regular API calls. I had to customize the code to get that to work:

https://github.com/google-gemini/generative-ai-python/blob/main/google/generativeai/client.py#L73

I haven't looked into it farther. I assume there's a way to call the discovery service and then upload the file using other credential formats.

Maybe I just need the headers:

  -H Authorization: Bearer ${access_token}" \
  -H "x-goog-user-project: ${project_id}" \

Like in the curl examples?

https://github.com/google-gemini/generative-ai-python/blob/main/samples/rest/tuned_models.sh#L10-L11

MarkDaoust commented 3 weeks ago

Okay, following up on my previous comment. It looks like the underlying create_file method doesn't actually support the necessary scopes.

If I go into samples/rest/files.sh and substitute in the ADC headers above, like in this commit:

https://github.com/MarkDaoust/generative-ai-python/commit/168cd6f3de481c03e3b7a6c9590b4725671b7ebf

I get:

{
  "error": {
    "code": 400,
    "message": "Request contains an invalid argument.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.DebugInfo",
        "detail": "No scopes defined for OAuth: generativelanguage.googleapis.com/google.ai.generativelanguage.v1beta.FileService.CreateFile"
      }
    ]
  }
}

So I think this is impossible to fix on my side and I need to ask the API owners to add the scopes for create_file.

This would be a good fix, because as it stands right now there's no way to upload a file and send it to a tuned model, without using an API key for the file, and oauth for the tuned model ☹️.

MarkDaoust commented 2 weeks ago

This is a valid complaint

I looked into this a little more.

So I'm betting there's not going to be a fix for this. Eventually tuned models will work with API keys, and a single credential will work for everything. Then this will be "resolved".