##// END OF EJS Templates
Add units to height and width in Image docstring.
nvdv -
Show More
@@ -1,1004 +1,1004 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Top-level display functions for displaying object in different formats."""
2 """Top-level display functions for displaying object in different formats."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7 from __future__ import print_function
7 from __future__ import print_function
8
8
9 try:
9 try:
10 from base64 import encodebytes as base64_encode
10 from base64 import encodebytes as base64_encode
11 except ImportError:
11 except ImportError:
12 from base64 import encodestring as base64_encode
12 from base64 import encodestring as base64_encode
13
13
14 import json
14 import json
15 import mimetypes
15 import mimetypes
16 import os
16 import os
17 import struct
17 import struct
18 import sys
18 import sys
19 import warnings
19 import warnings
20
20
21 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
21 from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode,
22 unicode_type)
22 unicode_type)
23 from IPython.testing.skipdoctest import skip_doctest
23 from IPython.testing.skipdoctest import skip_doctest
24
24
25 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
25 __all__ = ['display', 'display_pretty', 'display_html', 'display_markdown',
26 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
26 'display_svg', 'display_png', 'display_jpeg', 'display_latex', 'display_json',
27 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
27 'display_javascript', 'display_pdf', 'DisplayObject', 'TextDisplayObject',
28 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
28 'Pretty', 'HTML', 'Markdown', 'Math', 'Latex', 'SVG', 'JSON', 'Javascript',
29 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
29 'Image', 'clear_output', 'set_matplotlib_formats', 'set_matplotlib_close',
30 'publish_display_data']
30 'publish_display_data']
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33 # utility functions
33 # utility functions
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35
35
36 def _safe_exists(path):
36 def _safe_exists(path):
37 """Check path, but don't let exceptions raise"""
37 """Check path, but don't let exceptions raise"""
38 try:
38 try:
39 return os.path.exists(path)
39 return os.path.exists(path)
40 except Exception:
40 except Exception:
41 return False
41 return False
42
42
43 def _merge(d1, d2):
43 def _merge(d1, d2):
44 """Like update, but merges sub-dicts instead of clobbering at the top level.
44 """Like update, but merges sub-dicts instead of clobbering at the top level.
45
45
46 Updates d1 in-place
46 Updates d1 in-place
47 """
47 """
48
48
49 if not isinstance(d2, dict) or not isinstance(d1, dict):
49 if not isinstance(d2, dict) or not isinstance(d1, dict):
50 return d2
50 return d2
51 for key, value in d2.items():
51 for key, value in d2.items():
52 d1[key] = _merge(d1.get(key), value)
52 d1[key] = _merge(d1.get(key), value)
53 return d1
53 return d1
54
54
55 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
55 def _display_mimetype(mimetype, objs, raw=False, metadata=None):
56 """internal implementation of all display_foo methods
56 """internal implementation of all display_foo methods
57
57
58 Parameters
58 Parameters
59 ----------
59 ----------
60 mimetype : str
60 mimetype : str
61 The mimetype to be published (e.g. 'image/png')
61 The mimetype to be published (e.g. 'image/png')
62 objs : tuple of objects
62 objs : tuple of objects
63 The Python objects to display, or if raw=True raw text data to
63 The Python objects to display, or if raw=True raw text data to
64 display.
64 display.
65 raw : bool
65 raw : bool
66 Are the data objects raw data or Python objects that need to be
66 Are the data objects raw data or Python objects that need to be
67 formatted before display? [default: False]
67 formatted before display? [default: False]
68 metadata : dict (optional)
68 metadata : dict (optional)
69 Metadata to be associated with the specific mimetype output.
69 Metadata to be associated with the specific mimetype output.
70 """
70 """
71 if metadata:
71 if metadata:
72 metadata = {mimetype: metadata}
72 metadata = {mimetype: metadata}
73 if raw:
73 if raw:
74 # turn list of pngdata into list of { 'image/png': pngdata }
74 # turn list of pngdata into list of { 'image/png': pngdata }
75 objs = [ {mimetype: obj} for obj in objs ]
75 objs = [ {mimetype: obj} for obj in objs ]
76 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
76 display(*objs, raw=raw, metadata=metadata, include=[mimetype])
77
77
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79 # Main functions
79 # Main functions
80 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
81
81
82 def publish_display_data(data, metadata=None, source=None):
82 def publish_display_data(data, metadata=None, source=None):
83 """Publish data and metadata to all frontends.
83 """Publish data and metadata to all frontends.
84
84
85 See the ``display_data`` message in the messaging documentation for
85 See the ``display_data`` message in the messaging documentation for
86 more details about this message type.
86 more details about this message type.
87
87
88 The following MIME types are currently implemented:
88 The following MIME types are currently implemented:
89
89
90 * text/plain
90 * text/plain
91 * text/html
91 * text/html
92 * text/markdown
92 * text/markdown
93 * text/latex
93 * text/latex
94 * application/json
94 * application/json
95 * application/javascript
95 * application/javascript
96 * image/png
96 * image/png
97 * image/jpeg
97 * image/jpeg
98 * image/svg+xml
98 * image/svg+xml
99
99
100 Parameters
100 Parameters
101 ----------
101 ----------
102 data : dict
102 data : dict
103 A dictionary having keys that are valid MIME types (like
103 A dictionary having keys that are valid MIME types (like
104 'text/plain' or 'image/svg+xml') and values that are the data for
104 'text/plain' or 'image/svg+xml') and values that are the data for
105 that MIME type. The data itself must be a JSON'able data
105 that MIME type. The data itself must be a JSON'able data
106 structure. Minimally all data should have the 'text/plain' data,
106 structure. Minimally all data should have the 'text/plain' data,
107 which can be displayed by all frontends. If more than the plain
107 which can be displayed by all frontends. If more than the plain
108 text is given, it is up to the frontend to decide which
108 text is given, it is up to the frontend to decide which
109 representation to use.
109 representation to use.
110 metadata : dict
110 metadata : dict
111 A dictionary for metadata related to the data. This can contain
111 A dictionary for metadata related to the data. This can contain
112 arbitrary key, value pairs that frontends can use to interpret
112 arbitrary key, value pairs that frontends can use to interpret
113 the data. mime-type keys matching those in data can be used
113 the data. mime-type keys matching those in data can be used
114 to specify metadata about particular representations.
114 to specify metadata about particular representations.
115 source : str, deprecated
115 source : str, deprecated
116 Unused.
116 Unused.
117 """
117 """
118 from IPython.core.interactiveshell import InteractiveShell
118 from IPython.core.interactiveshell import InteractiveShell
119 InteractiveShell.instance().display_pub.publish(
119 InteractiveShell.instance().display_pub.publish(
120 data=data,
120 data=data,
121 metadata=metadata,
121 metadata=metadata,
122 )
122 )
123
123
124 def display(*objs, **kwargs):
124 def display(*objs, **kwargs):
125 """Display a Python object in all frontends.
125 """Display a Python object in all frontends.
126
126
127 By default all representations will be computed and sent to the frontends.
127 By default all representations will be computed and sent to the frontends.
128 Frontends can decide which representation is used and how.
128 Frontends can decide which representation is used and how.
129
129
130 Parameters
130 Parameters
131 ----------
131 ----------
132 objs : tuple of objects
132 objs : tuple of objects
133 The Python objects to display.
133 The Python objects to display.
134 raw : bool, optional
134 raw : bool, optional
135 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
135 Are the objects to be displayed already mimetype-keyed dicts of raw display data,
136 or Python objects that need to be formatted before display? [default: False]
136 or Python objects that need to be formatted before display? [default: False]
137 include : list or tuple, optional
137 include : list or tuple, optional
138 A list of format type strings (MIME types) to include in the
138 A list of format type strings (MIME types) to include in the
139 format data dict. If this is set *only* the format types included
139 format data dict. If this is set *only* the format types included
140 in this list will be computed.
140 in this list will be computed.
141 exclude : list or tuple, optional
141 exclude : list or tuple, optional
142 A list of format type strings (MIME types) to exclude in the format
142 A list of format type strings (MIME types) to exclude in the format
143 data dict. If this is set all format types will be computed,
143 data dict. If this is set all format types will be computed,
144 except for those included in this argument.
144 except for those included in this argument.
145 metadata : dict, optional
145 metadata : dict, optional
146 A dictionary of metadata to associate with the output.
146 A dictionary of metadata to associate with the output.
147 mime-type keys in this dictionary will be associated with the individual
147 mime-type keys in this dictionary will be associated with the individual
148 representation formats, if they exist.
148 representation formats, if they exist.
149 """
149 """
150 raw = kwargs.get('raw', False)
150 raw = kwargs.get('raw', False)
151 include = kwargs.get('include')
151 include = kwargs.get('include')
152 exclude = kwargs.get('exclude')
152 exclude = kwargs.get('exclude')
153 metadata = kwargs.get('metadata')
153 metadata = kwargs.get('metadata')
154
154
155 from IPython.core.interactiveshell import InteractiveShell
155 from IPython.core.interactiveshell import InteractiveShell
156
156
157 if not raw:
157 if not raw:
158 format = InteractiveShell.instance().display_formatter.format
158 format = InteractiveShell.instance().display_formatter.format
159
159
160 for obj in objs:
160 for obj in objs:
161 if raw:
161 if raw:
162 publish_display_data(data=obj, metadata=metadata)
162 publish_display_data(data=obj, metadata=metadata)
163 else:
163 else:
164 format_dict, md_dict = format(obj, include=include, exclude=exclude)
164 format_dict, md_dict = format(obj, include=include, exclude=exclude)
165 if not format_dict:
165 if not format_dict:
166 # nothing to display (e.g. _ipython_display_ took over)
166 # nothing to display (e.g. _ipython_display_ took over)
167 continue
167 continue
168 if metadata:
168 if metadata:
169 # kwarg-specified metadata gets precedence
169 # kwarg-specified metadata gets precedence
170 _merge(md_dict, metadata)
170 _merge(md_dict, metadata)
171 publish_display_data(data=format_dict, metadata=md_dict)
171 publish_display_data(data=format_dict, metadata=md_dict)
172
172
173
173
174 def display_pretty(*objs, **kwargs):
174 def display_pretty(*objs, **kwargs):
175 """Display the pretty (default) representation of an object.
175 """Display the pretty (default) representation of an object.
176
176
177 Parameters
177 Parameters
178 ----------
178 ----------
179 objs : tuple of objects
179 objs : tuple of objects
180 The Python objects to display, or if raw=True raw text data to
180 The Python objects to display, or if raw=True raw text data to
181 display.
181 display.
182 raw : bool
182 raw : bool
183 Are the data objects raw data or Python objects that need to be
183 Are the data objects raw data or Python objects that need to be
184 formatted before display? [default: False]
184 formatted before display? [default: False]
185 metadata : dict (optional)
185 metadata : dict (optional)
186 Metadata to be associated with the specific mimetype output.
186 Metadata to be associated with the specific mimetype output.
187 """
187 """
188 _display_mimetype('text/plain', objs, **kwargs)
188 _display_mimetype('text/plain', objs, **kwargs)
189
189
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
197 Parameters
197 Parameters
198 ----------
198 ----------
199 objs : tuple of objects
199 objs : tuple of objects
200 The Python objects to display, or if raw=True raw HTML data to
200 The Python objects to display, or if raw=True raw HTML data to
201 display.
201 display.
202 raw : bool
202 raw : bool
203 Are the data objects raw data or Python objects that need to be
203 Are the data objects raw data or Python objects that need to be
204 formatted before display? [default: False]
204 formatted before display? [default: False]
205 metadata : dict (optional)
205 metadata : dict (optional)
206 Metadata to be associated with the specific mimetype output.
206 Metadata to be associated with the specific mimetype output.
207 """
207 """
208 _display_mimetype('text/html', objs, **kwargs)
208 _display_mimetype('text/html', objs, **kwargs)
209
209
210
210
211 def display_markdown(*objs, **kwargs):
211 def display_markdown(*objs, **kwargs):
212 """Displays the Markdown representation of an object.
212 """Displays the Markdown representation of an object.
213
213
214 Parameters
214 Parameters
215 ----------
215 ----------
216 objs : tuple of objects
216 objs : tuple of objects
217 The Python objects to display, or if raw=True raw markdown data to
217 The Python objects to display, or if raw=True raw markdown data to
218 display.
218 display.
219 raw : bool
219 raw : bool
220 Are the data objects raw data or Python objects that need to be
220 Are the data objects raw data or Python objects that need to be
221 formatted before display? [default: False]
221 formatted before display? [default: False]
222 metadata : dict (optional)
222 metadata : dict (optional)
223 Metadata to be associated with the specific mimetype output.
223 Metadata to be associated with the specific mimetype output.
224 """
224 """
225
225
226 _display_mimetype('text/markdown', objs, **kwargs)
226 _display_mimetype('text/markdown', objs, **kwargs)
227
227
228
228
229 def display_svg(*objs, **kwargs):
229 def display_svg(*objs, **kwargs):
230 """Display the SVG representation of an object.
230 """Display the SVG representation of an object.
231
231
232 Parameters
232 Parameters
233 ----------
233 ----------
234 objs : tuple of objects
234 objs : tuple of objects
235 The Python objects to display, or if raw=True raw svg data to
235 The Python objects to display, or if raw=True raw svg data to
236 display.
236 display.
237 raw : bool
237 raw : bool
238 Are the data objects raw data or Python objects that need to be
238 Are the data objects raw data or Python objects that need to be
239 formatted before display? [default: False]
239 formatted before display? [default: False]
240 metadata : dict (optional)
240 metadata : dict (optional)
241 Metadata to be associated with the specific mimetype output.
241 Metadata to be associated with the specific mimetype output.
242 """
242 """
243 _display_mimetype('image/svg+xml', objs, **kwargs)
243 _display_mimetype('image/svg+xml', objs, **kwargs)
244
244
245
245
246 def display_png(*objs, **kwargs):
246 def display_png(*objs, **kwargs):
247 """Display the PNG representation of an object.
247 """Display the PNG representation of an object.
248
248
249 Parameters
249 Parameters
250 ----------
250 ----------
251 objs : tuple of objects
251 objs : tuple of objects
252 The Python objects to display, or if raw=True raw png data to
252 The Python objects to display, or if raw=True raw png data to
253 display.
253 display.
254 raw : bool
254 raw : bool
255 Are the data objects raw data or Python objects that need to be
255 Are the data objects raw data or Python objects that need to be
256 formatted before display? [default: False]
256 formatted before display? [default: False]
257 metadata : dict (optional)
257 metadata : dict (optional)
258 Metadata to be associated with the specific mimetype output.
258 Metadata to be associated with the specific mimetype output.
259 """
259 """
260 _display_mimetype('image/png', objs, **kwargs)
260 _display_mimetype('image/png', objs, **kwargs)
261
261
262
262
263 def display_jpeg(*objs, **kwargs):
263 def display_jpeg(*objs, **kwargs):
264 """Display the JPEG representation of an object.
264 """Display the JPEG representation of an object.
265
265
266 Parameters
266 Parameters
267 ----------
267 ----------
268 objs : tuple of objects
268 objs : tuple of objects
269 The Python objects to display, or if raw=True raw JPEG data to
269 The Python objects to display, or if raw=True raw JPEG data to
270 display.
270 display.
271 raw : bool
271 raw : bool
272 Are the data objects raw data or Python objects that need to be
272 Are the data objects raw data or Python objects that need to be
273 formatted before display? [default: False]
273 formatted before display? [default: False]
274 metadata : dict (optional)
274 metadata : dict (optional)
275 Metadata to be associated with the specific mimetype output.
275 Metadata to be associated with the specific mimetype output.
276 """
276 """
277 _display_mimetype('image/jpeg', objs, **kwargs)
277 _display_mimetype('image/jpeg', objs, **kwargs)
278
278
279
279
280 def display_latex(*objs, **kwargs):
280 def display_latex(*objs, **kwargs):
281 """Display the LaTeX representation of an object.
281 """Display the LaTeX representation of an object.
282
282
283 Parameters
283 Parameters
284 ----------
284 ----------
285 objs : tuple of objects
285 objs : tuple of objects
286 The Python objects to display, or if raw=True raw latex data to
286 The Python objects to display, or if raw=True raw latex data to
287 display.
287 display.
288 raw : bool
288 raw : bool
289 Are the data objects raw data or Python objects that need to be
289 Are the data objects raw data or Python objects that need to be
290 formatted before display? [default: False]
290 formatted before display? [default: False]
291 metadata : dict (optional)
291 metadata : dict (optional)
292 Metadata to be associated with the specific mimetype output.
292 Metadata to be associated with the specific mimetype output.
293 """
293 """
294 _display_mimetype('text/latex', objs, **kwargs)
294 _display_mimetype('text/latex', objs, **kwargs)
295
295
296
296
297 def display_json(*objs, **kwargs):
297 def display_json(*objs, **kwargs):
298 """Display the JSON representation of an object.
298 """Display the JSON representation of an object.
299
299
300 Note that not many frontends support displaying JSON.
300 Note that not many frontends support displaying JSON.
301
301
302 Parameters
302 Parameters
303 ----------
303 ----------
304 objs : tuple of objects
304 objs : tuple of objects
305 The Python objects to display, or if raw=True raw json data to
305 The Python objects to display, or if raw=True raw json data to
306 display.
306 display.
307 raw : bool
307 raw : bool
308 Are the data objects raw data or Python objects that need to be
308 Are the data objects raw data or Python objects that need to be
309 formatted before display? [default: False]
309 formatted before display? [default: False]
310 metadata : dict (optional)
310 metadata : dict (optional)
311 Metadata to be associated with the specific mimetype output.
311 Metadata to be associated with the specific mimetype output.
312 """
312 """
313 _display_mimetype('application/json', objs, **kwargs)
313 _display_mimetype('application/json', objs, **kwargs)
314
314
315
315
316 def display_javascript(*objs, **kwargs):
316 def display_javascript(*objs, **kwargs):
317 """Display the Javascript representation of an object.
317 """Display the Javascript representation of an object.
318
318
319 Parameters
319 Parameters
320 ----------
320 ----------
321 objs : tuple of objects
321 objs : tuple of objects
322 The Python objects to display, or if raw=True raw javascript data to
322 The Python objects to display, or if raw=True raw javascript data to
323 display.
323 display.
324 raw : bool
324 raw : bool
325 Are the data objects raw data or Python objects that need to be
325 Are the data objects raw data or Python objects that need to be
326 formatted before display? [default: False]
326 formatted before display? [default: False]
327 metadata : dict (optional)
327 metadata : dict (optional)
328 Metadata to be associated with the specific mimetype output.
328 Metadata to be associated with the specific mimetype output.
329 """
329 """
330 _display_mimetype('application/javascript', objs, **kwargs)
330 _display_mimetype('application/javascript', objs, **kwargs)
331
331
332
332
333 def display_pdf(*objs, **kwargs):
333 def display_pdf(*objs, **kwargs):
334 """Display the PDF representation of an object.
334 """Display the PDF representation of an object.
335
335
336 Parameters
336 Parameters
337 ----------
337 ----------
338 objs : tuple of objects
338 objs : tuple of objects
339 The Python objects to display, or if raw=True raw javascript data to
339 The Python objects to display, or if raw=True raw javascript data to
340 display.
340 display.
341 raw : bool
341 raw : bool
342 Are the data objects raw data or Python objects that need to be
342 Are the data objects raw data or Python objects that need to be
343 formatted before display? [default: False]
343 formatted before display? [default: False]
344 metadata : dict (optional)
344 metadata : dict (optional)
345 Metadata to be associated with the specific mimetype output.
345 Metadata to be associated with the specific mimetype output.
346 """
346 """
347 _display_mimetype('application/pdf', objs, **kwargs)
347 _display_mimetype('application/pdf', objs, **kwargs)
348
348
349
349
350 #-----------------------------------------------------------------------------
350 #-----------------------------------------------------------------------------
351 # Smart classes
351 # Smart classes
352 #-----------------------------------------------------------------------------
352 #-----------------------------------------------------------------------------
353
353
354
354
355 class DisplayObject(object):
355 class DisplayObject(object):
356 """An object that wraps data to be displayed."""
356 """An object that wraps data to be displayed."""
357
357
358 _read_flags = 'r'
358 _read_flags = 'r'
359 _show_mem_addr = False
359 _show_mem_addr = False
360
360
361 def __init__(self, data=None, url=None, filename=None):
361 def __init__(self, data=None, url=None, filename=None):
362 """Create a display object given raw data.
362 """Create a display object given raw data.
363
363
364 When this object is returned by an expression or passed to the
364 When this object is returned by an expression or passed to the
365 display function, it will result in the data being displayed
365 display function, it will result in the data being displayed
366 in the frontend. The MIME type of the data should match the
366 in the frontend. The MIME type of the data should match the
367 subclasses used, so the Png subclass should be used for 'image/png'
367 subclasses used, so the Png subclass should be used for 'image/png'
368 data. If the data is a URL, the data will first be downloaded
368 data. If the data is a URL, the data will first be downloaded
369 and then displayed. If
369 and then displayed. If
370
370
371 Parameters
371 Parameters
372 ----------
372 ----------
373 data : unicode, str or bytes
373 data : unicode, str or bytes
374 The raw data or a URL or file to load the data from
374 The raw data or a URL or file to load the data from
375 url : unicode
375 url : unicode
376 A URL to download the data from.
376 A URL to download the data from.
377 filename : unicode
377 filename : unicode
378 Path to a local file to load the data from.
378 Path to a local file to load the data from.
379 """
379 """
380 if data is not None and isinstance(data, string_types):
380 if data is not None and isinstance(data, string_types):
381 if data.startswith('http') and url is None:
381 if data.startswith('http') and url is None:
382 url = data
382 url = data
383 filename = None
383 filename = None
384 data = None
384 data = None
385 elif _safe_exists(data) and filename is None:
385 elif _safe_exists(data) and filename is None:
386 url = None
386 url = None
387 filename = data
387 filename = data
388 data = None
388 data = None
389
389
390 self.data = data
390 self.data = data
391 self.url = url
391 self.url = url
392 self.filename = None if filename is None else unicode_type(filename)
392 self.filename = None if filename is None else unicode_type(filename)
393
393
394 self.reload()
394 self.reload()
395 self._check_data()
395 self._check_data()
396
396
397 def __repr__(self):
397 def __repr__(self):
398 if not self._show_mem_addr:
398 if not self._show_mem_addr:
399 cls = self.__class__
399 cls = self.__class__
400 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
400 r = "<%s.%s object>" % (cls.__module__, cls.__name__)
401 else:
401 else:
402 r = super(DisplayObject, self).__repr__()
402 r = super(DisplayObject, self).__repr__()
403 return r
403 return r
404
404
405 def _check_data(self):
405 def _check_data(self):
406 """Override in subclasses if there's something to check."""
406 """Override in subclasses if there's something to check."""
407 pass
407 pass
408
408
409 def reload(self):
409 def reload(self):
410 """Reload the raw data from file or URL."""
410 """Reload the raw data from file or URL."""
411 if self.filename is not None:
411 if self.filename is not None:
412 with open(self.filename, self._read_flags) as f:
412 with open(self.filename, self._read_flags) as f:
413 self.data = f.read()
413 self.data = f.read()
414 elif self.url is not None:
414 elif self.url is not None:
415 try:
415 try:
416 try:
416 try:
417 from urllib.request import urlopen # Py3
417 from urllib.request import urlopen # Py3
418 except ImportError:
418 except ImportError:
419 from urllib2 import urlopen
419 from urllib2 import urlopen
420 response = urlopen(self.url)
420 response = urlopen(self.url)
421 self.data = response.read()
421 self.data = response.read()
422 # extract encoding from header, if there is one:
422 # extract encoding from header, if there is one:
423 encoding = None
423 encoding = None
424 for sub in response.headers['content-type'].split(';'):
424 for sub in response.headers['content-type'].split(';'):
425 sub = sub.strip()
425 sub = sub.strip()
426 if sub.startswith('charset'):
426 if sub.startswith('charset'):
427 encoding = sub.split('=')[-1].strip()
427 encoding = sub.split('=')[-1].strip()
428 break
428 break
429 # decode data, if an encoding was specified
429 # decode data, if an encoding was specified
430 if encoding:
430 if encoding:
431 self.data = self.data.decode(encoding, 'replace')
431 self.data = self.data.decode(encoding, 'replace')
432 except:
432 except:
433 self.data = None
433 self.data = None
434
434
435 class TextDisplayObject(DisplayObject):
435 class TextDisplayObject(DisplayObject):
436 """Validate that display data is text"""
436 """Validate that display data is text"""
437 def _check_data(self):
437 def _check_data(self):
438 if self.data is not None and not isinstance(self.data, string_types):
438 if self.data is not None and not isinstance(self.data, string_types):
439 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
439 raise TypeError("%s expects text, not %r" % (self.__class__.__name__, self.data))
440
440
441 class Pretty(TextDisplayObject):
441 class Pretty(TextDisplayObject):
442
442
443 def _repr_pretty_(self):
443 def _repr_pretty_(self):
444 return self.data
444 return self.data
445
445
446
446
447 class HTML(TextDisplayObject):
447 class HTML(TextDisplayObject):
448
448
449 def _repr_html_(self):
449 def _repr_html_(self):
450 return self.data
450 return self.data
451
451
452 def __html__(self):
452 def __html__(self):
453 """
453 """
454 This method exists to inform other HTML-using modules (e.g. Markupsafe,
454 This method exists to inform other HTML-using modules (e.g. Markupsafe,
455 htmltag, etc) that this object is HTML and does not need things like
455 htmltag, etc) that this object is HTML and does not need things like
456 special characters (<>&) escaped.
456 special characters (<>&) escaped.
457 """
457 """
458 return self._repr_html_()
458 return self._repr_html_()
459
459
460
460
461 class Markdown(TextDisplayObject):
461 class Markdown(TextDisplayObject):
462
462
463 def _repr_markdown_(self):
463 def _repr_markdown_(self):
464 return self.data
464 return self.data
465
465
466
466
467 class Math(TextDisplayObject):
467 class Math(TextDisplayObject):
468
468
469 def _repr_latex_(self):
469 def _repr_latex_(self):
470 s = self.data.strip('$')
470 s = self.data.strip('$')
471 return "$$%s$$" % s
471 return "$$%s$$" % s
472
472
473
473
474 class Latex(TextDisplayObject):
474 class Latex(TextDisplayObject):
475
475
476 def _repr_latex_(self):
476 def _repr_latex_(self):
477 return self.data
477 return self.data
478
478
479
479
480 class SVG(DisplayObject):
480 class SVG(DisplayObject):
481
481
482 # wrap data in a property, which extracts the <svg> tag, discarding
482 # wrap data in a property, which extracts the <svg> tag, discarding
483 # document headers
483 # document headers
484 _data = None
484 _data = None
485
485
486 @property
486 @property
487 def data(self):
487 def data(self):
488 return self._data
488 return self._data
489
489
490 @data.setter
490 @data.setter
491 def data(self, svg):
491 def data(self, svg):
492 if svg is None:
492 if svg is None:
493 self._data = None
493 self._data = None
494 return
494 return
495 # parse into dom object
495 # parse into dom object
496 from xml.dom import minidom
496 from xml.dom import minidom
497 svg = cast_bytes_py2(svg)
497 svg = cast_bytes_py2(svg)
498 x = minidom.parseString(svg)
498 x = minidom.parseString(svg)
499 # get svg tag (should be 1)
499 # get svg tag (should be 1)
500 found_svg = x.getElementsByTagName('svg')
500 found_svg = x.getElementsByTagName('svg')
501 if found_svg:
501 if found_svg:
502 svg = found_svg[0].toxml()
502 svg = found_svg[0].toxml()
503 else:
503 else:
504 # fallback on the input, trust the user
504 # fallback on the input, trust the user
505 # but this is probably an error.
505 # but this is probably an error.
506 pass
506 pass
507 svg = cast_unicode(svg)
507 svg = cast_unicode(svg)
508 self._data = svg
508 self._data = svg
509
509
510 def _repr_svg_(self):
510 def _repr_svg_(self):
511 return self.data
511 return self.data
512
512
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 _check_data(self):
523 def _check_data(self):
524 if self.data is not None and not isinstance(self.data, (dict, list)):
524 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))
525 raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data))
526
526
527 @property
527 @property
528 def data(self):
528 def data(self):
529 return self._data
529 return self._data
530
530
531 @data.setter
531 @data.setter
532 def data(self, data):
532 def data(self, data):
533 if isinstance(data, string_types):
533 if isinstance(data, string_types):
534 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
534 warnings.warn("JSON expects JSONable dict or list, not JSON strings")
535 data = json.loads(data)
535 data = json.loads(data)
536 self._data = data
536 self._data = data
537
537
538 def _repr_json_(self):
538 def _repr_json_(self):
539 return self.data
539 return self.data
540
540
541 css_t = """$("head").append($("<link/>").attr({
541 css_t = """$("head").append($("<link/>").attr({
542 rel: "stylesheet",
542 rel: "stylesheet",
543 type: "text/css",
543 type: "text/css",
544 href: "%s"
544 href: "%s"
545 }));
545 }));
546 """
546 """
547
547
548 lib_t1 = """$.getScript("%s", function () {
548 lib_t1 = """$.getScript("%s", function () {
549 """
549 """
550 lib_t2 = """});
550 lib_t2 = """});
551 """
551 """
552
552
553 class Javascript(TextDisplayObject):
553 class Javascript(TextDisplayObject):
554
554
555 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
555 def __init__(self, data=None, url=None, filename=None, lib=None, css=None):
556 """Create a Javascript display object given raw data.
556 """Create a Javascript display object given raw data.
557
557
558 When this object is returned by an expression or passed to the
558 When this object is returned by an expression or passed to the
559 display function, it will result in the data being displayed
559 display function, it will result in the data being displayed
560 in the frontend. If the data is a URL, the data will first be
560 in the frontend. If the data is a URL, the data will first be
561 downloaded and then displayed.
561 downloaded and then displayed.
562
562
563 In the Notebook, the containing element will be available as `element`,
563 In the Notebook, the containing element will be available as `element`,
564 and jQuery will be available. Content appended to `element` will be
564 and jQuery will be available. Content appended to `element` will be
565 visible in the output area.
565 visible in the output area.
566
566
567 Parameters
567 Parameters
568 ----------
568 ----------
569 data : unicode, str or bytes
569 data : unicode, str or bytes
570 The Javascript source code or a URL to download it from.
570 The Javascript source code or a URL to download it from.
571 url : unicode
571 url : unicode
572 A URL to download the data from.
572 A URL to download the data from.
573 filename : unicode
573 filename : unicode
574 Path to a local file to load the data from.
574 Path to a local file to load the data from.
575 lib : list or str
575 lib : list or str
576 A sequence of Javascript library URLs to load asynchronously before
576 A sequence of Javascript library URLs to load asynchronously before
577 running the source code. The full URLs of the libraries should
577 running the source code. The full URLs of the libraries should
578 be given. A single Javascript library URL can also be given as a
578 be given. A single Javascript library URL can also be given as a
579 string.
579 string.
580 css: : list or str
580 css: : list or str
581 A sequence of css files to load before running the source code.
581 A sequence of css files to load before running the source code.
582 The full URLs of the css files should be given. A single css URL
582 The full URLs of the css files should be given. A single css URL
583 can also be given as a string.
583 can also be given as a string.
584 """
584 """
585 if isinstance(lib, string_types):
585 if isinstance(lib, string_types):
586 lib = [lib]
586 lib = [lib]
587 elif lib is None:
587 elif lib is None:
588 lib = []
588 lib = []
589 if isinstance(css, string_types):
589 if isinstance(css, string_types):
590 css = [css]
590 css = [css]
591 elif css is None:
591 elif css is None:
592 css = []
592 css = []
593 if not isinstance(lib, (list,tuple)):
593 if not isinstance(lib, (list,tuple)):
594 raise TypeError('expected sequence, got: %r' % lib)
594 raise TypeError('expected sequence, got: %r' % lib)
595 if not isinstance(css, (list,tuple)):
595 if not isinstance(css, (list,tuple)):
596 raise TypeError('expected sequence, got: %r' % css)
596 raise TypeError('expected sequence, got: %r' % css)
597 self.lib = lib
597 self.lib = lib
598 self.css = css
598 self.css = css
599 super(Javascript, self).__init__(data=data, url=url, filename=filename)
599 super(Javascript, self).__init__(data=data, url=url, filename=filename)
600
600
601 def _repr_javascript_(self):
601 def _repr_javascript_(self):
602 r = ''
602 r = ''
603 for c in self.css:
603 for c in self.css:
604 r += css_t % c
604 r += css_t % c
605 for l in self.lib:
605 for l in self.lib:
606 r += lib_t1 % l
606 r += lib_t1 % l
607 r += self.data
607 r += self.data
608 r += lib_t2*len(self.lib)
608 r += lib_t2*len(self.lib)
609 return r
609 return r
610
610
611 # constants for identifying png/jpeg data
611 # constants for identifying png/jpeg data
612 _PNG = b'\x89PNG\r\n\x1a\n'
612 _PNG = b'\x89PNG\r\n\x1a\n'
613 _JPEG = b'\xff\xd8'
613 _JPEG = b'\xff\xd8'
614
614
615 def _pngxy(data):
615 def _pngxy(data):
616 """read the (width, height) from a PNG header"""
616 """read the (width, height) from a PNG header"""
617 ihdr = data.index(b'IHDR')
617 ihdr = data.index(b'IHDR')
618 # next 8 bytes are width/height
618 # next 8 bytes are width/height
619 w4h4 = data[ihdr+4:ihdr+12]
619 w4h4 = data[ihdr+4:ihdr+12]
620 return struct.unpack('>ii', w4h4)
620 return struct.unpack('>ii', w4h4)
621
621
622 def _jpegxy(data):
622 def _jpegxy(data):
623 """read the (width, height) from a JPEG header"""
623 """read the (width, height) from a JPEG header"""
624 # adapted from http://www.64lines.com/jpeg-width-height
624 # adapted from http://www.64lines.com/jpeg-width-height
625
625
626 idx = 4
626 idx = 4
627 while True:
627 while True:
628 block_size = struct.unpack('>H', data[idx:idx+2])[0]
628 block_size = struct.unpack('>H', data[idx:idx+2])[0]
629 idx = idx + block_size
629 idx = idx + block_size
630 if data[idx:idx+2] == b'\xFF\xC0':
630 if data[idx:idx+2] == b'\xFF\xC0':
631 # found Start of Frame
631 # found Start of Frame
632 iSOF = idx
632 iSOF = idx
633 break
633 break
634 else:
634 else:
635 # read another block
635 # read another block
636 idx += 2
636 idx += 2
637
637
638 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
638 h, w = struct.unpack('>HH', data[iSOF+5:iSOF+9])
639 return w, h
639 return w, h
640
640
641 class Image(DisplayObject):
641 class Image(DisplayObject):
642
642
643 _read_flags = 'rb'
643 _read_flags = 'rb'
644 _FMT_JPEG = u'jpeg'
644 _FMT_JPEG = u'jpeg'
645 _FMT_PNG = u'png'
645 _FMT_PNG = u'png'
646 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
646 _ACCEPTABLE_EMBEDDINGS = [_FMT_JPEG, _FMT_PNG]
647
647
648 def __init__(self, data=None, url=None, filename=None, format=None,
648 def __init__(self, data=None, url=None, filename=None, format=None,
649 embed=None, width=None, height=None, retina=False,
649 embed=None, width=None, height=None, retina=False,
650 unconfined=False, metadata=None):
650 unconfined=False, metadata=None):
651 """Create a PNG/JPEG image object given raw data.
651 """Create a PNG/JPEG image object given raw data.
652
652
653 When this object is returned by an input cell or passed to the
653 When this object is returned by an input cell or passed to the
654 display function, it will result in the image being displayed
654 display function, it will result in the image being displayed
655 in the frontend.
655 in the frontend.
656
656
657 Parameters
657 Parameters
658 ----------
658 ----------
659 data : unicode, str or bytes
659 data : unicode, str or bytes
660 The raw image data or a URL or filename to load the data from.
660 The raw image data or a URL or filename to load the data from.
661 This always results in embedded image data.
661 This always results in embedded image data.
662 url : unicode
662 url : unicode
663 A URL to download the data from. If you specify `url=`,
663 A URL to download the data from. If you specify `url=`,
664 the image data will not be embedded unless you also specify `embed=True`.
664 the image data will not be embedded unless you also specify `embed=True`.
665 filename : unicode
665 filename : unicode
666 Path to a local file to load the data from.
666 Path to a local file to load the data from.
667 Images from a file are always embedded.
667 Images from a file are always embedded.
668 format : unicode
668 format : unicode
669 The format of the image data (png/jpeg/jpg). If a filename or URL is given
669 The format of the image data (png/jpeg/jpg). If a filename or URL is given
670 for format will be inferred from the filename extension.
670 for format will be inferred from the filename extension.
671 embed : bool
671 embed : bool
672 Should the image data be embedded using a data URI (True) or be
672 Should the image data be embedded using a data URI (True) or be
673 loaded using an <img> tag. Set this to True if you want the image
673 loaded using an <img> tag. Set this to True if you want the image
674 to be viewable later with no internet connection in the notebook.
674 to be viewable later with no internet connection in the notebook.
675
675
676 Default is `True`, unless the keyword argument `url` is set, then
676 Default is `True`, unless the keyword argument `url` is set, then
677 default value is `False`.
677 default value is `False`.
678
678
679 Note that QtConsole is not able to display images if `embed` is set to `False`
679 Note that QtConsole is not able to display images if `embed` is set to `False`
680 width : int
680 width : int
681 Width to which to constrain the image in html
681 Width in pixels to which to constrain the image in html
682 height : int
682 height : int
683 Height to which to constrain the image in html
683 Height in pixels to which to constrain the image in html
684 retina : bool
684 retina : bool
685 Automatically set the width and height to half of the measured
685 Automatically set the width and height to half of the measured
686 width and height.
686 width and height.
687 This only works for embedded images because it reads the width/height
687 This only works for embedded images because it reads the width/height
688 from image data.
688 from image data.
689 For non-embedded images, you can just set the desired display width
689 For non-embedded images, you can just set the desired display width
690 and height directly.
690 and height directly.
691 unconfined: bool
691 unconfined: bool
692 Set unconfined=True to disable max-width confinement of the image.
692 Set unconfined=True to disable max-width confinement of the image.
693 metadata: dict
693 metadata: dict
694 Specify extra metadata to attach to the image.
694 Specify extra metadata to attach to the image.
695
695
696 Examples
696 Examples
697 --------
697 --------
698 # embedded image data, works in qtconsole and notebook
698 # embedded image data, works in qtconsole and notebook
699 # when passed positionally, the first arg can be any of raw image data,
699 # when passed positionally, the first arg can be any of raw image data,
700 # a URL, or a filename from which to load image data.
700 # a URL, or a filename from which to load image data.
701 # The result is always embedding image data for inline images.
701 # The result is always embedding image data for inline images.
702 Image('http://www.google.fr/images/srpr/logo3w.png')
702 Image('http://www.google.fr/images/srpr/logo3w.png')
703 Image('/path/to/image.jpg')
703 Image('/path/to/image.jpg')
704 Image(b'RAW_PNG_DATA...')
704 Image(b'RAW_PNG_DATA...')
705
705
706 # Specifying Image(url=...) does not embed the image data,
706 # Specifying Image(url=...) does not embed the image data,
707 # it only generates `<img>` tag with a link to the source.
707 # it only generates `<img>` tag with a link to the source.
708 # This will not work in the qtconsole or offline.
708 # This will not work in the qtconsole or offline.
709 Image(url='http://www.google.fr/images/srpr/logo3w.png')
709 Image(url='http://www.google.fr/images/srpr/logo3w.png')
710
710
711 """
711 """
712 if filename is not None:
712 if filename is not None:
713 ext = self._find_ext(filename)
713 ext = self._find_ext(filename)
714 elif url is not None:
714 elif url is not None:
715 ext = self._find_ext(url)
715 ext = self._find_ext(url)
716 elif data is None:
716 elif data is None:
717 raise ValueError("No image data found. Expecting filename, url, or data.")
717 raise ValueError("No image data found. Expecting filename, url, or data.")
718 elif isinstance(data, string_types) and (
718 elif isinstance(data, string_types) and (
719 data.startswith('http') or _safe_exists(data)
719 data.startswith('http') or _safe_exists(data)
720 ):
720 ):
721 ext = self._find_ext(data)
721 ext = self._find_ext(data)
722 else:
722 else:
723 ext = None
723 ext = None
724
724
725 if format is None:
725 if format is None:
726 if ext is not None:
726 if ext is not None:
727 if ext == u'jpg' or ext == u'jpeg':
727 if ext == u'jpg' or ext == u'jpeg':
728 format = self._FMT_JPEG
728 format = self._FMT_JPEG
729 if ext == u'png':
729 if ext == u'png':
730 format = self._FMT_PNG
730 format = self._FMT_PNG
731 else:
731 else:
732 format = ext.lower()
732 format = ext.lower()
733 elif isinstance(data, bytes):
733 elif isinstance(data, bytes):
734 # infer image type from image data header,
734 # infer image type from image data header,
735 # only if format has not been specified.
735 # only if format has not been specified.
736 if data[:2] == _JPEG:
736 if data[:2] == _JPEG:
737 format = self._FMT_JPEG
737 format = self._FMT_JPEG
738
738
739 # failed to detect format, default png
739 # failed to detect format, default png
740 if format is None:
740 if format is None:
741 format = 'png'
741 format = 'png'
742
742
743 if format.lower() == 'jpg':
743 if format.lower() == 'jpg':
744 # jpg->jpeg
744 # jpg->jpeg
745 format = self._FMT_JPEG
745 format = self._FMT_JPEG
746
746
747 self.format = unicode_type(format).lower()
747 self.format = unicode_type(format).lower()
748 self.embed = embed if embed is not None else (url is None)
748 self.embed = embed if embed is not None else (url is None)
749
749
750 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
750 if self.embed and self.format not in self._ACCEPTABLE_EMBEDDINGS:
751 raise ValueError("Cannot embed the '%s' image format" % (self.format))
751 raise ValueError("Cannot embed the '%s' image format" % (self.format))
752 self.width = width
752 self.width = width
753 self.height = height
753 self.height = height
754 self.retina = retina
754 self.retina = retina
755 self.unconfined = unconfined
755 self.unconfined = unconfined
756 self.metadata = metadata
756 self.metadata = metadata
757 super(Image, self).__init__(data=data, url=url, filename=filename)
757 super(Image, self).__init__(data=data, url=url, filename=filename)
758
758
759 if retina:
759 if retina:
760 self._retina_shape()
760 self._retina_shape()
761
761
762 def _retina_shape(self):
762 def _retina_shape(self):
763 """load pixel-doubled width and height from image data"""
763 """load pixel-doubled width and height from image data"""
764 if not self.embed:
764 if not self.embed:
765 return
765 return
766 if self.format == 'png':
766 if self.format == 'png':
767 w, h = _pngxy(self.data)
767 w, h = _pngxy(self.data)
768 elif self.format == 'jpeg':
768 elif self.format == 'jpeg':
769 w, h = _jpegxy(self.data)
769 w, h = _jpegxy(self.data)
770 else:
770 else:
771 # retina only supports png
771 # retina only supports png
772 return
772 return
773 self.width = w // 2
773 self.width = w // 2
774 self.height = h // 2
774 self.height = h // 2
775
775
776 def reload(self):
776 def reload(self):
777 """Reload the raw data from file or URL."""
777 """Reload the raw data from file or URL."""
778 if self.embed:
778 if self.embed:
779 super(Image,self).reload()
779 super(Image,self).reload()
780 if self.retina:
780 if self.retina:
781 self._retina_shape()
781 self._retina_shape()
782
782
783 def _repr_html_(self):
783 def _repr_html_(self):
784 if not self.embed:
784 if not self.embed:
785 width = height = klass = ''
785 width = height = klass = ''
786 if self.width:
786 if self.width:
787 width = ' width="%d"' % self.width
787 width = ' width="%d"' % self.width
788 if self.height:
788 if self.height:
789 height = ' height="%d"' % self.height
789 height = ' height="%d"' % self.height
790 if self.unconfined:
790 if self.unconfined:
791 klass = ' class="unconfined"'
791 klass = ' class="unconfined"'
792 return u'<img src="{url}"{width}{height}{klass}/>'.format(
792 return u'<img src="{url}"{width}{height}{klass}/>'.format(
793 url=self.url,
793 url=self.url,
794 width=width,
794 width=width,
795 height=height,
795 height=height,
796 klass=klass,
796 klass=klass,
797 )
797 )
798
798
799 def _data_and_metadata(self):
799 def _data_and_metadata(self):
800 """shortcut for returning metadata with shape information, if defined"""
800 """shortcut for returning metadata with shape information, if defined"""
801 md = {}
801 md = {}
802 if self.width:
802 if self.width:
803 md['width'] = self.width
803 md['width'] = self.width
804 if self.height:
804 if self.height:
805 md['height'] = self.height
805 md['height'] = self.height
806 if self.unconfined:
806 if self.unconfined:
807 md['unconfined'] = self.unconfined
807 md['unconfined'] = self.unconfined
808 if self.metadata:
808 if self.metadata:
809 md.update(self.metadata)
809 md.update(self.metadata)
810 if md:
810 if md:
811 return self.data, md
811 return self.data, md
812 else:
812 else:
813 return self.data
813 return self.data
814
814
815 def _repr_png_(self):
815 def _repr_png_(self):
816 if self.embed and self.format == u'png':
816 if self.embed and self.format == u'png':
817 return self._data_and_metadata()
817 return self._data_and_metadata()
818
818
819 def _repr_jpeg_(self):
819 def _repr_jpeg_(self):
820 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
820 if self.embed and (self.format == u'jpeg' or self.format == u'jpg'):
821 return self._data_and_metadata()
821 return self._data_and_metadata()
822
822
823 def _find_ext(self, s):
823 def _find_ext(self, s):
824 return unicode_type(s.split('.')[-1].lower())
824 return unicode_type(s.split('.')[-1].lower())
825
825
826 class Video(DisplayObject):
826 class Video(DisplayObject):
827
827
828 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
828 def __init__(self, data=None, url=None, filename=None, embed=False, mimetype=None):
829 """Create a video object given raw data or an URL.
829 """Create a video object given raw data or an URL.
830
830
831 When this object is returned by an input cell or passed to the
831 When this object is returned by an input cell or passed to the
832 display function, it will result in the video being displayed
832 display function, it will result in the video being displayed
833 in the frontend.
833 in the frontend.
834
834
835 Parameters
835 Parameters
836 ----------
836 ----------
837 data : unicode, str or bytes
837 data : unicode, str or bytes
838 The raw video data or a URL or filename to load the data from.
838 The raw video data or a URL or filename to load the data from.
839 Raw data will require passing `embed=True`.
839 Raw data will require passing `embed=True`.
840 url : unicode
840 url : unicode
841 A URL for the video. If you specify `url=`,
841 A URL for the video. If you specify `url=`,
842 the image data will not be embedded.
842 the image data will not be embedded.
843 filename : unicode
843 filename : unicode
844 Path to a local file containing the video.
844 Path to a local file containing the video.
845 Will be interpreted as a local URL unless `embed=True`.
845 Will be interpreted as a local URL unless `embed=True`.
846 embed : bool
846 embed : bool
847 Should the video be embedded using a data URI (True) or be
847 Should the video be embedded using a data URI (True) or be
848 loaded using a <video> tag (False).
848 loaded using a <video> tag (False).
849
849
850 Since videos are large, embedding them should be avoided, if possible.
850 Since videos are large, embedding them should be avoided, if possible.
851 You must confirm embedding as your intention by passing `embed=True`.
851 You must confirm embedding as your intention by passing `embed=True`.
852
852
853 Local files can be displayed with URLs without embedding the content, via::
853 Local files can be displayed with URLs without embedding the content, via::
854
854
855 Video('./video.mp4')
855 Video('./video.mp4')
856
856
857 mimetype: unicode
857 mimetype: unicode
858 Specify the mimetype for embedded videos.
858 Specify the mimetype for embedded videos.
859 Default will be guessed from file extension, if available.
859 Default will be guessed from file extension, if available.
860
860
861 Examples
861 Examples
862 --------
862 --------
863
863
864 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
864 Video('https://archive.org/download/Sita_Sings_the_Blues/Sita_Sings_the_Blues_small.mp4')
865 Video('path/to/video.mp4')
865 Video('path/to/video.mp4')
866 Video('path/to/video.mp4', embed=True)
866 Video('path/to/video.mp4', embed=True)
867 Video(b'raw-videodata', embed=True)
867 Video(b'raw-videodata', embed=True)
868 """
868 """
869 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
869 if url is None and isinstance(data, string_types) and data.startswith(('http:', 'https:')):
870 url = data
870 url = data
871 data = None
871 data = None
872 elif os.path.exists(data):
872 elif os.path.exists(data):
873 filename = data
873 filename = data
874 data = None
874 data = None
875
875
876 if data and not embed:
876 if data and not embed:
877 msg = ''.join([
877 msg = ''.join([
878 "To embed videos, you must pass embed=True ",
878 "To embed videos, you must pass embed=True ",
879 "(this may make your notebook files huge)\n",
879 "(this may make your notebook files huge)\n",
880 "Consider passing Video(url='...')",
880 "Consider passing Video(url='...')",
881 ])
881 ])
882 raise ValueError(msg)
882 raise ValueError(msg)
883
883
884 self.mimetype = mimetype
884 self.mimetype = mimetype
885 self.embed = embed
885 self.embed = embed
886 super(Video, self).__init__(data=data, url=url, filename=filename)
886 super(Video, self).__init__(data=data, url=url, filename=filename)
887
887
888 def _repr_html_(self):
888 def _repr_html_(self):
889 # External URLs and potentially local files are not embedded into the
889 # External URLs and potentially local files are not embedded into the
890 # notebook output.
890 # notebook output.
891 if not self.embed:
891 if not self.embed:
892 url = self.url if self.url is not None else self.filename
892 url = self.url if self.url is not None else self.filename
893 output = """<video src="{0}" controls>
893 output = """<video src="{0}" controls>
894 Your browser does not support the <code>video</code> element.
894 Your browser does not support the <code>video</code> element.
895 </video>""".format(url)
895 </video>""".format(url)
896 return output
896 return output
897
897
898 # Embedded videos are base64-encoded.
898 # Embedded videos are base64-encoded.
899 mimetype = self.mimetype
899 mimetype = self.mimetype
900 if self.filename is not None:
900 if self.filename is not None:
901 if not mimetype:
901 if not mimetype:
902 mimetype, _ = mimetypes.guess_type(self.filename)
902 mimetype, _ = mimetypes.guess_type(self.filename)
903
903
904 with open(self.filename, 'rb') as f:
904 with open(self.filename, 'rb') as f:
905 video = f.read()
905 video = f.read()
906 else:
906 else:
907 video = self.data
907 video = self.data
908 if isinstance(video, unicode_type):
908 if isinstance(video, unicode_type):
909 # unicode input is already b64-encoded
909 # unicode input is already b64-encoded
910 b64_video = video
910 b64_video = video
911 else:
911 else:
912 b64_video = base64_encode(video).decode('ascii').rstrip()
912 b64_video = base64_encode(video).decode('ascii').rstrip()
913
913
914 output = """<video controls>
914 output = """<video controls>
915 <source src="data:{0};base64,{1}" type="{0}">
915 <source src="data:{0};base64,{1}" type="{0}">
916 Your browser does not support the video tag.
916 Your browser does not support the video tag.
917 </video>""".format(mimetype, b64_video)
917 </video>""".format(mimetype, b64_video)
918 return output
918 return output
919
919
920 def reload(self):
920 def reload(self):
921 # TODO
921 # TODO
922 pass
922 pass
923
923
924 def _repr_png_(self):
924 def _repr_png_(self):
925 # TODO
925 # TODO
926 pass
926 pass
927 def _repr_jpeg_(self):
927 def _repr_jpeg_(self):
928 # TODO
928 # TODO
929 pass
929 pass
930
930
931 def clear_output(wait=False):
931 def clear_output(wait=False):
932 """Clear the output of the current cell receiving output.
932 """Clear the output of the current cell receiving output.
933
933
934 Parameters
934 Parameters
935 ----------
935 ----------
936 wait : bool [default: false]
936 wait : bool [default: false]
937 Wait to clear the output until new output is available to replace it."""
937 Wait to clear the output until new output is available to replace it."""
938 from IPython.core.interactiveshell import InteractiveShell
938 from IPython.core.interactiveshell import InteractiveShell
939 if InteractiveShell.initialized():
939 if InteractiveShell.initialized():
940 InteractiveShell.instance().display_pub.clear_output(wait)
940 InteractiveShell.instance().display_pub.clear_output(wait)
941 else:
941 else:
942 print('\033[2K\r', end='')
942 print('\033[2K\r', end='')
943 sys.stdout.flush()
943 sys.stdout.flush()
944 print('\033[2K\r', end='')
944 print('\033[2K\r', end='')
945 sys.stderr.flush()
945 sys.stderr.flush()
946
946
947
947
948 @skip_doctest
948 @skip_doctest
949 def set_matplotlib_formats(*formats, **kwargs):
949 def set_matplotlib_formats(*formats, **kwargs):
950 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
950 """Select figure formats for the inline backend. Optionally pass quality for JPEG.
951
951
952 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
952 For example, this enables PNG and JPEG output with a JPEG quality of 90%::
953
953
954 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
954 In [1]: set_matplotlib_formats('png', 'jpeg', quality=90)
955
955
956 To set this in your config files use the following::
956 To set this in your config files use the following::
957
957
958 c.InlineBackend.figure_formats = {'png', 'jpeg'}
958 c.InlineBackend.figure_formats = {'png', 'jpeg'}
959 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
959 c.InlineBackend.print_figure_kwargs.update({'quality' : 90})
960
960
961 Parameters
961 Parameters
962 ----------
962 ----------
963 *formats : strs
963 *formats : strs
964 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
964 One or more figure formats to enable: 'png', 'retina', 'jpeg', 'svg', 'pdf'.
965 **kwargs :
965 **kwargs :
966 Keyword args will be relayed to ``figure.canvas.print_figure``.
966 Keyword args will be relayed to ``figure.canvas.print_figure``.
967 """
967 """
968 from IPython.core.interactiveshell import InteractiveShell
968 from IPython.core.interactiveshell import InteractiveShell
969 from IPython.core.pylabtools import select_figure_formats
969 from IPython.core.pylabtools import select_figure_formats
970 # build kwargs, starting with InlineBackend config
970 # build kwargs, starting with InlineBackend config
971 kw = {}
971 kw = {}
972 from ipykernel.pylab.config import InlineBackend
972 from ipykernel.pylab.config import InlineBackend
973 cfg = InlineBackend.instance()
973 cfg = InlineBackend.instance()
974 kw.update(cfg.print_figure_kwargs)
974 kw.update(cfg.print_figure_kwargs)
975 kw.update(**kwargs)
975 kw.update(**kwargs)
976 shell = InteractiveShell.instance()
976 shell = InteractiveShell.instance()
977 select_figure_formats(shell, formats, **kw)
977 select_figure_formats(shell, formats, **kw)
978
978
979 @skip_doctest
979 @skip_doctest
980 def set_matplotlib_close(close=True):
980 def set_matplotlib_close(close=True):
981 """Set whether the inline backend closes all figures automatically or not.
981 """Set whether the inline backend closes all figures automatically or not.
982
982
983 By default, the inline backend used in the IPython Notebook will close all
983 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
984 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
985 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
986 a plot in one cell and then refine it in later cells. This can be accomplished
987 by::
987 by::
988
988
989 In [1]: set_matplotlib_close(False)
989 In [1]: set_matplotlib_close(False)
990
990
991 To set this in your config files use the following::
991 To set this in your config files use the following::
992
992
993 c.InlineBackend.close_figures = False
993 c.InlineBackend.close_figures = False
994
994
995 Parameters
995 Parameters
996 ----------
996 ----------
997 close : bool
997 close : bool
998 Should all matplotlib figures be automatically closed after each cell is
998 Should all matplotlib figures be automatically closed after each cell is
999 run?
999 run?
1000 """
1000 """
1001 from ipykernel.pylab.config import InlineBackend
1001 from ipykernel.pylab.config import InlineBackend
1002 cfg = InlineBackend.instance()
1002 cfg = InlineBackend.instance()
1003 cfg.close_figures = close
1003 cfg.close_figures = close
1004
1004
General Comments 0
You need to be logged in to leave comments. Login now