Google 驱动器 API 复制团队驱动器中的文件

Google Drive API copy a file in team drive

我正在编写一个函数,将我的 Google 驱动器中的文件夹复制到另一个文件夹。该函数适用于常规驱动器 space 中的文件夹。但是,当我 运行 它在团队驱动器文件夹中时,出现以下错误。

Traceback (most recent call last):
  File "C:/Code/catpython/driveapi_utils.py", line 232, in <module>
    test_copy_folder()
  File "C:/Code/catpython/driveapi_utils.py", line 221, in test_copy_folder
    copy_folder(service, src='xxxxxx',
  File "C:/Code/catpython/driveapi_utils.py", line 211, in copy_folder
    copy_folder(service, file.get('id'), file.get('name'), dst_parent_id, **kwargs)
  File "C:/Code/catpython/driveapi_utils.py", line 201, in copy_folder
    fileId=clone.get("id"),
AttributeError: 'NoneType' object has no attribute 'get'

我的代码如下:

def copy_folder(service, src, src_name, dst, **kwargs):
    """
    Copies a folder. It will create a new folder in dst with the same name as src,
    and copies the contents of src into the new folder
    src: Source folder's id
    dst: Destination folder's id that the source folder is going to be copied to
    """

    page_token = None
    while True:
        response = service.files().list(q="'%s' in parents and trashed = false" % src,
                                        supportsAllDrives=True,
                                        spaces='drive',
                                        fields='nextPageToken, files(id, name, mimeType)',
                                        pageToken=page_token,
                                        includeItemsFromAllDrives=True,
                                        ).execute()
        dst_parent_id = create_folder(service, src_name, dst, **kwargs)
        for file in response.get('files', []):
            # Process change
            print('Found file: %s (%s, %s)' % (file.get('name'), file.get('id'), file.get('mimeType')))
            if not file.get('mimeType') == 'application/vnd.google-apps.folder':
                clone = None
                try:
                    clone = service.files().copy(fileId=file.get('id'),
                                         body={'title': 'copiedFile',
                                               'parents': [{'kind': "drive#fileLink",
                                                            'id': dst_parent_id}],
                                               'supportsAllDrives': True,
                                               }).execute()
                except HttpError as httpe:
                    pass
                try:
                    service.files().update(
                        fileId=clone.get("id"),
                        addParents=dst_parent_id,
                        removeParents=src,
                        fields="id, parents",
                        supportsAllDrives=True
                    ).execute()
                except HttpError as httpe:
                    pass
            else:
                print('drilling into %s' % file.get('name'))
                copy_folder(service, file.get('id'), file.get('name'), dst_parent_id, **kwargs)
        page_token = response.get('nextPageToken', None)
        if page_token is None:
            break

我调试了代码,我认为副本 api 抛出了一个错误:

<HttpError 404 when requesting https://www.googleapis.com/drive/v3/files/1n7h04M6Rpz3m2J6MGZq8trlnADEBFLrK/copy?alt=json returned "File not found: 1n7h04M6Rpz3m2J6MGZq8trlnADEBFLrK.". Details: "File not found: 1n7h04M6Rpz3m2J6MGZq8trlnADEBFLrK.">

但是该文件确实存在,并且相同的代码适用于我个人 space 中的文件。我可以完全访问团队驱动器,正如您从代码中看到的那样,我可以查询文件并在其中创建文件夹。

可能缺少什么?还是有更好的实现方式?

修改点:

  • 从你的问题来看,service.files().list似乎没有出现错误。使用此信息,来自 service.files().listfields='nextPageToken, files(id, name, mimeType)',fou.nd 您正在使用 service 作为驱动器 API v3.
  • 当您使用Drive API v3时,您的service.files().copy请求需要修改。
    1. titlename.
    2. 'parents': [{'kind': "drive#fileLink", 'id': dst_parent_id}]'parents': [dst_parent_id].
  • 此外,'supportsAllDrives': True 未包含在请求正文中。我认为这就是您的错误消息的原因。

当以上几点反映到你的脚本中,就会变成下面这样。

修改后的脚本:

从:
clone = service.files().copy(fileId=file.get('id'),
                     body={'title': 'copiedFile',
                           'parents': [{'kind': "drive#fileLink",
                                        'id': dst_parent_id}],
                           'supportsAllDrives': True,
                           }).execute()
到:
clone = service.files().copy(fileId=file.get('id'),
                             body={'name': 'copiedFile',
                                   'parents': [dst_parent_id],
                                   },
                             supportsAllDrives=True).execute()

参考: