Spaces:
Running
Running
from pathlib import Path | |
from json import loads, dumps | |
from typing import Any, Callable, Optional, Union | |
from .text import Text | |
from .highlighter import JSONHighlighter, NullHighlighter | |
class JSON: | |
"""A renderable which pretty prints JSON. | |
Args: | |
json (str): JSON encoded data. | |
indent (Union[None, int, str], optional): Number of characters to indent by. Defaults to 2. | |
highlight (bool, optional): Enable highlighting. Defaults to True. | |
skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False. | |
ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False. | |
check_circular (bool, optional): Check for circular references. Defaults to True. | |
allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True. | |
default (Callable, optional): A callable that converts values that can not be encoded | |
in to something that can be JSON encoded. Defaults to None. | |
sort_keys (bool, optional): Sort dictionary keys. Defaults to False. | |
""" | |
def __init__( | |
self, | |
json: str, | |
indent: Union[None, int, str] = 2, | |
highlight: bool = True, | |
skip_keys: bool = False, | |
ensure_ascii: bool = False, | |
check_circular: bool = True, | |
allow_nan: bool = True, | |
default: Optional[Callable[[Any], Any]] = None, | |
sort_keys: bool = False, | |
) -> None: | |
data = loads(json) | |
json = dumps( | |
data, | |
indent=indent, | |
skipkeys=skip_keys, | |
ensure_ascii=ensure_ascii, | |
check_circular=check_circular, | |
allow_nan=allow_nan, | |
default=default, | |
sort_keys=sort_keys, | |
) | |
highlighter = JSONHighlighter() if highlight else NullHighlighter() | |
self.text = highlighter(json) | |
self.text.no_wrap = True | |
self.text.overflow = None | |
def from_data( | |
cls, | |
data: Any, | |
indent: Union[None, int, str] = 2, | |
highlight: bool = True, | |
skip_keys: bool = False, | |
ensure_ascii: bool = False, | |
check_circular: bool = True, | |
allow_nan: bool = True, | |
default: Optional[Callable[[Any], Any]] = None, | |
sort_keys: bool = False, | |
) -> "JSON": | |
"""Encodes a JSON object from arbitrary data. | |
Args: | |
data (Any): An object that may be encoded in to JSON | |
indent (Union[None, int, str], optional): Number of characters to indent by. Defaults to 2. | |
highlight (bool, optional): Enable highlighting. Defaults to True. | |
default (Callable, optional): Optional callable which will be called for objects that cannot be serialized. Defaults to None. | |
skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False. | |
ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False. | |
check_circular (bool, optional): Check for circular references. Defaults to True. | |
allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True. | |
default (Callable, optional): A callable that converts values that can not be encoded | |
in to something that can be JSON encoded. Defaults to None. | |
sort_keys (bool, optional): Sort dictionary keys. Defaults to False. | |
Returns: | |
JSON: New JSON object from the given data. | |
""" | |
json_instance: "JSON" = cls.__new__(cls) | |
json = dumps( | |
data, | |
indent=indent, | |
skipkeys=skip_keys, | |
ensure_ascii=ensure_ascii, | |
check_circular=check_circular, | |
allow_nan=allow_nan, | |
default=default, | |
sort_keys=sort_keys, | |
) | |
highlighter = JSONHighlighter() if highlight else NullHighlighter() | |
json_instance.text = highlighter(json) | |
json_instance.text.no_wrap = True | |
json_instance.text.overflow = None | |
return json_instance | |
def __rich__(self) -> Text: | |
return self.text | |
if __name__ == "__main__": | |
import argparse | |
import sys | |
parser = argparse.ArgumentParser(description="Pretty print json") | |
parser.add_argument( | |
"path", | |
metavar="PATH", | |
help="path to file, or - for stdin", | |
) | |
parser.add_argument( | |
"-i", | |
"--indent", | |
metavar="SPACES", | |
type=int, | |
help="Number of spaces in an indent", | |
default=2, | |
) | |
args = parser.parse_args() | |
from pip._vendor.rich.console import Console | |
console = Console() | |
error_console = Console(stderr=True) | |
try: | |
if args.path == "-": | |
json_data = sys.stdin.read() | |
else: | |
json_data = Path(args.path).read_text() | |
except Exception as error: | |
error_console.print(f"Unable to read {args.path!r}; {error}") | |
sys.exit(-1) | |
console.print(JSON(json_data, indent=args.indent), soft_wrap=True) | |