def dump_metadata(filename, show_row_group_metadata, out=sys.stdout):
    """Dump metadata about the parquet object with the given filename.

    Dump human-readable metadata to specified `out`. Optionally dump the row group metadata as well.
    """
    def println(value):
        """Write a new line containing `value` to `out`."""
        out.write(value + "\n")
    footer = read_footer(filename)
    println("File Metadata: {0}".format(filename))
    println("  Version: {0}".format(footer.version))
    println("  Num Rows: {0}".format(footer.num_rows))
    println("  k/v metadata: ")
    if footer.key_value_metadata:
        for item in footer.key_value_metadata:
            println("    {0}={1}".format(item.key, item.value))
    else:
        println("    (none)")
    println("  schema: ")
    for element in footer.schema:
        println("    {name} ({type}): length={type_length}, "
                "repetition={repetition_type}, "
                "children={num_children}, "
                "converted_type={converted_type}".format(
                    name=element.name,
                    type=parquet_thrift.Type._VALUES_TO_NAMES[element.type]  # pylint: disable=protected-access
                    if element.type else None,
                    type_length=element.type_length,
                    repetition_type=_get_name(parquet_thrift.FieldRepetitionType,
                                              element.repetition_type),
                    num_children=element.num_children,
                    converted_type=element.converted_type))
    if show_row_group_metadata:
        println("  row groups: ")
        for row_group in footer.row_groups:
            num_rows = row_group.num_rows
            size_bytes = row_group.total_byte_size
            println(
                "  rows={num_rows}, bytes={bytes}".format(num_rows=num_rows,
                                                          bytes=size_bytes))
            println("    chunks:")
            for col_group in row_group.columns:
                cmd = col_group.meta_data
                println("      type={type} file_offset={offset} "
                        "compression={codec} "
                        "encodings={encodings} path_in_schema={path_in_schema} "
                        "num_values={num_values} uncompressed_bytes={raw_bytes} "
                        "compressed_bytes={compressed_bytes} "
                        "data_page_offset={data_page_offset} "
                        "dictionary_page_offset={dictionary_page_offset}".format(
                            type=_get_name(parquet_thrift.Type, cmd.type),
                            offset=col_group.file_offset,
                            codec=_get_name(parquet_thrift.CompressionCodec, cmd.codec),
                            encodings=",".join(
                                [_get_name(
                                    parquet_thrift.Encoding, s) for s in cmd.encodings]),
                            path_in_schema=cmd.path_in_schema,
                            num_values=cmd.num_values,
                            raw_bytes=cmd.total_uncompressed_size,
                            compressed_bytes=cmd.total_compressed_size,
                            data_page_offset=cmd.data_page_offset,
                            dictionary_page_offset=cmd.dictionary_page_offset))
                with open(filename, 'rb') as file_obj:
                    offset = _get_offset(cmd)
                    file_obj.seek(offset, 0)
                    values_read = 0
                    println("      pages: ")
                    while values_read < num_rows:
                        page_header = _read_page_header(file_obj)
                        # seek past current page.
                        file_obj.seek(page_header.compressed_page_size, 1)
                        daph = page_header.data_page_header
                        type_ = _get_name(parquet_thrift.PageType, page_header.type)
                        raw_bytes = page_header.uncompressed_page_size
                        num_values = None
                        if page_header.type == parquet_thrift.PageType.DATA_PAGE:
                            num_values = daph.num_values
                            values_read += num_values
                        if page_header.type == parquet_thrift.PageType.DICTIONARY_PAGE:
                            pass

                        encoding_type = None
                        def_level_encoding = None
                        rep_level_encoding = None
                        if daph:
                            encoding_type = _get_name(parquet_thrift.Encoding, daph.encoding)
                            def_level_encoding = _get_name(
                                parquet_thrift.Encoding, daph.definition_level_encoding)
                            rep_level_encoding = _get_name(
                                parquet_thrift.Encoding, daph.repetition_level_encoding)

                        println("        page header: type={type} "
                                "uncompressed_size={raw_bytes} "
                                "num_values={num_values} encoding={encoding} "
                                "def_level_encoding={def_level_encoding} "
                                "rep_level_encoding={rep_level_encoding}".format(
                                    type=type_,
                                    raw_bytes=raw_bytes,
                                    num_values=num_values,
                                    encoding=encoding_type,
                                    def_level_encoding=def_level_encoding,
                                    rep_level_encoding=rep_level_encoding))
Dump metadata about the parquet object with the given filename.

    Dump human-readable metadata to specified `out`. Optionally dump the row group metadata as well.