diff --git a/fiftyone/server/decorators.py b/fiftyone/server/decorators.py
index 1d7e434e422..6f013b28944 100644
--- a/fiftyone/server/decorators.py
+++ b/fiftyone/server/decorators.py
@@ -5,11 +5,14 @@
| `voxel51.com `_
|
"""
+
+from json import JSONEncoder
import traceback
import typing as t
import logging
from bson import json_util
+import numpy as np
from fiftyone.core.utils import run_sync_task
@@ -18,6 +21,23 @@
from starlette.requests import Request
+class Encoder(JSONEncoder):
+ def default(self, o):
+ if isinstance(o, np.floating):
+ return float(o)
+
+ if isinstance(o, np.integer):
+ return int(o)
+
+ return JSONEncoder.default(self, o)
+
+
+async def create_response(response: dict):
+ return Response(
+ await run_sync_task(lambda: json_util.dumps(response, cls=Encoder))
+ )
+
+
def route(func):
async def wrapper(
endpoint: HTTPEndpoint, request: Request, *args
@@ -30,9 +50,8 @@ async def wrapper(
if isinstance(response, Response):
return response
- return Response(
- await run_sync_task(lambda: json_util.dumps(response))
- )
+ return await create_response(response)
+
except Exception as e:
logging.exception(e)
return JSONResponse(
diff --git a/tests/unittests/server_decorators_tests.py b/tests/unittests/server_decorators_tests.py
new file mode 100644
index 00000000000..a281ad1a2c3
--- /dev/null
+++ b/tests/unittests/server_decorators_tests.py
@@ -0,0 +1,32 @@
+"""
+FiftyOne Server decorators.
+
+| Copyright 2017-2024, Voxel51, Inc.
+| `voxel51.com `_
+|
+"""
+
+import unittest
+
+import numpy as np
+
+from fiftyone.server.decorators import create_response
+
+
+class TestNumPyResponse(unittest.IsolatedAsyncioTestCase):
+ async def test_numpy_response(self):
+ await create_response(
+ {
+ "float16": np.array([16.0], dtype=np.float16),
+ "float32": np.array([32.0], dtype=np.float32),
+ "float64": np.array([64.0], dtype=np.float64),
+ "int8": np.array([8], dtype=np.int8),
+ "int16": np.array([8], dtype=np.int16),
+ "int32": np.array([8], dtype=np.int32),
+ "int64": np.array([8], dtype=np.int64),
+ "uint8": np.array([8], dtype=np.uint8),
+ "uint6": np.array([8], dtype=np.uint16),
+ "uint32": np.array([8], dtype=np.uint32),
+ "uint64": np.array([8], dtype=np.uint64),
+ }
+ )