Flask: orjson instead of json module for decoding
Asked Answered
G

2

10

I'm using flask and have a lot of requests. The json module, which is used by flask, is quite slow. I automatically can use simplejson, but thats a bit slower, not faster. According to the documentation I can define a decoder (flask.json_decoder), but orjson doesn't have this class. I only have the function loads and dumps. Can somebody explain me, how I can exchange the json module with orjson? In the end I just want to use the loads and dumps function, but I can't connect my loose ends.

Greenish answered 19/2, 2020 at 8:47 Comment(0)
C
8

a very basic implementation could look like this:

class ORJSONDecoder:

    def __init__(self, **kwargs):
        # eventually take into consideration when deserializing
        self.options = kwargs

    def decode(self, obj):
        return orjson.loads(obj)


class ORJSONEncoder:

    def __init__(self, **kwargs):
        # eventually take into consideration when serializing
        self.options = kwargs

    def encode(self, obj):
        # decode back to str, as orjson returns bytes
        return orjson.dumps(obj).decode('utf-8')


app = Flask(__name__)
app.json_encoder = ORJSONEncoder
app.json_decoder = ORJSONDecoder
Concerned answered 21/8, 2020 at 4:47 Comment(3)
For the record: setting json_decoder will use it also for other internal Flask stuff. And due to the lack of object_hook, it subtly breaks e.g. session handling (I learned it the hard way when flash messages broke and I had to learn about Flask's tagged JSON to understand why).Daimon
flask.palletsprojects.com/en/2.0.x/api/#tagged-jsonReflation
Seems like a waste to decode the utf-8 string, given it will be written as bytes again to the wire.Oystercatcher
B
8

Since version 2.2.0 of Flask you should use code like this:

from flask.json.provider import JSONProvider
from flask import Flask
import orjson


class ORJSONProvider(JSONProvider):
    def __init__(self, *args, **kwargs):
        self.options = kwargs
        super().__init__(*args, **kwargs)
    
    def loads(self, s, **kwargs):
        return orjson.loads(s)
    
    def dumps(self, obj, **kwargs):
        # decode back to str, as orjson returns bytes
        return orjson.dumps(obj, option=orjson.OPT_NON_STR_KEYS).decode('utf-8')


app = Flask(__name__)
app.json = ORJSONProvider(app)
Breslau answered 29/12, 2022 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.