| | """ |
| | SPARKNET FastAPI Backend |
| | Provides RESTful API for Patent Wake-Up workflows. |
| | """ |
| |
|
| | from fastapi import FastAPI |
| | from fastapi.middleware.cors import CORSMiddleware |
| | from contextlib import asynccontextmanager |
| | from pathlib import Path |
| | from loguru import logger |
| |
|
| | |
| | app_state = {} |
| |
|
| | @asynccontextmanager |
| | async def lifespan(app: FastAPI): |
| | """Initialize SPARKNET components on startup""" |
| | logger.info("🚀 Starting SPARKNET API...") |
| |
|
| | try: |
| | |
| | from src.llm.langchain_ollama_client import get_langchain_client |
| | from src.workflow.langgraph_workflow import create_workflow |
| | from src.agents.planner_agent import PlannerAgent |
| | from src.agents.critic_agent import CriticAgent |
| | from src.agents.memory_agent import create_memory_agent |
| | from src.agents.vision_ocr_agent import VisionOCRAgent |
| |
|
| | |
| | logger.info("Initializing LangChain Ollama client...") |
| | app_state["llm_client"] = get_langchain_client( |
| | default_complexity='standard', |
| | enable_monitoring=False |
| | ) |
| |
|
| | |
| | logger.info("Initializing agents...") |
| | app_state["planner"] = PlannerAgent(llm_client=app_state["llm_client"]) |
| | app_state["critic"] = CriticAgent(llm_client=app_state["llm_client"]) |
| | app_state["memory"] = create_memory_agent( |
| | llm_client=app_state["llm_client"] |
| | ) |
| |
|
| | |
| | try: |
| | logger.info("Initializing VisionOCR agent...") |
| | vision_ocr = VisionOCRAgent(model_name="llava:7b") |
| | if vision_ocr.is_available(): |
| | app_state["vision_ocr"] = vision_ocr |
| | logger.success("✅ VisionOCR agent initialized with llava:7b") |
| | else: |
| | app_state["vision_ocr"] = None |
| | logger.warning("⚠️ llava:7b model not available, OCR features disabled") |
| | except Exception as e: |
| | logger.warning(f"⚠️ Failed to initialize VisionOCR: {e}, OCR features disabled") |
| | app_state["vision_ocr"] = None |
| |
|
| | |
| | logger.info("Creating LangGraph workflow...") |
| | app_state["workflow"] = create_workflow( |
| | llm_client=app_state["llm_client"], |
| | planner_agent=app_state["planner"], |
| | critic_agent=app_state["critic"], |
| | memory_agent=app_state["memory"], |
| | vision_ocr_agent=app_state.get("vision_ocr"), |
| | quality_threshold=0.80, |
| | max_iterations=3 |
| | ) |
| |
|
| | |
| | app_state["workflows"] = {} |
| | app_state["patents"] = {} |
| |
|
| | |
| | Path("uploads/patents").mkdir(parents=True, exist_ok=True) |
| | Path("outputs").mkdir(parents=True, exist_ok=True) |
| | Path("data/vector_store").mkdir(parents=True, exist_ok=True) |
| |
|
| | logger.success("✅ SPARKNET API initialized successfully!") |
| |
|
| | except Exception as e: |
| | logger.error(f"❌ Failed to initialize SPARKNET: {e}") |
| | raise |
| |
|
| | yield |
| |
|
| | |
| | logger.info("Shutting down SPARKNET API...") |
| | app_state.clear() |
| |
|
| | |
| | app = FastAPI( |
| | title="SPARKNET API", |
| | description="AI-Powered Research Valorization Platform", |
| | version="1.0.0", |
| | lifespan=lifespan, |
| | docs_url="/api/docs", |
| | redoc_url="/api/redoc" |
| | ) |
| |
|
| | |
| | app.add_middleware( |
| | CORSMiddleware, |
| | allow_origins=[ |
| | "http://localhost:3000", |
| | "http://localhost:3001", |
| | "http://localhost:3002", |
| | "http://127.0.0.1:3000", |
| | "http://127.0.0.1:3001", |
| | "http://127.0.0.1:3002", |
| | "http://172.24.50.21:3000", |
| | "http://172.24.50.21:3001", |
| | "http://172.24.50.21:3002" |
| | ], |
| | allow_credentials=True, |
| | allow_methods=["*"], |
| | allow_headers=["*"], |
| | ) |
| |
|
| | |
| | from api.routes import patents, workflows |
| |
|
| | app.include_router(patents.router, prefix="/api/patents", tags=["Patents"]) |
| | app.include_router(workflows.router, prefix="/api/workflows", tags=["Workflows"]) |
| |
|
| | @app.get("/") |
| | async def root(): |
| | """Root endpoint - health check""" |
| | return { |
| | "status": "operational", |
| | "service": "SPARKNET API", |
| | "version": "1.0.0", |
| | "message": "Welcome to SPARKNET - AI-Powered Research Valorization", |
| | "docs": "/api/docs" |
| | } |
| |
|
| | @app.get("/api/health") |
| | async def health(): |
| | """Detailed health check endpoint""" |
| | components_healthy = { |
| | "llm_client": app_state.get("llm_client") is not None, |
| | "workflow": app_state.get("workflow") is not None, |
| | "planner": app_state.get("planner") is not None, |
| | "critic": app_state.get("critic") is not None, |
| | "memory": app_state.get("memory") is not None |
| | } |
| |
|
| | all_healthy = all(components_healthy.values()) |
| |
|
| | return { |
| | "status": "healthy" if all_healthy else "degraded", |
| | "components": components_healthy, |
| | "statistics": { |
| | "active_workflows": len(app_state.get("workflows", {})), |
| | "processed_patents": len(app_state.get("patents", {})) |
| | } |
| | } |
| |
|
| | if __name__ == "__main__": |
| | import uvicorn |
| | uvicorn.run( |
| | "api.main:app", |
| | host="0.0.0.0", |
| | port=8000, |
| | reload=True, |
| | log_level="info" |
| | ) |
| |
|