MonilM commited on
Commit
f15a593
·
1 Parent(s): 6c095fc

Added NLP#2

Browse files
Files changed (2) hide show
  1. app.py +38 -34
  2. nlp_service.py +8 -2
app.py CHANGED
@@ -232,46 +232,19 @@ def extract_expense():
232
  extracted_text = "\n".join(extracted_lines)
233
  main_amount_ocr = find_main_amount(ocr_result) # Keep OCR amount extraction
234
 
235
- # --- NEW: Call NLP Function Directly ---
236
- nlp_analysis_result = None
237
- nlp_error = None
238
- if extracted_text:
239
- try:
240
- # Call the imported analysis function
241
- nlp_analysis_result = analyze_expense_text(extracted_text)
242
- print(f"NLP Service Analysis Result: {nlp_analysis_result}")
243
- # Check if the NLP analysis itself reported an error/failure
244
- if nlp_analysis_result.get("status") == "failed":
245
- nlp_error = nlp_analysis_result.get("message", "NLP processing failed")
246
- # Keep the result structure but note the failure
247
- except Exception as nlp_e:
248
- nlp_error = f"Error calling NLP analysis function: {nlp_e}"
249
- print(f"Error calling NLP function: {nlp_error}")
250
- nlp_analysis_result = None # Ensure result is None on exception during call
251
- else:
252
- nlp_error = "No text extracted from image for NLP analysis."
253
- # --- End NLP Call ---
254
-
255
- # Construct the response
256
  response_data = {
257
  "type": "photo",
258
  "extracted_text": extracted_text,
259
  "main_amount_ocr": main_amount_ocr, # Amount found by OCR regex logic
260
- "nlp_analysis": nlp_analysis_result, # Include the full NLP analysis result (or None)
261
- "nlp_error": nlp_error # Include any error from NLP call/processing
262
  }
263
 
264
- # Optional: Add top-level convenience fields based on successful NLP analysis
265
- if nlp_analysis_result and nlp_analysis_result.get("status") == "success":
266
- if nlp_analysis_result.get("action") == "add_expense":
267
- response_data['confirmed_expense_details'] = nlp_analysis_result.get('details')
268
- response_data['confirmation_message'] = nlp_analysis_result.get('message')
269
- elif nlp_analysis_result.get("action") == "query_expense":
270
- # Include query results if applicable (depends on nlp_service structure)
271
- response_data['query_message'] = nlp_analysis_result.get('message')
272
- response_data['query_criteria'] = nlp_analysis_result.get('criteria')
273
- response_data['query_results_count'] = nlp_analysis_result.get('results_count')
274
-
275
  return jsonify(response_data)
276
 
277
  except Exception as e:
@@ -285,6 +258,37 @@ def extract_expense():
285
 
286
  return jsonify({"error": "File processing failed"}), 500
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  # --- NEW: Health Check Endpoint ---
289
  @app.route('/health', methods=['GET'])
290
  def health_check():
 
232
  extracted_text = "\n".join(extracted_lines)
233
  main_amount_ocr = find_main_amount(ocr_result) # Keep OCR amount extraction
234
 
235
+ # --- REMOVED: NLP Call ---
236
+ # nlp_analysis_result = None
237
+ # nlp_error = None
238
+ # ... (removed NLP call logic) ...
239
+ # --- End Removed NLP Call ---
240
+
241
+ # Construct the response (only OCR results)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  response_data = {
243
  "type": "photo",
244
  "extracted_text": extracted_text,
245
  "main_amount_ocr": main_amount_ocr, # Amount found by OCR regex logic
 
 
246
  }
247
 
 
 
 
 
 
 
 
 
 
 
 
248
  return jsonify(response_data)
249
 
250
  except Exception as e:
 
258
 
259
  return jsonify({"error": "File processing failed"}), 500
260
 
261
+ # --- NEW: NLP Message Endpoint ---
262
+ @app.route('/message', methods=['POST'])
263
+ def process_message():
264
+ data = request.get_json()
265
+ if not data or 'text' not in data:
266
+ return jsonify({"error": "Missing 'text' field in JSON payload"}), 400
267
+
268
+ text_message = data['text']
269
+ if not text_message:
270
+ return jsonify({"error": "'text' field cannot be empty"}), 400
271
+
272
+ nlp_analysis_result = None
273
+ nlp_error = None
274
+ try:
275
+ # Call the imported analysis function
276
+ nlp_analysis_result = analyze_expense_text(text_message)
277
+ print(f"NLP Service Analysis Result: {nlp_analysis_result}")
278
+ # Check if the NLP analysis itself reported an error/failure
279
+ if nlp_analysis_result.get("status") == "failed":
280
+ nlp_error = nlp_analysis_result.get("message", "NLP processing failed")
281
+ # Return the failure result from NLP service
282
+ return jsonify(nlp_analysis_result), 400 # Or 200 with error status? Let's use 200 for now.
283
+
284
+ # Return the successful analysis result
285
+ return jsonify(nlp_analysis_result)
286
+
287
+ except Exception as nlp_e:
288
+ nlp_error = f"Error calling NLP analysis function: {nlp_e}"
289
+ print(f"Error calling NLP function: {nlp_error}")
290
+ return jsonify({"error": "An internal error occurred during NLP processing", "details": nlp_error}), 500
291
+
292
  # --- NEW: Health Check Endpoint ---
293
  @app.route('/health', methods=['GET'])
294
  def health_check():
nlp_service.py CHANGED
@@ -673,6 +673,7 @@ def call_gemini_api(text, api_key):
673
  }
674
  # Construct the payload based on Gemini API requirements
675
  # This prompt asks Gemini to act like the existing NLP service
 
676
  prompt = f"""Analyze the following text for expense tracking. Determine the intent ('add_expense' or 'query_expense') and extract relevant details.
677
 
678
  Text: "{text}"
@@ -721,6 +722,8 @@ Provide only the JSON output.
721
  logging.debug(f"Raw Gemini API response: {gemini_response_raw}")
722
 
723
  # --- Process gemini_response ---
 
 
724
  # Extract the text content which should contain the JSON
725
  if 'candidates' in gemini_response_raw and len(gemini_response_raw['candidates']) > 0:
726
  content = gemini_response_raw['candidates'][0].get('content', {}).get('parts', [{}])[0].get('text')
@@ -738,10 +741,11 @@ Provide only the JSON output.
738
  return parsed_result
739
  else:
740
  logging.warning("Gemini response parsed but lacks expected structure.")
 
741
  return {"action": "info", "status": "success", "message": f"Gemini suggestion: {content_cleaned}"}
742
  except json.JSONDecodeError as json_err:
743
  logging.warning(f"Failed to decode JSON from Gemini response: {json_err}. Raw content: {content_cleaned}")
744
- # Return the raw text as a message if JSON parsing fails
745
  return {"action": "info", "status": "success", "message": f"Gemini suggestion: {content_cleaned}"}
746
  else:
747
  logging.warning("No text content found in Gemini response candidates.")
@@ -763,7 +767,9 @@ Provide only the JSON output.
763
  logging.error(f"Gemini API error response (non-JSON): {e.response.text}")
764
  return None
765
  except Exception as e:
766
- logging.error(f"An unexpected error occurred during Gemini API call or processing: {e}")
 
 
767
  return None
768
 
769
 
 
673
  }
674
  # Construct the payload based on Gemini API requirements
675
  # This prompt asks Gemini to act like the existing NLP service
676
+ # Corrected indentation for the prompt string
677
  prompt = f"""Analyze the following text for expense tracking. Determine the intent ('add_expense' or 'query_expense') and extract relevant details.
678
 
679
  Text: "{text}"
 
722
  logging.debug(f"Raw Gemini API response: {gemini_response_raw}")
723
 
724
  # --- Process gemini_response ---
725
+ content = None # Initialize content to None
726
+ content_cleaned = None # Initialize content_cleaned to None
727
  # Extract the text content which should contain the JSON
728
  if 'candidates' in gemini_response_raw and len(gemini_response_raw['candidates']) > 0:
729
  content = gemini_response_raw['candidates'][0].get('content', {}).get('parts', [{}])[0].get('text')
 
741
  return parsed_result
742
  else:
743
  logging.warning("Gemini response parsed but lacks expected structure.")
744
+ # Return info message if structure is wrong but content exists
745
  return {"action": "info", "status": "success", "message": f"Gemini suggestion: {content_cleaned}"}
746
  except json.JSONDecodeError as json_err:
747
  logging.warning(f"Failed to decode JSON from Gemini response: {json_err}. Raw content: {content_cleaned}")
748
+ # Return the raw text as a message if JSON parsing fails but content exists
749
  return {"action": "info", "status": "success", "message": f"Gemini suggestion: {content_cleaned}"}
750
  else:
751
  logging.warning("No text content found in Gemini response candidates.")
 
767
  logging.error(f"Gemini API error response (non-JSON): {e.response.text}")
768
  return None
769
  except Exception as e:
770
+ # Include content_cleaned in the log if available during unexpected errors
771
+ error_context = f"Raw content (if available): {content_cleaned}" if content_cleaned else "No raw content parsed."
772
+ logging.error(f"An unexpected error occurred during Gemini API call or processing: {e}. {error_context}")
773
  return None
774
 
775