Alina
Alina

Reputation: 61

How to upload an image on dropbox using its API V2 (in python)?

I need to create a pipeline that would take an image from the dropbox, process it and upload it back (could be a different folder). The first two steps are easy, but there doesn't seem to be a way to upload the image to dropbox with the newer API V2. I have tried uploading a local image - read from computer and save it to dropbox, no success. The problem seems to be the format of the file, I get the following error:

expected request_binary as binary type

There are many examples for the text files and it works pretty well, while for the images the same solutions fail

import dropbox
from PIL import Image

dbx = dropbox.Dropbox('access_token') # Connecting to the account
metadata,file=dbx.files_download('/PATH_TO_IMAGE') # Getting the image from DropBox
im=Image.open(io.BytesIO(file.content)) # Getting the image to process

dbx.files_upload(im, '/PATH', mode=WriteMode('overwrite'))

Also tried:

dbx.files_upload_session_start(im)

Python3, dropbox SDK 9.4.0 actually I have tried putting the file in various formats, so instead of im there was also im.read(), np.array(im.getdata()).encode(), io.BytesIO(), local image from my computer but nothing works. And I do not understand how to transform the image data to 'request_binary as binary type'.

So what is needed, as I understand is a way to transform any file to 'request_binary'

TypeError: expected request_binary as binary type, got <class --SMTH ELSE-->

Upvotes: 1

Views: 1260

Answers (2)

Martin Thoma
Martin Thoma

Reputation: 136359

I'd do this:

import dropbox


def load_image(filepath: str) -> bytes:
    with open(filepath, "rb") as fp:
        contents = fp.read()
    return contents

contents = load_image("1.png")
dbx = dropbox.Dropbox("access_token")  # Connecting to the account
dbx.files_upload(
    contents, "/FOLDER/IMAGE.png", dropbox.files.WriteMode.add, mute=True
)

Upvotes: 1

Alina
Alina

Reputation: 61

Thanks to Greg I have found a solution, a bit easier than the one written in the example

import dropbox
from PIL import Image
import numpy as np
import io


def load_image(filepath: str) -> bytes:
    image = Image.open(filepath)  # any image
    l = np.array(image.getdata())

    # To transform an array into image using PIL:
    channels = l.size // (image.height * image.width)
    l = l.reshape(image.height, image.width, channels).astype(
        "uint8"
    )  # unit8 is necessary to convert
    im = Image.fromarray(l).convert("RGB")

    # to transform the image into bytes:
    with io.BytesIO() as output:
        im.save(output, format="PNG")
        contents = output.getvalue()
    return contents

contents = load_image("1.png")
dbx = dropbox.Dropbox("access_token")  # Connecting to the account
dbx.files_upload(
    contents, "/FOLDER/IMAGE.png", dropbox.files.WriteMode.add, mute=True
)

Upvotes: 1

Related Questions