Add models and utils modules
This commit is contained in:
124
src/utils/formatters.py
Normal file
124
src/utils/formatters.py
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
"""Output formatting utilities using Rich."""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.table import Table
|
||||||
|
from rich.text import Text
|
||||||
|
from rich.theme import Theme
|
||||||
|
|
||||||
|
from src.models.document import Document, SearchResult, SourceType
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
|
||||||
|
CUSTOM_THEME = Theme({
|
||||||
|
"title": "bold cyan",
|
||||||
|
"subtitle": "dim white",
|
||||||
|
"highlight": "yellow",
|
||||||
|
"source_openapi": "green",
|
||||||
|
"source_readme": "blue",
|
||||||
|
"source_code": "magenta",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def format_document_for_display(doc: Document, score: float = 0.0) -> Table:
|
||||||
|
"""Format a document for display in a table."""
|
||||||
|
table = Table(show_header=False, box=None, padding=(0, 1))
|
||||||
|
table.add_column("Label", style="dim")
|
||||||
|
table.add_column("Value")
|
||||||
|
|
||||||
|
source_style = get_source_style(doc.source_type)
|
||||||
|
|
||||||
|
table.add_row("Title", Text(doc.title, style="bold"))
|
||||||
|
table.add_row("Type", Text(doc.source_type.value, style=source_style))
|
||||||
|
table.add_row("File", Text(doc.file_path, style="dim"))
|
||||||
|
|
||||||
|
if score > 0:
|
||||||
|
table.add_row("Score", f"{score:.4f}")
|
||||||
|
|
||||||
|
content_preview = doc.content[:200] + "..." if len(doc.content) > 200 else doc.content
|
||||||
|
table.add_row("Content", content_preview)
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
|
||||||
|
def get_source_style(source_type: SourceType) -> str:
|
||||||
|
"""Get the Rich style for a source type."""
|
||||||
|
style_map = {
|
||||||
|
SourceType.OPENAPI: "source_openapi",
|
||||||
|
SourceType.README: "source_readme",
|
||||||
|
SourceType.CODE: "source_code",
|
||||||
|
}
|
||||||
|
return style_map.get(source_type, "white")
|
||||||
|
|
||||||
|
|
||||||
|
def format_search_results(results: list[SearchResult], show_scores: bool = True) -> Table:
|
||||||
|
"""Format search results as a table."""
|
||||||
|
table = Table(title="Search Results", show_lines=True)
|
||||||
|
table.add_column("#", width=4, style="dim")
|
||||||
|
table.add_column("Title", style="bold")
|
||||||
|
table.add_column("Type", width=8)
|
||||||
|
table.add_column("Preview")
|
||||||
|
|
||||||
|
for i, result in enumerate(results, 1):
|
||||||
|
source_style = get_source_style(result.document.source_type)
|
||||||
|
preview = result.document.content[:150]
|
||||||
|
if len(result.document.content) > 150:
|
||||||
|
preview += "..."
|
||||||
|
|
||||||
|
score_str = f"{result.score:.4f}" if show_scores else ""
|
||||||
|
|
||||||
|
table.add_row(
|
||||||
|
str(i),
|
||||||
|
Text(result.document.title, style="bold"),
|
||||||
|
Text(result.document.source_type.value, style=source_style),
|
||||||
|
preview,
|
||||||
|
)
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
|
||||||
|
def format_index_summary(
|
||||||
|
total: int, openapi: int, readme: int, code: int
|
||||||
|
) -> Table:
|
||||||
|
"""Format index statistics as a table."""
|
||||||
|
table = Table(title="Index Summary", show_header=False)
|
||||||
|
table.add_column("Metric", style="dim")
|
||||||
|
table.add_column("Count", justify="right")
|
||||||
|
|
||||||
|
table.add_row("Total Documents", str(total))
|
||||||
|
table.add_row("OpenAPI Specs", str(openapi))
|
||||||
|
table.add_row("README Files", str(readme))
|
||||||
|
table.add_row("Code Comments", str(code))
|
||||||
|
|
||||||
|
return table
|
||||||
|
|
||||||
|
|
||||||
|
def format_error(message: str) -> Text:
|
||||||
|
"""Format an error message."""
|
||||||
|
return Text(f"Error: {message}", style="red bold")
|
||||||
|
|
||||||
|
|
||||||
|
def format_success(message: str) -> Text:
|
||||||
|
"""Format a success message."""
|
||||||
|
return Text(message, style="green bold")
|
||||||
|
|
||||||
|
|
||||||
|
def format_info(message: str) -> Text:
|
||||||
|
"""Format an info message."""
|
||||||
|
return Text(message, style="cyan")
|
||||||
|
|
||||||
|
|
||||||
|
def print_json(data: Any) -> None:
|
||||||
|
"""Print data as JSON."""
|
||||||
|
console.print_json(data=data)
|
||||||
|
|
||||||
|
|
||||||
|
def format_help_header(command: str, description: str) -> Text:
|
||||||
|
"""Format a help header for a command."""
|
||||||
|
header = Text.assemble(
|
||||||
|
(f"$ api-docs {command}", "bold yellow"),
|
||||||
|
" — ",
|
||||||
|
(description, "italic"),
|
||||||
|
)
|
||||||
|
return header
|
||||||
Reference in New Issue
Block a user