""" Phase 0 Extraction routes: Fast JSON Extraction MVP. No database storage - just extract and return JSON candidates. Goal: 10-30 seconds per URL. """ from fastapi import APIRouter, HTTPException import time from ont_platform.core.extractors.web_extractor import extract_web_content from ont_platform.core.extraction.lightweight_extractor import LightweightExtractor router = APIRouter(prefix="/api/v1", tags=["extraction"]) @router.post("/extract/url") async def extract_url(url: str): """ Extract candidates from URL (Phase 0 MVP). Returns: { "url": "...", "title": "...", "entities": [...], "relations": [...], "extraction_time_sec": 0.5, "warnings": [...] } """ if not url: raise HTTPException(status_code=400, detail="url is required") start_time = time.time() try: # Step 1: Extract web content with Trafilatura extracted = extract_web_content(url=url) # Step 2: Extract JSON candidates with lightweight extractor lightweight = LightweightExtractor(use_llm=False) candidates = lightweight.extract( text=extracted.text, project_id="default", # Phase 0: no projects yet document_id="temp", ) extraction_time = time.time() - start_time # Return just the JSON (entities/relations are already dicts) return { "url": url, "title": extracted.title, "author": extracted.author, "published_date": extracted.publish_date, "language": extracted.language, "text_length": len(extracted.text), "entities": candidates.entities, "relations": candidates.relations, "extraction_time_sec": round(extraction_time, 2), "entity_count": len(candidates.entities), "relation_count": len(candidates.relations), "warnings": candidates.warnings, } except Exception as e: raise HTTPException(status_code=500, detail=f"Extraction failed: {str(e)}") __all__ = ["router"]