1"""An interface for publishing rich data to frontends. 2 3There are two components of the display system: 4 5* Display formatters, which take a Python object and compute the 6 representation of the object in various formats (text, HTML, SVG, etc.). 7* The display publisher that is used to send the representation data to the 8 various frontends. 9 10This module defines the logic display publishing. The display publisher uses 11the ``display_data`` message type that is defined in the IPython messaging 12spec. 13""" 14 15# Copyright (c) IPython Development Team. 16# Distributed under the terms of the Modified BSD License. 17 18from __future__ import print_function 19 20import sys 21 22from traitlets.config.configurable import Configurable 23from traitlets import List 24 25# This used to be defined here - it is imported for backwards compatibility 26from .display import publish_display_data 27 28#----------------------------------------------------------------------------- 29# Main payload class 30#----------------------------------------------------------------------------- 31 32class DisplayPublisher(Configurable): 33 """A traited class that publishes display data to frontends. 34 35 Instances of this class are created by the main IPython object and should 36 be accessed there. 37 """ 38 39 def _validate_data(self, data, metadata=None): 40 """Validate the display data. 41 42 Parameters 43 ---------- 44 data : dict 45 The formata data dictionary. 46 metadata : dict 47 Any metadata for the data. 48 """ 49 50 if not isinstance(data, dict): 51 raise TypeError('data must be a dict, got: %r' % data) 52 if metadata is not None: 53 if not isinstance(metadata, dict): 54 raise TypeError('metadata must be a dict, got: %r' % data) 55 56 # use * to indicate transient, update are keyword-only 57 def publish(self, data, metadata=None, source=None, **kwargs): 58 """Publish data and metadata to all frontends. 59 60 See the ``display_data`` message in the messaging documentation for 61 more details about this message type. 62 63 The following MIME types are currently implemented: 64 65 * text/plain 66 * text/html 67 * text/markdown 68 * text/latex 69 * application/json 70 * application/javascript 71 * image/png 72 * image/jpeg 73 * image/svg+xml 74 75 Parameters 76 ---------- 77 data : dict 78 A dictionary having keys that are valid MIME types (like 79 'text/plain' or 'image/svg+xml') and values that are the data for 80 that MIME type. The data itself must be a JSON'able data 81 structure. Minimally all data should have the 'text/plain' data, 82 which can be displayed by all frontends. If more than the plain 83 text is given, it is up to the frontend to decide which 84 representation to use. 85 metadata : dict 86 A dictionary for metadata related to the data. This can contain 87 arbitrary key, value pairs that frontends can use to interpret 88 the data. Metadata specific to each mime-type can be specified 89 in the metadata dict with the same mime-type keys as 90 the data itself. 91 source : str, deprecated 92 Unused. 93 transient: dict, keyword-only 94 A dictionary for transient data. 95 Data in this dictionary should not be persisted as part of saving this output. 96 Examples include 'display_id'. 97 update: bool, keyword-only, default: False 98 If True, only update existing outputs with the same display_id, 99 rather than creating a new output. 100 """ 101 102 # These are kwargs only on Python 3, not used there. 103 # For consistency and avoid code divergence we leave them here to 104 # simplify potential backport 105 transient = kwargs.pop('transient', None) 106 update = kwargs.pop('update', False) 107 108 # The default is to simply write the plain text data using sys.stdout. 109 if 'text/plain' in data: 110 print(data['text/plain']) 111 112 def clear_output(self, wait=False): 113 """Clear the output of the cell receiving output.""" 114 print('\033[2K\r', end='') 115 sys.stdout.flush() 116 print('\033[2K\r', end='') 117 sys.stderr.flush() 118 119 120class CapturingDisplayPublisher(DisplayPublisher): 121 """A DisplayPublisher that stores""" 122 outputs = List() 123 124 def publish(self, data, metadata=None, source=None, **kwargs): 125 126 # These are kwargs only on Python 3, not used there. 127 # For consistency and avoid code divergence we leave them here to 128 # simplify potential backport 129 transient = kwargs.pop('transient', None) 130 update = kwargs.pop('update', False) 131 132 self.outputs.append({'data':data, 'metadata':metadata, 133 'transient':transient, 'update':update}) 134 135 def clear_output(self, wait=False): 136 super(CapturingDisplayPublisher, self).clear_output(wait) 137 138 # empty the list, *do not* reassign a new list 139 self.outputs.clear() 140