Ashok75 commited on
Commit
1bc6e15
Β·
verified Β·
1 Parent(s): 10a21dd

Update run.py

Browse files
Files changed (1) hide show
  1. run.py +221 -90
run.py CHANGED
@@ -1,90 +1,221 @@
1
- # run.py - FastAPI Backend + Frontend Server (PORT 8080)
2
- from fastapi import FastAPI, HTTPException, Form, UploadFile, File, Request
3
- from fastapi.middleware.cors import CORSMiddleware
4
- from fastapi.responses import HTMLResponse, JSONResponse
5
- from fastapi.templating import Jinja2Templates
6
- import uvicorn
7
- from load_model import init_model
8
- from generate import generate_response
9
-
10
- # Initialize FastAPI app
11
- app = FastAPI(title="GAKR AI")
12
-
13
- # Templates (chat.html lives here)
14
- templates = Jinja2Templates(directory="templates")
15
-
16
- # CORS (for development)
17
- app.add_middleware(
18
- CORSMiddleware,
19
- allow_origins=["*"],
20
- allow_credentials=True,
21
- allow_methods=["*"],
22
- allow_headers=["*"],
23
- )
24
-
25
- # API Key
26
- API_KEY = "gakr-ai-2025-secret"
27
-
28
- # Load model ONCE at startup
29
- print("πŸš€ Starting GAKR AI Backend...")
30
- model, tokenizer = init_model(".")
31
-
32
- @app.get("/", response_class=HTMLResponse)
33
- async def home(request: Request):
34
- """Serve chat.html as homepage"""
35
- return templates.TemplateResponse("chat.html", {"request": request})
36
-
37
- @app.post("/api/chat")
38
- async def chat_endpoint(
39
- message: str = Form(...),
40
- api_key: str = Form(...),
41
- files: list[UploadFile] = File(None)
42
- ):
43
- """Main chat API endpoint"""
44
-
45
- # Validate API key
46
- if api_key != API_KEY:
47
- raise HTTPException(status_code=401, detail="Invalid API key")
48
-
49
- if not message.strip():
50
- raise HTTPException(status_code=400, detail="Message cannot be empty")
51
-
52
- try:
53
- system_prompt = (
54
- "You are GAKR AI (not Phi), a helpful and honest AI assistant. "
55
- "You know general information up to 2024. "
56
- "Never mention Phi, Microsoft, or your training origin."
57
- )
58
-
59
- response = generate_response(
60
- user_prompt=message,
61
- system_prompt=system_prompt,
62
- max_tokens=512,
63
- temperature=0.2,
64
- )
65
-
66
- return JSONResponse({
67
- "response": response,
68
- "status": "success"
69
- })
70
-
71
- except Exception as e:
72
- raise HTTPException(status_code=500, detail=f"Generation error: {str(e)}")
73
-
74
- @app.get("/health")
75
- async def health_check():
76
- return {"status": "healthy", "model_loaded": True}
77
-
78
- if __name__ == "__main__":
79
- print("\n" + "="*60)
80
- print("🌐 SERVER & CHAT LOCATION")
81
- print("="*60)
82
- print("πŸš€ CHAT INTERFACE: http://localhost:8000")
83
- print("πŸ“± ALTERNATIVE URL: http://127.0.0.1:8000")
84
- print("πŸ”§ API DOCUMENTATION: http://localhost:8000/docs")
85
- print("βœ… CHAT.HTML SERVED: templates/chat.html")
86
- print("πŸ“ TEMPLATES FOLDER: ./templates/")
87
- print("="*60)
88
-
89
- # πŸš€ RUN ON PORT 8000
90
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ run.py - FastAPI backend + frontend server for GAKR AI
4
+
5
+ Features:
6
+ - Serves templates/chat.html at "/"
7
+ - /api/analyze:
8
+ - prompt: required (must not be empty)
9
+ - files: optional list[UploadFile] (0, 1, many; any type)
10
+ - api_key: required
11
+ - If files are present β†’ file-analysis mode (different system prompt)
12
+ - If no files β†’ general assistant mode
13
+ - Detailed exceptions and logs for easier debugging
14
+ """
15
+
16
+ from typing import List, Optional
17
+
18
+ import json
19
+ import traceback
20
+
21
+ from fastapi import (
22
+ FastAPI,
23
+ HTTPException,
24
+ Form,
25
+ UploadFile,
26
+ File,
27
+ Request,
28
+ )
29
+ from fastapi.middleware.cors import CORSMiddleware
30
+ from fastapi.responses import HTMLResponse, JSONResponse
31
+ from fastapi.templating import Jinja2Templates
32
+ import uvicorn
33
+
34
+ from load_model import init_model
35
+ from generate import generate_response
36
+ from file_pipeline import process_files
37
+
38
+
39
+ # ============================================================
40
+ # APP SETUP
41
+ # ============================================================
42
+
43
+ app = FastAPI(title="GAKR AI")
44
+
45
+ # Templates (chat.html lives in ./templates)
46
+ templates = Jinja2Templates(directory="templates")
47
+
48
+ # CORS (open for dev; restrict origins in production)
49
+ app.add_middleware(
50
+ CORSMiddleware,
51
+ allow_origins=["*"], # change to specific origin in production
52
+ allow_credentials=True,
53
+ allow_methods=["*"],
54
+ allow_headers=["*"],
55
+ )
56
+
57
+ # API Key
58
+ API_KEY = "gakr-ai-2025-secret"
59
+
60
+ # Load model ONCE at startup
61
+ print("πŸš€ Starting GAKR AI Backend...")
62
+ try:
63
+ model, tokenizer = init_model(".")
64
+ print("βœ… Model initialized successfully")
65
+ except Exception as e:
66
+ print("❌ Failed to load model at startup:")
67
+ traceback.print_exc()
68
+ raise e
69
+
70
+
71
+ # ============================================================
72
+ # ROUTES
73
+ # ============================================================
74
+
75
+ @app.get("/", response_class=HTMLResponse)
76
+ async def home(request: Request):
77
+ """
78
+ Serve chat.html as homepage.
79
+ """
80
+ try:
81
+ return templates.TemplateResponse("chat.html", {"request": request})
82
+ except Exception as e:
83
+ # If template not found or other template error
84
+ traceback.print_exc()
85
+ raise HTTPException(
86
+ status_code=500,
87
+ detail=f"Failed to render chat.html: {str(e)}",
88
+ )
89
+
90
+
91
+ @app.post("/api/analyze")
92
+ async def analyze_endpoint(
93
+ prompt: str = Form(...), # required
94
+ api_key: str = Form(...),
95
+ files: Optional[List[UploadFile]] = File(None), # optional
96
+ ):
97
+ """
98
+ Main analysis endpoint.
99
+
100
+ Cases:
101
+ - prompt only (no files) β†’ general assistant mode
102
+ - prompt + one/many files β†’ file-analysis mode (uses file context)
103
+ """
104
+ try:
105
+ # ---------- Basic validation ----------
106
+ if api_key != API_KEY:
107
+ raise HTTPException(status_code=401, detail="Invalid API key")
108
+
109
+ if prompt is None:
110
+ raise HTTPException(status_code=400, detail="Prompt is missing")
111
+ if not prompt.strip():
112
+ raise HTTPException(status_code=400, detail="Prompt cannot be empty")
113
+
114
+ files = files or []
115
+
116
+ # ---------- Branch by presence of files ----------
117
+ if files:
118
+ # ----- CASE 1: prompt + files -----
119
+ try:
120
+ context = await process_files(files)
121
+ except Exception as extract_err:
122
+ traceback.print_exc()
123
+ raise HTTPException(
124
+ status_code=500,
125
+ detail=f"Error while processing uploaded files: {str(extract_err)}",
126
+ )
127
+
128
+ context_text = json.dumps(context, indent=2, ensure_ascii=False)
129
+ combined_user_prompt = f"""
130
+ User question:
131
+ {prompt}
132
+
133
+ Below is structured information extracted from the user's uploaded files.
134
+ The extraction was done by automated tools.
135
+
136
+ Your task:
137
+ 1. Answer the user's question as accurately as possible.
138
+ 2. Use the context when it is relevant.
139
+ 3. Highlight important patterns, risks, or opportunities.
140
+ 4. If some information is missing or uncertain, say so honestly.
141
+
142
+ Context:
143
+ {context_text}
144
+ """
145
+
146
+ system_prompt = (
147
+ "You are GAKR AI, a careful and honest analysis assistant that works with "
148
+ "structured summaries of files (tables, PDFs, documents, images, audio, video, etc.). "
149
+ "You never assume file contents beyond what the provided context states."
150
+ )
151
+
152
+ else:
153
+ # ----- CASE 2: prompt only -----
154
+ context = {"files": []} # keep structure consistent
155
+ combined_user_prompt = prompt
156
+
157
+ system_prompt = (
158
+ "You are GAKR AI, a helpful and honest general-purpose assistant. "
159
+ "You answer questions, explain concepts, help with reasoning and coding, "
160
+ "using your knowledge up to 2024. Be clear, concise, and direct."
161
+ )
162
+
163
+ # ---------- Generate with Phi‑3 ----------
164
+ try:
165
+ response_text = generate_response(
166
+ user_prompt=combined_user_prompt,
167
+ system_prompt=system_prompt,
168
+ max_tokens=512,
169
+ temperature=0.2,
170
+ )
171
+ except Exception as gen_err:
172
+ traceback.print_exc()
173
+ raise HTTPException(
174
+ status_code=500,
175
+ detail=f"Error during model generation: {str(gen_err)}",
176
+ )
177
+
178
+ return JSONResponse(
179
+ {
180
+ "response": response_text,
181
+ "context": context,
182
+ "status": "success",
183
+ }
184
+ )
185
+
186
+ except HTTPException:
187
+ # Let FastAPI handle HTTPException as-is
188
+ raise
189
+ except Exception as e:
190
+ # Unexpected error: log full traceback and return 500
191
+ traceback.print_exc()
192
+ raise HTTPException(
193
+ status_code=500,
194
+ detail=f"Unexpected backend error: {str(e)}",
195
+ )
196
+
197
+
198
+ @app.get("/health")
199
+ async def health_check():
200
+ """
201
+ Simple health check.
202
+ """
203
+ return {"status": "healthy", "model_loaded": True}
204
+
205
+
206
+ # ============================================================
207
+ # ENTRY POINT
208
+ # ============================================================
209
+
210
+ if __name__ == "__main__":
211
+ print("\n" + "=" * 60)
212
+ print("🌐 SERVER & CHAT LOCATION")
213
+ print("=" * 60)
214
+ print("πŸš€ CHAT INTERFACE: http://localhost:8080")
215
+ print("πŸ“± ALTERNATIVE URL: http://127.0.0.1:8080")
216
+ print("πŸ”§ API DOCUMENTATION: http://localhost:8080/docs")
217
+ print("βœ… CHAT.HTML SERVED: templates/chat.html")
218
+ print("πŸ“ TEMPLATES FOLDER: ./templates/")
219
+ print("=" * 60 + "\n")
220
+
221
+ uvicorn.run(app, host="0.0.0.0", port=8080)