Skip to content

Commit

Permalink
Various python updates (plotGlPixelRatio, template dimensions, json e…
Browse files Browse the repository at this point in the history
…ngine, AWS Lambda) (#76)

* Honor plotly figure's template width

* Set plotGlPixelRatio to 2x the scale factor

* Refactor to use plotly.py to_json method for json encoding

This will provide future compatibility with the plotly.py 5.0 JSON engine, and accelerated orjson encoder.

* Add --single-process chromium arg on AWS Lambda

* Update no_output_timeout for windows fetch
  • Loading branch information
jonmmease authored Feb 28, 2021
1 parent feda342 commit 4560ade
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 19 deletions.
4 changes: 3 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,9 @@ jobs:
steps:
- checkout
- run: echo $Host.Version
- run: .\repos\win_scripts\fetch_chromium.ps1
- run:
command: .\repos\win_scripts\fetch_chromium.ps1
no_output_timeout: 30m
- persist_to_workspace:
root: ./repos
paths:
Expand Down
3 changes: 0 additions & 3 deletions repos/kaleido/js/src/plotly/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ module.exports = {

mathJaxConfigQuery: '?config=TeX-AMS-MML_SVG',

// config option passed in render step
plotGlPixelRatio: 2.5,

// time [in ms] after which printToPDF errors when image isn't loaded
pdfPageLoadImgTimeout: 20000
}
8 changes: 4 additions & 4 deletions repos/kaleido/js/src/plotly/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ function render (info, mapboxAccessToken, topojsonURL) {

// Use parsed export request
info = parsed.result;
const figure = info.figure
const format = info.format
const encoded = info.encoded
const figure = info.figure;
const format = info.format;
const encoded = info.encoded;

// Build default config, and let figure.config override it
const defaultConfig = {
mapboxAccessToken: opts.mapboxAccessToken || null,
plotGlPixelRatio: opts.plotGlPixelRatio || cst.plotGlPixelRatio
plotGlPixelRatio: info.scale * 2
}
if (opts.topojsonURL) {
defaultConfig.topojsonURL = opts.topojsonURL
Expand Down
16 changes: 10 additions & 6 deletions repos/kaleido/py/kaleido/scopes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@


class BaseScope(object):
# Subclasses may override to specify a custom JSON encoder for input data
_json_encoder = None

# Tuple of class properties that will be passed as command-line
# flags to configure scope
_scope_flags = ()

# Specify default chromium arguments
_default_chromium_args = (
"--disable-gpu",
"--allow-file-access-from-files",
"--disable-breakpad",
"--disable-dev-shm-usage",
) + (
# Add "--single-process" when running on AWS Lambda. Flag is described
# as for debugging only by the chromium project, but it's the only way to get
# chromium headless working on Lambda
("--single-process",) if os.environ.get("LAMBDA_RUNTIME_DIR", None) else ()
)

_scope_chromium_args = ()
Expand Down Expand Up @@ -274,6 +277,9 @@ def chromium_args(self, val):
self._chromium_args = tuple(val)
self._shutdown_kaleido()

def _json_dumps(self, val):
return json.dumps(val)

def _perform_transform(self, data, **kwargs):
"""
Transform input data using the current scope, returning dict response with error code
Expand All @@ -287,9 +293,7 @@ def _perform_transform(self, data, **kwargs):
self._ensure_kaleido()

# Perform export
export_spec = json.dumps(
dict(kwargs, data=data),
cls=self._json_encoder).encode('utf-8')
export_spec = self._json_dumps(dict(kwargs, data=data)).encode('utf-8')

# Write to process and read result within a lock so that can be
# sure we're reading the response to our request
Expand Down
22 changes: 17 additions & 5 deletions repos/kaleido/py/kaleido/scopes/plotly.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import absolute_import
from kaleido.scopes.base import BaseScope, which
from _plotly_utils.utils import PlotlyJSONEncoder
import plotly.io as pio
import base64
import os
from pathlib import Path
Expand All @@ -10,7 +10,6 @@ class PlotlyScope(BaseScope):
"""
Scope for transforming Plotly figures to static images
"""
_json_encoder = PlotlyJSONEncoder
_all_formats = ("png", "jpg", "jpeg", "webp", "svg", "pdf", "eps", "json")
_text_formats = ("svg", "json", "eps")

Expand Down Expand Up @@ -73,6 +72,9 @@ def _initialize_mathax(self, mathjax=None):
def scope_name(self):
return "plotly"

def _json_dumps(self, val):
return pio.to_json(val, validate=False, remove_uids=False)

def transform(self, figure, format=None, width=None, height=None, scale=None):
"""
Convert a Plotly figure into a static image
Expand Down Expand Up @@ -115,9 +117,19 @@ def transform(self, figure, format=None, width=None, height=None, scale=None):
# Get figure layout
layout = figure.get("layout", {})

# Compute default width / height
width = width or layout.get("width", None) or self.default_width
height = height or layout.get("height", None) or self.default_height
# Compute image width / height
width = (
width
or layout.get("width", None)
or layout.get("template", {}).get("layout", {}).get("width", None)
or self.default_width
)
height = (
height
or layout.get("height", None)
or layout.get("template", {}).get("layout", {}).get("height", None)
or self.default_height
)

# Normalize format
original_format = format
Expand Down

0 comments on commit 4560ade

Please sign in to comment.