Skip to main content

perspective-python API

perspective.table contains Table and View, the data primitives of Perspective.

For usage, see the Python User Guide.

Table

View

perspective.core contains modules that implements perspective-python in various environments, most notably PerspectiveWidget and the various Perspective web server handlers.

Additionally, perspective.core defines several enums that provide easy access to aggregate options, different plugins, sort directions etc.

For usage of PerspectiveWidget and the Perspective web server handlers, see the User Guide in the sidebar.

PerspectiveWidget

PerspectiveWidget is a Perspective integration into JupyterLab.

class perspective.widget.widget.PerspectiveWidget(**kwargs: Any)

Bases: DOMWidget, PerspectiveViewer

: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

__init__(data, index=None, limit=None, server=False, client=True, **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.

  • Parameters:data (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 (str) – A column name to be used as the primary key. Ignored if server is True.
    • limit (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 (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 (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 (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"])

load(data, **options)

Load the widget with data. If running in client mode, this method serializes the data and calls the browser viewer’s load method. Otherwise, it calls Viewer.load() using super().

update(data)

Update the widget with new data. If running in client mode, this method serializes the data and calls the browser viewer’s update method. Otherwise, it calls Viewer.update() using super().

clear()

Clears the widget’s underlying Table.

In client mode, clears the _data attribute of the widget.

replace(data)

Replaces the widget’s Table with new data conforming to the same schema. Does not clear user-set state. If in client mode, serializes the data and sends it to the browser.

delete(delete_table=True)

Delete the Widget’s data and clears its internal state. If running in client mode, sends the delete() command to the browser. Otherwise calls delete on the underlying viewer.

  • Parameters:delete_table (bool) – whether the underlying Table will be deleted. Defaults to True.

perspective.widget.widget.set_jupyter_html_export(val)

Enables HTML export for Jupyter widgets, when set to True. HTML export can also be enabled by setting the environment variable PSP_JUPYTER_HTML_EXPORT to the string 1.

class perspective.viewer.viewer.PerspectiveViewer(**kwargs: Any)

Bases: PerspectiveTraitlets, object

PerspectiveViewer wraps the perspective.Table API and exposes an API around creating views, loading data, and updating data.

__init__(plugin='Datagrid', columns=None, group_by=None, split_by=None, aggregates=None, sort=None, filter=None, expressions=None, plugin_config=None, settings=True, theme=None, title=None, version=None)

Initialize an instance of PerspectiveViewer with the given viewer configuration. Do not pass a Table or data into the constructor - use the load() method to provide the viewer with data.

  • Keyword Arguments:
    • columns (list of str) – A list of column names to be visible to the user.
    • group_by (list of str) – A list of column names to use as group by.
    • split_by (list of str) – A list of column names to use as split by.
    • aggregates (dict of str to str) – A dictionary of column names to aggregate types, which specify aggregates for individual columns.
    • sort (list of list of str) – A list of lists, each list containing a column name and a sort direction (asc, desc, asc abs, desc abs, col asc, col desc, col asc abs, col desc abs).
    • filter (list of list of str) – A list of lists, each list containing a column name, a filter comparator, and a value to filter by.
    • expressions (list of str) – A list of string expressions which are applied to the view.
    • plugin (str/perspective.Plugin) – Which plugin to select by default.
    • plugin_config (dict) – A configuration for the plugin, i.e. the datagrid plugin or a chart plugin.
    • settings (bool) – Whether the perspective query settings panel should be open.
    • theme (str) – The color theme to use.
    • version (str) – The version this configuration is restored from. This should only be used when restoring a configuration, and should not be set manually.
Examples
>>> viewer = PerspectiveViewer(
... aggregates={"a": "avg"},
... group_by=["a"],
... sort=[["b", "desc"]],
... filter=[["a", ">", 1]],
... expressions=[""a" + 100"]
... )

property table

Returns the perspective.Table under management by the viewer.

load(data, **options)

Given a perspective.Table, a perspective.View, or data that can be handled by perspective.Table, pass it to the viewer. Like __init__, load accepts a perspective.Table, a dataset, or a schema. If running in client mode, load defers to the browser’s Perspective engine. This means that loading Python-only datasets, especially ones that cannot be serialized into JSON, may cause some issues.

load() resets the state of the viewer :

  • If a perspective.Table has already been loaded, **options is ignored as the options already set on the Table take precedence.
  • If a perspective.View is loaded, the options on the perspective.Table linked to the view take precedence.

If data is passed in, a perspective.Table is automatically created by this method, and the options passed to **config are extended to the new Table. If the widget already has a dataset, and the new data has different columns to the old one, then the widget state (pivots, sort, etc.) is cleared to prevent applying settings on columns that don’t exist.

  • Parameters:data (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 viewer.
  • Keyword Arguments:
    • name (str) – An optional name to reference the table by so it can be accessed from the front-end. If not provided, a name will be generated.
    • index (str) – A column name to be used as the primary key. Ignored if a Table or View is supplied.
    • limit (int) – A upper limit on the number of rows in the Table. Cannot be set at the same time as index. Ignored if a Table or View is supplied.
Examples
>>> from perspective import Table, PerspectiveViewer
>>> data = {"a": [1, 2, 3]}
>>> tbl = Table(data)
>>> viewer = PerspectiveViewer()
>>> viewer.load(tbl)
>>> viewer.load(data, index="a") # viewer state is reset
>>> viewer2 = PerspectiveViewer()
>>> viewer2.load(tbl.view())

update(data)

Update the table under management by the viewer with new data. This function follows the semantics of Table.update(), and will be affected by whether an index is set on the underlying table.

  • Parameters:
    • data (dict|:obj:list|:obj:pandas.DataFrame) – the
    • table. (update data for the) –

clear()

Clears the rows of this viewer’s Table.

replace(data)

Replaces the rows of this viewer’s Table with new data.

  • Parameters:
    • data (dict|:obj:list|:obj:pandas.DataFrame) – new data
    • schema. (to set into the table - must conform to the table's) –

save()

Get the viewer’s attribute as a dictionary, symmetric with restore so that a viewer’s configuration can be reproduced.

restore(**kwargs)

Restore a given set of attributes, passed as kwargs (e.g. dictionary). Symmetric with save so that a given viewer’s configuration can be reproduced.

reset()

Resets the viewer’s attributes and state, but does not delete or modify the underlying Table.

Examples

widget = PerspectiveWidget(data, group_by=[“date”], plugin=Plugin.XBAR) widget.reset() widget.plugin #

delete(delete_table=True)

Delete the Viewer’s data and clears its internal state. If delete_table is True, the underlying perspective.Table and the internal View object will be deleted.

  • Parameters:delete_table (bool) – whether the underlying Table will be deleted. Defaults to True.

Perspective Webserver Handlers

Perspective provides several ready-made integrations with webserver libraries that interfaces seamlessly with @finos/perspective-viewer in Javascript.

class perspective.handlers.tornado.PerspectiveTornadoHandler(*args, **kwargs)

Bases: PerspectiveHandlerBase, WebSocketHandler

PerspectiveTornadoHandler is a drop-in implementation of Perspective.

Use it inside Tornado routing to create a server-side Perspective that is ready to receive websocket messages from the front-end perspective-viewer. Because Tornado implements an event loop, this handler links Perspective with IOLoop.current() in order to defer expensive operations until the next free iteration of the event loop.

The Perspective client and server will automatically keep the Websocket alive without timing out.

Examples
>>> MANAGER = PerspectiveManager()
>>> MANAGER.host_table("data_source_one", Table(
... pd.read_csv("superstore.csv")))
>>> app = tornado.web.Application([
... (r"/", MainHandler),
... (r"/websocket", PerspectiveTornadoHandler, {
... "manager": MANAGER,
... "check_origin": True
... })
... ])

__init__(*args, **kwargs)

Create a new instance of the PerspectiveHandlerBase with the given Manager instance.

  • Keyword Arguments:
    • manager (PerspectiveManager) – A PerspectiveManager instance. Must be provided on initialization.
    • ( (check_origin) – obj`bool`): If True, all requests will be accepted regardless of origin. Defaults to False.
    • chunk_size (int) – Binary messages will not exceed this length (in bytes); payloads above this limit will be chunked across multiple messages. Defaults to 16_777_216 (16MB), and be disabled entirely with None.

on_message(*args, **kwargs)

When the websocket receives a message, send it to the process method of the PerspectiveManager with a reference to the post callback.

async write_message(message: str, binary: bool = False)

Websocket-specific implementation of writing a message to the websocket client. Must support writing either text or binary messages. Should only be called by this class’s post function, which handles all the perspective-specific logic

  • Parameters:
    • message (str) – the message to write
    • binary (bool**, optional) – whether or not to write as binary buffer

class perspective.handlers.starlette.PerspectiveStarletteHandler(**kwargs)

Bases: PerspectiveHandlerBase

PerspectiveStarletteHandler is a drop-in implementation of Perspective.

The Perspective client and server will automatically keep the Websocket alive without timing out.

Examples
>>> MANAGER = PerspectiveManager()
>>> MANAGER.host_table("data_source_one", Table(
... pd.read_csv("superstore.csv")))
>>> app = FastAPI()
>>> async def endpoint(websocket: Websocket):
... handler = PerspectiveStarletteHandler(manager, websocket)
... await handler.run()
... app.add_api_websocket_route('/websocket', endpoint)

__init__(**kwargs)

Create a new instance of the PerspectiveHandlerBase with the given Manager instance.

  • Keyword Arguments:
    • manager (PerspectiveManager) – A PerspectiveManager instance. Must be provided on initialization.
    • ( (check_origin) – obj`bool`): If True, all requests will be accepted regardless of origin. Defaults to False.
    • chunk_size (int) – Binary messages will not exceed this length (in bytes); payloads above this limit will be chunked across multiple messages. Defaults to 16_777_216 (16MB), and be disabled entirely with None.

async write_message(message: str, binary: bool = False)

Websocket-specific implementation of writing a message to the websocket client. Must support writing either text or binary messages. Should only be called by this class’s post function, which handles all the perspective-specific logic

  • Parameters:
    • message (str) – the message to write
    • binary (bool**, optional) – whether or not to write as binary buffer

class perspective.handlers.aiohttp.PerspectiveAIOHTTPHandler(**kwargs)

Bases: PerspectiveHandlerBase

PerspectiveAIOHTTPHandler is a drop-in implementation of Perspective.

Use it inside AIOHTTP routing to create a server-side Perspective that is ready to receive websocket messages from the front-end perspective-viewer.

The Perspective client and server will automatically keep the Websocket alive without timing out.

Examples
>>> manager = PerspectiveManager()
>>> async def websocket_handler(request):
... handler = PerspectiveAIOHTTPHandler(manager=manager, request=request)
... await handler.run()
>>> app = web.Application()
>>> app.router.add_get("/websocket", websocket_handler)

__init__(**kwargs)

Create a new instance of the PerspectiveHandlerBase with the given Manager instance.

  • Keyword Arguments:
    • manager (PerspectiveManager) – A PerspectiveManager instance. Must be provided on initialization.
    • ( (check_origin) – obj`bool`): If True, all requests will be accepted regardless of origin. Defaults to False.
    • chunk_size (int) – Binary messages will not exceed this length (in bytes); payloads above this limit will be chunked across multiple messages. Defaults to 16_777_216 (16MB), and be disabled entirely with None.

async write_message(message: str, binary: bool = False)

Websocket-specific implementation of writing a message to the websocket client. Must support writing either text or binary messages. Should only be called by this class’s post function, which handles all the perspective-specific logic

  • Parameters:
    • message (str) – the message to write
    • binary (bool**, optional) – whether or not to write as binary buffer

Perspective Websocket Clients

Perspective also provides several client interfaces to integrate with the above Perspective webserver handlers.

PerspectiveManager

PerspectiveManager implements a communication protocol between Perspective runtimes in different languages. Through its process() method, it allows runtimes to communicate instructions and interoperate.