python (3.11.7)
       1  from pathlib import Path
       2  from json import loads, dumps
       3  from typing import Any, Callable, Optional, Union
       4  
       5  from .text import Text
       6  from .highlighter import JSONHighlighter, NullHighlighter
       7  
       8  
       9  class ESC[4;38;5;81mJSON:
      10      """A renderable which pretty prints JSON.
      11  
      12      Args:
      13          json (str): JSON encoded data.
      14          indent (Union[None, int, str], optional): Number of characters to indent by. Defaults to 2.
      15          highlight (bool, optional): Enable highlighting. Defaults to True.
      16          skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False.
      17          ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False.
      18          check_circular (bool, optional): Check for circular references. Defaults to True.
      19          allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True.
      20          default (Callable, optional): A callable that converts values that can not be encoded
      21              in to something that can be JSON encoded. Defaults to None.
      22          sort_keys (bool, optional): Sort dictionary keys. Defaults to False.
      23      """
      24  
      25      def __init__(
      26          self,
      27          json: str,
      28          indent: Union[None, int, str] = 2,
      29          highlight: bool = True,
      30          skip_keys: bool = False,
      31          ensure_ascii: bool = False,
      32          check_circular: bool = True,
      33          allow_nan: bool = True,
      34          default: Optional[Callable[[Any], Any]] = None,
      35          sort_keys: bool = False,
      36      ) -> None:
      37          data = loads(json)
      38          json = dumps(
      39              data,
      40              indent=indent,
      41              skipkeys=skip_keys,
      42              ensure_ascii=ensure_ascii,
      43              check_circular=check_circular,
      44              allow_nan=allow_nan,
      45              default=default,
      46              sort_keys=sort_keys,
      47          )
      48          highlighter = JSONHighlighter() if highlight else NullHighlighter()
      49          self.text = highlighter(json)
      50          self.text.no_wrap = True
      51          self.text.overflow = None
      52  
      53      @classmethod
      54      def from_data(
      55          cls,
      56          data: Any,
      57          indent: Union[None, int, str] = 2,
      58          highlight: bool = True,
      59          skip_keys: bool = False,
      60          ensure_ascii: bool = False,
      61          check_circular: bool = True,
      62          allow_nan: bool = True,
      63          default: Optional[Callable[[Any], Any]] = None,
      64          sort_keys: bool = False,
      65      ) -> "JSON":
      66          """Encodes a JSON object from arbitrary data.
      67  
      68          Args:
      69              data (Any): An object that may be encoded in to JSON
      70              indent (Union[None, int, str], optional): Number of characters to indent by. Defaults to 2.
      71              highlight (bool, optional): Enable highlighting. Defaults to True.
      72              default (Callable, optional): Optional callable which will be called for objects that cannot be serialized. Defaults to None.
      73              skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False.
      74              ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False.
      75              check_circular (bool, optional): Check for circular references. Defaults to True.
      76              allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True.
      77              default (Callable, optional): A callable that converts values that can not be encoded
      78                  in to something that can be JSON encoded. Defaults to None.
      79              sort_keys (bool, optional): Sort dictionary keys. Defaults to False.
      80  
      81          Returns:
      82              JSON: New JSON object from the given data.
      83          """
      84          json_instance: "JSON" = cls.__new__(cls)
      85          json = dumps(
      86              data,
      87              indent=indent,
      88              skipkeys=skip_keys,
      89              ensure_ascii=ensure_ascii,
      90              check_circular=check_circular,
      91              allow_nan=allow_nan,
      92              default=default,
      93              sort_keys=sort_keys,
      94          )
      95          highlighter = JSONHighlighter() if highlight else NullHighlighter()
      96          json_instance.text = highlighter(json)
      97          json_instance.text.no_wrap = True
      98          json_instance.text.overflow = None
      99          return json_instance
     100  
     101      def __rich__(self) -> Text:
     102          return self.text
     103  
     104  
     105  if __name__ == "__main__":
     106  
     107      import argparse
     108      import sys
     109  
     110      parser = argparse.ArgumentParser(description="Pretty print json")
     111      parser.add_argument(
     112          "path",
     113          metavar="PATH",
     114          help="path to file, or - for stdin",
     115      )
     116      parser.add_argument(
     117          "-i",
     118          "--indent",
     119          metavar="SPACES",
     120          type=int,
     121          help="Number of spaces in an indent",
     122          default=2,
     123      )
     124      args = parser.parse_args()
     125  
     126      from pip._vendor.rich.console import Console
     127  
     128      console = Console()
     129      error_console = Console(stderr=True)
     130  
     131      try:
     132          if args.path == "-":
     133              json_data = sys.stdin.read()
     134          else:
     135              json_data = Path(args.path).read_text()
     136      except Exception as error:
     137          error_console.print(f"Unable to read {args.path!r}; {error}")
     138          sys.exit(-1)
     139  
     140      console.print(JSON(json_data, indent=args.indent), soft_wrap=True)