Plotly.io with external orca

Hey everyone!

I am currently trying to get the Python Plotly package to play nicely with serverless computing. This works perfectly apart from when I try to export an image using Orca.

Since it is difficult to install Orca inside of the container than runs my serverless function, I want to be able to run Orca in another container. This way, I can use the default container from the Orca repository quay.io/plotly/orca and simply start it together with the container for my function app.

Therefore, I need to be able to let the plotly.io module know that I have a running Orca server and it should use the running one instead of starting up one locally.

I have looked into the code of the plotly.io module and tried to set the pio.orca.config.port variable to the port that is exposed by my local container and the Orca server runs behind. However, currently the plotly.io module does not seem to check whether we already have a running server behind the given port and start one up anyway.

Am I able to change this behaviour in any way? I did not find anything in the code but I could have missed something.

Best
Alexander

Okay. I was able to get this running. So what I did was start the Orca server with the Docker image provided (quay.io/plotly/orca). This Orca server runs on port 9091 so we need to expose and map this port to a port on our machine. I did this as is done in an example in the Orca docs: docker run -d -p 9091:9091 quay.io/plotly/orca.

The python code to run the image export then reads:

import plotly.io as pio
import plotly.graph_objects as go
from _plotly_utils.utils import PlotlyJSONEncoder

from PIL import Image
import io
import requests
import json

trace = go.Scatter(x=[1, 2, 3], y=[4, 5, 6], marker={"color": "red"})
fig = go.Figure(data=[trace])

server_url = "http://localhost:9091"

request_params = {
    "figure": fig.to_dict(),
    "format": "png", # any format from "png", "jpeg", "webp", "svg", "pdf", "eps"
    "scale": 1,
    "width": 500,
    "height": 500
}
json_str = json.dumps(request_params, cls=PlotlyJSONEncoder)
response = requests.post(server_url + "/", data=json_str)
image = response.content
Image.open(io.BytesIO(image)).show()

I copied this from some code that I found in the plotly.py repository for running the Orca server. I was not able to find the PlotlyJSONEncoder in the public modules, so I had to use the private utils module.

But this lets you get the image as bytes from the Orca server that runs (basically) everywhere you like. The API for the post request is very close the the IO API provided by default (to_image() and write_image()).