Omnia-cy commited on
Commit
d176594
Β·
verified Β·
1 Parent(s): 8946d68

Create app.py

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