Skip to content

Commit

Permalink
feat: Add plotly-express JsPlugin implementation and registration (#150)
Browse files Browse the repository at this point in the history
This plumbs automatic JsPlugin registration - the server side depends on
deephaven/deephaven-core#4925.
  • Loading branch information
devinrsmith committed Dec 20, 2023
1 parent 04321a0 commit d6d0416
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 27 deletions.
6 changes: 3 additions & 3 deletions plugins/plotly-express/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = deephaven-plugin-plotly-express
description = Deephaven Chart Plugin
long_description = file: README.md
long_description_content_type = text/markdown
version = attr:deephaven.plot.express.__version__
version = 0.3.0.dev0
url = https://github.com/deephaven/deephaven-plugins
project_urls =
Source Code = https://github.com/deephaven/deephaven-plugins
Expand All @@ -25,7 +25,7 @@ package_dir=
=src
packages=find_namespace:
install_requires =
deephaven-plugin>=0.5.0
deephaven-plugin>=0.6.0
plotly
include_package_data = True

Expand All @@ -34,4 +34,4 @@ where=src

[options.entry_points]
deephaven.plugin =
registration_cls = deephaven.plot.express:ChartRegistration
registration_cls = deephaven.plot.express._register:ExpressRegistration
7 changes: 4 additions & 3 deletions plugins/plotly-express/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from setuptools import setup
import os
import subprocess
import json

# npm pack in js directory

Expand All @@ -18,11 +17,13 @@
os.makedirs(dest_dir, exist_ok=True)

# pack and unpack into the js plotly-express directory
subprocess.run(["npm", "pack", "--pack-destination", project], cwd=js_dir)
subprocess.run(
["npm", "pack", "--pack-destination", project], cwd=js_dir, check=True
)
# it is assumed that there is only one tarball in the directory
files = os.listdir(dest_dir)
for file in files:
subprocess.run(["tar", "-xzf", file], cwd=dest_dir)
subprocess.run(["tar", "-xzf", file], cwd=dest_dir, check=True)
os.remove(os.path.join(dest_dir, file))

# move the contents of the package directory to the plotly-express directory
Expand Down
21 changes: 0 additions & 21 deletions plugins/plotly-express/src/deephaven/plot/express/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import json

from deephaven.plugin import Registration, Callback
from deephaven.plugin.object_type import BidirectionalObjectType, MessageStream

from .communication.DeephavenFigureConnection import DeephavenFigureConnection
Expand Down Expand Up @@ -44,7 +43,6 @@

from .data import data_generators

__version__ = "0.3.0.dev0"

NAME = "deephaven.plot.express.DeephavenFigure"

Expand Down Expand Up @@ -101,22 +99,3 @@ def create_client_connection(
payload, references = figure_connection.on_data(initial_message, [])
connection.on_data(payload, references)
return figure_connection


class ChartRegistration(Registration):
"""
Register the DeephavenFigureType
"""

@classmethod
def register_into(cls, callback: Callback) -> None:
"""
Register the DeephavenFigureType
Args:
callback: Registration.Callback:
A function to call after registration
"""
callback.register(DeephavenFigureType)
73 changes: 73 additions & 0 deletions plugins/plotly-express/src/deephaven/plot/express/_js.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import importlib.resources
import json
import pathlib
import sys
from typing import Callable, ContextManager

from deephaven.plugin.js import JsPlugin


class ExpressJsPlugin(JsPlugin):
def __init__(
self,
name: str,
version: str,
main: str,
path: pathlib.Path,
) -> None:
self._name = name
self._version = version
self._main = main
self._path = path

@property
def name(self) -> str:
return self._name

@property
def version(self) -> str:
return self._version

@property
def main(self) -> str:
return self._main

def path(self) -> pathlib.Path:
return self._path


def _create_from_npm_package_json(
path_provider: Callable[[], ContextManager[pathlib.Path]]
) -> JsPlugin:
with path_provider() as tmp_js_path:
js_path = tmp_js_path
if not js_path.exists():
raise Exception(
f"Package is not installed in a normal python filesystem, '{js_path}' does not exist"
)
with (js_path / "package.json").open("rb") as f:
package_json = json.load(f)
return ExpressJsPlugin(
package_json["name"],
package_json["version"],
package_json["main"],
js_path,
)


def _resource_js_path() -> ContextManager[pathlib.Path]:
# TODO: Js content should be in same package directory
# https://github.com/deephaven/deephaven-plugins/issues/139
if sys.version_info < (3, 9):
return importlib.resources.path("js", "plotly-express")
else:
return importlib.resources.as_file(
importlib.resources.files("js").joinpath("plotly-express")
)


def create_js_plugin() -> JsPlugin:
# TODO: Include developer instructions for installing in editable mode
# https://github.com/deephaven/deephaven-plugins/issues/93
# TBD what editable mode looks like for JsPlugin
return _create_from_npm_package_json(_resource_js_path)
24 changes: 24 additions & 0 deletions plugins/plotly-express/src/deephaven/plot/express/_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from . import DeephavenFigureType
from ._js import create_js_plugin

from deephaven.plugin import Registration, Callback


class ExpressRegistration(Registration):
"""
Register the DeephavenFigureType and a JsPlugin
"""

@classmethod
def register_into(cls, callback: Callback) -> None:
"""
Register the DeephavenFigureType and a JsPlugin
Args:
callback: Registration.Callback:
A function to call after registration
"""
callback.register(DeephavenFigureType)
callback.register(create_js_plugin())

0 comments on commit d6d0416

Please sign in to comment.