예제 #1
0
def test_extract_format(ext: str, fmt: str, use_filename: bool) -> None:
    if use_filename:
        filename = f"chart.{ext}"
        assert extract_format(filename) == fmt
    else:
        with tempfile.NamedTemporaryFile(suffix=f".{ext}") as fp:
            assert extract_format(fp) == fmt
예제 #2
0
    def save(self, fp: Union[IO, str], fmt: Optional[str] = None) -> None:
        """Save a chart to file

        Parameters
        ----------
        fp : file or filename
            Location to save the result. For fmt in ["png", "pdf"], file must be binary.
            For fmt in ["svg", "vega", "vega-lite"], file must be text.
        fmt : string
            The format in which to save the chart. If not specified and fp is a string,
            fmt will be determined from the file extension.
        """
        if fmt is None:
            fmt = extract_format(fp)
        if fmt not in self.valid_formats:
            raise ValueError(
                f"Got fmt={fmt}; expected one of {self.valid_formats}")

        content = self.mimebundle(fmt).popitem()[1]
        if isinstance(content, dict):
            with maybe_open(fp, "w") as f:
                json.dump(content, f, indent=2)
        elif isinstance(content, str):
            with maybe_open(fp, "w") as f:
                f.write(content)
        elif isinstance(content, bytes):
            with maybe_open(fp, "wb") as f:
                f.write(content)
        else:
            raise ValueError(
                f"Unrecognized content type: {type(content)} for fmt={fmt!r}")
예제 #3
0
def _get_saver_for_format(
    fmt: Optional[str] = None, fp: Optional[Union[IO, str]] = None
) -> Type[Saver]:
    """Get an enabled Saver class that supports the specified format."""
    # TODO: allow other savers to be registered.
    if fmt is None:
        if fp is None:
            raise ValueError("Either fmt or fp must be specified")
        fmt = extract_format(fp)
    savers: List[Type[Saver]] = [BasicSaver, HTMLSaver, SeleniumSaver, NodeSaver]
    for s in savers:
        if fmt in s.valid_formats and s.enabled():
            return s
    raise ValueError(f"Unsupported format: {fmt!r}")
예제 #4
0
    def save(
        self, fp: Optional[Union[IO, str]] = None, fmt: Optional[str] = None
    ) -> Optional[Union[str, bytes]]:
        """Save a chart to file

        Parameters
        ----------
        fp : file or filename (optional)
            Location to save the result. For fmt in ["png", "pdf"], file must be binary.
            For fmt in ["svg", "vega", "vega-lite"], file must be text. If not specified,
            the serialized chart will be returned.
        fmt : string (optional)
            The format in which to save the chart. If not specified and fp is a string,
            fmt will be determined from the file extension.

        Returns
        -------
        chart : string, bytes, or None
            If fp is None, the serialized chart is returned.
            If fp is specified, the return value is None.
        """
        if fmt is None:
            if fp is None:
                raise ValueError("Must specify either `fp` or `fmt` when saving chart")
            fmt = extract_format(fp)
        if fmt not in self.valid_formats[self._mode]:
            raise ValueError(f"Got fmt={fmt}; expected one of {self.valid_formats}")

        content = self._serialize(fmt, "save")
        if fp is None:
            if isinstance(content, dict):
                return json.dumps(content)
            return content
        if isinstance(content, dict):
            with maybe_open(fp, "w") as f:
                json.dump(content, f, indent=2)
        elif isinstance(content, str):
            with maybe_open(fp, "w") as f:
                f.write(content)
        elif isinstance(content, bytes):
            with maybe_open(fp, "wb") as f:
                f.write(content)
        else:
            raise ValueError(
                f"Unrecognized content type: {type(content)} for fmt={fmt!r}"
            )
        return None
예제 #5
0
def _select_saver(
    method: Optional[Union[str, Type[Saver]]],
    mode: str,
    fmt: Optional[str] = None,
    fp: Optional[Union[IO, str]] = None,
) -> Type[Saver]:
    """Get an enabled Saver class that supports the specified format.

    Parameters
    ----------
    method : string or Saver class or None
        The saver class to use. If None, the saver class will be chosen
        automatically.
    mode : string
        One of "vega" or "vega-lite".
    fmt : string, optional
        The format to which the spec will be saved. If not specified, it
        is inferred from `fp`.
    fp : string or file-like object, optional
        Only referenced if fmt is None. The name is used to infer the format
        if possible.

    Returns
    -------
    Saver : Saver class
        The Saver subclass that implements the desired operation.
    """
    if isinstance(method, type) and issubclass(method, Saver):
        return method
    elif isinstance(method, str):
        if method in _SAVER_METHODS:
            return _SAVER_METHODS[method]
        else:
            raise ValueError(f"Unrecognized method: {method!r}")
    elif method is None:
        if fmt is None:
            if fp is None:
                raise ValueError("Either fmt or fp must be specified")
            fmt = extract_format(fp)
        for s in _SAVER_METHODS.values():
            if s.enabled() and fmt in s.valid_formats[mode]:
                return s
        raise ValueError(
            f"No enabled saver found that supports format={fmt!r}")
    else:
        raise ValueError(f"Unrecognized method: {method}")
예제 #6
0
def test_extract_format_failure() -> None:
    fp = io.StringIO()
    with pytest.raises(ValueError) as err:
        extract_format(fp)
    assert f"Cannot infer format from {fp}" in str(err.value)