Skip to content

Commit

Permalink
tabulate: replace tabulate with rich.table
Browse files Browse the repository at this point in the history
  • Loading branch information
fariss committed Sep 24, 2024
1 parent 8252653 commit 3eb0d89
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 43 deletions.
45 changes: 33 additions & 12 deletions capa/render/verbose.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@

from typing import cast

import tabulate
from rich.text import Text
from rich.console import Console
from rich.table import Table

import capa.rules
import capa.helpers
Expand All @@ -36,6 +35,7 @@
import capa.render.result_document as rd
from capa.rules import RuleSet
from capa.engine import MatchResults
from capa.render.utils import Console


def format_address(address: frz.Address) -> str:
Expand Down Expand Up @@ -163,12 +163,16 @@ def render_static_meta(console: Console, meta: rd.StaticMetadata):
total feature count 1918
"""

grid = Table.grid(padding=(0, 2))
grid.add_column(style="dim")
grid.add_column()

rows = [
("md5", meta.sample.md5),
("sha1", meta.sample.sha1),
("sha256", meta.sample.sha256),
("path", meta.sample.path),
("timestamp", meta.timestamp),
("timestamp", str(meta.timestamp)),
("capa version", meta.version),
("os", meta.analysis.os),
("format", meta.analysis.format),
Expand All @@ -177,15 +181,18 @@ def render_static_meta(console: Console, meta: rd.StaticMetadata):
("extractor", meta.analysis.extractor),
("base address", format_address(meta.analysis.base_address)),
("rules", "\n".join(meta.analysis.rules)),
("function count", len(meta.analysis.feature_counts.functions)),
("library function count", len(meta.analysis.library_functions)),
("function count", str(len(meta.analysis.feature_counts.functions))),
("library function count", str(len(meta.analysis.library_functions))),
(
"total feature count",
meta.analysis.feature_counts.file + sum(f.count for f in meta.analysis.feature_counts.functions),
str(meta.analysis.feature_counts.file + sum(f.count for f in meta.analysis.feature_counts.functions)),
),
]

console.print(tabulate.tabulate(rows, tablefmt="plain"))
for row in rows:
grid.add_row(*row)

console.print(grid)


def render_dynamic_meta(console: Console, meta: rd.DynamicMetadata):
Expand All @@ -207,27 +214,34 @@ def render_dynamic_meta(console: Console, meta: rd.DynamicMetadata):
total feature count 1918
"""

table = Table.grid(padding=(0, 2))
table.add_column(style="dim")
table.add_column()

rows = [
("md5", meta.sample.md5),
("sha1", meta.sample.sha1),
("sha256", meta.sample.sha256),
("path", meta.sample.path),
("timestamp", meta.timestamp),
("timestamp", str(meta.timestamp)),
("capa version", meta.version),
("os", meta.analysis.os),
("format", meta.analysis.format),
("arch", meta.analysis.arch),
("analysis", meta.flavor.value),
("extractor", meta.analysis.extractor),
("rules", "\n".join(meta.analysis.rules)),
("process count", len(meta.analysis.feature_counts.processes)),
("process count", str(len(meta.analysis.feature_counts.processes))),
(
"total feature count",
meta.analysis.feature_counts.file + sum(p.count for p in meta.analysis.feature_counts.processes),
str(meta.analysis.feature_counts.file + sum(p.count for p in meta.analysis.feature_counts.processes)),
),
]

console.print(tabulate.tabulate(rows, tablefmt="plain"))
for row in rows:
table.add_row(*row)

console.print(table)


def render_meta(console: Console, doc: rd.ResultDocument):
Expand Down Expand Up @@ -261,6 +275,10 @@ def render_rules(console: Console, doc: rd.ResultDocument):
console.print(capability)
had_match = True

table = Table.grid(padding=(0, 2))
table.add_column(style="dim")
table.add_column()

rows = []

ns = rule.meta.namespace
Expand Down Expand Up @@ -312,7 +330,10 @@ def render_rules(console: Console, doc: rd.ResultDocument):

rows.append(("matches", "\n".join(lines)))

console.print(tabulate.tabulate(rows, tablefmt="plain"))
for row in rows:
table.add_row(*row)

console.print(table)
console.print()

if not had_match:
Expand Down
11 changes: 9 additions & 2 deletions capa/render/vverbose.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import textwrap
from typing import Dict, Iterable, Optional

import tabulate
from rich.text import Text
from rich.table import Table

import capa.rules
import capa.helpers
Expand Down Expand Up @@ -403,7 +403,14 @@ def render_rules(console: Console, doc: rd.ResultDocument):
if rule.meta.description:
rows.append(("description", rule.meta.description))

console.writeln(tabulate.tabulate(rows, tablefmt="plain"))
grid = Table.grid(padding=(0, 2))
grid.add_column(style="dim")
grid.add_column()

for row in rows:
grid.add_row(*row)

console.writeln(grid)

if capa.rules.Scope.FILE in rule.meta.scopes:
matches = doc.rules[rule.meta.name].matches
Expand Down
67 changes: 38 additions & 29 deletions scripts/profile-time.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
import subprocess

import humanize
import tabulate
from rich import box
from rich.table import Table
from rich.console import Console

import capa.main
import capa.perf
Expand Down Expand Up @@ -104,41 +106,48 @@ def do_iteration():
samples = timeit.repeat(do_iteration, number=args.number, repeat=args.repeat)

logger.debug("perf: find capabilities: min: %0.2fs", (min(samples) / float(args.number)))
logger.debug("perf: find capabilities: avg: %0.2fs", (sum(samples) / float(args.repeat) / float(args.number)))
logger.debug(
"perf: find capabilities: avg: %0.2fs",
(sum(samples) / float(args.repeat) / float(args.number)),
)
logger.debug("perf: find capabilities: max: %0.2fs", (max(samples) / float(args.number)))

for counter, count in capa.perf.counters.most_common():
logger.debug("perf: counter: %s: %s", counter, count)

print(
tabulate.tabulate(
[(counter, humanize.intcomma(count)) for counter, count in capa.perf.counters.most_common()],
headers=["feature class", "evaluation count"],
tablefmt="github",
)
)
print()

print(
tabulate.tabulate(
[
(
args.label,
"{:,}".format(capa.perf.counters["evaluate.feature"]),
# python documentation indicates that min(samples) should be preferred,
# so lets put that first.
#
# https://docs.python.org/3/library/timeit.html#timeit.Timer.repeat
f"{(min(samples) / float(args.number)):.2f}s",
f"{(sum(samples) / float(args.repeat) / float(args.number)):.2f}s",
f"{(max(samples) / float(args.number)):.2f}s",
)
],
headers=["label", "count(evaluations)", "min(time)", "avg(time)", "max(time)"],
tablefmt="github",
)
console = Console()

table1 = Table(box=box.MARKDOWN)
table1.add_column("feature class")
table1.add_column("evaluation count")

for counter, count in capa.perf.counters.most_common():
table1.add_row(counter, humanize.intcomma(count))

console.print(table1)
console.print()

table2 = Table(box=box.MARKDOWN)
table2.add_column("label")
table2.add_column("count(evaluations)", style="magenta")
table2.add_column("min(time)", style="green")
table2.add_column("avg(time)", style="yellow")
table2.add_column("max(time)", style="red")

table2.add_row(
args.label,
# python documentation indicates that min(samples) should be preferred,
# so lets put that first.
#
# https://docs.python.org/3/library/timeit.html#timeit.Timer.repeat
"{:,}".format(capa.perf.counters["evaluate.feature"]),
f"{(min(samples) / float(args.number)):.2f}s",
f"{(sum(samples) / float(args.repeat) / float(args.number)):.2f}s",
f"{(max(samples) / float(args.number)):.2f}s",
)

console.print(table2)

return 0


Expand Down

0 comments on commit 3eb0d89

Please sign in to comment.