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.
- index (
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
ofstr
) – A list of column names to be visible to the user. - group_by (
list
ofstr
) – A list of column names to use as group by. - split_by (
list
ofstr
) – A list of column names to use as split by. - aggregates (
dict
ofstr
tostr
) – A dictionary of column names to aggregate types, which specify aggregates for individual columns. - sort (
list
oflist
ofstr
) – 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
oflist
ofstr
) – A list of lists, each list containing a column name, a filter comparator, and a value to filter by. - expressions (
list
ofstr
) – 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.
- columns (
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 theTable
take precedence. - If a
perspective.View
is loaded, the options on theperspective.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 aTable
orView
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 aTable
orView
is supplied.
- name (
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) –
- data (
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) –
- data (
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.
- manager (
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.
- manager (
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.
- manager (
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.