Omnia-cy commited on
Commit
09a9add
Β·
verified Β·
1 Parent(s): 9a89952

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -0
app.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File
2
+ import pandas as pd
3
+ import faiss
4
+ import pickle
5
+ import os
6
+ from sentence_transformers import SentenceTransformer
7
+ from exa_py import Exa
8
+ from groq import Groq
9
+
10
+ app = FastAPI()
11
+
12
+ # =============================
13
+ # πŸ”‘ KEYS
14
+ # =============================
15
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY")
16
+ EXA_API_KEY = os.getenv("EXA_API_KEY")
17
+
18
+ # clients
19
+ client = Groq(api_key=GROQ_API_KEY)
20
+ exa = Exa(api_key=EXA_API_KEY)
21
+
22
+ # =============================
23
+ # 🧠 LOAD MODELS
24
+ # =============================
25
+ embed_model = SentenceTransformer('all-mpnet-base-v2')
26
+
27
+ index = faiss.read_index("faiss_index.index")
28
+
29
+ with open("startup_texts.pkl", "rb") as f:
30
+ startup_texts = pickle.load(f)
31
+
32
+ # =============================
33
+ # πŸ” RETRIEVAL
34
+ # =============================
35
+ def retrieve_similar(problem, k=3):
36
+ vec = embed_model.encode([problem], convert_to_numpy=True)
37
+ distances, indices = index.search(vec, k)
38
+
39
+ return [
40
+ {"text": startup_texts[idx], "score": float(distances[0][i])}
41
+ for i, idx in enumerate(indices[0])
42
+ ]
43
+
44
+ # =============================
45
+ # 🌐 WEB SEARCH
46
+ # =============================
47
+ def search_web(query):
48
+ try:
49
+ response = exa.search(query, num_results=5)
50
+ return [r.text or r.summary or "" for r in response.results]
51
+ except:
52
+ return []
53
+
54
+ # =============================
55
+ # πŸ€– QWEN (Groq)
56
+ # =============================
57
+ def ask_qwen(prompt):
58
+ completion = client.chat.completions.create(
59
+ model="qwen/qwen3-32b",
60
+ messages=[
61
+ {"role": "system", "content": "You are a strict fact-checking analyst."},
62
+ {"role": "user", "content": prompt}
63
+ ],
64
+ temperature=0.3,
65
+ max_tokens=512
66
+ )
67
+ return completion.choices[0].message.content
68
+
69
+ # =============================
70
+ # 🧠 PIPELINE
71
+ # =============================
72
+ def analyze_problem(problem):
73
+
74
+ retrieved = retrieve_similar(problem)
75
+
76
+ if retrieved and retrieved[0]["score"] < 2.0:
77
+ context = "\n\n".join([r["text"] for r in retrieved])
78
+ else:
79
+ web = search_web(problem)
80
+ context = "\n\n".join(web[:3])
81
+
82
+ prompt = f"""
83
+ Problem:
84
+ {problem}
85
+
86
+ Evidence:
87
+ {context}
88
+
89
+ Output:
90
+ Status: SOLVED or UNSOLVED
91
+ Reason: one short sentence
92
+ Gaps:
93
+ - bullet points
94
+ New Problem:
95
+ rewrite
96
+ """
97
+
98
+ return ask_qwen(prompt)
99
+
100
+ # =============================
101
+ # πŸš€ API
102
+ # =============================
103
+ @app.post("/analyze")
104
+ async def analyze(file: UploadFile = File(...)):
105
+
106
+ df = pd.read_csv(file.file)
107
+
108
+ results = []
109
+
110
+ for p in df.iloc[:, 0].tolist():
111
+ try:
112
+ results.append(analyze_problem(p))
113
+ except Exception as e:
114
+ results.append(f"ERROR: {str(e)}")
115
+
116
+ return {
117
+ "success": True,
118
+ "results": results
119
+ }