-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsupabase_logger.py
More file actions
174 lines (149 loc) · 7.95 KB
/
supabase_logger.py
File metadata and controls
174 lines (149 loc) · 7.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import logging
import json
import os
from typing import Optional, Dict, Any
import datetime
import re
def convert_numpy_floats(obj):
if isinstance(obj, dict):
return {k: convert_numpy_floats(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [convert_numpy_floats(elem) for elem in obj]
elif isinstance(obj, float):
return obj
return obj
SUPABASE_PREDICTION_TABLE_NAME = os.getenv("SUPABASE_PREDICTION_TABLE_NAME")
def extract_simplified_contextual_outcome(analysis_response_text: str) -> Optional[str]:
if not analysis_response_text:
logging.warning("No analysis response text provided.")
return None
start = analysis_response_text.find("### EXECUTIVE_SUMMARY_START")
end = analysis_response_text.find("### EXECUTIVE_SUMMARY_END")
if start != -1 and end != -1 and end > start:
summary = analysis_response_text[start + len("### EXECUTIVE_SUMMARY_START"):end].strip()
else:
logging.info("No standard summary block found, using entire text.")
summary = analysis_response_text
extracted_value_from_source = None
logging_source_info = ""
for line in summary.splitlines():
if "DUAL RECOMMENDATION" in line:
m = re.search(r"\bOR\s+([^@|]+?)(?=\s*(?:@|\|))", line, re.IGNORECASE)
if m:
extracted_value_from_source = m.group(1).strip()
logging_source_info = "DUAL RECOMMENDATION"
break
if not extracted_value_from_source:
for line in summary.splitlines():
if "Preferred Outcome: Contextual" in line:
m = re.search(r"Contextual\s*\(([^)]+)\)", line)
if m:
raw_fallback_text = m.group(1).strip()
extracted_value_from_source = raw_fallback_text.split(" due to ")[0].split(" (")[0].strip()
logging_source_info = "Preferred Outcome: Contextual"
break
if not extracted_value_from_source:
logging.warning("Could not extract any contextual outcome candidate.")
return None
# Normalize the extracted string for comparison (handles case and internal spaces)
normalized_for_comparison = ' '.join(extracted_value_from_source.lower().split())
if normalized_for_comparison == "home win":
final_outcome = "Home"
logging.info(f"Extracted and simplified contextual outcome from {logging_source_info}: '{final_outcome}' (original: '{extracted_value_from_source}')")
return final_outcome
elif normalized_for_comparison == "away win":
final_outcome = "Away"
logging.info(f"Extracted and simplified contextual outcome from {logging_source_info}: '{final_outcome}' (original: '{extracted_value_from_source}')")
return final_outcome
else:
# No simplification for "Home Win" / "Away Win" applies. Return the extracted value as is.
logging.info(f"Extracted contextual outcome from {logging_source_info}: '{extracted_value_from_source}' (no 'Win' rule simplification)")
return extracted_value_from_source
def log_new_prediction_session(
supabase_client,
user_message_predict: str,
prediction_context: Dict[str, Any],
full_bot_response_predict: str
) -> Optional[str]:
logging.info("Attempting to create new prediction session entry in Supabase...")
if supabase_client is None:
logging.warning("Supabase client not provided or initialized. Cannot create prediction session.")
return None
if not prediction_context or not prediction_context.get('odds') or not prediction_context.get('prediction') or 'probabilities' not in prediction_context:
logging.error("Prediction context is incomplete or missing probabilities for saving.")
return None
try:
odds = prediction_context['odds']
teams = prediction_context.get('teams')
pred_code = prediction_context['prediction']
probabilities_data = prediction_context.get('probabilities', {})
statistical_pred_str = {"W": "Home", "D": "Draw", "L": "Away"}.get(pred_code, pred_code)
data_to_save = {
"user_message_predict": user_message_predict,
"match_teams": f"{teams[0]} - {teams[1]}" if teams and isinstance(teams, (list, tuple)) and len(teams) == 2 else None,
"home_odds": odds.get('W'),
"draw_odds": odds.get('D'),
"away_odds": odds.get('L'),
"statistical_prediction": statistical_pred_str,
"statistical_probabilities": json.dumps(probabilities_data),
"full_bot_response_predict": full_bot_response_predict,
"contextual_prediction": None,
"user_message_analyze": None,
"full_bot_response_analyze": None,
"updated_at": None
}
response = supabase_client.table(SUPABASE_PREDICTION_TABLE_NAME).insert([data_to_save]).execute()
if response and hasattr(response, 'data') and response.data:
new_id = response.data[0].get('id')
logging.info(f"Successfully created prediction session entry. Record ID: {new_id}")
return str(new_id)
elif response and hasattr(response, 'error') and response.error:
logging.error(f"Supabase insert failed for new session: {response.error.message if hasattr(response.error, 'message') else response.error}")
return None
else:
logging.warning(f"Supabase insert for new session executed, but unexpected response format: {response}")
return None
except Exception as e:
logging.exception(f"An unexpected error occurred during Supabase new session logging:")
return None
def update_prediction_session_analysis(
supabase_client,
session_id: str,
user_message_analyze: str,
full_bot_response_analyze: str,
prediction_context: Dict[str, Any]
) -> bool:
logging.info(f"Attempting to update prediction session entry ID {session_id} with analysis...")
if supabase_client is None:
logging.warning("Supabase client not provided or initialized. Cannot update prediction session.")
return False
if not session_id:
logging.error("No session_id provided for update.")
return False
try:
contextual_outcome = extract_simplified_contextual_outcome(full_bot_response_analyze)
if contextual_outcome is None:
logging.warning("Could not extract a contextual outcome from the analysis. "
"Setting contextual_prediction to null in the database.")
update_data = {
"user_message_analyze": user_message_analyze,
"contextual_prediction": contextual_outcome,
"full_bot_response_analyze": full_bot_response_analyze,
"updated_at": datetime.datetime.now(datetime.timezone.utc).isoformat()
}
response = supabase_client.table(SUPABASE_PREDICTION_TABLE_NAME).update(update_data).eq('id', session_id).execute()
if response and hasattr(response, 'data') and response.data:
logging.info(f"Successfully updated prediction session entry ID {session_id} with analysis.")
return True
elif response and hasattr(response, 'error') and response.error:
logging.error(f"Supabase update failed for session ID {session_id}: {response.error.message if hasattr(response.error, 'message') else response.error}")
return False
elif response and hasattr(response, 'count') and response.count > 0:
logging.info(f"Successfully updated prediction session entry ID {session_id} (Count: {response.count}).")
return True
else:
logging.warning(f"Supabase update for session ID {session_id} executed, but unexpected response format or no rows updated: {response}")
return False
except Exception as e:
logging.exception(f"An unexpected error occurred during Supabase session update for ID {session_id}:")
return False