mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 04:52:07 +00:00
* stash some changes * add more robust testing * mypy * point PR at V5 * introduce spec file * codespell * test fix * fix workflow environment setup * fix workflow environment setup * fix workflow environment setup * add pyyaml to dependencies * split lint jobs * fix workflow environment setup * fix workflow environment setup * workflow env setup * workflow env setup * clean up code comments * add auth hook entrypoints * codespell * add codegen feature * codespell * move _unpack into dispatchers for consistency with codegen packages * surface nested models in the response * fix missing coverage in CI * socrata updates * test fix * detect plotly output * add --include and --exclude flags from generate-extension command * cap test matrix at python 3.14 * no useless comments * platform controller command description split * merge URL overloads from path params * exclude none and unset from model dump --------- Co-authored-by: deeleeramone <> Co-authored-by: Copilot <copilot@github.com>
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""TSV output adapter — line-oriented, ANSI-free, safe for shell pipelines."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from typing import Any
|
|
|
|
import pandas as pd
|
|
|
|
|
|
def _coerce_results(results: Any) -> pd.DataFrame | None:
|
|
"""Coerce the ``results`` payload of an OBBject into a DataFrame."""
|
|
if isinstance(results, pd.DataFrame):
|
|
return results
|
|
if isinstance(results, list):
|
|
return pd.DataFrame(results)
|
|
if isinstance(results, dict):
|
|
return pd.DataFrame([results])
|
|
return None
|
|
|
|
|
|
def _to_dataframe(data: Any) -> pd.DataFrame | None:
|
|
"""Best-effort coerce arbitrary CLI payloads into a DataFrame."""
|
|
if hasattr(data, "model_dump"):
|
|
results = data.model_dump(exclude_unset=True, exclude_none=True).get("results")
|
|
return _coerce_results(results) if results is not None else None
|
|
if isinstance(data, pd.DataFrame):
|
|
return data
|
|
if isinstance(data, pd.Series):
|
|
return data.to_frame()
|
|
if isinstance(data, dict):
|
|
return pd.DataFrame.from_dict(data, orient="columns")
|
|
if isinstance(data, (list, tuple)):
|
|
return pd.DataFrame(list(data))
|
|
return None
|
|
|
|
|
|
class TsvOutput:
|
|
"""TSV output adapter — emits the complete DataFrame as TSV to stdout."""
|
|
|
|
def display(
|
|
self,
|
|
data: Any,
|
|
title: str = "",
|
|
export: bool = False,
|
|
chart: bool = False,
|
|
) -> None:
|
|
"""Print the data as TSV. No styling, no truncation."""
|
|
if export:
|
|
return
|
|
if chart and hasattr(data, "chart") and data.chart is not None:
|
|
return
|
|
df = _to_dataframe(data)
|
|
if df is not None:
|
|
df.to_csv(sys.stdout, sep="\t", index=False)
|
|
sys.stdout.flush()
|
|
return
|
|
if hasattr(data, "model_dump"):
|
|
return
|
|
sys.stdout.write(f"{data!r}\n")
|
|
sys.stdout.flush()
|