如何使用 ujson 作为 Flask 编码器/解码器?

Posted

技术标签:

【中文标题】如何使用 ujson 作为 Flask 编码器/解码器?【英文标题】:How can I use ujson as a Flask encoder/decoder? 【发布时间】:2021-01-20 00:01:36 【问题描述】:

我已经看到,曾经可以像这样在 Flask 应用程序中使用 simplejson 作为 JSON 编码器/解码器:

from simplejson import JSONEncoder, JSONDecoder

app.json_encoder = JSONEncoder
app.json_decoder = JSONDecoder

但是ujson没有这样的对象:

>>> from ujson import JSONEncoder
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'JSONEncoder' from 'ujson' (/.../site-packages/ujson.cpython-38-x86_64-linux-gnu.so

我尝试了什么

我想到了这样的事情:

from uuid import UUID, uuid4

import ujson as json
from flask import Flask, jsonify
from flask.json import JSONEncoder


class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, UUID):
            return str(obj)
        return JSONEncoder.default(self, obj)

    def encode(self, o):
        return json.dumps(o)


app = Flask(__name__)
app.json_encoder = CustomJSONEncoder


@app.route("/")
def index():
    return jsonify("foo": uuid4())


app.run()

但我不确定,因为对解码器的帮助表明:

 |  decode(self, s, _w=<built-in method match of re.Pattern object at 0x7f6a608404b0>, _PY3=True)
 |      Return the Python representation of ``s`` (a ``str`` or ``unicode``
 |      instance containing a JSON document)
 |  
 |  raw_decode(self, s, idx=0, _w=<built-in method match of re.Pattern object at 0x7f6a608404b0>, _PY3=True)
 |      Decode a JSON document from ``s`` (a ``str`` or ``unicode``
 |      beginning with a JSON document) and return a 2-tuple of the Python
 |      representation and the index in ``s`` where the document ended.
 |      Optionally, ``idx`` can be used to specify an offset in ``s`` where
 |      the JSON document begins.
 |      
 |      This can be used to decode a JSON document from a string that may
 |      have extraneous data at the end.

我的实现好吗?我将如何支持那些其他参数?什么时候使用decode,什么时候使用raw_decode

当我运行它时,我得到:

[2020-10-09 10:54:52,063] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "main.py", line 28, in index
    return jsonify("foo": uuid4())
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/json/__init__.py", line 370, in jsonify
    dumps(data, indent=indent, separators=separators) + "\n",
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/json/__init__.py", line 211, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
    return cls(
  File "main.py", line 14, in encode
    return json.dumps(o)
TypeError: UUID('1f45a2bc-c964-48f0-b2f5-9ef7a2557966') is not JSON serializable

【问题讨论】:

另见:ultrajson/issues/433 【参考方案1】:

您可以像这样使用try 块:

import ujson as json
from flask.json import JSONEncoder


class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        try:
            return json.dumps(obj)
        except TypeError:
            return JSONEncoder.default(self, obj)


from flask import Flask

app = Flask(__name__)
app.json_encoder = CustomJSONEncoder

【讨论】:

以上是关于如何使用 ujson 作为 Flask 编码器/解码器?的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的 ujson 转储中包含私有属性?

将用户构建的 json 编码器传递到 Flask 的 jsonify

scala ujson.read() 返回 ujson.Obj

Flask-SqlAlchemy、Bcrypt、Postgres 的编码问题

使用 uJson 库理解这个可变递归函数

JSON 转储非数字浮点数与 Python 的 ujson 模块