Skip to content

Tabular

tabular

Tabular strategy — convert homogeneous list[dict] to pipe-separated table.

TabularStrategy

Bases: SmeltStrategy

Convert JSON arrays of objects to pipe-separated tables.

Source code in packages/axm-smelt/src/axm_smelt/strategies/tabular.py
Python
class TabularStrategy(SmeltStrategy):
    """Convert JSON arrays of objects to pipe-separated tables."""

    @property
    def name(self) -> str:
        """Strategy identifier used in the registry."""
        return "tabular"

    @property
    def category(self) -> str:
        """Strategy category (``structural``)."""
        return "structural"

    def apply(self, ctx: SmeltContext) -> SmeltContext:
        """Convert homogeneous ``list[dict]`` to pipe-separated tables.

        Uses ``ctx.parsed`` when available to skip
        ``json.loads``. Recurses into nested dicts to tabularize
        inner arrays.
        """
        parsed = ctx.parsed
        if parsed is None:
            text = ctx.text
            stripped = text.strip()
            if not stripped or stripped[0] not in ("[", "{"):
                return ctx
            try:
                parsed = json.loads(stripped)
            except (json.JSONDecodeError, ValueError):
                return ctx

        if isinstance(parsed, list):
            table = to_table(parsed)
            if table is not None:
                return SmeltContext(text=table, format=ctx.format, parsed=None)
            return ctx

        if isinstance(parsed, dict):
            result, changed = _tabularize_dict(parsed)
            if changed:
                return SmeltContext(
                    text=json.dumps(result, separators=(",", ":"), ensure_ascii=False),
                    format=ctx.format,
                )

        return ctx
category property

Strategy category (structural).

name property

Strategy identifier used in the registry.

apply(ctx)

Convert homogeneous list[dict] to pipe-separated tables.

Uses ctx.parsed when available to skip json.loads. Recurses into nested dicts to tabularize inner arrays.

Source code in packages/axm-smelt/src/axm_smelt/strategies/tabular.py
Python
def apply(self, ctx: SmeltContext) -> SmeltContext:
    """Convert homogeneous ``list[dict]`` to pipe-separated tables.

    Uses ``ctx.parsed`` when available to skip
    ``json.loads``. Recurses into nested dicts to tabularize
    inner arrays.
    """
    parsed = ctx.parsed
    if parsed is None:
        text = ctx.text
        stripped = text.strip()
        if not stripped or stripped[0] not in ("[", "{"):
            return ctx
        try:
            parsed = json.loads(stripped)
        except (json.JSONDecodeError, ValueError):
            return ctx

    if isinstance(parsed, list):
        table = to_table(parsed)
        if table is not None:
            return SmeltContext(text=table, format=ctx.format, parsed=None)
        return ctx

    if isinstance(parsed, dict):
        result, changed = _tabularize_dict(parsed)
        if changed:
            return SmeltContext(
                text=json.dumps(result, separators=(",", ":"), ensure_ascii=False),
                format=ctx.format,
            )

    return ctx

collect_ordered_keys(items)

Collect unique keys from dicts in first-seen insertion order.

Source code in packages/axm-smelt/src/axm_smelt/strategies/tabular.py
Python
def collect_ordered_keys(items: list[dict[str, JsonValue]]) -> list[str]:
    """Collect unique keys from dicts in first-seen insertion order."""
    keys: list[str] = []
    seen: set[str] = set()
    for item in items:
        for k in item:
            if k not in seen:
                keys.append(k)
                seen.add(k)
    return keys

render_rows(items, keys)

Render each dict as a pipe-separated row according to keys.

Source code in packages/axm-smelt/src/axm_smelt/strategies/tabular.py
Python
def render_rows(items: list[dict[str, JsonValue]], keys: list[str]) -> list[str]:
    """Render each dict as a pipe-separated row according to *keys*."""
    rows: list[str] = []
    for item in items:
        cells = [_format_cell(item.get(k, "")) if k in item else "" for k in keys]
        rows.append("|".join(cells))
    return rows

to_table(data)

Convert a list of dicts to a pipe-separated table, or return None.

Source code in packages/axm-smelt/src/axm_smelt/strategies/tabular.py
Python
def to_table(data: object) -> str | None:
    """Convert a list of dicts to a pipe-separated table, or return None."""
    if not isinstance(data, list) or not data:
        return None
    if not all(isinstance(item, dict) for item in data):
        return None

    keys = collect_ordered_keys(data)
    header = "|".join(keys)
    rows = render_rows(data, keys)
    return "\n".join([header, *rows])