Skip to content Skip to sidebar Skip to footer

How To Upload A File To Google Drive Using Python And The Drive Api V3

I have tried uploading file to Google Drive from my local system using a Python script but I keep getting HttpError 403. The script is as follows: from googleapiclient.http import

Solution 1:

Answer:

Delete your token.pickle file and re-run your application.

More Information:

As long as you have the correct set of credentials then all that is required when you update the scopes of your application is to re-obtain a token. Delete the token file located in the application's root folder, then run the application again. If you have the https://www.googleapis.com/auth/drive scope, and the Gmail API enabled in the developer console, you should be good.

References:

Solution 2:

"Insufficient Permission: Request had insufficient authentication scopes."

Means that the user you have authenticated with has not granted your application permission to do what you are trying to do.

The files.create method requires that you have authenticated the user with one of the following scopes.

enter image description here

while your code does appear to be using the full on drive scope. What i suspect has happens is that you have authenticated your user then changed the scope in your code and not promoted the user to login again and grant consent. You need to remove the users consent from your app either by having them remove it directly in their google account or just deleteing the credeitnals you have stored in your app. This will force the user to login again.

There is also an approval prompt force option to the google login but am not a python dev so im not exactly sure how to force that. it should be something like the prompt='consent' line below.

flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                           client_secret=CLIENT_SECRET,
                           scope='https://spreadsheets.google.com/feeds '+
                           'https://docs.google.com/feeds',
                           redirect_uri='http://example.com/auth_return',
                           prompt='consent')

consent screen

If done correctly the user should see a screen like this

enter image description here

Prompting them to grant you full access to their drive account

Token pickle

If you are following googles tutorial here https://developers.google.com/drive/api/v3/quickstart/python you need to delete the token.pickle that contains the users stored consent.

if os.path.exists('token.pickle'):
    withopen('token.pickle', 'rb') as token:
        creds = pickle.load(token)

Solution 3:

You can use the google-api-python-client to build a Drive service for using Drive API.

  • Get your Authorization as by following the first 10 steps of this answer.
  • If you want the user to go through consent screen only once, then store the credentials in a file. They include a refresh token that app can use to request authorization after expired.Example

With a valid Drive Service you can upload a file by calling a function like the following upload_file:

defupload_file(drive_service, filename, mimetype, upload_filename, resumable=True, chunksize=262144):
    media = MediaFileUpload(filename, mimetype=mimetype, resumable=resumable, chunksize=chunksize)
    # Add all the writable properties you want the file to have in the body!
    body = {"name": upload_filename} 
    request = drive_service.files().create(body=body, media_body=media).execute()
    if getFileByteSize(filename) > chunksize:
        response = Nonewhile response isNone:
            chunk = request.next_chunk()
            if chunk:
                status, response = chunk
                if status:
                    print("Uploaded %d%%." % int(status.progress() * 100))
    print("Upload Complete!")

Now pass in the parameters and call the function...

# Upload file
upload_file(drive_service, 'my_local_image.png', 'image/png', 'my_imageination.png' )

You will see the file with the name: my_imageination.png in your Google Drive root folder.

More about the Drive API v3 service and available methods here.


getFileSize() function:

defgetFileByteSize(filename):
    # Get file size in pythonfrom os import stat
    file_stats = stat(filename)
    print('File Size in Bytes is {}'.format(file_stats.st_size))
    return file_stats.st_size

Uploading to certain folder(s) in your drive is easy...

Just add the parent folder Id(s) in the body of the request.

Here are the properties of a File. parents[] property of File

Example:

request_body = {
  "name": "getting_creative_now.png",
  "parents": ['myFiRsTPaRentFolderId',
              'MyOtherParentId',
              'IcanTgetEnoughParentsId'],
}

Solution 4:

To use the scope 'https://www.googleapis.com/auth/drive' you need to submit the google app for verification.

Find the image for scope

So use the scope 'https://www.googleapis.com/auth/drive.file' instead of 'https://www.googleapis.com/auth/drive' to upload files without verification.

Also use SCOPES as list.

ex: SCOPES = ['https://www.googleapis.com/auth/drive.file']

I can successfully upload and download the files to google drive by using the above SCOPE.

Solution 5:

I found the solution for uploading a file to google drive. Here it is:

import requests
import json
url ="https://www.googleapis.com/oauth2/v4/token"

        payload ="{\n\"" \
                  "client_id\": \"CLIENT_ID" \
                  "\",\n\"" \
                  "client_secret\": \"CLIENT SECRET" \
                  "\",\n\"" \
                  "refresh_token\": \"REFRESH TOKEN" \
                  "\",\n\"" \
                  "grant_type\": \"refresh_token\"\n" \
                  "}"
        headers = {
            'grant_type': 'authorization_code',
            'Content-Type': 'application/json'
        }

        response = requests.request("POST", url, headers=headers, data=payload)

        res = json.loads(response.text.encode('utf8'))


        headers = {
            "Authorization": "Bearer %s"% res['access_token']
        }
        para = {
            "name": "file_path",
            "parents": "google_drive_folder_id"
        }
        files = {
            'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),
            # 'file': open("./gb.png", "rb")
            'file': ('mimeType', open("file_path", "rb"))
        }
        r = requests.post(
            "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
            headers=headers,
            files=files
        )
        print(r.text)

For generating client id, client secret and refresh token, you can follow the link :- click here

Post a Comment for "How To Upload A File To Google Drive Using Python And The Drive Api V3"