CoolFace
Apppublic

areesha-06/flutter-docs-api

sourceHugging Faceapache-2.0updated 3mo agoView on Hugging Face
0likes
app.py113 linesDownload Raw Back to root
1"""2FastAPI RAG server3--------------------4Loads the FAISS index + metadata, embeds incoming queries,5retrieves top-k chunks, and calls Groq to generate an answer6grounded in those chunks.7 8Run locally:9    uvicorn app:app --reload --port 800010 11Env vars needed (.env file):12    GROQ_API_KEY=your_key_here13"""14 15import json16import os17 18import faiss19import numpy as np20from dotenv import load_dotenv21from fastapi import FastAPI22from fastapi.middleware.cors import CORSMiddleware23from groq import Groq24from pydantic import BaseModel25from sentence_transformers import SentenceTransformer26 27load_dotenv()28 29INDEX_FILE = "flutter_docs.index"30METADATA_FILE = "flutter_docs_meta.jsonl"31MODEL_NAME = "all-MiniLM-L6-v2"32TOP_K = 433 34app = FastAPI(title="Flutter Docs RAG API")35 36# Allow the React frontend (adjust origin for production deploy)37app.add_middleware(38    CORSMiddleware,39    allow_origins=["*"],40    allow_methods=["*"],41    allow_headers=["*"],42)43 44print("Loading embedding model...")45embed_model = SentenceTransformer(MODEL_NAME)46 47print("Loading FAISS index...")48index = faiss.read_index(INDEX_FILE)49 50print("Loading metadata...")51metadata = []52with open(METADATA_FILE, "r", encoding="utf-8") as f:53    for line in f:54        metadata.append(json.loads(line))55 56groq_client = Groq(api_key=os.getenv("GROQ_API_KEY"))57 58 59class QueryRequest(BaseModel):60    question: str61 62 63def retrieve(question: str, k: int = TOP_K):64    query_vec = embed_model.encode([question], convert_to_numpy=True).astype("float32")65    faiss.normalize_L2(query_vec)66    scores, indices = index.search(query_vec, k)67    results = []68    for score, idx in zip(scores[0], indices[0]):69        if idx == -1:70            continue71        chunk = metadata[idx]72        results.append({**chunk, "score": float(score)})73    return results74 75 76def build_prompt(question: str, chunks: list):77    context = "\n\n---\n\n".join(78        f"Source: {c['title']} ({c['url']})\n{c['text']}" for c in chunks79    )80    return f"""You are a helpful assistant answering questions about Flutter using only the provided documentation excerpts. If the answer isn't in the excerpts, say you don't know rather than guessing.81 82Documentation excerpts:83{context}84 85Question: {question}86 87Answer clearly and concisely. Cite the source URL(s) you used at the end."""88 89 90@app.post("/query")91def query(req: QueryRequest):92    chunks = retrieve(req.question)93    prompt = build_prompt(req.question, chunks)94 95    completion = groq_client.chat.completions.create(96        # Groq's model lineup changes fairly often -- if this errors with97        # "model not found", check console.groq.com/docs/models for the98        # current list and swap the id here.99        model="llama-3.3-70b-versatile",100        messages=[{"role": "user", "content": prompt}],101        temperature=0.2,102    )103 104    answer = completion.choices[0].message.content105    sources = list({c["url"] for c in chunks})106 107    return {"answer": answer, "sources": sources}108 109 110@app.get("/health")111def health():112    return {"status": "ok", "chunks_loaded": len(metadata)}113