pythonflaskbackblaze

Backblaze Python SDK v2 - serve file response from memory


I want some files (images in this case) in a private bucket on Backblaze to be exposed by an API endpoint in Flask. I'm not sure how to handle the DownloadedFile object that is returned from bucket.download_file_by_name

@app.route('/b2-image/<filename>', methods=('GET',))
def b2_image(filename):
    info = InMemoryAccountInfo()
    b2_api = B2Api(info)
    app_key_id = env['MY_KEY_ID']
    app_key = env['MY_KEY']

    b2_api.authorize_account('production', app_key_id, app_key)
    bucket = b2_api.get_bucket_by_name(env['MY_BUCKET'])

    file = bucket.download_file_by_name(filename)

    bytes = BytesIO()

    #something sort of like this??? 
    #return Response(bytes.read(file), mimetype='image/jpeg')
    

bucket.download_file_by_name returns a DownloadedFile object, I'm not sure how to handle it. The documentation provides no examples and seems to suggest I'm supposed to do something like:

file = bucket.download_file_by_name(filename)

#this obviously doesn't make any sense
image_file = file.save(file, file)

Solution

  • I had been trying the following but it wasn't working:

    file = bucket.download_file_by_name(filename)
    f = BytesIO()
    file.save(f)
    
    return Response(f.read(), mimetype='image/jpeg')
    

    This SO Answer gave me the clue I needed, specifically setting the seek value on the BytesIO object:

    #this works
    file = bucket.download_file_by_name(filename)
    f = BytesIO()
    file.save(f)
    f.seek(0)
    
    return Response(f.read(), mimetype='image/jpeg')