123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- 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 = True,
- 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
- @classmethod
- def from_data(
- cls,
- data: Any,
- indent: Union[None, int, str] = 2,
- highlight: bool = True,
- skip_keys: bool = False,
- ensure_ascii: bool = True,
- 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:
- with open(args.path, "rt") as json_file:
- json_data = json_file.read()
- 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)
|