From 46b9acc7fdc7041e3240ee4d57dc60a446b5788f Mon Sep 17 00:00:00 2001 From: Jeroen Dries Date: Mon, 19 Feb 2024 17:40:27 +0100 Subject: [PATCH] json output format: more robust with respect to unknown types https://github.com/Open-EO/openeo-geopyspark-driver/issues/643 --- openeo_driver/save_result.py | 14 +++++++++++++- tests/test_save_result.py | 20 +++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/openeo_driver/save_result.py b/openeo_driver/save_result.py index c505fb87..bc160328 100644 --- a/openeo_driver/save_result.py +++ b/openeo_driver/save_result.py @@ -4,6 +4,7 @@ import tempfile import warnings import logging +from datetime import datetime, date from pathlib import Path from shutil import copy from tempfile import mkstemp @@ -171,13 +172,24 @@ def write_assets(self, directory: Union[str, Path]) -> Dict[str, StacAsset]: :return: STAC assets dictionary: https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md#assets """ + + def json_serial(obj): + """JSON serializer for objects not serializable by default json code""" + + if isinstance(obj, (datetime, date)): + return obj.isoformat() + else: + return str(obj) + + + # TODO: There is something wrong here: arg is called `directory`, # but implementation and actual usage handles it as a file path (take parent to get directory) output_dir = Path(directory).parent output_file = output_dir / "result.json" with open(output_file, 'w') as f: import json - json.dump(self.prepare_for_json(), f) + json.dump(self.prepare_for_json(), f,default=json_serial) return {"result.json":{ "href":str(output_file), "roles": ["data"], diff --git a/tests/test_save_result.py b/tests/test_save_result.py index fd6fcde7..b8d57362 100644 --- a/tests/test_save_result.py +++ b/tests/test_save_result.py @@ -1,3 +1,4 @@ +import datetime import json from pathlib import Path @@ -9,7 +10,7 @@ from openeo.metadata import CollectionMetadata from openeo_driver.datacube import DriverVectorCube from openeo_driver.save_result import AggregatePolygonResult, SaveResult, AggregatePolygonSpatialResult, \ - AggregatePolygonResultCSV + AggregatePolygonResultCSV, JSONResult from .data import load_json, json_normalize, get_path @@ -172,3 +173,20 @@ def test_load_csv(self): [4646.262612301313, 4865.926572218383, 5178.517363510712], [4645.719597475695, 4865.467252259935, 5177.803342998465], ] + +def test_jsonresult(tmp_path): + + the_data = { + "bla":"bla", + "bla2":np.nan, + "bla3":{'bla':'bla'}, + "bla4":datetime.datetime.fromisocalendar(2020,3,1) + } + JSONResult(the_data).write_assets(tmp_path/"bla") + + the_path = tmp_path.joinpath("result.json") + actual_data = json.load(the_path.open()) + assert { 'bla': 'bla', + 'bla2': None, + 'bla3': {'bla': 'bla'}, + 'bla4': '2020-01-13T00:00:00'} == actual_data \ No newline at end of file