diff --git a/.circleci/config.yml b/.circleci/config.yml index 751f16a0..069469ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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: diff --git a/repos/kaleido/js/src/plotly/constants.js b/repos/kaleido/js/src/plotly/constants.js index 914b7c1f..ab8a213d 100644 --- a/repos/kaleido/js/src/plotly/constants.js +++ b/repos/kaleido/js/src/plotly/constants.js @@ -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 } diff --git a/repos/kaleido/js/src/plotly/render.js b/repos/kaleido/js/src/plotly/render.js index 1da555f3..51127a23 100644 --- a/repos/kaleido/js/src/plotly/render.js +++ b/repos/kaleido/js/src/plotly/render.js @@ -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 diff --git a/repos/kaleido/py/kaleido/scopes/base.py b/repos/kaleido/py/kaleido/scopes/base.py index 449cd881..2c4fae44 100644 --- a/repos/kaleido/py/kaleido/scopes/base.py +++ b/repos/kaleido/py/kaleido/scopes/base.py @@ -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 = () @@ -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 @@ -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 diff --git a/repos/kaleido/py/kaleido/scopes/plotly.py b/repos/kaleido/py/kaleido/scopes/plotly.py index e6b4b442..977fa960 100644 --- a/repos/kaleido/py/kaleido/scopes/plotly.py +++ b/repos/kaleido/py/kaleido/scopes/plotly.py @@ -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 @@ -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") @@ -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 @@ -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