16

So far I can upload file to the folder if it exists. I can't figure out a way to create one though. So if the folder does not exist, my script dies.

import sys from pydrive.auth import GoogleAuth from pydrive.drive import GoogleDrive gpath = '2015' fname = 'Open Drive Replacements 06_01_2015.xls' gauth = GoogleAuth() gauth.LocalWebserverAuth() drive = GoogleDrive(gauth) file_list = drive.ListFile({'q': "'root' in parents and trashed=false"}).GetList() for file1 in file_list: if file1['title'] == gpath: id = file1['id'] file1 = drive.CreateFile({'title': fname, "parents": [{"kind": "drive#fileLink","id": id}]}) file1.SetContentFile(fname) file1.Upload() 

Can you please help me modify the above code to create folder gpath if it does not exist?

2

3 Answers 3

15

Based on the documentation, it should be

file1 = drive.CreateFile({'title': fname, "parents": [{"id": id}], "mimeType": "application/vnd.google-apps.folder"}) 

Update: As of Apr 2020, documentation (v3) has been updated with API docs and shows:

folder_id = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E' file_metadata = { 'name': 'photo.jpg', 'parents': [folder_id] } media = MediaFileUpload('files/photo.jpg', mimetype='image/jpeg', resumable=True) file = drive_service.files().create(body=file_metadata, media_body=media, fields='id').execute() print 'File ID: %s' % file.get('id') 
Sign up to request clarification or add additional context in comments.

5 Comments

For completeness, you will also need to call .Upload() on file1 after the above to actually commit the operation. file1['id'] will then contain the id of the created folder.
It does not work for me. the response I get is GoogleDriveFile({'title': 'TEST-SOLAL-API', 'mimeType': 'application/vnd.google-apps.folder'}) but it does not create any folder I check on the source code and it says This method would not upload a file to GoogleDrive. Am I missing something?
@Solal - documentation must've been updated. The CreateFile method is no longer referred to in the documentation referenced.
@Solal @alofgran hey don't this is correct, CreateFile still works for me both for creating files and for folders. @Solan, did you call Upload() on the object returned by create file?
I was looking for something similar, but in Go, and this doesn't work because it will create every time the folder again. Now the documentation doesn't explain how to look for files in a particular (multi-level) sub-folder ... At least in Go there is no ListFile for a particular subdirectory ... one can check if some name is in one of the parents ... but that would be something different than the exact folder. There must be a way, but it's not documented in the link you sent :(
3

I had the same problem and stumbled over this issue. Here is the code I came up with:

import os from pydrive2.auth import GoogleAuth from pydrive2.drive import GoogleDriv class GoogleDriveConnection: _gauth = None _drive = None @staticmethod def get() -> GoogleDrive: """ This will return a valid google drive connection :return: A valid GoogleDrive connection """ if GoogleDriveConnection._gauth is None or GoogleDriveConnection._drive == None: GoogleDriveConnection._gauth = GoogleAuth() GoogleDriveConnection._gauth.LoadCredentialsFile(os.path.join(os.path.dirname(__file__), "mycredentials.txt")) # this assume you have saved your credentials, like this: gauth.SaveCredentialsFile("mycredentials.txt") GoogleDriveConnection._drive = GoogleDrive(GoogleDriveConnection._gauth) return GoogleDriveConnection._drive @staticmethod def upload_image(image_path: str, folder_path: str) -> str: """ Uploads an image to the google drive, and returns the https path to it :param image_path: Path to the image, has to end in an image type else the type won't be guessed correctly :param folder_path: The folder path it should have in the google drive (to structure the data there) :return: The https path to the uploaded image file, will be empty if the image_path is invalid """ if os.path.exists(image_path): google_drive = GoogleDriveConnection.get() image = google_drive.CreateFile() image.SetContentFile(image_path) # load local file data into the File instance # to remove the path from the filename image["title"] = os.path.basename(image_path) if folder_path: parent_id = GoogleDriveConnection.get_folder_id(folder_path) image["parents"] = [{"id": parent_id}] image.Upload() # creates a file in your drive with the name return "https://drive.google.com/uc?id=" + str(image['id']) return "" @staticmethod def get_folder_id(folder_path: str, element_index=0, last_parent=None) -> str: """ Gets the id of the given folder path, this function will create the folders, if they do not exist, so it will always return a valid id, the folder_path elements can be separated like normals via a slash. :param folder_path: Given folder path :param element_index: Element index needed for recursive creation of the element :param last_parent: Last parent only needed for recursive creation of the folder hierarchy :return: The id to the last folder in the path """ folder_path_elements = folder_path.split("/") if len(folder_path_elements) == element_index: return last_parent folder_list = GoogleDriveConnection.get().ListFile({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList() current_folder_name = folder_path_elements[element_index] for item in folder_list: if item['title'] == current_folder_name and item["parents"][0] == last_parent: return GoogleDriveConnection.get_folder_id(folder_path, element_index + 1, item['id']) # not in the list -> folder has to be created file_metadata = {'title': current_folder_name, 'mimeType': 'application/vnd.google-apps.folder'} if last_parent is not None: file_metadata['parents'] = [{"id": last_parent}] new_folder = GoogleDriveConnection.get().CreateFile(file_metadata) new_folder.Upload() return GoogleDriveConnection.get_folder_id(folder_path, element_index + 1, new_folder["id"]) 

This enables you to load up images to Google drive and if you call get_folder_id it will give you the id of that folder, if the folder does not exist it will be created.

Comments

1

the answer above didnt work for me, this did work. It returns the id of the newly created folder

def createRemoteFolder(folderName, parentID ): folderlist = (drive.ListFile ({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()) titlelist = [x['title'] for x in folderlist] if folderName in titlelist: for item in folderlist: if item['title']==folderName: return item['id'] file_metadata = { 'title': folderName, 'mimeType': 'application/vnd.google-apps.folder', 'parents': [{"id": parentID}] } file0 = drive.CreateFile(file_metadata) file0.Upload() return file0['id'] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.