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

У меня глупый вопрос о PyDrive. Я пытаюсь создать REST API с помощью FastAPI, который будет загружать изображение на Google Диск с помощью PyDrive. Вот мой код:

from fastapi import FastAPI, File
from starlette.requests import Request
from starlette.responses import JSONResponse
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

app = FastAPI()


@app.post('/upload')
def upload_drive(img_file: bytes=File(...)):
    g_login = GoogleAuth()
    g_login.LoadCredentialsFile("google-drive-credentials.txt")

    if g_login.credentials is None:
        g_login.LocalWebserverAuth()
    elif g_login.access_token_expired:
        g_login.Refresh()
    else:
        g_login.Authorize()
    g_login.SaveCredentialsFile("google-drive-credentials.txt")
    drive = GoogleDrive(g_login)

    file_drive = drive.CreateFile({'title':'test.jpg'})
    file_drive.SetContentString(img_file) 
    file_drive.Upload()

После попытки доступа к моей конечной точке я получаю эту ошибку:

file_drive.SetContentString(img_file)
  File "c:\users\aldho\anaconda3\envs\fastai\lib\site-packages\pydrive\files.py", line 155, in SetContentString
    self.content = io.BytesIO(content.encode(encoding))
AttributeError: 'bytes' object has no attribute 'encode'

Что я должен сделать, чтобы выполнить эту очень простую задачу?

Спасибо за вашу помощь!

**

ОБНОВЛЕНО

**

Спасибо за ответ и комментарий от Станисласа Морбье, вот мой обновленный и рабочий код:

from fastapi import FastAPI, File
from starlette.requests import Request
from starlette.responses import JSONResponse
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from PIL import Image
import os

app = FastAPI()


@app.post('/upload')
def upload_drive(filename, img_file: bytes=File(...)):
    try:
        g_login = GoogleAuth()
        g_login.LocalWebserverAuth()
        drive = GoogleDrive(g_login)

        file_drive = drive.CreateFile({'title':filename, 'mimeType':'image/jpeg'})

        if not os.path.exists('temp/' + filename):
            image = Image.open(io.BytesIO(img_file))
            image.save('temp/' + filename)
            image.close()

        file_drive.SetContentFile('temp/' + filename)
        file_drive.Upload()

        return {"success": True}
    except Exception as e:
        print('ERROR:', str(e))
        return {"success": False}

Спасибо ребята


person Aldo Suhartono Putra    schedule 27.10.2019    source источник


Ответы (2)


SetContentString требуется параметр типа str, а не bytes. Вот документация:

Установите содержимое этого файла в виде строки.

Создает экземпляр io.BytesIO строки в кодировке utf-8. Устанавливает mimeType как «текстовый/обычный», если не указано иное.

Поэтому вы должны декодировать img_file (типа bytes) в utf-8:

file_drive.SetContentString(img_file.decode('utf-8'))
person Stanislas Morbieu    schedule 27.10.2019
comment
Здравствуйте @stanislas-morbieu, спасибо за ваш ответ, однако, попробовав ваш код, я получаю эту ошибку: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte - person Aldo Suhartono Putra; 27.10.2019
comment
Я забыл это учесть. Я думаю, что вы не можете использовать SetContentString тогда. SetContentFile может быть единственным вариантом: вам, возможно, придется сохранить его во временный файл, чтобы передать имя файла в качестве аргумента для SetContentFile. - person Stanislas Morbieu; 28.10.2019
comment
Спасибо, я тоже не знаю об этом, я опубликую свой обновленный и рабочий код. Большое спасибо за ваш ответ - person Aldo Suhartono Putra; 28.10.2019

Используйте 1_

Это решило мою проблему

person Lakhani Aliraza    schedule 25.07.2020