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