Skip to content

Commit 770312e

Browse files
committed
centralize orjson library use; extend serializer to_json function to return in byte form if specified
1 parent 8f9d46c commit 770312e

File tree

6 files changed

+23
-16
lines changed

6 files changed

+23
-16
lines changed

biothings/hub/api/handlers/base.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
# see https://github.com/biothings/biothings.api/commit/59c0d78f758018b0d87836657a2b5d1a700503a1
77
# import pandas.io.json as pdjson
88
# replace pandas json encoder with orjson:
9-
import orjson
109
from tornado.web import RequestHandler
1110

1211
from biothings import config
12+
from biothings.utils import serializer
1313

1414

1515
class DefaultHandler(RequestHandler):
@@ -26,10 +26,9 @@ def write(self, result):
2626
# "result": result,
2727
# "status": "ok"
2828
# }, iso_dates=True)
29-
orjson.dumps(
29+
serializer.to_json({
3030
{"result": result, "status": "ok"},
31-
option=orjson.OPT_NON_STR_KEYS | orjson.OPT_NAIVE_UTC,
32-
).decode()
31+
})
3332
)
3433

3534
def write_error(self, status_code, **kwargs):

biothings/hub/dataload/dumper.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, Tuple, Union
2121
from urllib import parse as urlparse
2222

23+
from biothings.utils import serializer
24+
2325
try:
2426
import docker
2527
from docker.errors import ImageNotFound, NotFound, NullResource
@@ -28,7 +30,6 @@
2830
except ImportError:
2931
docker_avail = False
3032

31-
import orjson
3233
import requests
3334

3435
from biothings import config as btconfig
@@ -1883,7 +1884,7 @@ def _run_api_and_store_to_disk(
18831884
try:
18841885
for filename, obj in fn():
18851886
fn_byte_arr = buffer.setdefault(filename, bytearray())
1886-
fn_byte_arr.extend(orjson.dumps(obj) + b"\n")
1887+
fn_byte_arr.extend(serializer.to_json(obj, return_bytes=True) + b"\n")
18871888
if len(fn_byte_arr) >= buffer_size:
18881889
with open(f"{filename}.{pid}", "ab") as f:
18891890
f.write(fn_byte_arr)

biothings/utils/dotfield.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import orjson
21
from biothings.utils import serializer
32

43

@@ -22,8 +21,7 @@ def make_object(attr, value):
2221
# s += "}" * (len(attr_list))
2322
# return json.loads(s)
2423

25-
# New implementation using orjson module
26-
s += orjson.dumps(value).decode("utf-8") # decoding is necessary because orjson dumps into bytes
24+
s += serializer.to_json(value)
2725
s += "}" * (len(attr_list))
2826
return serializer.load_json(s)
2927

biothings/utils/serializer.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def orjson_default(o):
2828
raise TypeError(f"Type {type(o)} not serializable")
2929

3030

31-
def to_json(data, indent=False, sort_keys=False):
31+
def to_json(data, indent=False, sort_keys=False, return_bytes=False):
3232
# default option:
3333
# OPT_NON_STR_KEYS: non string dictionary key, e.g. integer
3434
# OPT_NAIVE_UTC: use UTC as the timezone when it's missing
@@ -37,7 +37,14 @@ def to_json(data, indent=False, sort_keys=False):
3737
option |= orjson.OPT_INDENT_2
3838
if sort_keys:
3939
option |= orjson.OPT_SORT_KEYS
40-
return orjson.dumps(data, default=orjson_default, option=option).decode()
40+
41+
byte_dump = orjson.dumps(data, default=orjson_default, option=option)
42+
if return_bytes:
43+
return byte_dump
44+
45+
return byte_dump.decode()
46+
47+
# return orjson.dumps(data, default=orjson_default, option=option).decode()
4148

4249

4350
def to_json_file(data, fobj, indent=False, sort_keys=False):

biothings/web/analytics/channels.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import asyncio
33
import certifi
44
import logging
5-
import orjson
65
import ssl
76

7+
from biothings.utils import serializer
88
from biothings.web.analytics.events import Event, Message
99

1010

@@ -81,7 +81,7 @@ async def send(self, event):
8181
"user_id": str(event._cid(1)),
8282
"events": events[i : i + 25],
8383
}
84-
await self.send_request(session, self.url, orjson.dumps(data))
84+
await self.send_request(session, self.url, serializer.to_json(data, return_bytes=True))
8585

8686
async def send_request(self, session, url, data):
8787
retries = 0

tests/web/analytics/test_channels.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import aiohttp
22
import asyncio
3-
import orjson
43
import pytest
54

65
from aioresponses import aioresponses
6+
7+
from biothings.utils import serializer
78
from biothings.web.analytics.channels import SlackChannel, GA4Channel, GAChannel
89
from biothings.web.analytics.events import GAEvent, Message
910
from unittest.mock import patch
@@ -91,7 +92,8 @@ async def test_send_GA4():
9192
async def test_send_GA4_request_retries():
9293
channel = GA4Channel("G-XXXXXX", "SECRET")
9394
url = channel.url
94-
data = orjson.dumps({"test": "data"})
95+
# data = orjson.dumps({"test": "data"})
96+
data = serializer.to_json({"test": "data"}, return_bytes=True)
9597

9698
async with aiohttp.ClientSession() as session:
9799
with aioresponses() as responses:
@@ -109,7 +111,7 @@ async def test_send_GA4_request_retries():
109111
async def test_send_GA4_request_max_retries():
110112
channel = GA4Channel("G-XXXXXX", "SECRET")
111113
url = channel.url
112-
data = orjson.dumps({"test": "data"})
114+
data = serializer.to_json({"test": "data"}, return_bytes=True)
113115

114116
async with aiohttp.ClientSession() as session:
115117
with aioresponses() as responses:

0 commit comments

Comments
 (0)