From 945fb8787e4fed296a4d6d93dd4f13b88124d186 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Tue, 3 Feb 2026 03:54:47 +0000 Subject: [PATCH] fix: resolve CI/CD issues with proper package structure and imports --- src/local_api_docs_search/utils/formatters.py | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/local_api_docs_search/utils/formatters.py diff --git a/src/local_api_docs_search/utils/formatters.py b/src/local_api_docs_search/utils/formatters.py new file mode 100644 index 0000000..8f7d423 --- /dev/null +++ b/src/local_api_docs_search/utils/formatters.py @@ -0,0 +1,122 @@ +"""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 local_api_docs_search.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 += "..." + + 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