NitinBot001 commited on
Commit
0f0096d
·
verified ·
1 Parent(s): 2303f84

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +190 -192
main.py CHANGED
@@ -1,192 +1,190 @@
1
- import os
2
- import uuid
3
- import json
4
- import requests
5
- from flask import Flask, request, jsonify
6
- from werkzeug.utils import secure_filename
7
- 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__)
22
- CORS(app)
23
-
24
- # Step 2: API Endpoints aur Session Storage
25
- API_ENDPOINTS = {
26
- "skin_disease": "https://your-api-domain.com/skin-disease-detection",
27
- "medicine_info": "http://localhost:5002/api/query",
28
- "report_reading": "https://your-api-domain.com/report-reading",
29
- "disease_query": "http://localhost:5001/ask"
30
- }
31
- SESSIONS = {}
32
-
33
- # Step 3: Gemini se Query Classify karne ka Function
34
- def classify_query_with_gemini(query: str):
35
- """User ki query ko Gemini API ka istemal karke classify karta hai."""
36
- model = genai.GenerativeModel('gemini-2.5-flash-lite')
37
-
38
- # *** PROMPT HAS BEEN IMPROVED ***
39
- prompt = f"""
40
- Analyze the user's medical query and classify it into one of the following categories:
41
- - skin_disease: For queries about skin conditions, rashes, moles, spots, or any visible symptoms on the skin.
42
- - 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) .
43
- - report_reading: For queries asking to interpret or explain a medical report, lab test, or blood work from an image.
44
- - disease_query: For general questions about diseases, symptoms, causes, or treatments.
45
-
46
- Based on the classification, determine if an image is essential to answer the query accurately.
47
- Generate response in English only.
48
-
49
- The user query is:
50
- ---START OF QUERY---
51
- {query}
52
- ---END OF QUERY---
53
-
54
- Provide the output ONLY in a valid JSON format with two keys: "category" (string) and "image_required" (boolean).
55
-
56
- Example 1:
57
- Query: "what are the symptoms of typhoid"
58
- Output: {{"category": "disease_query", "image_required": false}}
59
-
60
- Example 2:
61
- Query: "I have a red circular rash on my arm, what is it?"
62
- Output: {{"category": "skin_disease", "image_required": true}}
63
-
64
- Example 3:
65
- Query: "Can you tell me what this lab report says?"
66
- Output: {{"category": "report_reading", "image_required": true}}
67
-
68
- Example 4:
69
- Query: "What is this white pill with 'IP 204' written on it?"
70
- Output: {{"category": "medicine_info", "image_required": true}}
71
- """
72
-
73
- try:
74
- response = model.generate_content(prompt)
75
- cleaned_text = response.text.strip().replace('```json', '').replace('```', '')
76
- result = json.loads(cleaned_text)
77
- return result
78
- except Exception as e:
79
- print(f"Gemini API call ya JSON parsing mein error: {e}")
80
- return None
81
-
82
- # Step 4: API Routes (Endpoints)
83
- @app.route('/start_session', methods=['POST'])
84
- def start_session():
85
- session_id = str(uuid.uuid4())
86
- SESSIONS[session_id] = {"status": "started"}
87
- print(f"Session started: {session_id}")
88
- return jsonify({"session_id": session_id}), 200
89
-
90
- @app.route('/process_query', methods=['POST'])
91
- def process_query():
92
- data = request.get_json()
93
- session_id = data.get('session_id')
94
- query = data.get('query')
95
-
96
- if not session_id or session_id not in SESSIONS:
97
- return jsonify({"error": "Invalid or missing session_id"}), 400
98
- if not query:
99
- return jsonify({"error": "Query is required"}), 400
100
-
101
- print(f"Session {session_id}: Query received: '{query}'")
102
- classification = classify_query_with_gemini(query)
103
-
104
- if not classification:
105
- return jsonify({"error": "Could not classify the query."}), 500
106
-
107
- SESSIONS[session_id]['classification'] = classification
108
- SESSIONS[session_id]['query'] = query
109
-
110
- if classification.get('image_required'):
111
- print(f"Session {session_id}: Image required for category '{classification.get('category')}'")
112
- return jsonify({
113
- "status": "image_required",
114
- "message": "Please send the request to /process_with_image with the required photo."
115
- }), 200
116
- else:
117
- print(f"Session {session_id}: No image required. Forwarding to '{classification.get('category')}' API.")
118
- # Asli API ko call karein (Abhi ke liye mock response)
119
- # Session se query aur classification nikalein
120
- query = SESSIONS[session_id].get('query')
121
- classification = SESSIONS[session_id].get('classification')
122
- category = classification['category']
123
- endpoint_url = API_ENDPOINTS.get(category)
124
- response = requests.post(endpoint_url, json={"query": query}) or requests.post(endpoint_url, data={"query": query}) or requests.post(endpoint_url, files={"query": query}) or requests.post(endpoint_url, payload={"query": query})
125
- del SESSIONS[session_id]
126
- print(f"Session {session_id} closed.")
127
- return jsonify({
128
- "status": "success",
129
- "response": response.json(),
130
- "data": f"Information about '{query}': This is a tuned response from the {classification.get('category')} service."
131
- })
132
-
133
- @app.route('/process_with_image', methods=['POST'])
134
- def process_with_image():
135
- session_id = request.form.get('session_id')
136
-
137
- if not session_id or session_id not in SESSIONS:
138
- return jsonify({"error": "Invalid or missing session_id"}), 400
139
-
140
- if 'photo' not in request.files:
141
- return jsonify({"error": "No photo file found in the request"}), 400
142
-
143
- file = request.files['photo']
144
- if file.filename == '':
145
- return jsonify({"error": "No selected file"}), 400
146
-
147
- # Session se query aur classification nikalein
148
- query = SESSIONS[session_id].get('query')
149
- classification = SESSIONS[session_id].get('classification')
150
- category = classification['category']
151
- endpoint_url = API_ENDPOINTS.get(category)
152
-
153
- print(f"Session {session_id}: Image received. Preparing to forward to '{category}' API.")
154
-
155
- # *** NEW: FORWARDING LOGIC THAT MATCHES YOUR CURL COMMAND ***
156
- # The file object from Flask needs its stream to be readable by `requests`
157
- # We pass the file stream, filename, and mimetype to requests
158
- # The dictionary key 'file' matches the '-F file=@...' part of your curl command
159
- files_payload = {'file': (file.filename, file.stream, file.mimetype)}
160
-
161
- # The dictionary key 'query' matches the '-F query=...' part
162
- data_payload = {'query': query}
163
-
164
- try:
165
- # NOTE: Neeche di gayi line asli API call hai.
166
- # Jab aapka backend service (e.g., http://localhost:5002/api/query) taiyaar ho,
167
- # to is line ko uncomment kar dein.
168
-
169
- response_from_service = requests.post(endpoint_url, files=files_payload, data=data_payload)
170
- response_from_service.raise_for_status() # Agar 4xx/5xx error ho to exception raise karega
171
- tuned_response = response_from_service.json() # Assume service returns JSON
172
-
173
- # Abhi ke liye, hum ek mock response bhej rahe hain
174
- mock_response = {
175
- "status": "success",
176
- "response": tuned_response,
177
- "data": f"Analysis for '{query}' based on your image: This is a tuned MOCK response from the {category} service."
178
- }
179
-
180
- # Session close karein
181
- del SESSIONS[session_id]
182
- print(f"Session {session_id} closed.")
183
-
184
- return jsonify(mock_response)
185
-
186
- except requests.exceptions.RequestException as e:
187
- del SESSIONS[session_id]
188
- print(f"Session {session_id} closed after failed API call.")
189
- return jsonify({"status": "error", "message": f"Backend service call failed: {e}"}), 503
190
-
191
- if __name__ == '__main__':
192
- app.run(debug=True, port=5000)
 
1
+ import os
2
+ import uuid
3
+ import json
4
+ import requests
5
+ from flask import Flask, request, jsonify
6
+ from werkzeug.utils import secure_filename
7
+ 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__)
22
+ CORS(app)
23
+
24
+ # Step 2: API Endpoints aur Session Storage
25
+ API_ENDPOINTS = {
26
+ "skin_disease": "https://your-api-domain.com/skin-disease-detection",
27
+ "medicine_info": "http://localhost:5002/api/query",
28
+ "report_reading": "https://your-api-domain.com/report-reading",
29
+ "disease_query": "http://localhost:5001/ask"
30
+ }
31
+ SESSIONS = {}
32
+
33
+ # Step 3: Gemini se Query Classify karne ka Function
34
+ def classify_query_with_gemini(query: str):
35
+ """User ki query ko Gemini API ka istemal karke classify karta hai."""
36
+ model = genai.GenerativeModel('gemini-2.5-flash-lite')
37
+
38
+ # *** PROMPT HAS BEEN IMPROVED ***
39
+ prompt = f"""
40
+ Analyze the user's medical query and classify it into one of the following categories:
41
+ - skin_disease: For queries about skin conditions, rashes, moles, spots, or any visible symptoms on the skin.
42
+ - 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) .
43
+ - report_reading: For queries asking to interpret or explain a medical report, lab test, or blood work from an image.
44
+ - disease_query: For general questions about diseases, symptoms, causes, or treatments.
45
+
46
+ Based on the classification, determine if an image is essential to answer the query accurately.
47
+ Generate response in English only.
48
+
49
+ The user query is:
50
+ ---START OF QUERY---
51
+ {query}
52
+ ---END OF QUERY---
53
+
54
+ Provide the output ONLY in a valid JSON format with two keys: "category" (string) and "image_required" (boolean).
55
+
56
+ Example 1:
57
+ Query: "what are the symptoms of typhoid"
58
+ Output: {{"category": "disease_query", "image_required": false}}
59
+
60
+ Example 2:
61
+ Query: "I have a red circular rash on my arm, what is it?"
62
+ Output: {{"category": "skin_disease", "image_required": true}}
63
+
64
+ Example 3:
65
+ Query: "Can you tell me what this lab report says?"
66
+ Output: {{"category": "report_reading", "image_required": true}}
67
+
68
+ Example 4:
69
+ Query: "What is this white pill with 'IP 204' written on it?"
70
+ Output: {{"category": "medicine_info", "image_required": true}}
71
+ """
72
+
73
+ try:
74
+ response = model.generate_content(prompt)
75
+ cleaned_text = response.text.strip().replace('```json', '').replace('```', '')
76
+ result = json.loads(cleaned_text)
77
+ return result
78
+ except Exception as e:
79
+ print(f"Gemini API call ya JSON parsing mein error: {e}")
80
+ return None
81
+
82
+ # Step 4: API Routes (Endpoints)
83
+ @app.route('/start_session', methods=['POST'])
84
+ def start_session():
85
+ session_id = str(uuid.uuid4())
86
+ SESSIONS[session_id] = {"status": "started"}
87
+ print(f"Session started: {session_id}")
88
+ return jsonify({"session_id": session_id}), 200
89
+
90
+ @app.route('/process_query', methods=['POST'])
91
+ def process_query():
92
+ data = request.get_json()
93
+ session_id = data.get('session_id')
94
+ query = data.get('query')
95
+
96
+ if not session_id or session_id not in SESSIONS:
97
+ return jsonify({"error": "Invalid or missing session_id"}), 400
98
+ if not query:
99
+ return jsonify({"error": "Query is required"}), 400
100
+
101
+ print(f"Session {session_id}: Query received: '{query}'")
102
+ classification = classify_query_with_gemini(query)
103
+
104
+ if not classification:
105
+ return jsonify({"error": "Could not classify the query."}), 500
106
+
107
+ SESSIONS[session_id]['classification'] = classification
108
+ SESSIONS[session_id]['query'] = query
109
+
110
+ if classification.get('image_required'):
111
+ print(f"Session {session_id}: Image required for category '{classification.get('category')}'")
112
+ return jsonify({
113
+ "status": "image_required",
114
+ "message": "Please send the request to /process_with_image with the required photo."
115
+ }), 200
116
+ else:
117
+ print(f"Session {session_id}: No image required. Forwarding to '{classification.get('category')}' API.")
118
+ # Asli API ko call karein (Abhi ke liye mock response)
119
+ # Session se query aur classification nikalein
120
+ query = SESSIONS[session_id].get('query')
121
+ classification = SESSIONS[session_id].get('classification')
122
+ category = classification['category']
123
+ endpoint_url = API_ENDPOINTS.get(category)
124
+ response = requests.post(endpoint_url, json={"query": query}) or requests.post(endpoint_url, data={"query": query}) or requests.post(endpoint_url, files={"query": query}) or requests.post(endpoint_url, payload={"query": query})
125
+ del SESSIONS[session_id]
126
+ print(f"Session {session_id} closed.")
127
+ return jsonify({
128
+ "status": "success",
129
+ "response": response.json(),
130
+ "data": f"Information about '{query}': This is a tuned response from the {classification.get('category')} service."
131
+ })
132
+
133
+ @app.route('/process_with_image', methods=['POST'])
134
+ def process_with_image():
135
+ session_id = request.form.get('session_id')
136
+
137
+ if not session_id or session_id not in SESSIONS:
138
+ return jsonify({"error": "Invalid or missing session_id"}), 400
139
+
140
+ if 'photo' not in request.files:
141
+ return jsonify({"error": "No photo file found in the request"}), 400
142
+
143
+ file = request.files['photo']
144
+ if file.filename == '':
145
+ return jsonify({"error": "No selected file"}), 400
146
+
147
+ # Session se query aur classification nikalein
148
+ query = SESSIONS[session_id].get('query')
149
+ classification = SESSIONS[session_id].get('classification')
150
+ category = classification['category']
151
+ endpoint_url = API_ENDPOINTS.get(category)
152
+
153
+ print(f"Session {session_id}: Image received. Preparing to forward to '{category}' API.")
154
+
155
+ # *** NEW: FORWARDING LOGIC THAT MATCHES YOUR CURL COMMAND ***
156
+ # The file object from Flask needs its stream to be readable by `requests`
157
+ # We pass the file stream, filename, and mimetype to requests
158
+ # The dictionary key 'file' matches the '-F file=@...' part of your curl command
159
+ files_payload = {'file': (file.filename, file.stream, file.mimetype)}
160
+
161
+ # The dictionary key 'query' matches the '-F query=...' part
162
+ data_payload = {'query': query}
163
+
164
+ try:
165
+ # NOTE: Neeche di gayi line asli API call hai.
166
+ # Jab aapka backend service (e.g., http://localhost:5002/api/query) taiyaar ho,
167
+ # to is line ko uncomment kar dein.
168
+
169
+ response_from_service = requests.post(endpoint_url, files=files_payload, data=data_payload)
170
+ response_from_service.raise_for_status() # Agar 4xx/5xx error ho to exception raise karega
171
+ tuned_response = response_from_service.json() # Assume service returns JSON
172
+
173
+ # Abhi ke liye, hum ek mock response bhej rahe hain
174
+ mock_response = {
175
+ "status": "success",
176
+ "response": tuned_response,
177
+ "data": f"Analysis for '{query}' based on your image: This is a tuned MOCK response from the {category} service."
178
+ }
179
+
180
+ # Session close karein
181
+ del SESSIONS[session_id]
182
+ print(f"Session {session_id} closed.")
183
+
184
+ return jsonify(mock_response)
185
+
186
+ except requests.exceptions.RequestException as e:
187
+ del SESSIONS[session_id]
188
+ print(f"Session {session_id} closed after failed API call.")
189
+ return jsonify({"status": "error", "message": f"Backend service call failed: {e}"}), 503
190
+