Search code examples
pythonpython-requestsuploadgoogle-drive-api

Google Drive API "Post" Method, uploading an image file with meta data, Python


I'm trying to upload an image file with meta data in Python.

I know there's a very convenient Python API, but I want to use "Post" Method so that I can use "aiohttp" with it.

After reading the official documents, I coded as below and got 400 error.

What's going wrong with it?

import requests
import json
import sys

with open('storage.json', 'r') as file:
    token = json.load(file)
    token = token["access_token"]

url = 'https://www.googleapis.com/upload/drive/v3/files'
file_metadata = {
    'Content-Type': 'application/json; charset=UTF-8',
    'name': 'test.jpg',
    'parents': [],
    'mimeType': None
}
media = {
    'Content-Type': 'image/jpeg',
    'file': open('test2.jpg', 'rb'),
}
data = {
    'MetaData': file_metadata,
    'Media': media,
}

headers = {
    'Authorization': 'Bearer {}'.format(token),
    'Content-Type': 'multipart/related',
    'Content-Length': str(sys.getsizeof(data)),
}
params = {
    'uploadType': 'multipart'
}

res = requests.post(url, data=data, params=params, headers=headers)
print(res)

Solution

  • In your script, how about the following modification?

    Modified script:

    import requests
    import json
    
    with open('storage.json', 'r') as file:
        token = json.load(file)
        token = token["access_token"]
    
    url = "https://www.googleapis.com/upload/drive/v3/files"
    file_metadata = {"name": "test.jpg"}
    data = {
        "MetaData": (
            "metadata",
            json.dumps(file_metadata),
            "application/json; charset=UTF-8",
        ),
        "Media": open("test2.jpg", "rb"),
    }
    
    headers = { "Authorization": "Bearer {}".format(token) }
    params = {"uploadType": "multipart"}
    
    res = requests.post(url, files=data, params=params, headers=headers)
    print(res.text)
    

    Testing:

    When this script is run, the following result is returned.

    {
     "kind": "drive#file",
     "id": "###",
     "name": "test.jpg",
     "mimeType": "image/jpeg"
    }
    

    In this case, the file is uploaded to the root folder. When you want to put the file to the specific folder, please add 'parents': ['###folderId###'] to file_metadata.

    Reference: