rairo commited on
Commit
4b20182
·
verified ·
1 Parent(s): 3fc1f49

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +135 -13
main.py CHANGED
@@ -45,7 +45,75 @@ bucket = storage.bucket()
45
 
46
  # --- Gemini Client ---
47
  client = genai.Client(api_key=os.getenv("Gemini"))
48
- model_name = "gemini-2.0-flash-thinking-exp"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  interventions_offered = {
51
  "Marketing Support": [
@@ -897,36 +965,90 @@ def get_shortlist():
897
 
898
 
899
  # Lepharo AI Screening endpoint
900
- @app.route('/api/lepharo_evaluate', methods=['POST'])
901
- def lepharo_evaluate_participant():
902
- try:
903
- data = request.json
904
- participant_id = data.get("participantId")
905
- participant_info = data.get("participantInfo", {})
906
 
907
- evaluator = LepharoEvaluator()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
908
  prompt = evaluator.generate_prompt(participant_info)
909
 
 
 
 
 
 
910
  response = client.models.generate_content(
911
  model=model_name,
912
  contents=prompt
913
  )
914
 
915
- evaluation = evaluator.parse_gemini_response(response.text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916
 
917
  return jsonify({
918
  "status": "success",
919
  "participantId": participant_id,
920
- "evaluation": evaluation
921
- })
 
922
 
923
  except Exception as e:
 
 
 
 
924
  return jsonify({
925
  "status": "error",
926
- "message": str(e)
 
 
927
  }), 500
928
 
929
-
930
  @app.route('/api/lepharo_batch-evaluate', methods=['POST'])
931
  def lepharo_batch_evaluate():
932
  try:
 
45
 
46
  # --- Gemini Client ---
47
  client = genai.Client(api_key=os.getenv("Gemini"))
48
+ model_name = "gemini-2.0-flash"
49
+
50
+ import logging
51
+ import uuid
52
+ import time
53
+ from flask import g, request, jsonify
54
+
55
+ # ---------- Logging setup ----------
56
+ LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
57
+
58
+ logging.basicConfig(
59
+ level=LOG_LEVEL,
60
+ format="%(asctime)s %(levelname)s %(name)s %(message)s",
61
+ )
62
+ logger = logging.getLogger("api")
63
+
64
+ # ---------- Request/Response hooks ----------
65
+ @app.before_request
66
+ def _start_timer():
67
+ g.request_id = request.headers.get("X-Request-Id", str(uuid.uuid4()))
68
+ g.t0 = time.time()
69
+
70
+ # Minimal safe logging (avoid dumping full participantInfo / bank statements)
71
+ body_preview = None
72
+ try:
73
+ if request.is_json:
74
+ j = request.get_json(silent=True)
75
+ if isinstance(j, dict):
76
+ body_preview = {"keys": list(j.keys())}
77
+ else:
78
+ body_preview = {"type": str(type(j))}
79
+ else:
80
+ body_preview = {"content_type": request.content_type}
81
+ except Exception:
82
+ body_preview = {"parse": "failed"}
83
+
84
+ logger.info(
85
+ "REQ id=%s %s %s ip=%s ua=%s body=%s",
86
+ g.request_id,
87
+ request.method,
88
+ request.path,
89
+ request.headers.get("X-Forwarded-For", request.remote_addr),
90
+ request.user_agent.string,
91
+ body_preview,
92
+ )
93
+
94
+ @app.after_request
95
+ def _log_response(resp):
96
+ dt_ms = int((time.time() - getattr(g, "t0", time.time())) * 1000)
97
+ logger.info(
98
+ "RES id=%s %s %s status=%s ms=%s",
99
+ getattr(g, "request_id", "-"),
100
+ request.method,
101
+ request.path,
102
+ resp.status_code,
103
+ dt_ms,
104
+ )
105
+ resp.headers["X-Request-Id"] = getattr(g, "request_id", "-")
106
+ return resp
107
+
108
+ @app.errorhandler(Exception)
109
+ def _unhandled_exception(err):
110
+ # This is the big one: logs stack trace
111
+ logger.exception("UNHANDLED id=%s path=%s", getattr(g, "request_id", "-"), request.path)
112
+ return jsonify({
113
+ "status": "error",
114
+ "message": "Internal server error",
115
+ "requestId": getattr(g, "request_id", "-"),
116
+ }), 500
117
 
118
  interventions_offered = {
119
  "Marketing Support": [
 
965
 
966
 
967
  # Lepharo AI Screening endpoint
968
+ from google.api_core import exceptions as gexc # optional, if installed
 
 
 
 
 
969
 
970
+ @app.route("/api/evaluate", methods=["POST"])
971
+ def evaluate_participant():
972
+ # Validate JSON early (bad JSON should be 400, not 500)
973
+ if not request.is_json:
974
+ return jsonify({
975
+ "status": "error",
976
+ "message": "Content-Type must be application/json",
977
+ "requestId": getattr(g, "request_id", "-"),
978
+ }), 400
979
+
980
+ data = request.get_json(silent=True)
981
+ if not isinstance(data, dict):
982
+ return jsonify({
983
+ "status": "error",
984
+ "message": "Invalid JSON body",
985
+ "requestId": getattr(g, "request_id", "-"),
986
+ }), 400
987
+
988
+ participant_id = data.get("participantId")
989
+ participant_info = data.get("participantInfo") or {}
990
+
991
+ if not participant_id:
992
+ return jsonify({"status": "error", "message": "Missing participantId"}), 400
993
+ if not isinstance(participant_info, dict):
994
+ return jsonify({"status": "error", "message": "participantInfo must be an object"}), 400
995
+
996
+ try:
997
+ evaluator = GenericEvaluator()
998
  prompt = evaluator.generate_prompt(participant_info)
999
 
1000
+ logger.info("EVAL id=%s participantId=%s prompt_chars=%s",
1001
+ getattr(g, "request_id", "-"),
1002
+ participant_id,
1003
+ len(prompt))
1004
+
1005
  response = client.models.generate_content(
1006
  model=model_name,
1007
  contents=prompt
1008
  )
1009
 
1010
+ txt = getattr(response, "text", "") or ""
1011
+ logger.info("EVAL id=%s participantId=%s gemini_text_chars=%s",
1012
+ getattr(g, "request_id", "-"),
1013
+ participant_id,
1014
+ len(txt))
1015
+
1016
+ evaluation = evaluator.parse_gemini_response(txt)
1017
+
1018
+ # If Gemini returned something you couldn't parse, don’t hide it.
1019
+ # Return 502 so you can see it's an upstream/model-output problem.
1020
+ if isinstance(evaluation, dict) and evaluation.get("error"):
1021
+ logger.warning("EVAL_PARSE_FAIL id=%s participantId=%s err=%s",
1022
+ getattr(g, "request_id", "-"),
1023
+ participant_id,
1024
+ evaluation.get("error"))
1025
+ return jsonify({
1026
+ "status": "error",
1027
+ "participantId": participant_id,
1028
+ "message": "Model output could not be parsed/validated",
1029
+ "details": evaluation, # contains error + raw_response/parsed_data
1030
+ "requestId": getattr(g, "request_id", "-"),
1031
+ }), 502
1032
 
1033
  return jsonify({
1034
  "status": "success",
1035
  "participantId": participant_id,
1036
+ "evaluation": evaluation,
1037
+ "requestId": getattr(g, "request_id", "-"),
1038
+ }), 200
1039
 
1040
  except Exception as e:
1041
+ # Logs full traceback, but response stays safe
1042
+ logger.exception("EVAL_FAIL id=%s participantId=%s",
1043
+ getattr(g, "request_id", "-"),
1044
+ participant_id)
1045
  return jsonify({
1046
  "status": "error",
1047
+ "participantId": participant_id,
1048
+ "message": "Evaluation failed",
1049
+ "requestId": getattr(g, "request_id", "-"),
1050
  }), 500
1051
 
 
1052
  @app.route('/api/lepharo_batch-evaluate', methods=['POST'])
1053
  def lepharo_batch_evaluate():
1054
  try: