Как загрузить файл на Google Drive, используя Python и Drive API v3 - PullRequest
0 голосов
/ 12 февраля 2020

Я попытался загрузить файл на Google Диск с моей локальной системы, используя скрипт Python, но я продолжаю получать HttpError 403. Сценарий выглядит следующим образом:

from googleapiclient.http import MediaFileUpload
from googleapiclient import discovery
import httplib2
import auth

SCOPES = "https://www.googleapis.com/auth/drive"
CLIENT_SECRET_FILE = "client_secret.json"
APPLICATION_NAME = "test"
authInst = auth.auth(SCOPES, CLIENT_SECRET_FILE, APPLICATION_NAME)
credentials = authInst.getCredentials()
http = credentials.authorize(httplib2.Http())
drive_serivce = discovery.build('drive', 'v3', credentials=credentials)
file_metadata = {'name': 'gb1.png'}
media = MediaFileUpload('./gb.png',
                        mimetype='image/png')
file = drive_serivce.files().create(body=file_metadata,
                                    media_body=media,
                                    fields='id').execute()
print('File ID: %s' % file.get('id'))

Ошибка:

googleapiclient.errors.HttpError: <HttpError 403 when requesting
https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&alt=json&fields=id 
returned "Insufficient Permission: Request had insufficient authentication scopes.">

Использую ли я правильную область действия в коде или что-то пропустил?

Я также пробовал скрипт, который нашел в Интернете, и он работает нормально, но проблема в том, что он требует c токен, срок действия которого истекает через некоторое время. Так как я могу динамически обновить sh токен?

Вот мой код:

import json
import requests
headers = {
    "Authorization": "Bearer TOKEN"}
para = {
    "name": "account.csv",
    "parents": ["FOLDER_ID"]
}
files = {
    'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),
    'file': ('mimeType', open("./test.csv", "rb"))
}
r = requests.post(
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
    headers=headers,
    files=files
)
print(r.text)

Ответы [ 3 ]

0 голосов
/ 12 февраля 2020

Ответ:

Удалите файл token.pickle и перезапустите приложение.

Дополнительная информация:

Пока у вас есть правильный набор учетных данных, тогда все, что требуется при обновлении областей приложения, - это повторно получить токен. Удалите файл токена, расположенный в папке приложения root, затем снова запустите приложение. Если у вас есть область действия https://www.googleapis.com/auth/drive, и API Gmail, включенная в консоли разработчика, у вас все должно быть в порядке.

Ссылки:

0 голосов
/ 13 февраля 2020

Вы можете использовать google-api- python -клиент для создания службы Drive для использования Drive API .

  • Получите авторизацию, выполнив первые 10 шагов этого ответа .
  • Если вы хотите, чтобы пользователь go через экран согласия только один раз, то store учетные данные в файле. Они включают токен refre sh, который приложение может использовать для запроса авторизации после истечения срока действия . Пример

С действительным Служба накопителей вы можете загрузить файл, вызвав функцию, подобную следующей upload_file:

def upload_file(drive_service, filename, mimetype, upload_filename, resumable=True, chunksize=262144):
    media = MediaFileUpload(filename, mimetype=mimetype, resumable=resumable, chunksize=chunksize)
    # Add all the writable properties you want the file to have in the body!
    body = {"name": upload_filename} 
    request = drive_service.files().create(body=body, media_body=media).execute()
    if getFileByteSize(filename) > chunksize:
        response = None
        while response is None:
            chunk = request.next_chunk()
            if chunk:
                status, response = chunk
                if status:
                    print("Uploaded %d%%." % int(status.progress() * 100))
    print("Upload Complete!")

Теперь передайте параметры и вызовите функцию ...

# Upload file
upload_file(drive_service, 'my_local_image.png', 'image/png', 'my_imageination.png' )

Вы увидите файл с именем: my_imageination.png в папке Google Drive root.

Подробнее о службе Drive API v3 и доступных методах здесь .


getFileSize() Функция:

def getFileByteSize(filename):
    # Get file size in python
    from os import stat
    file_stats = stat(filename)
    print('File Size in Bytes is {}'.format(file_stats.st_size))
    return file_stats.st_size

Загрузка в определенные папки на вашем диске очень проста ...

Просто добавьте идентификаторы родительской папки в тело запроса.

Вот свойства файла . parents[] property of File

Пример:

request_body = {
  "name": "getting_creative_now.png",
  "parents": ['myFiRsTPaRentFolderId',
              'MyOtherParentId',
              'IcanTgetEnoughParentsId'],
}

0 голосов
/ 12 февраля 2020

"Недостаточное разрешение: у запроса недостаточно областей проверки подлинности."

Означает, что пользователь, с которым вы прошли проверку подлинности, не предоставил вашему приложению разрешение на выполнение того, что вы пытаетесь сделать.

Для метода files.create требуется, чтобы вы аутентифицировали пользователя с помощью одной из следующих областей:

enter image description here

в то время как ваш код, похоже, использует полный объем диска. Я подозреваю, что произошло то, что вы аутентифицировали своего пользователя, а затем изменили область действия в своем коде и не предлагали пользователю снова войти в систему и дать согласие. Вам необходимо удалить согласие пользователей из вашего приложения, либо попросив удалить его непосредственно в своем аккаунте Google, либо просто удалив учетные данные, которые вы сохранили в своем приложении. Это заставит пользователя снова войти в систему.

Существует также опция принудительного подтверждения приглашения для входа в Google, но я не являюсь python разработчиком, поэтому я не совсем уверен, как это сделать. это должно быть что-то вроде строки приглашения = «согласие» ниже.

flow = OAuth2WebServerFlow(client_id=CLIENT_ID,
                           client_secret=CLIENT_SECRET,
                           scope='https://spreadsheets.google.com/feeds '+
                           'https://docs.google.com/feeds',
                           redirect_uri='http://example.com/auth_return',
                           prompt='consent')

экран согласия

Если все сделано правильно, пользователь должен увидеть такой экран

enter image description here

Предлагая им предоставить вам полный доступ к их учетной записи привода

Token pickle

Если вы читаете учебник по Google здесь https://developers.google.com/drive/api/v3/quickstart/python вам нужно удалить token.pickle, который содержит сохраненное согласие пользователей.

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
        creds = pickle.load(token)
...