Skip to content

Commit

Permalink
RestAPI: CustomJSONEncoder support bytes objects
Browse files Browse the repository at this point in the history
In Aiida 2.0, REST (where flask 1 was updated to flask 2), bytes objects are not supported anymore.
Because Flask 1.x was based on simplejson, that inherently converts bytes objects into strings.
In flask 2.0.0, it was redesigned based on the default python json.
See here: https://flask.palletsprojects.com/en/2.0.x/changes/ and here pallets/flask#3555
The conversion of a bytes array into `str` in the `CustomJSONEncoder` is implemented to workaround.

Co-authored-by: Jusong Yu <jusong.yeu@gmail.com>

Cherry-pick: ef9c544
  • Loading branch information
eimrek authored and sphuber committed Jul 13, 2022
1 parent 874c8df commit 6d22744
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
6 changes: 6 additions & 0 deletions aiida/restapi/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ def default(self, o):
o.hour).zfill(2), str(o.minute).zfill(2),
str(o.second).zfill(2)])

# To support bytes objects, try to decode to a string
try:
return o.decode('utf-8')
except (UnicodeDecodeError, AttributeError):
pass

# If not returned yet, do it in the default way
return JSONEncoder.default(self, o)

Expand Down
15 changes: 15 additions & 0 deletions tests/restapi/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,21 @@ def test_structure_download(self):
structure_data = load_node(node_uuid)._exportcontent('xsf')[0] # pylint: disable=protected-access
assert rv_obj.data == structure_data

def test_structure_download_false(self):
"""
Test download=false that displays the content in the browser instead
of downloading the structure file
"""
from aiida.orm import load_node

node_uuid = self.get_dummy_data()['structuredata'][0]['uuid']
url = f'{self.get_url_prefix()}/nodes/{node_uuid}/download?download_format=xsf&download=False'
with self.app.test_client() as client:
rv_obj = client.get(url)
response = json.loads(rv_obj.data)
structure_data = load_node(node_uuid)._exportcontent('xsf')[0] # pylint: disable=protected-access
assert response['data']['download']['data'] == structure_data.decode('utf-8')

def test_cif(self):
"""
Test download of cif file
Expand Down

0 comments on commit 6d22744

Please sign in to comment.