diff --git a/python/cli/table.py b/python/cli/table.py
new file mode 100644
index 0000000..7e6a4d8
--- /dev/null
+++ b/python/cli/table.py
@@ -0,0 +1,204 @@
+#
+# Copyright 2016 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import sys
+
+from google.protobuf.message import Message
+from termcolor import colored
+
+_printfn = lambda l: sys.stdout.write(l + '\n')
+
+
+class TablePrinter(object):
+    """Simple tabular data printer utility. For usage, see bottom of file"""
+
+    def __init__(self):
+        self.max_field_lengths = {}
+        self.field_names = {}
+        self.cell_values = {}
+
+    def add_cell(self, row_number, field_key, field_name, value):
+        if not isinstance(value, str):
+            value = str(value)
+        self._add_field_type(field_key, field_name)
+        row = self.cell_values.setdefault(row_number, {})
+        row[field_key] = value
+        self._update_max_length(field_key, value)
+
+    def number_of_rows(self):
+        return len(self.cell_values)
+
+    def print_table(self, header=None, printfn=_printfn, dividers=10):
+
+        if header is not None:
+            printfn(header)
+
+        field_keys = sorted(self.field_names.keys())
+
+        if not field_keys:
+            printfn('table empty')
+            return
+
+        def p_sep():
+            printfn('+' + '+'.join(
+                [(self.max_field_lengths[k] + 2) * '-'
+                 for k in field_keys]) + '+')
+
+        p_sep()
+
+        printfn('| ' + ' | '.join(
+            '%%%ds' % self.max_field_lengths[k] % self.field_names[k]
+            for k in field_keys) + ' |')
+        p_sep()
+
+        for i in range(len(self.cell_values)):
+            row = self.cell_values[i]
+            printfn(colored('| ' + ' | '.join(
+                '%%%ds' % self.max_field_lengths[k] % row.get(k, '')
+                for k in field_keys
+            ) + ' |'))
+            if not ((i + 1) % dividers):
+                p_sep()
+
+        if (i + 1) % dividers:
+            p_sep()
+
+    def _update_max_length(self, field_key, string):
+        length = len(string)
+        if length > self.max_field_lengths.get(field_key, 0):
+            self.max_field_lengths[field_key] = length
+
+    def _add_field_type(self, field_key, field_name):
+        if field_key not in self.field_names:
+            self.field_names[field_key] = field_name
+            self._update_max_length(field_key, field_name)
+        else:
+            assert self.field_names[field_key] == field_name
+
+
+def print_pb_list_as_table(header, items, fields_to_omit=None,
+                           printfn=_printfn, dividers=10, show_nulls=False,
+                           presfns={}):
+    from utils import pb2dict
+
+    t = TablePrinter()
+    for row, obj in enumerate(items):
+        assert isinstance(obj, Message)
+
+        def set_row(pd_dict, _row, field, value, t, prefix,
+                      fields_to_omit, number):
+            fname = prefix + field.name
+            if fname in fields_to_omit:
+                return
+            if isinstance(value, Message):
+                add(_row, value, fname + '.',
+                    100 * (number + field.number))
+            else:
+                presentationfn = presfns[fname] if fname in presfns else lambda x: x
+                t.add_cell(_row, number + field.number, fname,
+                           presentationfn(pd_dict.get(field.name)))
+
+        def add(_row, pb, prefix='', number=0):
+            d = pb2dict(pb)
+            if show_nulls:
+                fields = pb.DESCRIPTOR.fields
+                for field in fields:
+                    set_row(d,
+                            _row,
+                            field,
+                            getattr(pb, field.name),
+                            t,
+                            prefix,
+                            fields_to_omit,
+                            number)
+            else:
+                fields = pb.ListFields()
+                for (field, value) in fields:
+                    set_row(d,
+                            _row,
+                            field,
+                            value,
+                            t,
+                            prefix,
+                            fields_to_omit,
+                            number)
+        add(row, obj)
+
+    t.print_table(header, printfn, dividers)
+
+
+def print_pb_as_table(header, pb, fields_to_omit={}, printfn=_printfn,
+                      show_nulls=False):
+
+    from utils import pb2dict
+
+    def is_repeated_item(msg):
+        return hasattr(msg, "extend")
+
+    def set_cell(pb, field, value, t, prefix, fields_to_omit):
+        d = pb2dict(pb)
+        fname = prefix + field.name
+
+        if fname in fields_to_omit:
+            return
+        if isinstance(value, Message):
+            pr(value, fname + '.')
+        elif is_repeated_item(value): # handles any list
+            row = t.number_of_rows()
+            t.add_cell(row, 0, 'field', fname)
+            t.add_cell(row, 1, 'value',
+                       '{} item(s)'.format(len(d.get(field.name))))
+        else:
+            row = t.number_of_rows()
+            t.add_cell(row, 0, 'field', fname)
+            t.add_cell(row, 1, 'value', value)
+
+
+    t = TablePrinter()
+
+    def pr(_pb, prefix=''):
+        if show_nulls:
+            fields = _pb.DESCRIPTOR.fields
+            for field in sorted(fields, key=lambda f: f.number):
+                set_cell(_pb,
+                        field,
+                        getattr(_pb, field.name),
+                        t,
+                        prefix,
+                        fields_to_omit)
+        else:
+            fields = _pb.ListFields()
+            for (field, value) in sorted(fields, key=lambda (f, v): f.number):
+                set_cell(_pb,
+                        field,
+                        value,
+                        t,
+                        prefix,
+                        fields_to_omit)
+
+    pr(pb)
+
+    t.print_table(header, printfn)
+
+
+if __name__ == '__main__':
+    import random
+
+    t = TablePrinter()
+    for row in range(10):
+        t.add_cell(row, 0, 'id', row + 100)
+        t.add_cell(row, 1, 'name', 'Joe Somebody')
+        t.add_cell(row, 2, 'ows', '${}'.format(random.randint(10, 100000)))
+    t.print_table()
