Skip to content

PlotlyJSONEncoder doesn't work with simplejson #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
blankclemens opened this issue Mar 1, 2016 · 5 comments
Closed

PlotlyJSONEncoder doesn't work with simplejson #415

blankclemens opened this issue Mar 1, 2016 · 5 comments
Assignees

Comments

@blankclemens
Copy link

Building a web app using flask and the PlotlyJSONEncoder doesn't work as soon as simplejson is installed. Flask will automatically use simplejson then (and doesn't provide the option to use the inbuilt one), with which PlotlyJSONEncoder breaks simplejson.

E.g. my flask code

if __name__ == "__main__":
    app.json_encoder = plotly.utils.PlotlyJSONEncoder
    app.run(threaded=True,
            host="127.0.0.1",
            port=int("5001")
            )

works fine until simplejson is installed, then it throws type errors:

Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\flask\app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Anaconda3\lib\site-packages\flask\app.py", line 1813, in wsgi_app
    ctx.push()
  File "C:\Anaconda3\lib\site-packages\flask\ctx.py", line 321, in push
    self.session = self.app.open_session(self.request)
  File "C:\Anaconda3\lib\site-packages\flask\app.py", line 825, in open_session
    return self.session_interface.open_session(self, request)
  File "C:\Anaconda3\lib\site-packages\flask\sessions.py", line 302, in open_session
    s = self.get_signing_serializer(app)
  File "C:\Anaconda3\lib\site-packages\flask\sessions.py", line 299, in get_signing_serializer
    signer_kwargs=signer_kwargs)
  File "C:\Anaconda3\lib\site-packages\itsdangerous.py", line 519, in __init__
    self.is_text_serializer = is_text_serializer(serializer)
  File "C:\Anaconda3\lib\site-packages\itsdangerous.py", line 69, in is_text_serializer
    return isinstance(serializer.dumps({}), text_type)
  File "C:\Anaconda3\lib\site-packages\flask\sessions.py", line 85, in dumps
    return json.dumps(_tag(value), separators=(',', ':'))
  File "C:\Anaconda3\lib\site-packages\flask\json.py", line 128, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "C:\Anaconda3\lib\site-packages\simplejson\__init__.py", line 406, in dumps
    **kw).encode(obj)
TypeError: __init__() got an unexpected keyword argument 'tuple_as_array'

Where tuple_as_array is just an example, if I delete this one it will throw the same with all other json keywords (use_decimal, allow_nan, etc... ).

Since simplejson is the de facto standard and it's pretty hard to make sure that a package is not installed, I would assume that the best way would be to adopt the Plotly encoder to work with simplejson as well.

The installed versions are up to date according to Anaconda.

@etpinard
Copy link
Contributor

etpinard commented Mar 1, 2016

Possibly a duplicate of #197

@blankclemens
Copy link
Author

Hmm, I've read through this but I don't think it's the same issue. Python/Anaconda/pip still work fine, and so does simplejson when used without the Plotly encoder. My versions:

plotly: 1.9.6
simplejson: 3.8.2
flask: 0.10.1
python: 3.4.4
Anaconda: 2.4.1 (64-bit)

@blankclemens
Copy link
Author

If somebody want's to test it, here's a absolutely simple example which works when simplejson is not installed, otherwise it raises the error above:

from flask import Flask, jsonify
import plotly

app = Flask(__name__)

@app.route('/')
def test():
    return jsonify({})

if __name__ == "__main__":
    app.debug = True
    app.json_encoder = plotly.utils.PlotlyJSONEncoder
    app.run(host="127.0.0.1", port=int("5000"))

Update: Testet it also on an ubuntu pc without Anaconda, a plain python 3 - fails there as well as soon as simplejson is installed.

@tarzzz
Copy link
Contributor

tarzzz commented Mar 10, 2016

Its more of a Flask issue than Plotly's. This simple snippet does not work when simplejson is installed on system:

from flask import Flask, jsonify

import json
app = Flask(__name__)

@app.route('/')
def test():
    return jsonify({})

if __name__ == "__main__":
    app.debug = True
    app.json_encoder = json.JSONEncoder
    app.run(host="127.0.0.1", port=int("5000"))

Since PlotlyJSONEncoder is inherited from the native json module, it behaves similarly.

@tarzzz
Copy link
Contributor

tarzzz commented Mar 10, 2016

A workaround for this is to create a custom JSON Encoder which inherits both from PlotlyJSONEncoder and simplejson.JSONEncoder.

from flask import Flask, jsonify
import plotly
import simplejson
app = Flask(__name__)


class CustomJSONEncoder( simplejson.JSONEncoder, plotly.utils.PlotlyJSONEncoder):
    pass

@app.route('/')
def test():
    return jsonify({})

if __name__ == "__main__":
    app.debug = True
    app.json_encoder = CustomJSONEncoder
    app.run(host="127.0.0.1", port=int("5000"))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants