1

I have some images saved in mongodb and I used mongoengine and flask to save them. Now I want to make it json serializable so I can send it to a react frontend. This is the code that I used to decode the binary string.

from base64 import urlsafe_b64decode, b64encode
import json
from flask import Flask, Blueprint, jsonify
import bson
import json

from ..db_models.member import Member
from ..db_models.image import Image

bp_api = Blueprint('bp_api', '__name__', url_prefix='/api')

@bp_api.route('/get-recent-10')
def recent_10():
    recent_imgs = Image.objects.order_by('-updated')[:5]  #[5] is just giving the attributes of Imag object so no..
    print(recent_imgs)
    member_data = []
    for i in recent_imgs:
        #print(i)
        #print(i.member_id)
        #related_member = Member.objects(__raw__={"_id":i.member_id}).first()
        member_data.append(i.member_id.name)
    print(dir(recent_imgs[0].img_file.read()))
    print(type(recent_imgs[0].img_file.read()))
    
    img_b64_data = [b64decode(img.img_file.read()).decode('utf-8') for img in recent_imgs]  #THIS IS THE LINE THAT THROWS ERROR.
    recent_imgs = [json.loads(i.to_json()) for i in recent_imgs]
    return {
        "recent_imgs": recent_imgs,
        "img_b64_data": img_b64_data,
        "related_members": member_data

    }

But it throws error UnicodeDecodeError: 'utf-8' codec can't decode byte and the reason for that is .decode('utf-8'). To make sure the binary is not malformed or no problem with mongoengine I wrote the image to a file using this function and it worked prefectly fine.

@bp_api.route('/downloadimg/<img_id>')  ###TEMP
def downloadimg(img_id):
    img = Image.objects(__raw__={"_id":bson.ObjectId(img_id)}).first()
    img_bin = img.img_file.read()
    with open('new.png', 'wb') as fh:
        fh.write(img_bin)

    return 'OK'

Can someone tell me why I cannot decode the binary string?

davidism
  • 121,510
  • 29
  • 395
  • 339
Rimzan
  • 11
  • 3
  • Have you tried **bson.Binary(img.img_file.read())** to convert the object retrieved to binary form? – tad Jan 08 '23 at 12:53
  • 1
    Yeah, I tried it. But I think img.img_file.read() is already a binary string. No point of using bson.Binary() again. – Rimzan Jan 08 '23 at 12:55
  • Er, I think the issue is `b64decode`: you are meant to use `b64encode` without `.decode('utf-8')`, no? At least that's what you'd do with a regular binary file – Lodinn Jan 08 '23 at 13:42
  • Yep did that already. then I cannot jsonify the the binary string of image, since it is binary data. No jsonify, no fetching using react. – Rimzan Jan 08 '23 at 13:50
  • Oh my bad. It seems the trick is to use `b64encode` WITH `.decode('utf-8')`. See https://stackoverflow.com/a/37239382 – Lodinn Jan 08 '23 at 14:43
  • Do not forget mimetypes! – Lodinn Jan 08 '23 at 14:48

0 Answers0