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