1import json
2import os
3
4import sys
5import traceback
6
7from .supported_data_type import _standardize_value
8from .display_log import debug
9
10IS_PY3K = True
11if sys.version_info[0] < 3:
12    IS_PY3K = False
13
14if IS_PY3K:
15    from urllib.request import urlopen
16else:
17    from urllib2 import urlopen
18
19__all__ = ['display']
20
21HOST = "http://127.0.0.1"
22PORT_ENV = int(os.getenv("PYCHARM_DISPLAY_PORT", "-1"))
23PORT = PORT_ENV
24if PORT == -1:
25    PORT = None
26
27
28def display(data):
29    if not PORT:
30        debug("Error: Can't display plot, PORT value is %s" % PORT_ENV)
31    if data is None:
32        debug("Error: Can't display empty data")
33    if PORT and data is not None:
34        repr_display_attr = getattr(data, '_repr_display_', None)
35        if callable(repr_display_attr):
36            message_spec = repr_display_attr()
37            if len(message_spec) != 2:
38                debug('Error: Tuple length expected is 2 but was %d' % len(message_spec))
39                return
40
41            message_spec = _standardize_value(message_spec)
42            _send_display_message({
43                    'type': message_spec[0],
44                    'body': message_spec[1]
45                })
46            return
47        else:
48            debug("Error: '_repr_display_' isn't callable")
49
50    # just print to python console
51    print(repr(data))
52
53
54def _send_display_message(message_spec):
55    serialized = json.dumps(message_spec)
56    buffer = serialized.encode()
57    try:
58        debug("Sending display message to %s:%s\n" % (HOST, PORT))
59        url = HOST + ":" + str(PORT) + "/api/python.scientific"
60        urlopen(url, buffer)
61    except OSError as _:
62        sys.stderr.write("Error: failed to send plot to %s:%s\n" % (HOST, PORT))
63        traceback.print_exc()
64        sys.stderr.flush()
65