File size: 5,512 Bytes
a9dc537 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
"""
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
# Global state for application lifecycle
app_state = {}
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Initialize SPARKNET components on startup"""
logger.info("🚀 Starting SPARKNET API...")
try:
# Import here to avoid circular dependencies
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
# Initialize LangChain client
logger.info("Initializing LangChain Ollama client...")
app_state["llm_client"] = get_langchain_client(
default_complexity='standard',
enable_monitoring=False
)
# Initialize agents
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"]
)
# Initialize VisionOCR agent if llava model is available
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
# Initialize workflow
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
)
# Storage for active workflows and patents
app_state["workflows"] = {}
app_state["patents"] = {}
# Ensure directories exist
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
# Cleanup on shutdown
logger.info("Shutting down SPARKNET API...")
app_state.clear()
# Create FastAPI application
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"
)
# CORS middleware for frontend
app.add_middleware(
CORSMiddleware,
allow_origins=[
"http://localhost:3000", # Next.js dev server
"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", # Server IP
"http://172.24.50.21:3001",
"http://172.24.50.21:3002"
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Import and include routers
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"
)
|