Guest User

fast cgi daemon

a guest
Aug 2nd, 2025
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.94 KB | Source Code | 0 0
  1. import os, json
  2. from fastapi import FastAPI, Request
  3. from fastapi.middleware.cors import CORSMiddleware
  4. from pydantic import BaseModel
  5. from sklearn.feature_extraction.text import TfidfVectorizer
  6. from sklearn.metrics.pairwise import cosine_similarity
  7.  
  8. app = FastAPI()
  9.  
  10. import logging
  11. logging.basicConfig(level=logging.DEBUG)
  12.  
  13. # CORS for OpenWebUI on 192.168.88.239
  14. app.add_middleware(
  15.     CORSMiddleware,
  16.     allow_origins=["http://192.168.88.239"],
  17.     allow_credentials=True,
  18.     allow_methods=["*"],
  19.     allow_headers=["*"],
  20. )
  21.  
  22. class QueryRequest(BaseModel):
  23.     question: str
  24.     top_k: int = 3
  25.     system_prompt: str = ""
  26.  
  27. chunks = []
  28. chunk_ids = []
  29. vectorizer = None
  30. embeddings = None
  31.  
  32.  
  33. def load_docs_for_tenant(tenant_id):
  34.     global chunks, chunk_ids, vectorizer, embeddings
  35.     chunks.clear()
  36.     chunk_ids.clear()
  37.  
  38.     # Look for JSON files in the docling.json directory
  39.     docling_dir = f"./docling/{tenant_id}/docling.json"
  40.     if not os.path.exists(docling_dir):
  41.         print(f"Warning: No docling directory found for tenant {tenant_id} at {docling_dir}")
  42.         # Initialize empty vectorizer to prevent errors
  43.         vectorizer = TfidfVectorizer()
  44.         embeddings = None
  45.         return
  46.  
  47.     # If it's a directory, look for JSON files inside it
  48.     if os.path.isdir(docling_dir):
  49.         json_files = [f for f in os.listdir(docling_dir) if f.endswith('.json')]
  50.         if not json_files:
  51.             print(f"Warning: No JSON files found in {docling_dir}")
  52.             vectorizer = TfidfVectorizer()
  53.             embeddings = None
  54.             return
  55.        
  56.         # Load all JSON files in the directory
  57.         for json_file in json_files:
  58.             path = os.path.join(docling_dir, json_file)
  59.             try:
  60.                 with open(path, "r", encoding="utf-8") as f:
  61.                     data = json.load(f)
  62.                    
  63.                     # Extract text from the texts section
  64.                     if isinstance(data, dict) and "texts" in data:
  65.                         texts = data["texts"]
  66.                         for i, text_item in enumerate(texts):
  67.                             if isinstance(text_item, dict) and "text" in text_item:
  68.                                 text_content = text_item["text"].strip()
  69.                                 if text_content:
  70.                                     chunks.append(text_content)
  71.                                     chunk_ids.append(f"{json_file}_text_{i}")
  72.                    
  73.                     # Also try to extract from body children if they have direct text
  74.                     elif isinstance(data, dict) and "body" in data:
  75.                         body_data = data["body"]
  76.                         if isinstance(body_data, dict) and "children" in body_data:
  77.                             # Process children recursively to extract text
  78.                             def extract_text_from_children(children):
  79.                                 text_parts = []
  80.                                 for child in children:
  81.                                     if isinstance(child, dict):
  82.                                         if "text" in child:
  83.                                             text_parts.append(child["text"])
  84.                                         if "children" in child:
  85.                                             text_parts.extend(extract_text_from_children(child["children"]))
  86.                                 return text_parts
  87.                            
  88.                             text_parts = extract_text_from_children(body_data["children"])
  89.                             for i, text in enumerate(text_parts):
  90.                                 if text.strip():
  91.                                     chunks.append(text.strip())
  92.                                     chunk_ids.append(f"{json_file}_chunk_{i}")
  93.             except Exception as e:
  94.                 print(f"Error loading {path}: {e}")
  95.                 continue
  96.     else:
  97.         # Fallback to original behavior if it's a file
  98.         try:
  99.             with open(docling_dir, "r", encoding="utf-8") as f:
  100.                 data = json.load(f)
  101.                 for i, entry in enumerate(data):
  102.                     body = entry.get("body", "").strip()
  103.                     if body:
  104.                         chunks.append(body)
  105.                         chunk_ids.append(entry.get("id", f"chunk{i}"))
  106.         except Exception as e:
  107.             print(f"Error loading {docling_dir}: {e}")
  108.  
  109.     if chunks:
  110.         print(f"Loaded {len(chunks)} chunks for tenant {tenant_id}")
  111.         vectorizer = TfidfVectorizer().fit(chunks)
  112.         embeddings = vectorizer.transform(chunks)
  113.     else:
  114.         print(f"Warning: No valid chunks found for tenant {tenant_id}")
  115.         vectorizer = TfidfVectorizer()
  116.         embeddings = None
  117.  
  118.  
  119. def query(question: str, top_k: int = 3):
  120.     if not chunks or embeddings is None:
  121.         return []
  122.    
  123.     q_vec = vectorizer.transform([question])
  124.     sims = cosine_similarity(q_vec, embeddings)[0]
  125.     indices = sims.argsort()[-top_k:][::-1]
  126.     return [{"id": chunk_ids[i], "text": chunks[i], "score": float(sims[i])} for i in indices]
  127.  
  128.  
  129. @app.post("/query")
  130. async def query_docs(req: QueryRequest, request: Request):
  131.     # Extract tenant_id from system prompt
  132.     tenant_id = "default"
  133.     if req.system_prompt:
  134.         import re
  135.         # Look for "tenant: {tenant_id}" at the beginning of the prompt
  136.         tenant_match = re.search(r'^tenant:\s*(\w+)', req.system_prompt.strip(), re.IGNORECASE | re.MULTILINE)
  137.         if tenant_match:
  138.             tenant_id = tenant_match.group(1).lower()
  139.    
  140.     load_docs_for_tenant(tenant_id)
  141.     return {"results": query(req.question, req.top_k)}
  142.  
  143.  
  144. @app.get("/health")
  145. async def health_check():
  146.     return {"status": "ok"}
  147.  
  148.  
  149. if __name__ == "__main__":
  150.     print("Starting FastAPI server...")
  151.     import uvicorn
  152.     print("Uvicorn imported successfully")
  153.     uvicorn.run(app, host="0.0.0.0", port=5000)
  154.     print("Server started")
  155.  
Advertisement
Add Comment
Please, Sign In to add comment