Deephaven Community Core supports bidirectional plugins that allow clients to connect to and manage objects created on the server through remote procedure protocol (RPC). What does that mean? You can create apps like chat servers, interactive widgets, and more. This blog will walk you through a simple example that uses bidirectional plugins to serialize and deserialize a function and its return values.
This blog uses Python's pickle package to serialize and deserialize objects. Pickle is a powerful tool, but it can be dangerous to use with untrusted data. Never unpickle data that you don't trust.
Setup
First, create a directory to put everything into. We'll call it plugin
.
mkdir plugin
cd plugin
Next, clone the plugin-python-rpc-pickle repository into the folder. It contains the code for the server and client plugins.
git clone [email protected]:deephaven-examples/plugin-python-rpc-pickle.git
This example will be run via Docker. Let's start by creating a Dockerfile
, which will build the Deephaven server image with the server-side plugin installed.
FROM ghcr.io/deephaven/server:0.28.1
COPY plugin-python-rpc-pickle /plugin-python-rpc-pickle
RUN cd /plugin-python-rpc-pickle/python-server-plugin && pip install .
Next, put a docker-compose.yml
file in the same folder. This will start the Deephaven server with the plugin installed and use anonymous authentication to allow the client to connect easily.
version: "3.4"
services:
deephaven:
build: .
ports:
- "${DEEPHAVEN_PORT:-10000}:10000"
volumes:
- ./data:/data
environment:
- START_OPTS=-Xmx4g -DAuthHandlers=io.deephaven.auth.AnonymousAuthenticationHandler
Code
Then, start up the Deephaven server via docker compose up
and run the following script on the server:
from dhexample.rpc_pickle_server import RemoteShell
shell = RemoteShell(scope=globals())
def make_string(a, b, c):
return f"{a} - {b} - {c} #"
Now create the following script (client.py
) that will be run via the Deephaven Python client:
from pydeephaven import Session
s = Session()
shell_ticket = s.exportable_objects["shell"]
shell_plugin = s.plugin_client(shell_ticket)
from dhexample.rpc_pickle_client import RemoteShellProxy
shell = RemoteShellProxy(shell_plugin)
string_result = shell.run("make_string", 1, 2, 3)
print(string_result)
Put it all together
Lastly, create a shell script, which we'll call setup_client.sh
, to configure and install what's necessary to run the client.
#!/bin/bash
# Ensure Python 3.11 is installed
if [ ! -d "./venv" ]; then
rm -rf ./venv
python3.11 -m venv ./venv
fi
source ./venv/bin/activate
pushd plugin-python-rpc-pickle/python-client-plugin
pip3.11 install pydeephaven==0.28.1
pip3.11 install .
popd
python3.11 client.py
Make the shell script executable (chmod +x setup_client.sh
) and run it (./setup_client.sh
) to install, configure, and run the client script.
That's all it took to send objects from the server to the client and back again! This example is a simple one but translates to more sophisticated use cases. For instance, a chat server was demonstrated during our July 28 developer demos. Bidirectional plugins would also be a perfect candidate to take the Deephaven + Weaviate integration to the next level.
Reach out
Our Community Slack continues to grow. Reach out to us here with any questions or comments you have!