Python Google Drive API: Permission Denied Error When Uploading Files Using files().insert()

Getting Permission Error with Google Drive File Upload

I’m working on a Python script to upload files to Google Drive using the API. I set up everything in the developer console - created a project, turned on the Drive API, and added OAuth 2.0 credentials (desktop application type).

Most API calls work fine, but when I try to upload a file using the files().insert() method, I get this error:

googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart&convert=false&useContentAsIndexableText=false&alt=json returned "Insufficient Permission">

Here’s my code:

auth_creds = authenticate_user()
http_client = auth_creds.authorize(httplib2.Http())
drive_service = discovery.build('drive', 'v2', http=http_client)

FOLDER_ID = "0B2hMhYwUjVamfnp1VHWtaGOXeHJoaH8PdFOOZlKvbmF2eGtxXF25UkGzc2iWNIeEVYi6dEE"

# Check folder permissions
folder_perms = drive_service.permissions().list(fileId=FOLDER_ID).execute()

print("FOLDER PERMISSIONS:")
for permission in folder_perms["items"]:
    for key in permission:
        print(key, permission[key])

print()

parent_folder = {
    "isRoot": False,
    "kind": "drive#parentReference",
    "id": FOLDER_ID
}

drive_service.files().insert(
    body={"parents": [parent_folder]},
    media_body='./my_file.txt',
    convert=False,
    useContentAsIndexableText=False
).execute()

The folder shows these permissions:

(u'withLink', True)
(u'kind', u'drive#permission')
(u'etag', u'"G-x1stDJXuRP9SHzw_W2ElLgdSl/jdxIlEegVZvNArsUsWJywv96L9"')
(u'role', u'writer')
(u'type', u'anyone')
(u'id', u'anyoneWithLink')

What permission am I missing to make file uploads work?

Switch to Drive v3 API instead of v2. The v2 API’s been deprecated for ages and causes weird permission issues even when everything looks right. Change your discovery.build call to discovery.build('drive', 'v3', http=http_client) and update the parent structure to use ‘parents’: [FOLDER_ID] directly instead of the parentReference object.

Had this exact problem a few months back - it’s likely your OAuth scopes. Your folder permissions look fine, but your app probably doesn’t have write access to Google Drive. When you set up OAuth, you need https://www.googleapis.com/auth/drive.file or https://www.googleapis.com/auth/drive scope, not just read-only. Check your authenticate_user() function and make sure the scopes parameter includes write permissions. If you changed scopes recently, delete your stored credentials file (token.json or whatever) to force re-auth with the new permissions. Your existing token might still only have read access even though your code now requests write access.

Your media_body parameter format is wrong. The files().insert() method needs a MediaFileUpload object, not a string path. Import MediaFileUpload from googleapiclient.http and fix it like this:

from googleapiclient.http import MediaFileUpload

media = MediaFileUpload('./my_file.txt', resumable=True)
drive_service.files().insert(
    body={"parents": [parent_folder], "title": "my_file.txt"},
    media_body=media,
    convert=False,
    useContentAsIndexableText=False
).execute()

You’re also missing the “title” field in your body parameter. Without the MediaFileUpload wrapper, the API can’t recognize the file format and throws misleading permission errors instead of format errors. This tripped me up when I started with the Drive API too.