如何使用Google Drive API通过服务帐户访问域中的共享文件?

2024-05-13 22:33:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试从Python 3.7脚本访问有关Google共享驱动器文件的一些简单信息:

The last time a Google Sheets file on a shared drive was modified.

我已经在GCP Drive API菜单中创建了一个服务帐户,它可以通过Sheets API访问/编辑/etc Google Sheets,没有任何问题

但是,当我对驱动器API使用相同的服务帐户时,它不会返回其自己文件夹(其中仅包含一个文件:“Getting Started”)之外的文件的任何信息。该帐户可以访问所有云API,具有与GSuite中API控制菜单中包含的驱动器API相关的所有作用域的全域授权

服务帐户的电子邮件地址已正确添加到共享驱动器中的所有文件夹中

有什么想法吗?基本上,我所需要的是知道任何给定用户最后一次修改工作表是什么时候

secret_cred_file = ...
SCOPES = ['https://www.googleapis.com/auth/drive']
credentials = service_account.Credentials.from_service_account_file(secret_cred_file, scopes=SCOPES)
service = discovery.build('drive', 'v3', credentials=credentials)
results = service.files().list(pageSize=10, fields="nextPageToken, files(id, name,modifiedTime)").execute()
items = results.get('files', [])

PS:我已经看到了:Getting files from shared folder但它没有帮助


Tags: 文件文件夹api信息servicegoogle菜单帐户
2条回答

通过向列表方法添加一些参数,我可以列出共享驱动器文件,而无需模拟用户,如google documentation所述:

Implement shared drive support

Shared drives follow different organization, sharing, and ownership models from My Drive. If your app is going to create and manage files on shared drives, you must implement shared drive support in your app. To begin, you need to include the supportsAllDrives=true query parameter in your requests when your app performs these operations:

files.get, files.list, files.create, files.update, files.copy, files.delete, changes.list, changes.getStartPageToken, permissions.list, permissions.get, permissions.create, permissions.update, permissions.delete

Search for content on a shared drive

Use the files.list method to search for shared drives. This section covers shared drive-specific fields in the files.list method. To search for shared drive, refer to Search for files and folders.

The files.list method contains the following shared drive-specific fields and query modes:

driveId — ID of shared drive to search.

includeItemsFromAllDrives — Whether shared drive items should be included in results. If not present or set to false, then shared drive items are not returned.

corpora — Bodies of items (files/documents) to which the query applies. Supported bodies are user, domain, drive, and allDrives. Prefer user or drive to allDrives for efficiency.

supportsAllDrives — Whether the requesting application supports both My Drives and shared drives. If false, then shared drive items are not included in the response.

示例

service.files().list(includeItemsFromAllDrives=True, supportsAllDrives=True, pageSize=10, fields="nextPageToken, files(id, name,modifiedTime)").execute()

请记住,文件夹或文件需要与服务帐户共享

您需要模拟您的用户。

不可能通过API调用一次性获取域中的所有文件

Service Accounts文章中说:

Service accounts are not members of your Google Workspace domain, unlike user accounts. For example, if you share assets with all members in your Google Workspace domain, they will not be shared with service accounts...This doesn't apply when using domain-wide delegation, because API calls are authorized as the impersonated user, not the service account itself.

不幸的是,你不能只与服务帐户共享一个文件。要获取域中的所有文件,您需要:

  1. 模拟管理员帐户并获取所有用户的列表
  2. 模拟每个用户并为每个用户发出驱动器API请求

这里是Python Library,特别是this section的一个很好的快速开始

请记住在GCP控制台和管理控制台中设置权限,尽管看起来您这样做是正确的

示例脚本

from google.oauth2 import service_account
from googleapiclient.discovery import build

def main():

    SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly',
        'https://www.googleapis.com/auth/admin.directory.user.readonly']
    SERVICE_ACCOUNT_FILE = 'credentials.json'

    credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    # Admin SDK to get users
    admin_delegated_credentials = credentials.with_subject('[ADMIN_EMAIL]')
    admin_service = build(
        'admin',
        'directory_v1',
        credentials=admin_delegated_credentials
        )

    admin_results = admin_service.users().list(customer='my_customer', maxResults=10,
                                orderBy='email').execute()
    users = admin_results.get('users', [])

    if not users:
        print('No users in the domain.')
    else:
        for user in users:
            print(u'{0} ({1})'.format(user['primaryEmail'],
                user['name']['fullName']))

            # Drive to get files for each user
            delegated_credentials = credentials.with_subject(user['primaryEmail'])

            drive_service = build(
                'drive',
                'v3',
                credentials=delegated_credentials
                )
            drive_results = drive_service.files().list(
                pageSize=10,
                fields="nextPageToken, files(id, name,modifiedTime)"
                ).execute()
            items = drive_results.get('files', [])

            if not items:
                print('No files found.')
            else:
                print('Files:')
                for item in items:
                    print(u'{0} ({1})'.format(item['name'],
                        item['id']))

if __name__ == '__main__':
    main()

说明

此脚本有两个作用域:

  • "https://www.googleapis.com/auth/drive.metadata.readonly"
  • "https://www.googleapis.com/auth/admin.directory.user.readonly"

在GCP云控制台中初始化的项目也已从管理控制台中被授予这些作用域>;安全性>;API控制>;域范围授权>;新增

脚本要做的第一件事是使用from_service_account_file构建凭据:

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

然后它构建委托的凭证,即要模拟的用户:

admin_delegated_credentials = credentials.with_subject('[ADMIN_EMAIL]')

从那里,它可以正常地构建服务。它获取用户列表,循环浏览用户并列出他们的文件。你可以根据自己的需要来调整

参考文献

相关问题 更多 >