Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fix widget plugin python warnings #740

Merged
merged 4 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions plugins/utilities/src/deephaven/plugin/utilities/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import abc
import logging
from functools import partial
from typing import Callable, ContextManager
from typing import Callable, ContextManager, Type
import importlib.resources
import json
import pathlib
Expand All @@ -13,6 +13,35 @@
__all__ = ["is_enterprise_environment", "create_js_plugin"]


class CommonJsPlugin(JsPlugin):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of having all the individual plugin classes (UiJsPlugin, ExpressJsPlugin, MatplotlibJsPlugin)? They all do the exact same thing.

We should just get rid of the plugin_class parameter entirely (deprecate first, release, then remove), and then it can just create a CommonJsPlugin in there.

Or is there another reason to be able to specify a custom class?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason that I know of.
I've got #741 up to remove them from the plugins

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 is_enterprise_environment() -> bool:
"""
Check if the environment is an enterprise environment.
Expand All @@ -25,7 +54,7 @@ def is_enterprise_environment() -> bool:


def _create_from_npm_package_json(
path_provider: Callable[[], ContextManager[pathlib.Path]], plugin_class: abc.ABCMeta
path_provider: Callable[[], ContextManager[pathlib.Path]]
) -> JsPlugin:
"""
Create a JsPlugin from an npm package.json file.
Expand All @@ -44,7 +73,7 @@ def _create_from_npm_package_json(
)
with (js_path / "package.json").open("rb") as f:
package_json = json.load(f)
return plugin_class(
return CommonJsPlugin(
package_json["name"],
package_json["version"],
package_json["main"],
Expand Down Expand Up @@ -89,7 +118,9 @@ def _resource_js_path(


def create_js_plugin(
package_namespace: str, js_name: str, plugin_class: abc.ABCMeta
package_namespace: str,
js_name: str,
plugin_class: Type[CommonJsPlugin] = CommonJsPlugin,
) -> JsPlugin:
"""
Create a JsPlugin from an npm package.json file.
Expand All @@ -100,10 +131,10 @@ def create_js_plugin(
js_name:
The resource name
plugin_class:
The class to create. It must be a subclass of JsPlugin.
The class to create. It must be a subclass of CommonJsPlugin.

Returns:
The created JsPlugin
"""
js_path = _resource_js_path_provider(package_namespace, js_name)
return _create_from_npm_package_json(js_path, plugin_class)
return _create_from_npm_package_json(js_path)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from deephaven.plugin.js import JsPlugin


# This plugin allows the Python plugin to register a JavaScript plugin.
# The properties will be filled in during the registration process.
class {{ cookiecutter.__py_js_plugin_obj_name }}(JsPlugin):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
class {{ cookiecutter.__registration_name }}(Registration):
@classmethod
def register_into(cls, callback: Callback) -> None:
callback = DheSafeCallbackWrapper(callback)

# Register the Python plugin
callback.register({{ cookiecutter.__type_name }})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from deephaven.plugin.object_type import MessageStream


class {{ cookiecutter.__object_name }}:
"""
This is a simple object that demonstrates how to send messages to the client.
Expand All @@ -12,7 +13,7 @@ class {{ cookiecutter.__object_name }}:
_connection: MessageStream: The connection to the client
"""
def __init__(self):
self._connection: MessageStream = None
self._connection = None

def send_message(self, message: str) -> None:
"""
Expand All @@ -24,7 +25,7 @@ def send_message(self, message: str) -> None:
if self._connection:
self._connection.send_message(message)

def _set_connection(self, connection: MessageStream) -> None:
def set_connection(self, connection: MessageStream) -> None:
"""
Set the connection to the client.
This is called on the object when it is created.
Expand All @@ -33,7 +34,3 @@ def _set_connection(self, connection: MessageStream) -> None:
connection: The connection to the client
"""
self._connection = connection




Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

# Create a custom message stream to send messages to the client


class {{ cookiecutter.__message_stream_name }}(MessageStream):
"""
A custom MessageStream
Expand All @@ -20,10 +21,12 @@ def __init__(self, obj: Any, client_connection: MessageStream):
super().__init__()
self._client_connection = client_connection

# Start the message stream. All we do is send a blank message to start. Client will respond with the initial state.
# Start the message stream.
# All we do is send a blank message to start.
# Client will respond with the initial state.
self._client_connection.on_data(b"", [])

obj._set_connection(self)
obj.set_connection(self)

def send_message(self, message: str) -> None:
"""
Expand Down Expand Up @@ -57,6 +60,7 @@ def on_close(self) -> None:
"""
pass


# The object type that will be registered with the plugin system.
# The object is bidirectional, meaning it can send messages to and from the client.
# A MessageStream is created for each object that is created. This needs to be saved and tied to the object.
Expand Down