Download src/main.py from Lp012/RSCE: direct link, hf CLI and curl.
- Browser
- Download file 5.16 kB
-
https://huggingface.co/spaces/Lp012/RSCE/resolve/main/src/main.py
- Command line
-
hf download hf://spaces/Lp012/RSCE/src/main.py
-
curl -L -o main.py https://huggingface.co/spaces/Lp012/RSCE/resolve/main/src/main.py
5.16 kB
| import asyncio | |
| import logging | |
| import sys | |
| import typer | |
| from rich.console import Console | |
| from src.config import settings | |
| from src.pipeline import run_full_pipeline | |
| from src.presentation import print_cli_report, export_report_to_json | |
| # Ensure UTF-8 stdout so the rich report (✔, box-drawing glyphs) renders on | |
| # Windows or when output is redirected, instead of crashing with UnicodeEncodeError. | |
| try: | |
| sys.stdout.reconfigure(encoding="utf-8") | |
| sys.stderr.reconfigure(encoding="utf-8") | |
| except (AttributeError, ValueError): | |
| pass | |
| # Configure logging | |
| logging.basicConfig(level=logging.WARNING, format="%(asctime)s - %(levelname)s - %(message)s") | |
| app = typer.Typer(help="Research Synthesis & Contradiction Engine (RSCE) CLI") | |
| console = Console() | |
| async def run_pipeline( | |
| query: str, | |
| max_papers: int, | |
| output_json: bool, | |
| seed_claim: str | None = None, | |
| date_from: int | None = None, | |
| date_to: int | None = None, | |
| journals: list[str] | None = None | |
| ): | |
| """Orchestrate the end-to-end pipeline stages: | |
| Ingestion & Extraction -> Contradiction Detection -> CLI/JSON Presentation | |
| """ | |
| if not settings.gemini_api_key and not settings.openai_api_key: | |
| console.print( | |
| "[bold red]Error:[/bold red] No LLM API keys configured. " | |
| "Please set GEMINI_API_KEY or OPENAI_API_KEY in your .env file.", | |
| style="red" | |
| ) | |
| sys.exit(1) | |
| # 1. Run full pipeline | |
| with console.status(f"[bold green]Running end-to-end research synthesis pipeline for: '{query}'...[/bold green]"): | |
| try: | |
| state = await run_full_pipeline( | |
| query, | |
| max_papers=max_papers, | |
| seed_claim=seed_claim, | |
| date_from=date_from, | |
| date_to=date_to, | |
| journals=journals | |
| ) | |
| except Exception as e: | |
| console.print(f"[bold red]Pipeline execution failed: {e}[/bold red]") | |
| sys.exit(1) | |
| if not state.papers: | |
| console.print("[yellow]No papers were found for the given query. Exiting.[/yellow]") | |
| return | |
| # 2. Print Rich Terminal Report | |
| if state.report: | |
| time_elapsed = state.report.metadata.get("time_elapsed", 0.0) | |
| cost_estimate = state.report.metadata.get("cost_estimate", 0.0) | |
| print_cli_report( | |
| report=state.report, | |
| query=query, | |
| time_elapsed=time_elapsed, | |
| cost_estimate=cost_estimate | |
| ) | |
| else: | |
| console.print("[bold red]Error: No report was generated.[/bold red]") | |
| sys.exit(1) | |
| # 3. Optional JSON Export & Graph Export (Phase 3) | |
| if output_json: | |
| try: | |
| saved_path = export_report_to_json(state.report, query) | |
| console.print(f"\n[green]✔ Full synthesis report exported to:[/green] [bold cyan]{saved_path}[/bold cyan]") | |
| # Export graph as well | |
| from src.graph.claim_graph import build_claim_graph | |
| from src.graph.graph_export import export_graph_to_cytoscape_json, export_graph_to_gexf | |
| from src.presentation.json_export import generate_query_slug | |
| G = build_claim_graph(state.claims, state.contradictions, state.papers) | |
| slug = generate_query_slug(query) or "claim_graph" | |
| from pathlib import Path | |
| project_root = Path(__file__).resolve().parents[1] | |
| json_graph_path = project_root / "data" / "sample_runs" / f"{slug}_graph.json" | |
| gexf_graph_path = project_root / "data" / "sample_runs" / f"{slug}_graph.gexf" | |
| export_graph_to_cytoscape_json(G, str(json_graph_path)) | |
| export_graph_to_gexf(G, str(gexf_graph_path)) | |
| console.print(f"[green]✔ Claim-evidence graph exported to:[/green] [bold cyan]{json_graph_path}[/bold cyan] and [bold cyan]{gexf_graph_path}[/bold cyan]\n") | |
| except Exception as e: | |
| console.print(f"[red]Failed to export JSON report/graph: {e}[/red]") | |
| def analyze( | |
| query: str = typer.Argument(..., help="Research question to analyze"), | |
| max_papers: int = typer.Option(settings.max_papers, "--max-papers", "-n", help="Maximum papers to fetch"), | |
| output_json: bool = typer.Option(False, "--json", "-j", help="Export report output to a structured JSON file"), | |
| seed_claim: str | None = typer.Option(None, "--seed-claim", "-s", help="Optional user assertion to bias contradiction detection toward"), | |
| date_from: int | None = typer.Option(None, "--date-from", help="Optional minimum publication year filter (inclusive)"), | |
| date_to: int | None = typer.Option(None, "--date-to", help="Optional maximum publication year filter (inclusive)"), | |
| journals: list[str] | None = typer.Option(None, "--journal", "-jnl", help="Optional journal name(s) to restrict search to (can specify multiple times)"), | |
| ) -> None: | |
| """Analyze a research question for contradictory claims across papers.""" | |
| asyncio.run(run_pipeline(query, max_papers, output_json, seed_claim, date_from, date_to, journals)) | |
| if __name__ == "__main__": | |
| app() | |