I am trying to add some overloading to the Flask JSON encoder/decoder to add datetime encoding/decoding but only succeeded through a 'hack'.
from flask import Flask, flash, url_for, redirect, render_template_string
from flask.json import JSONEncoder, JSONDecodertemplate = """
<!DOCTYPE html>
<html><head><title>Test JSON encoder/decoder</title></head><body>
{% with messages = get_flashed_messages(with_categories=true) %}{% if messages %}{% for message in messages %}
<p>Flash: {{ message }}</p>
{% endfor %}{% endif %}{% endwith %}
<p>Flash should be: ['Flash message', 'success']</p>
<p><a href="{{ url_for('index') }}">Try again</a></p>
</body></html>
"""class CustomJSONEncoder(JSONEncoder):""" Do nothing custom json encoder """def default(self, obj):# My custom logic here# ...# orreturn super(CustomJSONEncoder, self).defaults(obj)class CustomJSONDecoder(JSONDecoder):""" Do nothing custom json decoder """def __init__(self, *args, **kargs):_ = kargs.pop('object_hook', None)super(CustomJSONDecoder, self).__init__(object_hook=self.decoder, *args, **kargs)def decoder(self, d):# My custom logic here# ...# orreturn dapp = Flask(__name__, static_url_path='')
app.config['SECRET_KEY'] = 'secret-key'
app.json_encoder = CustomJSONEncoder
app.json_decoder = CustomJSONDecoder@app.route('/')
def index():flash('Flash message', 'success')return redirect(url_for('display'))@app.route('/b')
def display():return render_template_string(template)if __name__ == '__main__':app.run(debug=True, port=5200)
The hack is that I should copy some code from the Flask.sessions.TaggedJSONSerializer like that:
import uuid
from base64 import b64decode
from werkzeug.http import parse_date
from markupsafe import Markup
from flask._compat import iteritemsclass CustomJSONDecoder(JSONDecoder):""" Do nothing custom json decoder """def __init__(self, *args, **kargs):_ = kargs.pop('object_hook', None)super(CustomJSONDecoder, self).__init__(object_hook=self.decoder, *args, **kargs)def decode(self, d):# My custom logic here# ...# Copy of the code from Flask.sessions.TaggedJSONSerializer(object).loads(self, value).object_hook(obj)if len(d) == 1:the_key, the_value = next(iteritems(d))if the_key == ' t':return tuple(the_value)elif the_key == ' u':return uuid.UUID(the_value)elif the_key == ' b':return b64decode(the_value)elif the_key == ' m':return Markup(the_value)elif the_key == ' d':return parse_date(the_value)return d
Do I do it 'correctly' or there is something that I miss?