NitinBot001 commited on
Commit
3f6b886
·
verified ·
1 Parent(s): ad21c2e

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +133 -93
main.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
  import os
2
  import uuid
3
  import json
@@ -8,88 +10,75 @@ import google.generativeai as genai
8
  from dotenv import load_dotenv
9
  from flask_cors import CORS
10
 
11
-
12
- # Step 1: API Key aur Environment Setup
13
  load_dotenv()
14
  try:
15
  genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
16
  except TypeError:
17
- print("ERROR: Google API Key nahi mila.")
18
- print("Ek .env file banayein aur usmein 'GOOGLE_API_KEY=your_key_here' likhein.")
19
  exit()
20
 
21
  app = Flask(__name__, static_folder='.', static_url_path='')
22
  CORS(app)
23
 
24
- # Serve static files (CSS, JS, images)
25
  @app.route('/<path:path>')
26
  def serve_static(path):
27
  return send_from_directory('.', path)
28
 
29
- # Serve the main page
30
  @app.route('/')
31
  def serve_index():
32
  return send_from_directory('.', 'index.html')
33
 
34
- # Step 2: API Endpoints aur Session Storage
35
  API_ENDPOINTS = {
36
- "skin_disease": "https://your-api-domain.com/skin-disease-detection",
37
  "medicine_info": "http://localhost:5002/api/query",
38
- "report_reading": "https://your-api-domain.com/report-reading",
39
  "disease_query": "http://localhost:5001/ask"
40
  }
 
 
41
  SESSIONS = {}
42
 
43
- # Step 3: Gemini se Query Classify karne ka Function
44
  def classify_query_with_gemini(query: str):
45
- """User ki query ko Gemini API ka istemal karke classify karta hai."""
46
  model = genai.GenerativeModel('gemini-2.5-flash-lite')
47
 
48
- # *** PROMPT HAS BEEN IMPROVED ***
49
  prompt = f"""
50
  Analyze the user's medical query and classify it into one of the following categories:
51
  - skin_disease: For queries about skin conditions, rashes, moles, spots, or any visible symptoms on the skin.
52
- - medicine_info: For query about medicine(like how to use it, side effects, etc.) and also questions about a specific Medicine shown in attached image (optional) .
53
- - report_reading: For queries asking to interpret or explain a medical report, lab test, or blood work from an image.
54
  - disease_query: For general questions about diseases, symptoms, causes, or treatments.
55
 
56
- Based on the classification, determine if an image is essential to answer the query accurately.
57
- Generate response in English only.
58
-
59
- The user query is:
60
- ---START OF QUERY---
61
- {query}
62
- ---END OF QUERY---
63
-
64
- Provide the output ONLY in a valid JSON format with two keys: "category" (string) and "image_required" (boolean).
65
-
66
- Example 1:
67
- Query: "what are the symptoms of typhoid"
68
- Output: {{"category": "disease_query", "image_required": false}}
69
-
70
- Example 2:
71
- Query: "I have a red circular rash on my arm, what is it?"
72
- Output: {{"category": "skin_disease", "image_required": true}}
73
-
74
- Example 3:
75
- Query: "Can you tell me what this lab report says?"
76
- Output: {{"category": "report_reading", "image_required": true}}
77
 
78
- Example 4:
79
- Query: "What is this white pill with 'IP 204' written on it?"
80
- Output: {{"category": "medicine_info", "image_required": true}}
 
 
 
 
81
  """
82
 
83
  try:
84
  response = model.generate_content(prompt)
85
  cleaned_text = response.text.strip().replace('```json', '').replace('```', '')
86
  result = json.loads(cleaned_text)
 
87
  return result
88
  except Exception as e:
89
- print(f"Gemini API call ya JSON parsing mein error: {e}")
90
- return None
 
91
 
92
- # Step 4: API Routes (Endpoints)
93
  @app.route('/start_session', methods=['POST'])
94
  def start_session():
95
  session_id = str(uuid.uuid4())
@@ -111,37 +100,58 @@ def process_query():
111
  print(f"Session {session_id}: Query received: '{query}'")
112
  classification = classify_query_with_gemini(query)
113
 
114
- if not classification:
115
- return jsonify({"error": "Could not classify the query."}), 500
116
-
117
  SESSIONS[session_id]['classification'] = classification
118
  SESSIONS[session_id]['query'] = query
119
 
120
  if classification.get('image_required'):
121
- print(f"Session {session_id}: Image required for category '{classification.get('category')}'")
122
  return jsonify({
123
  "status": "image_required",
124
- "message": "Please send the request to /process_with_image with the required photo."
 
125
  }), 200
126
  else:
127
- print(f"Session {session_id}: No image required. Forwarding to '{classification.get('category')}' API.")
128
- # Asli API ko call karein (Abhi ke liye mock response)
129
- # Session se query aur classification nikalein
130
- query = SESSIONS[session_id].get('query')
131
- classification = SESSIONS[session_id].get('classification')
132
  category = classification['category']
133
  endpoint_url = API_ENDPOINTS.get(category)
134
- if category == "medicine_info":
135
- response = requests.post(endpoint_url, json={"main_query": query})
136
- else:
137
- response = requests.post(endpoint_url, data={"main_query": query})
138
- del SESSIONS[session_id]
139
- print(f"Session {session_id} closed.")
140
- return jsonify({
141
- "status": "success",
142
- "response": response.json(),
143
- "data": f"Information about '{query}': This is a tuned response from the {classification.get('category')} service."
144
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
  @app.route('/process_with_image', methods=['POST'])
147
  def process_with_image():
@@ -151,52 +161,82 @@ def process_with_image():
151
  return jsonify({"error": "Invalid or missing session_id"}), 400
152
 
153
  if 'photo' not in request.files:
154
- return jsonify({"error": "No photo file found in the request"}), 400
155
 
156
  file = request.files['photo']
157
  if file.filename == '':
158
- return jsonify({"error": "No selected file"}), 400
159
 
160
- # Session se query aur classification nikalein
161
  query = SESSIONS[session_id].get('query')
162
  classification = SESSIONS[session_id].get('classification')
163
- category = classification['category']
164
  endpoint_url = API_ENDPOINTS.get(category)
165
 
166
- print(f"Session {session_id}: Image received. Preparing to forward to '{category}' API.")
167
-
168
- # *** NEW: FORWARDING LOGIC THAT MATCHES YOUR CURL COMMAND ***
169
- # The file object from Flask needs its stream to be readable by `requests`
170
- # We pass the file stream, filename, and mimetype to requests
171
- # The dictionary key 'file' matches the '-F file=@...' part of your curl command
172
- files_payload = {'file': (file.filename, file.stream, file.mimetype)}
173
 
174
- # The dictionary key 'query' matches the '-F query=...' part
175
- data_payload = {'query': query}
176
 
177
  try:
178
- # NOTE: Neeche di gayi line asli API call hai.
179
- # Jab aapka backend service (e.g., http://localhost:5002/api/query) taiyaar ho,
180
- # to is line ko uncomment kar dein.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
- response_from_service = requests.post(endpoint_url, files=files_payload, data=data_payload)
183
- response_from_service.raise_for_status() # Agar 4xx/5xx error ho to exception raise karega
184
- tuned_response = response_from_service.json() # Assume service returns JSON
185
-
186
- # Abhi ke liye, hum ek mock response bhej rahe hain
187
- mock_response = {
188
- "status": "success",
189
- "response": tuned_response,
190
- "data": f"Analysis for '{query}' based on your image: This is a tuned MOCK response from the {category} service."
191
- }
192
 
193
- # Session close karein
194
  del SESSIONS[session_id]
195
- print(f"Session {session_id} closed.")
196
 
197
- return jsonify(mock_response)
 
 
 
 
198
 
199
  except requests.exceptions.RequestException as e:
 
200
  del SESSIONS[session_id]
201
- print(f"Session {session_id} closed after failed API call.")
202
- return jsonify({"status": "error", "message": f"Backend service call failed: {e}"}), 503
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # main.py - FIXED VERSION
2
+
3
  import os
4
  import uuid
5
  import json
 
10
  from dotenv import load_dotenv
11
  from flask_cors import CORS
12
 
13
+ # Step 1: API Key and Environment Setup
 
14
  load_dotenv()
15
  try:
16
  genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
17
  except TypeError:
18
+ print("ERROR: Google API Key not found.")
19
+ print("Create a .env file and add 'GOOGLE_API_KEY=your_key_here'")
20
  exit()
21
 
22
  app = Flask(__name__, static_folder='.', static_url_path='')
23
  CORS(app)
24
 
25
+ # Serve static files
26
  @app.route('/<path:path>')
27
  def serve_static(path):
28
  return send_from_directory('.', path)
29
 
 
30
  @app.route('/')
31
  def serve_index():
32
  return send_from_directory('.', 'index.html')
33
 
34
+ # Step 2: FIXED API Endpoints
35
  API_ENDPOINTS = {
36
+ "skin_disease": "http://localhost:5003/api/skin", # Update when ready
37
  "medicine_info": "http://localhost:5002/api/query",
38
+ "report_reading": "http://localhost:5004/api/report", # Update when ready
39
  "disease_query": "http://localhost:5001/ask"
40
  }
41
+
42
+ # Session storage
43
  SESSIONS = {}
44
 
45
+ # Step 3: Query Classification Function
46
  def classify_query_with_gemini(query: str):
47
+ """Classify user query using Gemini API"""
48
  model = genai.GenerativeModel('gemini-2.5-flash-lite')
49
 
 
50
  prompt = f"""
51
  Analyze the user's medical query and classify it into one of the following categories:
52
  - skin_disease: For queries about skin conditions, rashes, moles, spots, or any visible symptoms on the skin.
53
+ - medicine_info: For queries about medicines (usage, side effects, identification from image).
54
+ - report_reading: For queries asking to interpret medical reports, lab tests, or blood work from images.
55
  - disease_query: For general questions about diseases, symptoms, causes, or treatments.
56
 
57
+ Determine if an image is essential to answer the query accurately.
58
+
59
+ User query: "{query}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ Output ONLY valid JSON with "category" (string) and "image_required" (boolean).
62
+
63
+ Examples:
64
+ "what are the symptoms of typhoid" -> {{"category": "disease_query", "image_required": false}}
65
+ "I have a red rash on my arm" -> {{"category": "skin_disease", "image_required": true}}
66
+ "What does this lab report say?" -> {{"category": "report_reading", "image_required": true}}
67
+ "What is this white pill?" -> {{"category": "medicine_info", "image_required": true}}
68
  """
69
 
70
  try:
71
  response = model.generate_content(prompt)
72
  cleaned_text = response.text.strip().replace('```json', '').replace('```', '')
73
  result = json.loads(cleaned_text)
74
+ print(f"Classification result: {result}")
75
  return result
76
  except Exception as e:
77
+ print(f"Classification error: {e}")
78
+ # Default fallback
79
+ return {"category": "disease_query", "image_required": False}
80
 
81
+ # Step 4: API Routes
82
  @app.route('/start_session', methods=['POST'])
83
  def start_session():
84
  session_id = str(uuid.uuid4())
 
100
  print(f"Session {session_id}: Query received: '{query}'")
101
  classification = classify_query_with_gemini(query)
102
 
 
 
 
103
  SESSIONS[session_id]['classification'] = classification
104
  SESSIONS[session_id]['query'] = query
105
 
106
  if classification.get('image_required'):
107
+ print(f"Session {session_id}: Image required for '{classification.get('category')}'")
108
  return jsonify({
109
  "status": "image_required",
110
+ "message": "Please upload an image via /process_with_image endpoint",
111
+ "category": classification.get('category')
112
  }), 200
113
  else:
114
+ # Process without image
 
 
 
 
115
  category = classification['category']
116
  endpoint_url = API_ENDPOINTS.get(category)
117
+
118
+ if not endpoint_url:
119
+ return jsonify({"error": f"No endpoint configured for category: {category}"}), 500
120
+
121
+ try:
122
+ print(f"Forwarding to {category} API at {endpoint_url}")
123
+
124
+ # FIXED: Proper request format for each service
125
+ if category == "disease_query":
126
+ # disease.py expects 'query' field
127
+ response = requests.post(endpoint_url, json={"query": query})
128
+ elif category == "medicine_info":
129
+ # medicine.py expects 'main_query' field
130
+ response = requests.post(endpoint_url, json={"main_query": query})
131
+ else:
132
+ # Default format for future services
133
+ response = requests.post(endpoint_url, json={"query": query})
134
+
135
+ response.raise_for_status()
136
+ result = response.json()
137
+
138
+ # Clean up session
139
+ del SESSIONS[session_id]
140
+ print(f"Session {session_id} closed successfully")
141
+
142
+ return jsonify({
143
+ "status": "success",
144
+ "category": category,
145
+ "response": result
146
+ })
147
+
148
+ except requests.exceptions.RequestException as e:
149
+ print(f"Error calling {category} API: {e}")
150
+ del SESSIONS[session_id]
151
+ return jsonify({
152
+ "error": f"Failed to reach {category} service",
153
+ "details": str(e)
154
+ }), 503
155
 
156
  @app.route('/process_with_image', methods=['POST'])
157
  def process_with_image():
 
161
  return jsonify({"error": "Invalid or missing session_id"}), 400
162
 
163
  if 'photo' not in request.files:
164
+ return jsonify({"error": "No photo file found in request"}), 400
165
 
166
  file = request.files['photo']
167
  if file.filename == '':
168
+ return jsonify({"error": "No file selected"}), 400
169
 
170
+ # Get session data
171
  query = SESSIONS[session_id].get('query')
172
  classification = SESSIONS[session_id].get('classification')
173
+ category = classification.get('category')
174
  endpoint_url = API_ENDPOINTS.get(category)
175
 
176
+ if not endpoint_url:
177
+ del SESSIONS[session_id]
178
+ return jsonify({"error": f"No endpoint configured for category: {category}"}), 500
 
 
 
 
179
 
180
+ print(f"Session {session_id}: Processing image for '{category}'")
 
181
 
182
  try:
183
+ # FIXED: Proper request format based on category
184
+ if category == "medicine_info":
185
+ # medicine.py expects 'file' and 'main_query'
186
+ files = {'file': (file.filename, file.stream, file.mimetype)}
187
+ data = {'main_query': query}
188
+ response = requests.post(endpoint_url, files=files, data=data)
189
+
190
+ elif category == "disease_query":
191
+ # disease.py doesn't typically need images, but if it did:
192
+ files = {'file': (file.filename, file.stream, file.mimetype)}
193
+ data = {'query': query}
194
+ response = requests.post(endpoint_url, files=files, data=data)
195
+
196
+ else:
197
+ # Default format for skin_disease, report_reading
198
+ files = {'file': (file.filename, file.stream, file.mimetype)}
199
+ data = {'query': query}
200
+ response = requests.post(endpoint_url, files=files, data=data)
201
 
202
+ response.raise_for_status()
203
+ result = response.json()
 
 
 
 
 
 
 
 
204
 
205
+ # Clean up session
206
  del SESSIONS[session_id]
207
+ print(f"Session {session_id} closed successfully")
208
 
209
+ return jsonify({
210
+ "status": "success",
211
+ "category": category,
212
+ "response": result
213
+ })
214
 
215
  except requests.exceptions.RequestException as e:
216
+ print(f"Error calling {category} API with image: {e}")
217
  del SESSIONS[session_id]
218
+ return jsonify({
219
+ "error": f"Failed to reach {category} service",
220
+ "details": str(e)
221
+ }), 503
222
+
223
+ @app.route('/health', methods=['GET'])
224
+ def health_check():
225
+ """Health check endpoint to verify services"""
226
+ service_status = {}
227
+
228
+ for service, url in API_ENDPOINTS.items():
229
+ try:
230
+ # Try to connect to each service
231
+ if "localhost" in url:
232
+ test_url = url.replace('/ask', '').replace('/api/query', '')
233
+ requests.get(test_url, timeout=1)
234
+ service_status[service] = "✅ Running"
235
+ except:
236
+ service_status[service] = "❌ Not reachable"
237
+
238
+ return jsonify({
239
+ "main_service": "✅ Running",
240
+ "connected_services": service_status,
241
+ "sessions_active": len(SESSIONS)
242
+ })