Reputation: 5287
I'm looking to print JSON to the command line, in python, with ASCII colors. For example, the (excellent) jq
utility will color-ify JSON using bold ASCII colors like so:
curl --silent http://coinabul.com/api.php | jq .
Does anyone know how to accomplish this effect from Python? A couple of SO questions provide some good information on using ASCII colors from python (e.g. Print in terminal with colors using Python?), but this effect requires combining the pretty-printing machinery with the colorify-ing machinery in a different way, I think.
Upvotes: 17
Views: 14236
Reputation: 1456
Use https://github.com/willmcgugan/rich
from rich.console import Console
from rich.theme import Theme
from rich.highlighter import RegexHighlighter, _combine_regex
my_theme = Theme(
{
"repr.str": "bright_blue",
"repr.value_str": "green",
}
)
class ReprHighlighter(RegexHighlighter):
"""Highlights the text typically produced from ``__repr__`` methods."""
base_style = "repr."
highlights = [
r"(?P<tag_start>\<)(?P<tag_name>[\w\-\.\:]*)(?P<tag_contents>[\w\W]*?)(?P<tag_end>\>)",
r"(?P<attrib_name>[\w_]{1,50})=(?P<attrib_value>\"?[\w_]+\"?)?",
r"(?P<brace>[\{\[\(\)\]\}])",
_combine_regex(
r"(?P<ipv4>[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})",
r"(?P<ipv6>([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})",
r"(?P<eui64>(?:[0-9A-Fa-f]{1,2}-){7}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{1,2}:){7}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{4}\.){3}[0-9A-Fa-f]{4})",
r"(?P<eui48>(?:[0-9A-Fa-f]{1,2}-){5}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{1,2}:){5}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})",
r"(?P<call>[\w\.]*?)\(",
r"\b(?P<bool_true>True)\b|\b(?P<bool_false>False)\b|\b(?P<none>None)\b",
r"(?P<ellipsis>\.\.\.)",
r"(?P<number>(?<!\w)\-?[0-9]+\.?[0-9]*(e[\-\+]?\d+?)?\b|0x[0-9a-fA-F]*)",
r"(?P<path>\B(\/[\w\.\-\_\+]+)*\/)(?P<filename>[\w\.\-\_\+]*)?",
r":(?<![\\\w]) (?P<value_str>b?\'\'\'.*?(?<!\\)\'\'\'|b?\'.*?(?<!\\)\'|b?\"\"\".*?(?<!\\)\"\"\"|b?\".*?(?<!\\)\")",
r"(?<![\\\w])(?P<str>b?\'\'\'.*?(?<!\\)\'\'\'|b?\'.*?(?<!\\)\'|b?\"\"\".*?(?<!\\)\"\"\"|b?\".*?(?<!\\)\")",
r"(?P<uuid>[a-fA-F0-9]{8}\-[a-fA-F0-9]{4}\-[a-fA-F0-9]{4}\-[a-fA-F0-9]{4}\-[a-fA-F0-9]{12})",
r"(?P<url>(https|http|ws|wss):\/\/[0-9a-zA-Z\$\-\_\+\!`\(\)\,\.\?\/\;\:\&\=\%\#]*)",
),
]
console = Console(theme=my_theme, highlighter=ReprHighlighter())
json_str = json.dumps(json_object, indent=4, sort_keys=True)
console.print(json_str)
only value_str
was added into ReprHighlighter
Upvotes: 3
Reputation: 2791
Use Pygments library:
import json
from pygments import highlight
from pygments.lexers import JsonLexer
from pygments.formatters import TerminalFormatter
json_object = json.loads('{"foo":"bar"}')
json_str = json.dumps(json_object, indent=4, sort_keys=True)
print(highlight(json_str, JsonLexer(), TerminalFormatter()))
Upvotes: 34
Reputation: 249582
This should get you started (it prints keys in blue):
import json
import urllib2
# ANSI color terminal escape sequences
OKBLUE = '\033[94m'
ENDC = '\033[0m'
def pretty(keyvals, indent=''):
print '{'
for key, val in keyvals.iteritems():
print '{} {}"{}"{}:'.format(indent, OKBLUE, key, ENDC),
if isinstance(val, dict):
pretty(val, indent + ' ')
elif isinstance(val, str):
print '"{}",'.format(val)
else:
print '{},'.format(val)
print indent + '},'
req = urllib2.Request('http://coinabul.com/api.php', headers={
'User-Agent': 'Mozilla/5.0',
})
page = urllib2.urlopen(req)
parsed = json.load(page)
pretty(parsed)
Upvotes: 2