#python #google-drive-api #google-oauth #google-admin-sdk #google-api-python-client
#python #google-drive-api #google-oauth #google-admin-sdk #google-api-python-client
Вопрос:
Я написал скрипт, который будет искать файлы в файлах нескольких пользователей в нашей компании. Проблема в том, что скрипт работает, но только в течение определенного периода времени, но затем он получает ошибки HTTP 401, скорее всего, из-за истечения срока действия токена доступа. Я использую учетную запись службы с включенным делегированием домена и использую Google.библиотека python oauth2 для создания объекта службы диска (см. Код ниже). Я хотел программно получить токен обновления и сгенерировать новые токены доступа, когда истекает срок действия текущих. Проблема в том, что нет документации о том, как это сделать, используя учетные записи служб. Существует с обычными пользовательскими интерактивными потоками oauth. Мой вопрос в том, как я могу использовать объект drive для извлечения токена обновления, а затем создать новые токены доступа. Я знаю, что мне придется каким-то образом использовать закрытый ключ моей учетной записи службы, но не уверен.
Я читал эти два документа. https://developers.google.com/identity/protocols/oauth2
https://developers.google.com/identity/protocols/oauth2/service-account
- Создание объекта службы диска с олицетворением пользователя
from google.oauth2 import service_account
import googleapiclient.discovery
def impersonate_user(user_to_impersonate, key_file, domain):
scopes = ['https://www.googleapis.com/auth/drive',]
if user_to_impersonate is None:
raise InvalidDomainUser(f"{user_to_impersonate} is not a member of {domain}")
if key_file is None:
raise FileNotFoundError(f"{key_file} is not a valid service account file")
delegated_credentials = service_account.Credentials.from_service_account_file(
key_file, scopes=scopes)
# Impersonate User.
delegated_credentials = delegated_credentials.with_subject(user_to_impersonate)
drive_service = googleapiclient.discovery.build('drive', 'v2', credentials=delegated_credentials)
# Set new drive resource object
return drive_service
- Список файлов на диске пользователя
service = impersonate_user(user_to_impersonate, key_file, domain):
children = service.children().list(folderId=folderId,maxResults=1000, **param).execute()
for child in items:
item = service.files().get(fileId=child['id']).execute()
print(item.get("title", None))
Комментарии:
1. Когда вы говорите «скрипт работает, но только в течение определенного периода времени», сколько времени конкретно? После создания службы вы используете ее только один раз для листинга? Или вы снова используете тот же объект service по истечении длительного времени?
2. Привет, срок его действия истекает примерно через 1 час 3600 секунд. После этого каждый вызов api приводит к ошибке 401. Я использую один и тот же объект диска в течение определенного периода времени, ЕСЛИ только файл или папка на диске этого пользователя не принадлежат кому-то другому, и в этом случае я повторно создам этот объект, выдав себя за нового пользователя
3. Почему вы не создаете новый объект service каждый раз, когда он вам нужен (по истечении длительного времени)?
4. Кроме того, убедитесь, что
user_to_impersonate
это всегда пользователь из того же домена, что и учетная запись службы. Вы можете передать ему пустое значение. Но на самом деле ваш случай звучит так, что, несмотря на создание учетных записей службы acocunt, ваш код вместо этого использует токен доступа для создания объекта service.5. Эй, так что теперь я заработал. Это была логическая ошибка в моем коде. Но, похоже, сейчас это работает. Спасибо за помощь!
Ответ №1:
Олицетворение пользователя генерирует токен доступа, срок действия которого истекает. Чтобы получить новый токен доступа, вы просто создаете его так же, как и в первый раз. Учетные записи служб не имеют понятия о токене обновления, вы просто создаете новый токен доступа, используя свои учетные данные.
Источник: встроенная поддержка учетной записи службы Google в Xkit
Ответ №2:
Это базовый код для учетной записи службы с помощью python. Вам нужно будет добавить часть делегирования.
Пока вы используете ту же службу, библиотека должна получать вам новый токен доступа, когда он когда-либо понадобится. Срок его действия не должен истекать.
"""Hello drive"""
from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']
KEY_FILE_LOCATION = '<REPLACE_WITH_JSON_FILE>'
VIEW_ID = '<REPLACE_WITH_VIEW_ID>'
def drive():
"""Initializes an drive service object.
Returns:
An authorized drive service object.
"""
credentials = ServiceAccountCredentials.from_json_keyfile_name(
KEY_FILE_LOCATION, SCOPES)
# Build the service object.
drive = build('drive', 'v3', credentials=credentials)
return drive
Комментарии:
1. Привет, да, кажется, что срок его действия истекает через 1 час. Я получаю эту ошибку
<HttpError 401 when requesting https://www.googleapis.com/drive/v2/files/fileidhere/children?maxResults=1000amp;alt=json returned "Invalid Credentials">
в файле libsite-packagesgoogleapiclienthttp.py