Skip to content

Commit

Permalink
feat: add path argument to save jsdom result to file
Browse files Browse the repository at this point in the history
See #21
  • Loading branch information
juba committed Oct 8, 2023
1 parent b82d037 commit f73f2f9
Showing 1 changed file with 72 additions and 11 deletions.
83 changes: 72 additions & 11 deletions src/pyobsplot/obsplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
import shutil
import os
import signal
from pathlib import Path
from subprocess import Popen, PIPE, SubprocessError
from IPython.display import display
from IPython.display import display, SVG, HTML
from typing import Any
import warnings
from ipywidgets.embed import embed_minimal_html


from .widget import ObsplotWidget
from .jsdom import ObsplotJsdom
Expand Down Expand Up @@ -153,10 +157,37 @@ def __call__(self, *args, **kwargs) -> ObsplotWidget:
"""
Method called when an instance is called.
"""
path = None
if "path" in kwargs:
path = kwargs["path"]
del kwargs["path"]
spec = self.get_spec(*args, **kwargs)
return ObsplotWidget(
res = ObsplotWidget(
spec, theme=self._theme, default=self._default, debug=self._debug
) # type: ignore
if path is not None:
ObsplotWidgetCreator.save_to_file(path, res)
else:
return res

@staticmethod
def save_to_file(path: str, res: ObsplotWidget) -> None:
"""
Save an Obsplot object generated by a widget creator to a file.
Args:
path (str): path to output file.
res (ObsplotWidget): result of a call to Obsplot().
Raises:
RuntimeWarning: if the file extension doesn't match the Obsplot type.
"""
extension = Path(path).suffix.lower()
if extension not in [".html", ".htm"]:
warnings.warn(
"Output file extension should be one of 'html' or 'htm'", RuntimeWarning
)
embed_minimal_html(path, views=[res])


class ObsplotJsdomCreator(ObsplotCreator):
Expand All @@ -179,16 +210,22 @@ def __call__(self, *args, **kwargs) -> None:
raise RuntimeError(
"Server has ended, please recreate your plot generator object."
)
path = None
if "path" in kwargs:
path = kwargs["path"]
del kwargs["path"]
spec = self.get_spec(*args, **kwargs)
display(
ObsplotJsdom(
spec,
port=self._port,
theme=self._theme,
default=self._default,
debug=self._debug,
).plot()
)
res = ObsplotJsdom(
spec,
port=self._port,
theme=self._theme,
default=self._default,
debug=self._debug,
).plot()
if path is None:
display(res)
else:
ObsplotJsdomCreator.save_to_file(path, res)

def start_server(self):
"""
Expand Down Expand Up @@ -234,3 +271,27 @@ def close(self):
"""
if self._proc is not None:
os.killpg(os.getpgid(self._proc.pid), signal.SIGTERM)

@staticmethod
def save_to_file(path: str, res: SVG | HTML) -> None:
"""
Save an Obsplot object generated by a Jsdom creator to a file.
Args:
path (str): path to output file.
res (SVG | HTML): result of a call to Obsplot().
Raises:
RuntimeWarning: if the file extension doesn't match the Obsplot type.
"""
extension = Path(path).suffix.lower()
if extension not in [".html", ".svg", ".htm"]:
warnings.warn(
"Output file extension should be one of 'html' or 'svg'", RuntimeWarning
)
if isinstance(res, HTML) and extension == ".svg":
warnings.warn(
f"Output is HTML but file extension is '{extension}'", RuntimeWarning
)
with open(path, "w") as f:
f.write(res.data)

0 comments on commit f73f2f9

Please sign in to comment.