##// END OF EJS Templates
Merge pull request #10000 from aleury/feat/json-expanded...
Min RK -
r22948:282feaff merge
parent child Browse files
Show More
@@ -190,7 +190,7 b' def display_pretty(*objs, **kwargs):'
190
190
191 def display_html(*objs, **kwargs):
191 def display_html(*objs, **kwargs):
192 """Display the HTML representation of an object.
192 """Display the HTML representation of an object.
193
193
194 Note: If raw=False and the object does not have a HTML
194 Note: If raw=False and the object does not have a HTML
195 representation, no HTML will be shown.
195 representation, no HTML will be shown.
196
196
@@ -513,13 +513,35 b' class SVG(DisplayObject):'
513
513
514 class JSON(DisplayObject):
514 class JSON(DisplayObject):
515 """JSON expects a JSON-able dict or list
515 """JSON expects a JSON-able dict or list
516
516
517 not an already-serialized JSON string.
517 not an already-serialized JSON string.
518
518
519 Scalar types (None, number, string) are not allowed, only dict or list containers.
519 Scalar types (None, number, string) are not allowed, only dict or list containers.
520 """
520 """
521 # wrap data in a property, which warns about passing already-serialized JSON
521 # wrap data in a property, which warns about passing already-serialized JSON
522 _data = None
522 _data = None
523 def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=None):
524 """Create a JSON display object given raw data.
525
526 Parameters
527 ----------
528 data : dict or list
529 JSON data to display. Not an already-serialized JSON string.
530 Scalar types (None, number, string) are not allowed, only dict
531 or list containers.
532 url : unicode
533 A URL to download the data from.
534 filename : unicode
535 Path to a local file to load the data from.
536 expanded : boolean
537 Metadata to control whether a JSON display component is expanded.
538 metadata: dict
539 Specify extra metadata to attach to the json display object.
540 """
541 self.expanded = expanded
542 self.metadata = metadata
543 super(JSON, self).__init__(data=data, url=url, filename=filename)
544
523 def _check_data(self):
545 def _check_data(self):
524 if self.data is not None and not isinstance(self.data, (dict, list)):
546 if self.data is not None and not isinstance(self.data, (dict, list)):
525 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
547 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
@@ -527,7 +549,7 b' class JSON(DisplayObject):'
527 @property
549 @property
528 def data(self):
550 def data(self):
529 return self._data
551 return self._data
530
552
531 @data.setter
553 @data.setter
532 def data(self, data):
554 def data(self, data):
533 if isinstance(data, string_types):
555 if isinstance(data, string_types):
@@ -535,8 +557,14 b' class JSON(DisplayObject):'
535 data = json.loads(data)
557 data = json.loads(data)
536 self._data = data
558 self._data = data
537
559
560 def _data_and_metadata(self):
561 md = {'expanded': self.expanded}
562 if self.metadata:
563 md.update(self.metadata)
564 return self.data, md
565
538 def _repr_json_(self):
566 def _repr_json_(self):
539 return self.data
567 return self._data_and_metadata()
540
568
541 css_t = """$("head").append($("<link/>").attr({
569 css_t = """$("head").append($("<link/>").attr({
542 rel: "stylesheet",
570 rel: "stylesheet",
@@ -562,7 +590,7 b' class Javascript(TextDisplayObject):'
562
590
563 In the Notebook, the containing element will be available as `element`,
591 In the Notebook, the containing element will be available as `element`,
564 and jQuery will be available. Content appended to `element` will be
592 and jQuery will be available. Content appended to `element` will be
565 visible in the output area.
593 visible in the output area.
566
594
567 Parameters
595 Parameters
568 ----------
596 ----------
@@ -622,7 +650,7 b' def _pngxy(data):'
622 def _jpegxy(data):
650 def _jpegxy(data):
623 """read the (width, height) from a JPEG header"""
651 """read the (width, height) from a JPEG header"""
624 # adapted from http://www.64lines.com/jpeg-width-height
652 # adapted from http://www.64lines.com/jpeg-width-height
625
653
626 idx = 4
654 idx = 4
627 while True:
655 while True:
628 block_size = struct.unpack('>H', data[idx:idx+2])[0]
656 block_size = struct.unpack('>H', data[idx:idx+2])[0]
@@ -755,10 +783,10 b' class Image(DisplayObject):'
755 self.unconfined = unconfined
783 self.unconfined = unconfined
756 self.metadata = metadata
784 self.metadata = metadata
757 super(Image, self).__init__(data=data, url=url, filename=filename)
785 super(Image, self).__init__(data=data, url=url, filename=filename)
758
786
759 if retina:
787 if retina:
760 self._retina_shape()
788 self._retina_shape()
761
789
762 def _retina_shape(self):
790 def _retina_shape(self):
763 """load pixel-doubled width and height from image data"""
791 """load pixel-doubled width and height from image data"""
764 if not self.embed:
792 if not self.embed:
@@ -872,7 +900,7 b' class Video(DisplayObject):'
872 elif os.path.exists(data):
900 elif os.path.exists(data):
873 filename = data
901 filename = data
874 data = None
902 data = None
875
903
876 if data and not embed:
904 if data and not embed:
877 msg = ''.join([
905 msg = ''.join([
878 "To embed videos, you must pass embed=True ",
906 "To embed videos, you must pass embed=True ",
@@ -894,13 +922,13 b' class Video(DisplayObject):'
894 Your browser does not support the <code>video</code> element.
922 Your browser does not support the <code>video</code> element.
895 </video>""".format(url)
923 </video>""".format(url)
896 return output
924 return output
897
925
898 # Embedded videos are base64-encoded.
926 # Embedded videos are base64-encoded.
899 mimetype = self.mimetype
927 mimetype = self.mimetype
900 if self.filename is not None:
928 if self.filename is not None:
901 if not mimetype:
929 if not mimetype:
902 mimetype, _ = mimetypes.guess_type(self.filename)
930 mimetype, _ = mimetypes.guess_type(self.filename)
903
931
904 with open(self.filename, 'rb') as f:
932 with open(self.filename, 'rb') as f:
905 video = f.read()
933 video = f.read()
906 else:
934 else:
@@ -910,7 +938,7 b' class Video(DisplayObject):'
910 b64_video = video
938 b64_video = video
911 else:
939 else:
912 b64_video = base64_encode(video).decode('ascii').rstrip()
940 b64_video = base64_encode(video).decode('ascii').rstrip()
913
941
914 output = """<video controls>
942 output = """<video controls>
915 <source src="data:{0};base64,{1}" type="{0}">
943 <source src="data:{0};base64,{1}" type="{0}">
916 Your browser does not support the video tag.
944 Your browser does not support the video tag.
@@ -954,7 +982,7 b' def set_matplotlib_formats(*formats, **kwargs):'
954 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
982 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
955
983
956 To set this in your config files use the following::
984 To set this in your config files use the following::
957
985
958 c.InlineBackend.figure_formats = {'png', 'jpeg'}
986 c.InlineBackend.figure_formats = {'png', 'jpeg'}
959 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
987 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
960
988
@@ -979,19 +1007,19 b' def set_matplotlib_formats(*formats, **kwargs):'
979 @skip_doctest
1007 @skip_doctest
980 def set_matplotlib_close(close=True):
1008 def set_matplotlib_close(close=True):
981 """Set whether the inline backend closes all figures automatically or not.
1009 """Set whether the inline backend closes all figures automatically or not.
982
1010
983 By default, the inline backend used in the IPython Notebook will close all
1011 By default, the inline backend used in the IPython Notebook will close all
984 matplotlib figures automatically after each cell is run. This means that
1012 matplotlib figures automatically after each cell is run. This means that
985 plots in different cells won't interfere. Sometimes, you may want to make
1013 plots in different cells won't interfere. Sometimes, you may want to make
986 a plot in one cell and then refine it in later cells. This can be accomplished
1014 a plot in one cell and then refine it in later cells. This can be accomplished
987 by::
1015 by::
988
1016
989 In [1]: set_matplotlib_close(False)
1017 In [1]: set_matplotlib_close(False)
990
1018
991 To set this in your config files use the following::
1019 To set this in your config files use the following::
992
1020
993 c.InlineBackend.close_figures = False
1021 c.InlineBackend.close_figures = False
994
1022
995 Parameters
1023 Parameters
996 ----------
1024 ----------
997 close : bool
1025 close : bool
@@ -1001,4 +1029,3 b' def set_matplotlib_close(close=True):'
1001 from ipykernel.pylab.config import InlineBackend
1029 from ipykernel.pylab.config import InlineBackend
1002 cfg = InlineBackend.instance()
1030 cfg = InlineBackend.instance()
1003 cfg.close_figures = close
1031 cfg.close_figures = close
1004
@@ -66,7 +66,7 b' def test_image_filename_defaults():'
66 def _get_inline_config():
66 def _get_inline_config():
67 from ipykernel.pylab.config import InlineBackend
67 from ipykernel.pylab.config import InlineBackend
68 return InlineBackend.instance()
68 return InlineBackend.instance()
69
69
70 @dec.skip_without('matplotlib')
70 @dec.skip_without('matplotlib')
71 def test_set_matplotlib_close():
71 def test_set_matplotlib_close():
72 cfg = _get_inline_config()
72 cfg = _get_inline_config()
@@ -135,24 +135,32 b' def test_displayobject_repr():'
135 def test_json():
135 def test_json():
136 d = {'a': 5}
136 d = {'a': 5}
137 lis = [d]
137 lis = [d]
138 md = {'expanded': False}
139 md2 = {'expanded': True}
138 j = display.JSON(d)
140 j = display.JSON(d)
139 nt.assert_equal(j._repr_json_(), d)
141 j2 = display.JSON(d, expanded=True)
140
142 nt.assert_equal(j._repr_json_(), (d, md))
143 nt.assert_equal(j2._repr_json_(), (d, md2))
144
141 with warnings.catch_warnings(record=True) as w:
145 with warnings.catch_warnings(record=True) as w:
142 warnings.simplefilter("always")
146 warnings.simplefilter("always")
143 j = display.JSON(json.dumps(d))
147 j = display.JSON(json.dumps(d))
144 nt.assert_equal(len(w), 1)
148 nt.assert_equal(len(w), 1)
145 nt.assert_equal(j._repr_json_(), d)
149 nt.assert_equal(j._repr_json_(), (d, md))
146
150 nt.assert_equal(j2._repr_json_(), (d, md2))
151
147 j = display.JSON(lis)
152 j = display.JSON(lis)
148 nt.assert_equal(j._repr_json_(), lis)
153 j2 = display.JSON(lis, expanded=True)
149
154 nt.assert_equal(j._repr_json_(), (lis, md))
155 nt.assert_equal(j2._repr_json_(), (lis, md2))
156
150 with warnings.catch_warnings(record=True) as w:
157 with warnings.catch_warnings(record=True) as w:
151 warnings.simplefilter("always")
158 warnings.simplefilter("always")
152 j = display.JSON(json.dumps(lis))
159 j = display.JSON(json.dumps(lis))
153 nt.assert_equal(len(w), 1)
160 nt.assert_equal(len(w), 1)
154 nt.assert_equal(j._repr_json_(), lis)
161 nt.assert_equal(j._repr_json_(), (lis, md))
155
162 nt.assert_equal(j2._repr_json_(), (lis, md2))
163
156 def test_video_embedding():
164 def test_video_embedding():
157 """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash"""
165 """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash"""
158 v = display.Video("http://ignored")
166 v = display.Video("http://ignored")
@@ -172,15 +180,15 b' def test_video_embedding():'
172 assert not v.embed
180 assert not v.embed
173 html = v._repr_html_()
181 html = v._repr_html_()
174 nt.assert_not_in('src="data:', html)
182 nt.assert_not_in('src="data:', html)
175
183
176 v = display.Video(f.name, embed=True)
184 v = display.Video(f.name, embed=True)
177 html = v._repr_html_()
185 html = v._repr_html_()
178 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
186 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
179
187
180 v = display.Video(f.name, embed=True, mimetype='video/other')
188 v = display.Video(f.name, embed=True, mimetype='video/other')
181 html = v._repr_html_()
189 html = v._repr_html_()
182 nt.assert_in('src="data:video/other;base64,YWJj"',html)
190 nt.assert_in('src="data:video/other;base64,YWJj"',html)
183
191
184 v = display.Video(b'abc', embed=True, mimetype='video/mp4')
192 v = display.Video(b'abc', embed=True, mimetype='video/mp4')
185 html = v._repr_html_()
193 html = v._repr_html_()
186 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
194 nt.assert_in('src="data:video/mp4;base64,YWJj"',html)
@@ -188,4 +196,3 b' def test_video_embedding():'
188 v = display.Video(u'YWJj', embed=True, mimetype='video/xyz')
196 v = display.Video(u'YWJj', embed=True, mimetype='video/xyz')
189 html = v._repr_html_()
197 html = v._repr_html_()
190 nt.assert_in('src="data:video/xyz;base64,YWJj"',html)
198 nt.assert_in('src="data:video/xyz;base64,YWJj"',html)
191
General Comments 0
You need to be logged in to leave comments. Login now