Клиентская библиотека Google Api для python не возвращает nextPageToken в Files: метод списка с запросом - PullRequest
1 голос
/ 11 апреля 2019

Мне нужно получить список всех файлов и папок на диске Google, принадлежащих пользователю. По некоторым причинам метод file.list не возвращает nextPageToken в ответ, и я вижу только несколько результатов, так как не могу перейти на следующую страницу.

Я пробовал API Client Library для Python и API Explorer, но я получаю только несколько записей на пользователя.

Мой код


users = ['user1@domain.com', 'user2@domain.com']
drive_array = []

if users: 
    for item in users:
        page_token_drive = None
        query = "'%s' in owners" % (item)
        while True:
            drive_result = service_drive.files().list(q=query, corpora='domain', includeTeamDriveItems=False, 
                                                      supportsTeamDrives=False, fields='nextPageToken, files(id,owners)', 
                                                      pageToken=page_token_drive).execute()
            drive_array.extend(drive_result.get('files', []))
            page_token_drive = drive_result.get('nextPageToken', None)
            if not page_token_drive:
                break

Я ожидаю получить идентификатор файла и массив владельцев для всех файлов, принадлежащих пользователю

[
    {
        "id": "12344",
        "owners": [
            {
                "kind": "drive#user",
                "displayName": "User1 User1",
                "photoLink": "https://lg",
                "me": false,
                "permissionId": "1234556",
                "emailAddress": "user1@domain.com"
            }
        ]
    },
    {
        "id": "09875",
        "owners": [
            {
                "kind": "drive#user",
                "displayName": "User1 User1",
                "photoLink": "https://lh5",
                "me": false,
                "permissionId": "56565665655656566",
                "emailAddress": "user1@domain.com"
            }
        ]
    }
]

1 Ответ

0 голосов
/ 24 мая 2019

Согласно документации , для авторизации запросов к API G Suite вам необходимо использовать OAuth 2.0, и у вас есть два варианта (или потоков , если вы хотите придерживаться официальная терминология):

  1. Авторизация пользователя с экраном согласия (например, OAuth 2.0 для установленных приложений )
  2. Делегирование по всему домену для приложений сервер-сервер (например, Использование OAuth 2.0 для приложений сервер-сервер )

С первой опцией, когда пользователь завершает поток, вы можете получить доступ только к его ресурсам. Поэтому, если вы хотите отобразить все содержимое диска для разных пользователей в домене G Suite, вам нужно использовать второй вариант.

Я также рекомендую использовать клиент Python pagination для управления списком файлов.

Вот рабочий пример варианта 1 (Python 3.6)

import os
import pickle

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

SCOPES = ['https://www.googleapis.com/auth/drive', ]
users = ['user1@domain.eu', 'user2@domain.eu']

# we check if we save the credentials in the past and we reuse them
if not os.path.exists('credentials.dat'):

    # no credentials found, we run the standard auth flow
    flow = InstalledAppFlow.from_client_secrets_file('client_id.json', SCOPES)
    credentials = flow.run_local_server()

    with open('credentials.dat', 'wb') as credentials_dat:
        pickle.dump(credentials, credentials_dat)
else:
    with open('credentials.dat', 'rb') as credentials_dat:
        credentials = pickle.load(credentials_dat)

if credentials.expired:
    credentials.refresh(Request())

drive_sdk = build('drive', 'v3', credentials=credentials)

# drive files API
drive_files_api = drive_sdk.files()

for item in users:
    query = "'{}' in owners".format(item)

    drive_list_params = {
        'q': query,
        'corpora': 'domain',
        'includeTeamDriveItems': False,
        'supportsTeamDrives': False,
        'fields': 'files(id,owners),nextPageToken',
    }

    # first request
    files_list_req = drive_files_api.list(**drive_list_params)

    while files_list_req is not None:
        drive_file_list = files_list_req.execute()

        print(drive_file_list.get('files', []))

        # pagination handling
        files_list_req = drive_files_api.list_next(files_list_req, drive_file_list)

Если вы запустите это, вам будет предложено авторизоваться, и на вашем диске будет запущен скрипт со списком файлов, принадлежащих другим пользователям и предоставленных вам.

Если вы хотите использовать межсерверный поток с делегированием по всему домену для перечисления всех файлов (не только тех, которые вам предоставлены), вот еще один рабочий пример.

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

SCOPES = ['https://www.googleapis.com/auth/drive', ]
users = ['user1@domain.eu', 'user2@domain.eu']

credentials = service_account.Credentials.from_service_account_file('client_secret.json', scopes=SCOPES)

for item in users:
    delegated_credentials = credentials.with_subject(item)
    drive_sdk = build('drive', 'v3', credentials=delegated_credentials)

    # drive files API
    drive_files_api = drive_sdk.files()

    drive_list_params = {
        'corpora': 'domain',
        'includeTeamDriveItems': False,
        'supportsTeamDrives': False,
        'fields': 'files(id,owners),nextPageToken',
    }

    # first request
    files_list_req = drive_files_api.list(**drive_list_params)

    while files_list_req is not None:
        drive_file_list = files_list_req.execute()

        print(drive_file_list.get('files', []))

        # pagination handling
        files_list_req = drive_files_api.list_next(files_list_req, drive_file_list)
...