【问题标题】:Google API to create/update files on 'Shared with me' foldersGoogle API 在“与我共享”文件夹中创建/更新文件
【发布时间】:2022-07-22 23:33:29
【问题描述】:

我一直在尝试使用 Google API 在另一个用户与我共享的文件夹上创建文件(我确保我有编辑权限)。当我将 files.create 模块与 supportsAllDrives=True 一起使用时,我收到以下错误消息:

{ "errorMessage": "https://www.googleapis.com/upload/drive/v3/files?supportsTeamDrives=true&alt=json&uploadType=multipart returned "File not found: 1aLcUoiiI36mbCt7ZzWoHr8RN1nIPlPg7.". 详细信息: "[{'domain': 'global', 'reason': 'notFound', 'message': 'File未找到:1aLcUoiiI36mbCt7ZzWoHr8RN1nIPlPg7.','locationType':'parameter','location':'fileId'}]">", "errorType": "HttpError", "requestId": "fc549b9e-9590-4ab4-8aaa-f5cea87ba4b6", “堆栈跟踪”: [ " 文件 "/var/task/lambda_function.py",第 154 行,在 lambda_handler\n upload_file(service, download_path, file_name, file_name, folder_id, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')\n", " 文件 "/var/task/lambda_function.py",第 78 行,在 upload_file\n file = service.files().create(\n", " 文件 "/opt/python/googleapiclient/_helpers.py",第 131 行,在 positional_wrapper\n 中返回已包装(*args, **kwargs)\n", " 文件 "/opt/python/googleapiclient/http.py",第 937 行,在执行中\n 引发 HttpError(resp, content, uri=self.uri)\n" ] }

经过一番深入研究,我发现“共享驱动器”与“与我共享”不同,到目前为止我发现的所有 API 仅适用于“共享驱动器”。 supportsTeamDrives=True 已被弃用,我无法在文档中找到相关的替换参数。 file.list api 有一个参数sharedWithMe=True,我不确定如何在我的代码中使用它,因为file.create 无论如何都看不到“与我共享”文件夹的文件夹 ID。任何建议都提前表示感谢!

我当前的代码:

def upload_file(service, file_name_with_path, file_name, description, folder_id, mime_type):  
    
media_body = MediaFileUpload(file_name_with_path, mimetype=mime_type)

body = {
    'name': file_name,
    'title': file_name,
    'description': description,
    'mimeType': mime_type,
    'parents': [folder_id]
}

file = service.files().create(
    supportsAllDrives=True,
    supportsTeamDrives=True,
    body=body,
    media_body=media_body).execute()

【问题讨论】:

    标签: google-drive-api google-api-python-client google-drive-shared-drive


    【解决方案1】:

    修改答案以包含更多详细信息:

    您是正确的“共享驱动器”“与我共享”不同。首先,您需要从与您共享的文件夹中获取 ID,为此您可以使用 files:list。要将文件上传到该文件夹​​或任何类型的文件夹,您可以使用以下修改后的代码:

    from __future__ import print_function
    import pickle
    import os.path
    from googleapiclient.http import MediaFileUpload
    from googleapiclient.discovery import build
    from google_auth_oauthlib.flow import InstalledAppFlow
    from google.auth.transport.requests import Request
    from google.oauth2 import credentials, service_account
    
    # Scopes required by this endpoint -> https://developers.google.com/drive/api/v3/reference/files/create
    SCOPES = ['https://www.googleapis.com/auth/drive']
    """
    To upload/create a file in to a 'Shared with me' folder this script has the following configured:
    
    1. Project:
        * Create project 
        * Enable the Google Workspace API the service account will be using:     https://developers.google.com/workspace/guides/create-project
    
    2.Consent screen:
        * Configure the consent screen for the application 
        * Create credentials for your service account depending on the type of application to be used with https://developers.google.com/workspace/guides/create-credentials#create_a_service_account 
        Once your Service Account is created you are taken back to the credentials list (https://console.cloud.google.com/apis/credential) click on the created Service Account, next click on ‘Advanced settings’ and copy your client ID
    
    3. Scopes
        * Collect the scopes needed for your service account/application
         https://developers.google.com/identity/protocols/oauth2/scopes
    
    4. Grant access to user data to a service account in Google Workspace https://admin.google.com/ac/owl/domainwidedelegation
        * In the "Client ID" field, paste the client ID  from your service account
        * In the "OAuth Scopes" field, enter a comma-delimited list of the scopes required by your application. This is the same set of scopes you defined when configuring the OAuth consent screen.
        * Click Authorize.
    
    5. In your code you need to impersonate the account the folder was shared with, if it was your account, you add your account here:
        credentials = service_account.Credentials.from_service_account_file(
                    SERVICE_ACCOUNT_FILE, scopes=SCOPES)
        delegated_creds = credentials.with_subject('user@domain.info')
    """
    
    def main():
    
        SERVICE_ACCOUNT_FILE = 'drive.json' #Service Account credentials from Step 2
    
        credentials = service_account.Credentials.from_service_account_file(
                    SERVICE_ACCOUNT_FILE, scopes=SCOPES)
        delegated_creds = credentials.with_subject('user@domain.xyz')
    
        service = build('drive', 'v3', credentials=delegated_creds)
    
    
        media = MediaFileUpload(
            'xfiles.jpg',
            mimetype='image/jpeg',
            resumable=True
            )
        request = service.files().create(
            media_body=media,
            body={'name': 'xfile new pic', 'parents': ['1Gb0BH1NFz30eau8SbwMgXYXDjTTITByE']} #In here 1Gb0BH1NFz3xxxxxxxxxxx is the 'Shared With ME'FolderID to upload this file to
            )
    
        response = None
        while response is None:
                status, response = request.next_chunk()
                if status:
                    print("Uploaded %d%%." % int(status.progress() * 100))
        print("Upload Complete!")
    
    
    if __name__ == '__main__':
        main()

    地点:

    parents 是与您共享的文件夹的 ID。

    查看更多documentation details

    【讨论】:

    • 谢谢!问题是这基本上与我最初尝试过的代码相同(我在我的问题中包含了 sn-p)。您唯一添加的组件是检查上传进度。无论如何我尝试了代码,但仍然没有运气。代码错误仍然显示“未找到文件夹 ID”。
    • @YashaswiAnanth 查看我的更新答案。这是可能且可行的,无需在这里设置额外的端点。
    • 谢谢!我还没有尝试过这种方式,会让你知道它是怎么回事。在与 Google API 支持代理聊天后(我将对话详情放在下面作为答案),我决定目前最简单的方法是请求文件夹的所有者让我成为“共同所有者”或完全所有者。然后代码起作用了。目前看来,尽管拥有权限,但能够访问另一个用户的文件夹只是一个 GUI 功能。有人告诉我,开发人员已被告知此缺点,并将尝试在未来提供它。
    【解决方案2】:

    与 Google Workspace API 专家交谈后,发现没有可用的 API 来执行上述任务。为清楚起见,请参考我的目标文件夹所在的图片。

    Difference between 'Shared Drive' and 'Shared with me' (image)

    以下是支持代理的回复:

    我查看了您的代码,一切都做得很完美,所以我与 我们的驾驶专家,他们向我解释说“与 我”这不仅仅是一个标签,因为你不是所有者 文件,(就像您在“我的云端硬盘”中一样)也不是 共同所有者(如果他们位于“共享驱动器”中)它不允许 您可以使用任何类型的 API 来自动创建文件或 删除或与此相关的任何事情。

    在这种情况下,您可以在云端硬盘上制作副本并自动执行 在那里,只是不时地在文件中更新它 与您共享,或者只是要求用户将其移动到“共享驱动器” 并从那里访问它。

    我承认我有点失望,尽管有权限这样做,但没有 API 方法可以在其他用户的文件夹中添加/删除/编辑。作为开发人员,我的理解是 CLI 是与任何服务交互的终极最强大的方式。 GUI 仅次于 CLI,它只是一种更具视觉吸引力的媒介。通常,当我们无法使用 GUI 执行任务时,我们会求助于 CLI 并管理高粒度和精度。

    但这是一个完全颠倒的场景!我无法理解我如何能够访问“共享文件夹”并通过 GUI 进行添加和删除,但无法使用脚本执行相同操作。我现在明白“与我共享”只是一个标签,而不是我访问文件夹的“位置”,但我肯定会假设有另一种 API 方式来访问属于另一个用户的文件夹(使用该人的用户名/ID 用于标识,文件夹路径作为目标,验证我是否有权对身份验证进行上述更改,如果没有则返回错误,最后执行 API)。

    如果有人能够向我解释是否有特定原因导致最终用户无法使用它,我很乐意了解它。

    编辑强>

    我在这里发布解决方案有点晚了,但问题是我的 API 使用的 google 工作区服务帐户没有对我尝试查询的共享驱动器的写入权限。为服务帐户授予所需的编辑权限后,我的代码就可以完美运行了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-03
      相关资源
      最近更新 更多