简体   繁体   中英

Create a folder (if not exists) on google drive and upload a file to it using Python script

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?

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')

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.

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']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM