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.
application/vnd.google-apps.folderand with no extension." So you would create the folder in much the same way you're already creating the file.