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: Initialize an instance of :class`~perspective.PerspectiveWidget`
  with the given table/data and viewer configuration.
  
  If a pivoted DataFrame or MultiIndex table is passed in, the widget
  preserves pivots and applies them.  See `PerspectiveViewer.__init__` for
  arguments that transform the view shown in the widget.
  
  Args:
      data (:obj:`Table`|:obj:`View`|:obj:`dict`|:obj:`list`|:obj:`pandas.DataFrame`|:obj:`bytes`|:obj:`str`): a
          `perspective.Table` instance, a `perspective.View` instance, or
          a dataset to be loaded in the widget.
  
  Keyword Arguments:
      index (:obj:`str`): A column name to be used as the primary key.
          Ignored if `server` is True.
  
      limit (:obj:`int`): A upper limit on the number of rows in the Table.
          Cannot be set at the same time as `index`, ignored if `server`
          is True.
  
      server (:obj:`bool`): Whether to run Perspective in "server-only"
          mode, where the front-end client does not have its own Table,
          and instead reads all data and operations from Python.
  
      client (:obj:`bool`):  If True, convert the dataset into an Apache Arrow
          binary and create the Table in Javascript using a copy of the
          data. Defaults to False.
  
      kwargs (:obj:`dict`): configuration options for the `PerspectiveViewer`,
          and `Table` constructor if `data` is a dataset.
  
  Examples:
      >>> widget = PerspectiveWidget(
      ...     {"a": [1, 2, 3]},
      ...     aggregates={"a": "avg"},
      ...     group_by=["a"],
      ...     sort=[["b", "desc"]],
      ...     filter=[["a", ">", 1]],
      ...     expressions=[""a" + 100"])
docstr_tok: ["Initialize","an","instance","of",":","class","`","~perspective.PerspectiveWidget","`","with","the","given","table\/data","and","viewer","configuration",".","If","a","pivoted","DataFrame","or","MultiIndex","table","is","passed","in",",","the","widget","preserves","pivots","and","applies","them",".","See","`","PerspectiveViewer.__init__","`","for","arguments","that","transform","the","view","shown","in","the","widget",".","Args",":","data","(",":","obj",":","`","Table","`","|",":","obj",":","`","View","`","|",":","obj",":","`","dict","`","|",":","obj",":","`","list","`","|",":","obj",":","`","pandas.DataFrame","`","|",":","obj",":","`","bytes","`","|",":","obj",":","`","str","`",")",":","a","`","perspective.Table","`","instance",",","a","`","perspective.View","`","instance",",","or","a","dataset","to","be","loaded","in","the","widget",".","Keyword","Arguments",":","index","(",":","obj",":","`","str","`",")",":","A","column","name","to","be","used","as","the","primary","key",".","Ignored","if","`","server","`","is","True",".","limit","(",":","obj",":","`","int","`",")",":","A","upper","limit","on","the","number","of","rows","in","the","Table",".","Can","not","be","set","at","the","same","time","as","`","index","`",",","ignored","if","`","server","`","is","True",".","server","(",":","obj",":","`","bool","`",")",":","Whether","to","run","Perspective","in","``","server-only","''","mode",",","where","the","front-end","client","does","not","have","its","own","Table",",","and","instead","reads","all","data","and","operations","from","Python",".","client","(",":","obj",":","`","bool","`",")",":","If","True",",","convert","the","dataset","into","an","Apache","Arrow","binary","and","create","the","Table","in","Javascript","using","a","copy","of","the","data",".","Defaults","to","False",".","kwargs","(",":","obj",":","`","dict","`",")",":","configuration","options","for","the","`","PerspectiveViewer","`",",","and","`","Table","`","constructor","if","`","data","`","is","a","dataset",".","Examples",":",">",">",">","widget","=","PerspectiveWidget","(","...","{","``","a","''",":","[","1",",","2",",","3","]","}",",","...","aggregates=","{","``","a","''",":","``","avg","''","}",",","...","group_by=","[","``","a","''","]",",","...","sort=","[","[","``","b","''",",","``","desc","''","]","]",",","...","filter=","[","[","``","a","''",",","``",">","''",",","1","]","]",",","...","expressions=","[","``","''","a","''","+","100","''","]",")"]
code: def __init__(
      self,
      data,
      index=None,
      limit=None,
      server=False,
      client=not is_libpsp(),
      **kwargs,
  ):
      """Initialize an instance of :class`~perspective.PerspectiveWidget`
      with the given table/data and viewer configuration.
  
      If a pivoted DataFrame or MultiIndex table is passed in, the widget
      preserves pivots and applies them.  See `PerspectiveViewer.__init__` for
      arguments that transform the view shown in the widget.
  
      Args:
          data (:obj:`Table`|:obj:`View`|:obj:`dict`|:obj:`list`|:obj:`pandas.DataFrame`|:obj:`bytes`|:obj:`str`): a
              `perspective.Table` instance, a `perspective.View` instance, or
              a dataset to be loaded in the widget.
  
      Keyword Arguments:
          index (:obj:`str`): A column name to be used as the primary key.
              Ignored if `server` is True.
  
          limit (:obj:`int`): A upper limit on the number of rows in the Table.
              Cannot be set at the same time as `index`, ignored if `server`
              is True.
  
          server (:obj:`bool`): Whether to run Perspective in "server-only"
              mode, where the front-end client does not have its own Table,
              and instead reads all data and operations from Python.
  
          client (:obj:`bool`):  If True, convert the dataset into an Apache Arrow
              binary and create the Table in Javascript using a copy of the
              data. Defaults to False.
  
          kwargs (:obj:`dict`): configuration options for the `PerspectiveViewer`,
              and `Table` constructor if `data` is a dataset.
  
      Examples:
          >>> widget = PerspectiveWidget(
          ...     {"a": [1, 2, 3]},
          ...     aggregates={"a": "avg"},
          ...     group_by=["a"],
          ...     sort=[["b", "desc"]],
          ...     filter=[["a", ">", 1]],
          ...     expressions=["\"a\" + 100"])
      """
      # Trigger special flow when receiving an ArrayBuffer/binary
      self._pending_binary = None
  
      # If `self.client` is True, the front-end `<perspective-viewer>` is
      # given a copy of the data serialized to JSON, and the Python kernel
      # does not create a `perspective.Table.`
      self.client = client
  
      # If `self.server` is True, the widget runs in server-only mode where
      # the front-end `<perspective-viewer>` does not create a Table, and
      # will proxy all operations back to the server.
      self.server = server
  
      # Pass table load options to the front-end, unless in server mode
      self._options = {}
  
      if index is not None and limit is not None:
          raise PerspectiveError(
              "Index and Limit cannot be set at the same time!"
          )
  
      # Parse the dataset we pass in - if it's Pandas, preserve pivots
      if isinstance(data, pandas.DataFrame) or isinstance(
          data, pandas.Series
      ):
          data, config = deconstruct_pandas(data)
  
          if config.get("group_by", None) and "group_by" not in kwargs:
              kwargs.update({"group_by": config["group_by"]})
  
          if config.get("split_by", None) and "split_by" not in kwargs:
              kwargs.update({"split_by": config["split_by"]})
  
          if config.get("columns", None) and "columns" not in kwargs:
              kwargs.update({"columns": config["columns"]})
  
      # Initialize the viewer
      super(PerspectiveWidget, self).__init__(**kwargs)
  
      # Handle messages from the the front end
      # `PerspectiveJupyterClient.send()`:
      # - The "data" value of the message should be a JSON-serialized string.
      # - Both `on_msg` and `@observe("value")` must be specified on the
      # handler for custom messages to be parsed by the Python widget.
      self.on_msg(self.handle_message)
  
      if self.client:
          if is_libpsp():
              from ..libpsp import Table
  
              if isinstance(data, Table):
                  raise PerspectiveError(
                      "Client mode PerspectiveWidget expects data or schema, not a `perspective.Table`!"
                  )
  
          if index is not None:
              self._options["index"] = index
  
          if limit is not None:
              self._options["limit"] = limit
  
          # cache self._data so creating multiple views don't reserialize the
          # same data
          if not hasattr(self, "_data") or self._data is None:
              self._data = _serialize(data)
      else:
          # If an empty dataset is provided, don't call `load()` and wait
          # for the user to call `load()`.
          if data is None:
              if index is not None or limit is not None:
                  raise PerspectiveError(
                      "Cannot initialize PerspectiveWidget `index` or `limit` without a Table, data, or schema!"
                  )
          else:
              if index is not None:
                  self._options.update({"index": index})
  
              if limit is not None:
                  self._options.update({"limit": limit})
  
              self.load(data, **self._options)
  
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 1 to create a new PerspectiveWidget object from inherited base classes: DOMWidget, PerspectiveViewer with example: obj = PerspectiveWidget(data, index, limit, server, client)