|
|
""" |
|
|
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" |
|
|
) |
|
|
|