Pretty print json or yaml with color in python

Overview

From the command line, pretty print json or yaml in color.

Also, some python objects (objects that have basestring, int, long, float, dict, list and \ _ \ _ dict \ _ \ _) can be displayed in color.

From the command line

# json
$ echo '{ "name": "pp.py", "list": [ 1, 2, 3, "Da!" ] }' | pp.py

#yaml
$ echo '{ name: pp.py, list: [ 1, 2, 3, Da! ] }' | pp.py

pp_cmdline.png

As a module

>>> import pp
>>> pp.pprint({ "name": "pp.py", "list": [ 1, 2, 3, "Da!" ] })
{
  list: [ 1, 2, 3, "Da!", ],
  name: "pp.py",
}

pp_module.png

Pprintf for logging

>>> import pp
>>> import logging
>>> logging.basicConfig()
>>> logging.warning( pp.pprintf( object ) )

pp_logging.png

Source

pp.py


#!/bin/env python
# -*- coding: utf-8 -*-

class color:
    BLUE = '\033[1;34m'
    BLUEL = '\033[0;34m'
    GREEN = '\033[1;32m'
    GREENL = '\033[0;32m'
    CYAN = '\033[1;36m'
    CYANL = '\033[0;36m'
    RED = '\033[1;31m'
    REDL = '\033[0;31m'
    PURPLE = '\033[1;35m'
    PURPLEL = '\033[0;35m'
    YELLOW = '\033[1;33m'
    BROWN = '\033[0;33m'
    WHITE = '\033[1;37m'
    GRAYL = '\033[0;37m'
    GRAYD = '\033[1;30m'
    BLACK = '\033[0;30m'
    ENDC = '\033[0m'

def pretty_convert(obj):
    if isinstance(obj, (float)):
        return u'{1}{2}{0}'.format(color.ENDC, color.PURPLEL, obj)
    elif isinstance(obj, ( bool )):
        return u'{1}{2}{0}'.format(color.ENDC, color.CYAN, obj)
    elif isinstance(obj, ( int, long, complex )):
        return u'{1}{2}{0}'.format(color.ENDC, color.BLUE, obj)
    elif isinstance(obj, ( unicode )):
        return u'{1}"{0}{2}{3}{0}{1}"{0}'.format(color.ENDC, color.REDL, color.RED, obj)
    elif isinstance(obj, ( str )):
        return u'{1}"{0}{2}{3}{0}{1}"{0}'.format(color.ENDC, color.REDL, color.RED, unicode(obj,'utf-8'))
    elif isinstance(obj, ( dict )):
        return dict((u'{1}{2}:{0}'.format(color.ENDC, color.YELLOW,k), pretty_convert(v)) for k, v in obj.items())
    elif isinstance(obj, (list, tuple)):
        return map(pretty_convert, obj)
    elif isinstance(obj, type(None)):
        return 'None'
    elif hasattr(obj, '__dict__') :
        return dict((u'{1}{2}:{0}'.format(color.ENDC, color.YELLOW,k), pretty_convert(v)) for k, v in obj.__dict__.items())
    else:
        return '<pp: cannot decode>'

def walk_obj(buf, obj, indent_num=2, depth=0, eol='', wrap_len=60, wrap_total=100, lf='\n'):
    indent = ' '*indent_num*depth
    buf.write(u'{0}'.format(eol if not eol else eol+indent) )
    if isinstance(obj, (basestring, int, float, complex)):
        buf.write(u'{0}'.format(obj).replace(lf, '{0}{1} '.format(lf, indent)) )
    elif isinstance(obj, ( dict )):
        if not obj:
            buf.write('{}')
            return
        eol, eol_org = lf, eol
        buf.write('{ ')
        for key in sorted(obj.keys()):
            buf.write(u'{0}{1}{2}{3} '.format(eol, indent, ' '*indent_num, key))
            walk_obj(buf=buf, obj=obj[key], indent_num=indent_num, depth=depth+1, eol='', wrap_len=wrap_len, lf=lf )
            buf.write(',')
        buf.write('{0}}}'.format(eol if not eol else eol+indent) )
        eol=eol_org
    elif isinstance(obj, (list, tuple)):
        if not obj:
            buf.write('[]')
            return
        eol_org, indent_org = eol, indent
        for item in obj:
            if isinstance(item, (list, dict)):
                eol = lf
                break
            else:
                eol = ''
                indent = ''
                continue
        if max(map(len,obj if obj else " " )) > wrap_len or sum(map(len,obj)) > wrap_total:
            eol = lf
        buf.write('[ ')
        for item in obj:
            walk_obj(buf=buf, obj=item, indent_num=indent_num, depth=depth+1, eol=eol, wrap_len=wrap_len, lf=lf )
            buf.write(', ')
        buf.write('{0}]'.format(eol if not eol else eol+indent_org) )
        eol, indent = eol_org, indent_org

def pprint(obj, indent=2, b=None, lf='\n'):
    if not b:
        import sys, codecs
        b = codecs.getwriter('utf_8')(sys.stdout)
    walk_obj(b, pretty_convert(obj), indent_num=indent)
    b.write(lf)

def pprintf(obj, indent=2):
    from StringIO import StringIO
    buf=StringIO()
    walk_obj(buf, pretty_convert(obj), indent_num=indent)
    return buf.getvalue()


if __name__ == '__main__':
  import sys
  import codecs
  import json

  if len(sys.argv) < 2:
     raw_data = codecs.getreader('utf_8')(sys.stdin).read()
  else:
     raw_data = codecs.open(sys.argv[1], 'r', 'utf_8').read()

  indent = 2 if len(sys.argv) <3 else int(sys.argv[2])

  parsed_data = None
  try:
      parsed_data = json.loads(raw_data)
  except ValueError as e1:
      #print e1
      try:
          import yaml
          parsed_data = yaml.load(raw_data)
      except yaml.scanner.ScannerError as e2:
          #print e2
          pass
  if not parsed_data:
      sys.exit(2)

  pprint(parsed_data, indent)
  b = codecs.getwriter('utf_8')(sys.stdout)

https://github.com/aminamid/pp

Recommended Posts

Pretty print json or yaml with color in python
Output color characters to pretty with python
Handling yaml with python
[Python] Use JSON with Python
Handling json in python
Think yaml with python
Output log in JSON format with Python standard logging
Mutual conversion between JSON and YAML / TOML in Python
Get in touch with functional programming in JavaScript or Python 3
Auto-complete YAML content with Python
Easily format JSON in Python
Scraping with selenium in Python
Working with LibreOffice in Python
POST json with Python3 script
Debugging with pdb in Python
Working with sounds in Python
Scraping with Tor in Python
Tweet with image in Python
Combined with permutations in Python
Format json with Vim (with python)
Read json data with python
Number recognition in images with Python
How to not escape Japanese when dealing with json in python
Testing with random numbers in Python
GOTO in Python with Sublime Text 3
Write JSON Schema in Python DSL
Working with LibreOffice in Python: import
Scraping with Selenium in Python (Basic)
CSS parsing with cssutils in Python
Run mruby with Python or Blender
Numer0n with items made in Python
Dynamically load json type in python
Handling of JSON files in Python
JSON encoding and decoding with python
Use rospy with virtualenv in Python3
Use Python in pyenv with NeoVim
[Python3] Save the mean and covariance matrix in json with pandas
Heatmap with Dendrogram in Python + matplotlib
Read files in parallel with Python
Password generation in texto with python
Use OpenCV with Python 3 in Window
Until dealing with python in Atom
Get started with Python in Blender
Working with DICOM images in Python
[Python] Specify dynamically changing attributes in Selenium with XPATH (or CSS selector)
Write documentation in Sphinx with Python Livereload
Get additional data in LDAP with python
Spiral book in Python! Python with a spiral book! (Chapter 14 ~)
Try to reproduce color film with Python
Use print in a Python2 lambda expression
Try logging in to qiita with Python
Stress Test with Locust written in Python
Python3> in keyword> True with partial match?
Exclusive control with lock file in Python
Device monitoring with On-box Python in IOS-XE
Try working with binary data in Python
Express Python yield in JavaScript or Java
Draw Nozomi Sasaki in Excel with python
OR the List in Python (zip function)
Tips for dealing with binaries in Python
Display Python 3 in the browser with MAMP