class_docstr: :class`~perspective.PerspectiveWidget` allows for Perspective to be used
  in the form of a Jupyter IPython widget.
  
  Using `perspective.Table`, you can create a widget that extends the full
  functionality of `perspective-viewer`.  Changes on the viewer can be
  programatically set on the :class`~perspective.PerspectiveWidget` instance,
  and state is maintained across page refreshes.
  
  Examples:
      >>> from perspective import Table, PerspectiveWidget
      >>> data = {
      ...     "a": [1, 2, 3],
      ...     "b": [
      ...         "2019/07/11 7:30PM",
      ...         "2019/07/11 8:30PM",
      ...         "2019/07/11 9:30PM"
      ...     ]
      ... }
      >>> tbl = Table(data, index="a")
      >>> widget = PerspectiveWidget(
      ...     tbl,
      ...     group_by=["a"],
      ...     sort=[["b", "desc"]],
      ...     filter=[["a", ">", 1]]
      ... )
      >>> widget.sort
      [["b", "desc"]]
      >>> widget.sort.append(["a", "asc"])
      >>> widget.sort
      [["b", "desc"], ["a", "asc"]]
      >>> widget.update({"a": [4, 5]}) # Browser UI updates
docstr: Send a message to the front-end either containing the name of a
  hosted view in Python, so the front-end can create a table in the
  Perspective WebAssembly client, or if `server` is True, the name of a
  Table in python, or the serialized dataset with options if `client`
  is True.
  
  If the front-end requests data and it has not been loaded yet,
  an error will be logged, and the front-end will wait for `load()` to
  be called, which will notify the front-end of new data.
docstr_tok: ["Send","a","message","to","the","front-end","either","containing","the","name","of","a","hosted","view","in","Python",",","so","the","front-end","can","create","a","table","in","the","Perspective","WebAssembly","client",",","or","if","`","server","`","is","True",",","the","name","of","a","Table","in","python",",","or","the","serialized","dataset","with","options","if","`","client","`","is","True",".","If","the","front-end","requests","data","and","it","has","not","been","loaded","yet",",","an","error","will","be","logged",",","and","the","front-end","will","wait","for","`","load","(",")","`","to","be","called",",","which","will","notify","the","front-end","of","new","data","."]
code: def _make_load_message(self):
      """Send a message to the front-end either containing the name of a
      hosted view in Python, so the front-end can create a table in the
      Perspective WebAssembly client, or if `server` is True, the name of a
      Table in python, or the serialized dataset with options if `client`
      is True.
  
      If the front-end requests data and it has not been loaded yet,
      an error will be logged, and the front-end will wait for `load()` to
      be called, which will notify the front-end of new data.
      """
      msg_data = None
  
      if self.client and self._data is not None:
          # Send serialized data to the browser, which will run Perspective
          # in client mode: there is no table in the Python kernel.
          msg_data = {"data": self._data, "options": self._options}
      elif self.server and self.table_name is not None:
          # If the `server` kwarg is set during initialization, Perspective
          # will run in server-only mode, where a Table is hosted in the
          # kernel and the front-end proxies pivots, sorts, data requests
          # etc. to the kernel and does not run a Table in the front-end.
          msg_data = {"table_name": self.table_name}
      elif self.table_name is not None:
          # If a view is hosted by the widget's manager (by default),
          # run Perspective in client-server mode: a Table will be created
          # in the front-end that mirrors the Table hosted in the kernel,
          # and updates and edits will be synchronized across the client
          # and the server.
          msg_data = {
              "table_name": self.table_name,
              "options": {},
          }
  
          index = self.table.get_index()
          limit = self.table.get_limit()
  
          if index is not None:
              msg_data["options"]["index"] = index
          elif limit is not None:
              msg_data["options"]["limit"] = limit
  
      if msg_data is not None:
          return _PerspectiveWidgetMessage(-2, "table", msg_data)
      else:
          raise PerspectiveError(
              "Widget does not have any data loaded - use the `load()` method to provide it with data."
          )
  
imports: import base64
  import jinja2
  import json
  import os
  from datetime import date, datetime
  from functools import partial
  import numpy
  import pandas
  from ipywidgets import DOMWidget
  from traitlets import Unicode, observe
  from ..core._version import __version__
  from ..core.data import deconstruct_pandas
  from ..core.exception import PerspectiveError
  from ..libpsp import is_libpsp
  from ..viewer import PerspectiveViewer
label_desc: Use image node_id 9 for calling the PerspectiveWidget obj's underlying member method code with example usage: obj._make_load_message() and returns: _PerspectiveWidgetMessage