mirror of
https://github.com/Textualize/rich.git
synced 2025-08-04 10:08:40 +00:00
added print_json
This commit is contained in:
parent
69ea180f75
commit
6e76b2216f
11 changed files with 159 additions and 2 deletions
|
@ -5,12 +5,17 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
## [10.8.0] - 2020-08-28
|
||||
|
||||
### Added
|
||||
|
||||
- Added Panel.subtitle
|
||||
- Added Panel.subtitle_align
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug where calling `rich.reconfigure` within a `pytest_configure` hook would lead to a crash
|
||||
- Fixed highlight not being passed through options https://github.com/willmcgugan/rich/issues/1404
|
||||
|
||||
## [10.7.0] - 2021-08-05
|
||||
|
||||
|
|
|
@ -69,6 +69,24 @@ The :meth:`~rich.console.Console.log` methods offers the same capabilities as pr
|
|||
|
||||
To help with debugging, the log() method has a ``log_locals`` parameter. If you set this to ``True``, Rich will display a table of local variables where the method was called.
|
||||
|
||||
|
||||
Printing JSON
|
||||
-------------
|
||||
|
||||
The :meth:`~rich.console.Console.print_json` method will pretty print (format and style) a string containing JSON. Here's a short example::
|
||||
|
||||
console.print_json('[false, true, null, "foo"]')
|
||||
|
||||
You can also *log* json by printing a :class:`~rich.json.JSON` object::
|
||||
|
||||
from rich.json import JSON
|
||||
console.print_json(JSON('["foo", "bar"]'))
|
||||
|
||||
Because printing JSON is a common requirement, you may import ``print_json`` from the main namespace::
|
||||
|
||||
from rich import print_json
|
||||
|
||||
|
||||
Low level output
|
||||
----------------
|
||||
|
||||
|
@ -78,6 +96,7 @@ Here's an example::
|
|||
|
||||
>>> console.out("Locals", locals())
|
||||
|
||||
|
||||
Rules
|
||||
-----
|
||||
|
||||
|
|
7
docs/source/reference/json.rst
Normal file
7
docs/source/reference/json.rst
Normal file
|
@ -0,0 +1,7 @@
|
|||
rich.json
|
||||
=========
|
||||
|
||||
.. automodule:: rich.json
|
||||
:members:
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
name = "rich"
|
||||
homepage = "https://github.com/willmcgugan/rich"
|
||||
documentation = "https://rich.readthedocs.io/en/latest/"
|
||||
version = "10.7.0"
|
||||
version = "10.8.0"
|
||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||
authors = ["Will McGugan <willmcgugan@gmail.com>"]
|
||||
license = "MIT"
|
||||
|
|
|
@ -69,6 +69,17 @@ def print(
|
|||
return write_console.print(*objects, sep=sep, end=end)
|
||||
|
||||
|
||||
def print_json(json: str, indent: int = 4, highlight: bool = True) -> None:
|
||||
"""Pretty prints JSON. Output will be valid JSON.
|
||||
|
||||
Args:
|
||||
json (str): A string containing JSON.
|
||||
indent (int, optional): Number of spaces to indent. Defaults to 4.
|
||||
"""
|
||||
|
||||
get_console().print_json(json, indent=indent, highlight=highlight)
|
||||
|
||||
|
||||
def inspect(
|
||||
obj: Any,
|
||||
*,
|
||||
|
|
|
@ -1583,6 +1583,7 @@ class Console:
|
|||
height=height,
|
||||
no_wrap=no_wrap,
|
||||
markup=markup,
|
||||
highlight=highlight,
|
||||
)
|
||||
|
||||
new_segments: List[Segment] = []
|
||||
|
@ -1613,6 +1614,17 @@ class Console:
|
|||
else:
|
||||
self._buffer.extend(new_segments)
|
||||
|
||||
def print_json(self, json:str, indent:int=4, highlight:bool=True) -> None:
|
||||
"""Pretty prints JSON. Output will be valid JSON.
|
||||
|
||||
Args:
|
||||
json (str): A string containing JSON.
|
||||
indent (int, optional): Number of spaces to indent. Defaults to 4.
|
||||
"""
|
||||
from rich.json import JSON
|
||||
json_renderable = JSON(json, indent=indent, highlight=highlight)
|
||||
self.print(json_renderable)
|
||||
|
||||
def update_screen(
|
||||
self,
|
||||
renderable: RenderableType,
|
||||
|
|
|
@ -88,6 +88,12 @@ DEFAULT_STYLES: Dict[str, Style] = {
|
|||
"repr.filename": Style(color="bright_magenta"),
|
||||
"rule.line": Style(color="bright_green"),
|
||||
"rule.text": Style.null(),
|
||||
"json.brace": Style(bold=True),
|
||||
"json.bool_true": Style(color="bright_green", italic=True),
|
||||
"json.bool_false": Style(color="bright_red", italic=True),
|
||||
"json.null": Style(color="magenta", italic=True),
|
||||
"json.number": Style(color="cyan", bold=True, italic=False),
|
||||
"json.str": Style(color="green", italic=False, bold=False),
|
||||
"prompt": Style.null(),
|
||||
"prompt.choices": Style(color="magenta", bold=True),
|
||||
"prompt.default": Style(color="cyan", bold=True),
|
||||
|
|
|
@ -101,6 +101,20 @@ class ReprHighlighter(RegexHighlighter):
|
|||
]
|
||||
|
||||
|
||||
class JSONHighlighter(RegexHighlighter):
|
||||
"""Highlights JSON"""
|
||||
|
||||
base_style = "json."
|
||||
highlights = [
|
||||
_combine_regex(
|
||||
r"(?P<brace>[\{\[\(\)\]\}])",
|
||||
r"\b(?P<bool_true>true)\b|\b(?P<bool_false>false)\b|\b(?P<null>null)\b",
|
||||
r"(?P<number>(?<!\w)\-?[0-9]+\.?[0-9]*(e[\-\+]?\d+?)?\b|0x[0-9a-fA-F]*)",
|
||||
r"(?<![\\\w])(?P<str>b?\".*?(?<!\\)\")",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
from .console import Console
|
||||
|
||||
|
|
64
rich/json.py
Normal file
64
rich/json.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
from json import loads, dumps
|
||||
|
||||
from .text import Text
|
||||
from .highlighter import JSONHighlighter, NullHighlighter
|
||||
|
||||
|
||||
class JSON:
|
||||
"""A rebderable which pretty prints JSON.
|
||||
|
||||
Args:
|
||||
json (str): JSON encoded data.
|
||||
indent (int, optional): Number of characters to indent by. Defaults to True.
|
||||
highlight (bool, optional): Enable highlighting. Defaults to True.
|
||||
"""
|
||||
|
||||
def __init__(self, json: str, indent: int = 4, highlight: bool = True) -> None:
|
||||
data = loads(json)
|
||||
json = dumps(data, indent=indent)
|
||||
highlighter = JSONHighlighter() if highlight else NullHighlighter()
|
||||
self.text = highlighter(json)
|
||||
self.text.no_wrap = True
|
||||
self.text.overflow = None
|
||||
|
||||
def __rich__(self) -> Text:
|
||||
return self.text
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
j = """
|
||||
{ "atomic": [false, true, null],
|
||||
"widget": {
|
||||
"debug": true,
|
||||
"window": {
|
||||
"title": "Sample Konfabulator Widget",
|
||||
"name": "main_window",
|
||||
"width": 500,
|
||||
"height": 500
|
||||
},
|
||||
"image": {
|
||||
"src": "Images/Sun.png",
|
||||
"name": "sun1",
|
||||
"hOffset": 250,
|
||||
"vOffset": 250,
|
||||
"alignment": "center"
|
||||
},
|
||||
"text": {
|
||||
"data": "Click Here",
|
||||
"size": 36,
|
||||
"style": "bold",
|
||||
"name": "text1",
|
||||
"hOffset": 250,
|
||||
"vOffset": 100,
|
||||
"alignment": "center",
|
||||
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
|
||||
}
|
||||
}}
|
||||
"""
|
||||
from rich.console import Console
|
||||
|
||||
console = Console()
|
||||
|
||||
print(dumps(loads(j)))
|
||||
|
||||
console.print(JSON(j), soft_wrap=True)
|
|
@ -117,6 +117,15 @@ def test_print():
|
|||
assert console.file.getvalue() == "foo\n"
|
||||
|
||||
|
||||
def test_print_json():
|
||||
console = Console(file=io.StringIO(), color_system="truecolor")
|
||||
console.print_json('[false, true, null, "foo"]')
|
||||
result = console.file.getvalue()
|
||||
print(repr(result))
|
||||
expected = '\x1b[1m[\x1b[0m\n \x1b[3;91mfalse\x1b[0m,\n \x1b[3;92mtrue\x1b[0m,\n \x1b[3;35mnull\x1b[0m,\n \x1b[32m"foo"\x1b[0m\n\x1b[1m]\x1b[0m\n'
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_log():
|
||||
console = Console(
|
||||
file=io.StringIO(),
|
||||
|
|
|
@ -28,6 +28,16 @@ def test_rich_print():
|
|||
console.file = backup_file
|
||||
|
||||
|
||||
def test_rich_print_json():
|
||||
console = rich.get_console()
|
||||
with console.capture() as capture:
|
||||
rich.print_json('[false, true, null, "foo"]')
|
||||
result = capture.get()
|
||||
print(repr(result))
|
||||
expected = '[\n false,\n true,\n null,\n "foo"\n]\n'
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_rich_print_X():
|
||||
console = rich.get_console()
|
||||
output = io.StringIO()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue