diff --git a/clients/python/sliderule/session.py b/clients/python/sliderule/session.py index 18f7fbc5f..0819eb148 100644 --- a/clients/python/sliderule/session.py +++ b/clients/python/sliderule/session.py @@ -105,6 +105,21 @@ 12: "STRING" } +def _json_encoder(obj): + if isinstance(obj, (bytes, bytearray)): + return obj.decode('utf-8') + if isinstance(obj, numpy.integer): + return int(obj) + if isinstance(obj, numpy.floating): + return float(obj) + if isinstance(obj, numpy.ndarray): + return obj.tolist() + if isinstance(obj, numpy.bool_): + return bool(obj) + if isinstance(obj, numpy.void): + return None + return obj + ############################################################################### # CLASSES ############################################################################### @@ -211,7 +226,7 @@ def source (self, api, parm=None, stream=False, callbacks=None, path="/source", # Construct Payload if isinstance(parm, dict): - payload = json.dumps(parm) + payload = json.dumps(parm, default=_json_encoder) else: payload = parm diff --git a/clients/python/tests/test_apis.py b/clients/python/tests/test_apis.py index 9d772b076..8f5e55c27 100644 --- a/clients/python/tests/test_apis.py +++ b/clients/python/tests/test_apis.py @@ -1,8 +1,12 @@ """Tests for sliderule APIs.""" +import json +import numpy as np import pytest +import requests import sliderule from sliderule import icesat2 +from sliderule.session import Session from pathlib import Path import os @@ -129,3 +133,31 @@ def test_toregion(self): region = sliderule.toregion(os.path.join(TESTDIR, 'data/polygon.geojson')) assert len(region["poly"]) == 5 # 5 coordinate pairs assert {'lon', 'lat'} <= region["poly"][0].keys() + + def test_toregion_int_coords_json_serializable(self): + region = sliderule.toregion([ + {"lon": -120, "lat": -25}, + {"lon": -95, "lat": -25}, + {"lon": -95, "lat": 0}, + {"lon": -120, "lat": 0}, + {"lon": -120, "lat": -25}, + ]) + json.dumps(region["poly"]) + + def test_toregion_numpy_int_coords_request_serializable(self, monkeypatch): + session = Session() + + def fake_get(*args, **kwargs): + raise requests.ConnectionError("blocked") + + monkeypatch.setattr(session.session, "get", fake_get) + + poly = [ + {"lon": np.int64(-120), "lat": np.int64(-25)}, + {"lon": np.int64(-95), "lat": np.int64(-25)}, + {"lon": np.int64(-95), "lat": np.int64(0)}, + {"lon": np.int64(-120), "lat": np.int64(0)}, + {"lon": np.int64(-120), "lat": np.int64(-25)}, + ] + rsps = session.source("version", {"poly": poly}, stream=False) + assert rsps == "Connection error"