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: Given a message from `PerspectiveJupyterClient.send()`, process the
  message and return the result to `self.post`.
  
  Args:
      widget: a reference to the `Widget` instance that received the
          message.
      content (dict): the message from the front-end. Automatically
          de-serialized by ipywidgets.
      buffers : optional arraybuffers from the front-end, if any.
docstr_tok: ["Given","a","message","from","`","PerspectiveJupyterClient.send","(",")","`",",","process","the","message","and","return","the","result","to","`","self.post","`",".","Args",":","widget",":","a","reference","to","the","`","Widget","`","instance","that","received","the","message",".","content","(","dict",")",":","the","message","from","the","front-end",".","Automatically","de-serialized","by","ipywidgets",".","buffers",":","optional","arraybuffers","from","the","front-end",",","if","any","."]
code: def handle_message(self, widget, content, buffers):
      """Given a message from `PerspectiveJupyterClient.send()`, process the
      message and return the result to `self.post`.
  
      Args:
          widget: a reference to the `Widget` instance that received the
              message.
          content (dict): the message from the front-end. Automatically
              de-serialized by ipywidgets.
          buffers : optional arraybuffers from the front-end, if any.
      """
      if self._pending_binary:
          msg = self._pending_binary
  
          # manager looks at the `binary_length` flag so make sure to
          # get rid of it before passing to `_process`.
          del msg["binary_length"]
  
          # arrow is a `MemoryView` - convert to bytes
          arrow = buffers[0].tobytes()
          msg["args"].insert(0, arrow)
  
          # Send the message to the manager to process
          post_callback = partial(self.post, msg_id=msg["id"])
          self.manager._process(msg, post_callback)
          self._pending_binary = None
          return
  
      if content["type"] == "cmd":
          parsed = json.loads(content["data"])
  
          if parsed["cmd"] == "init":
              self.post({"id": -1, "data": None})
          elif parsed["cmd"] == "table":
              # return the dataset or table name to the front-end
              msg = self._make_load_message()
              self.send(msg.to_dict())
          else:
              # If the message has `binary_length` set, wait for the arrow
              # and join it with the JSON message.
              if parsed.get("binary_length"):
                  self._pending_binary = parsed
                  return
  
              # For all calls to Perspective, process it in the manager.
              post_callback = partial(self.post, msg_id=parsed["id"])
              self.manager._process(parsed, post_callback)
  
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 8 for calling the PerspectiveWidget obj's underlying member method code with example usage: obj.handle_message(widget, content, buffers) without return types