"""\
Copyright (c) 2023, Flagstaff Solutions, LLC
All rights reserved.
"""
import inspect
from abc import ABC
[docs]
def get_all_function_arguments(frame):
"""Iterates over all function arguments, including *args and **kwargs"""
arg_values = inspect.getargvalues(frame[0])
# Positional arguments
for arg_name in arg_values.args:
arg_value = arg_values.locals[arg_name]
yield arg_value
# Varargs
if arg_values.varargs:
# pylint: disable=use-yield-from
for arg_value in arg_values.locals[arg_values.varargs]:
yield arg_value
# Kwargs
if arg_values.keywords:
# pylint: disable=use-yield-from
for arg_value in arg_values.locals[arg_values.keywords].values():
yield arg_value
[docs]
class GoFigrBackend(ABC):
"""Base class for figure backends, e.g. matplotlib or plotly"""
[docs]
def is_compatible(self, fig):
"""Returns True if this backend is compatible with a figure"""
raise NotImplementedError
[docs]
def is_interactive(self, fig):
"""Returns True if the figure supports interactive (HTML) output"""
raise NotImplementedError
[docs]
def is_static(self, fig):
"""Returns True if the figure is static (e.g. an image)"""
return not self.is_interactive(fig)
[docs]
def get_title(self, fig):
"""\
Extracts figure title
:param fig: figure to extract title from
:return: figure title, or None if not available
"""
raise NotImplementedError
[docs]
def add_interactive_watermark(self, fig, rev, watermark):
"""\
Adds watermark to a figure using the backend's native objects (if supported by the backend)
:param fig: figure to watermark
:param rev: FigureRevision object
:param watermark: DefaultWatermark instance
:return: modified figure
"""
raise NotImplementedError
[docs]
def close(self, fig):
"""\
Closes a figure and prevents it from being displayed.
:param fig: figure to close
:return: None
"""
raise NotImplementedError
[docs]
def get_backend_name(self):
"""\
Gets a human-readable name of this backend.
:return: backend name, a string
"""
raise NotImplementedError
[docs]
def get_backend(figure, backends):
"""\
Gets the backend compatible with a figure
:param figure: figure to find a backend for
:param backends: list of backends to search
:return: GoFigr backend compatible with the figure, or ValueError if none are compatible.
"""
for back in backends:
if back.is_compatible(figure):
return back
raise ValueError(f"Could not find a backend compatible with {figure}. "
f"Checked: {', '.join([str(back) for back in backends])}")