Как выполнить возобновляемую загрузку файлов на Google Drive с помощью python - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь загрузить большие файлы (больше 5 МБ) на Google Drive. Исходя из документации Google , мне нужно настроить возобновляемый сеанс загрузки. Если сеанс успешно запущен, вы получите ответ с URI сеанса. Затем отправьте еще один запрос на URI, который, как я предполагаю, является вашим файлом.

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

Что Google хочет начать? Возобновляемая загрузка

POST https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable HTTP/1.1
Authorization: Bearer [YOUR_AUTH_TOKEN]
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: application/octet-stream

{
  "name": "myObject"
}

Как я это сделал в Python

import requests
from oauth2client.service_account import ServiceAccountCredentials

credentials = ServiceAccountCredentials.from_json_keyfile_dict(
    keyfile_dict=[SERVICE_ACCOUNT_JSON],
    scopes='https://www.googleapis.com/auth/drive')

delegated_credentials = credentials.create_delegated([EMAIL_ADDRESS])

access_token = delegated_credentials.get_access_token().access_token

url = "https://www.googleapis.com/upload/drive/v3/files"

querystring = {"uploadType": "resumable"}

payload = '{"name": "myObject", "parents": "[PARENT_FOLDER]"}'
headers = {
    'Content-Length': "38",
    'Content-Type': "application/json",
    'X-Upload-Content-Type': "application/octet-stream",
    'Authorization': "Bearer " + access_token
    }

response = requests.request(
    "POST", url, data=payload, headers=headers, params=querystring)

print(response.headers['Location'])

URI местоположения успешного ответа

https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=[SOME_LONG_ID]

PUT Запрос Google хочет

PUT https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=[SOME_LONG_ID] HTTP/1.1
Content-Length: 2000000
Content-Type: application/octet-stream

[BYTES 0-1999999]

PUT-запрос в python - это где я начинаю заблудиться

uri = response.headers['Location']

headers = {
    'Content-Length': "2000000",
    'Content-Type': "application/json"
    }

response = requests.request(
    "PUT", uri, headers=headers)

Я хотел бы знать, как завершить этот запрос PUT с указанием пути к моему файлу и любой другой необходимой информации. Спасибо за помощь.

1 Ответ

0 голосов
/ 02 июля 2019

Вы почти сделали это, просто пара вещей:

Относительно полезной нагрузки первого запроса, когда вы инициируете возобновляемую загрузку и отправляете метаданные:

payload = '{"name": "myObject", "parents": "[PARENT_FOLDER]"}'

Вы должны поместить это так, чтобы сохранить файл в выбранной папке:

payload = '{"name": "myObject2", "parents": ["PARENT_FOLDER_ID"]}'

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

Для второй части возобновляемой загрузки (загрузки файла) вам просто нужно получить файл, который вы хотите загрузить, и отправить его как тело запроса с параметром «data» в запросе, подобным этому:

  uri = response.headers['Location']

    headers = {
        'Content-Length': "2000000",
        'Content-Type': "image/jpeg"  
    }

    #Open the file and stored it in data2
    in_file = open("filepath to the file", "rb")  # opening for [r]eading as [b]inary
    data2 = in_file.read()

    #Send the file in the request
    response = requests.request(
        "PUT", uri, data=data2, headers=headers)

Используя функцию open () [2] с путем к файлу, включая имя файла (относительное или абсолютное) и используя «rb» в качестве второго параметра для чтения файла в двоичном режиме, вы получите необработанный двоичный файл (файл) объект) и применив к нему функцию read () [3], вы получите двоичные данные, которые и есть то, что ожидает запрос в теле запроса (параметр data).

Я проверил приведенный выше код, загрузив изображение в определенную папку, и оно заработало. Не забудьте изменить тип контента.

[1] https://developers.google.com/drive/api/v3/reference/files

[2] https://docs.python.org/3/library/functions.html#open

[3] https://www.w3schools.com/python/python_file_open.asp

...