How to setup uploading binary objects through flask_restless endpoint?

220 views Asked by At

I am working on a REST python application and I have picked flask_restless to build endpoints connected to the database. One of the tables I would like to manage is storing binary files as blobs (LargeBinary). I have noticed, though, that flask_restless requires json data for POST requests. I tried to apply base64 to the binary file contents and wrap it with json, but ultimately flask_restless passed file contents to sqlalchemy as a string and the SQLite backend complained that it requires bytes input (quite rightly so). I tried searching the interwebs for a solution, but either I am formulating my query incorrectly, or actually there is none.

So, is there a way to configure the endpoint managed with flask_restless to accept binary file as an attachment? Or rather the suggested solution would be to setup the endpoint for that particular table directly with flask (I did that before in another app), away from flask_restless?

1

There are 1 answers

0
Wojciech J. Migda On BEST ANSWER

It turns out that sending an attachment is not possible. So I dug deeper into how to send base64-encoded attachments which would then be saved as blobs.

For that I used pre- and post-processing facility of flask_restless:

def pp_get_single_image(result=None, **kw):
    import base64
    result['image'] = base64.b64encode(result['image']).decode('utf8')

def pp_get_many_images(result=None, search_params=None, **kw):
    result['objects'] = [pp_get_single_image(d) or d for d in result['objects']]

def pp_post_image_in(data=None, **kw):
    import base64
    data['image'] = base64.b64decode(data['image'])

def pp_post_image_out(result=None, **kw):
    import base64
    result['image'] = base64.b64encode(result['image']).decode('utf8')

postprocessors=dict(GET_SINGLE=[pp_get_single_image], GET_MANY=[pp_get_many_images], POST=[pp_post_image_out])
preprocessors=dict(POST=[pp_post_image_in])

manager = flask_restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(Image, methods=['GET', 'POST', 'DELETE'],
               postprocessors=pp_image.postprocessors,
               preprocessors=pp_image.preprocessors)