pythongoogle-api-clientgoogle-api-python-client

Move a file with Google-Drive-API


Is it possible to explicitly move a file through python's googleapiclient module? I want to create the following function, given a file, original path and destination path:

def move_file(service, filename, init_drive_path, drive_path, copy=False):
    """Moves a file in Google Drive from one location to another.

    service: Drive API service instance.
    filename (string): full name of file on drive
    init_drive_path (string): initial file location on Drive
    drive_path (string): the file path to move the file in on Drive
    copy (boolean): file should be saved in both locations

    Returns nothing.
    """

Currently I have been executing this through manually downloading the file and then re-uploading it to the desired location, however this is not practical for big files and seems like a work-around method anyway.

Here's the documentation for the methods available on the google-drive-api.


EDIT See solution below:


Solution

  • Found it here. You just need to retrieve the file and folder ID and then use the update method. The remove_parents parameter can be excluded if you want to leave a copy of the file in the old folder(s)

        file_id = '***'
        folder_id = '***'
    
        # Retrieve the existing parents to remove
        file = drive_service.files().get(fileId=file_id, fields='parents').execute()
        previous_parents = ",".join(file.get('parents'))
    
        # Move the file to the new folder
        file = drive_service.files().update(
            fileId=file_id,
            addParents=folder_id,
            removeParents=previous_parents,
            fields='id, parents'
        ).execute()
    

    (Note I have not included my basic helper functions _getFileId and _getFolderId) So my original function will look something like:

        def move_file(service, filename, init_drive_path, drive_path, copy=False):
            """Moves a file in Google Drive from one location to another.
        
                service: Drive API service instance.
                'filename' (string): file path on local machine, or a bytestream
                to use as a file.
                'init_drive_path' (string): the file path the file was initially in on Google
                Drive (in <folder>/<folder>/<folder> format).
                'drive_path' (string): the file path to move the file in on Google
                Drive (in <folder>/<folder>/<folder> format).
                'copy' (boolean): file should be saved in both locations
        
                Returns nothing.
            """
            file_id = _getFileId(service, filename, init_drive_path)
            folder_id = _getFolderId(service, drive_path)
        
            if not file_id or not folder_id:
                raise Exception('Did not find file specefied: {}/{}'.format(init_drive_path, filename))
        
            file = service.files().get(fileId=file_id, fields='parents').execute()
            
            if copy:
                previous_parents = ''
            else:
                previous_parents = ",".join(file.get('parents'))
    
            file = service.files().update(
                fileId=file_id,
                addParents=folder_id,
                removeParents=previous_parents,
                fields='id, parents'
            ).execute()