Загрузка строки изображения на Google Диск с помощью pydrive

Мне нужно загрузить строку изображения (как ту, которую вы получаете от requests.get(url).content) на диск Google с помощью пакета PyDrive. Я проверил похожий вопрос, но был принят ответ, чтобы сохранить его. во временном файле на локальном диске, а затем загрузите его.
Однако я не могу этого сделать из-за ограничений локального хранилища и разрешений.
Ранее принятым ответом было использование SetContentString(image_string.decode('utf-8')), поскольку

SetContentString требуется параметр типа str, а не bytes.

Однако возникла ошибка: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte, как и в комментариях к этому ответу.
Есть ли способ сделать это без использования временного файла, используя PIL/BytesIO/все, что может преобразовать его для правильной загрузки в виде строки? или как-то с помощью PIL манипулировать изображением и загружать с помощью SetContentFile()?

Основной пример того, что я пытаюсь сделать, это:

img_content = requests.get('https://i.imgur.com/A5gIh7W.jpeg')
file = drive.CreateFile({...})
file.setContentString(img_content.decode('utf-8'))
file.Upload()

person Samarth Bhatia    schedule 12.05.2021    source источник
comment
Спасибо, что задали этот вопрос! Даже после нескольких часов поиска я не смог найти подобную проблему где-либо еще.   -  person aQwus jargon    schedule 17.07.2021


Ответы (1)


Когда я увидел документ (Загрузить и обновить файл content) pydrive, он говорит следующее.

Управлять содержимым файла так же просто, как управлять метаданными файла. Вы можете установить содержимое файла с помощью SetContentFile(имя файла) или SetContentString(content) и вызвать Upload() так же, как вы это делали для загрузки или обновления метаданных файла.

И я искал способ прямой загрузки двоичных данных на Google Диск. Но я не мог найти его. Из этой ситуации я подумал, что такого метода может и не быть. Итак, в этом ответе я хотел бы предложить загружать двоичные данные с помощью модуля requests. В этом случае токен доступа извлекается из сценария авторизации pydrive. Пример сценария выглядит следующим образом.

Пример сценария:

from pydrive.auth import GoogleAuth
import io
import json
import requests


url = 'https://i.imgur.com/A5gIh7W.jpeg' # Please set the direct link of the image file.
filename = 'sample file' # Please set the filename on Google Drive.
folder_id = 'root' # Please set the folder ID. The file is put to this folder.

gauth = GoogleAuth()
gauth.LocalWebserverAuth()
metadata = {
    "name": filename,
    "parents": [folder_id]
}
files = {
    'data': ('metadata', json.dumps(metadata), 'application/json'),
    'file': io.BytesIO(requests.get(url).content)
}
r = requests.post(
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
    headers={"Authorization": "Bearer " + gauth.credentials.access_token},
    files=files
)
print(r.text)

Примечание:

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

  • В этом случае используется uploadType=multipart. В официальном документе говорится следующее. Ссылка

    Используйте этот тип загрузки, чтобы быстро передать небольшой файл (5 МБ или меньше) и метаданные, описывающие файл, в одном запросе. Чтобы выполнить многокомпонентную загрузку, см. Выполнение многокомпонентной загрузки.

    • When you want to upload the data of the large size, please use the resumable upload. Ref

Использованная литература:

person Tanaike    schedule 12.05.2021
comment
Спасибо, это работает безупречно. Жаль, что PyDrive не может справиться с такой простой задачей. - person Samarth Bhatia; 13.05.2021
comment
@Самарт Бхатия Спасибо за ответ. Я рад, что ваша проблема была решена. - person Tanaike; 14.05.2021
comment
@Tanaike Отличный ответ! Мне было интересно, можем ли мы указать размеры изображения при загрузке на диск Google. - person aQwus jargon; 17.07.2021