5

I'm struggling to correctly upload a file to Google Drive through their API. I'm using Python and I'm aware that there is a client library for Google's API. Here is what I currently have. When running the below code, an empty untitled document is created in Google Drive and it's not in the correct directory, root/level_1. I'm not sure what I'm doing wrong with the data and files object. Is there anything that stands out from the code?

Here are the docs that I was following.

import json
import requests

url = "https://www.googleapis.com/upload/drive/v2/files?access_token=ACCESS_TOKEN&uploadType=multipart"
files = {"file": requests.get("image_url").content}
data = {
    "title": "image_url.jpg",
    "parents": ["root", "level_1"]
}

response = requests.post(url, data=json.dumps(data), files=files)
# json.loads(response.text)["title"] = "Untitled"
return response
Petesta
  • 1,623
  • 3
  • 19
  • 29

4 Answers4

4

How about this modification?

Modification points :

  • When you use Drive API, the access token is required to be included in header.
  • When you want to insert the file to parents you want, please use folder ID.
    • The folder ID is ##### of https://drive.google.com/drive/folders/#####.
    • If you want to insert the file to root folder, you can use root as the ID.

Modified script :

import json
import requests

headers = {"Authorization": "Bearer " + ACCESS_TOKEN}
para = {
    "title": "image_url.jpg",
    "parents": [{"id": "root"}, {"id": "### folder ID ###"}]
}
files = {
    "data": ("metadata", json.dumps(para), "application/json; charset=UTF-8"),
    "file": requests.get("image_url").content
}
response = requests.post("https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart", headers=headers, files=files)

return response

Note :

  • This modified script was used Drive API v2 by adjusting to your script.
  • Please be careful the following points.
    • In this modified script, the image file retrieved from image_url is uploaded to root folder and the folder with ### folder ID ### of Google Drive as the filename of "image_url.jpg".
    • In this case, "image_url.jpg" has 2 parents. So when one of them is deleted, the file in the both parents is removed.
  • When you use this script, please confirm the following 2 points again.
    • Whether Drive API is enabled.
    • Whether access token includes the scopes for uploading files to Google Drive.

If I misunderstand your question, I'm sorry.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • How do you get the access_token? I don't understand their doc and each time I'm getting close it requires a webpage to be open and confirm the auth.. I would like to do my api to google-drive – Jay Cee Jul 12 '18 at 11:12
  • 2
    @Jay Cee I could know the method for retrieving the access tokena and refresh token by cheking [here](https://developers.google.com/identity/protocols/OAuth2). And I have posted as an answer for retrieving access token. How about [this](https://stackoverflow.com/questions/42815450/refresh-google-drive-access-token/42822060#42822060)? If this was not what you want, I'm sorry. – Tanaike Jul 12 '18 at 22:21
  • 2
    @Jay Cee I'm glad your issue was solved. Thank you for your reply. – Tanaike Jul 13 '18 at 23:55
  • Thanks this helped me to know how to upload a file via requests. But how can I do this with `uploadType=resumable` – Yashik Jun 28 '19 at 13:08
  • @Yashik Thank you for your comment. For example, are these information useful for your situation? [Ref1](https://stackoverflow.com/search?q=python+drive+api+resumable+upload) and [Ref2](https://developers.google.com/drive/api/v3/manage-uploads#resumable) If these were not useful for your situation, I apologize. – Tanaike Jun 28 '19 at 23:34
0

I don't think you can set the directory when uploading, so 'root' will always be the default. Let it be uploaded in the root folder first, then move the file. For the full code implementation using Python, follow Wesley Chun's blog: Uploading & Downloading files with Python:

snippet:

DRIVE = build('drive', 'v2', http=creds.authorize(Http()))

FILES = (
    ('hello.txt', False),
    ('hello.txt', True),
)
for filename, convert in FILES:
    metadata = {'title': filename}
    res = DRIVE.files().insert(convert=convert, body=metadata,
            media_body=filename, fields='mimeType,exportLinks').execute()
    if res:
        print('Uploaded "%s" (%s)' % (filename, res['mimeType']))

Also, check the official Drive API Uploading Files doc.

To choose the folder for upload, check this SO post.

ReyAnthonyRenacia
  • 17,219
  • 5
  • 37
  • 56
0
import requests
f = open("img.png", "r")
files = {
  "metadata": ("",'{"name": "rhondu.png"}', 'application/json'),
    'laadu': ('', open('img.png', 'rb'), 'image/png')
}
file = [("",'{"name": "rhondu420.png"}', 'application/json'), ('', open('img.png', 'rb'), 'image/png', {'Expires': '0'})]
url = "https://www.googleapis.com/upload/drive/v3/files?access_token=ya29.A0ARrdaM8rd7nXLkz39QxqZOJp_DyVqAkQ98WErWhkuBmsihgFIGQ6TKF5YvWmtamWZXVqQD_Ey10hVy-5nsJskibD7-5obCOvDzySMlhXInFIHzHWJrONHXpO-l8JQ6UODgxHJermFEbvpAC20WMX5mPRAqRxoA"``
res = requests.post(url, files=files)
print(res.text) (edited) 
RYX
  • 37
  • 1
  • 1
  • 4
0

Update for Google drive API v3

import json
import requests

headers = {"Authorization": "Bearer " + ACCESS_TOKEN}
para = {
    "name": "image_url.jpg",
    "parents": ["### folder ID ###"]
}
files = {
    "data": ("metadata", json.dumps(para), "application/json; charset=UTF-8"),
    "file": open(filepath, 'rb').read() # don't forget to close file handle here
}
response = requests.post("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart", headers=headers, files=files)

return response