kgauvin603 commited on
Commit
ed9459f
·
verified ·
1 Parent(s): 23dd0d8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -0
app.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # --- Imports ---
2
+ import os
3
+ import re
4
+ import gradio as gr
5
+ import openai
6
+ from datetime import datetime
7
+ from bs4 import BeautifulSoup
8
+
9
+ # --- API Keys + Colab support ---
10
+ import os
11
+
12
+ openai_api_key = os.environ.get("OPENAI_API_KEY")
13
+ openrouter_key = os.environ.get("OPENROUTER")
14
+
15
+ if not openai_api_key:
16
+ raise ValueError("OPENAI_API_KEY environment variable is not set.")
17
+ if not openrouter_key:
18
+ raise ValueError("OPENROUTER environment variable is not set.")
19
+
20
+
21
+ client = openai.OpenAI(api_key=openai_api_key)
22
+ openai_rater = openai.OpenAI(api_key=openrouter_key, base_url="https://openrouter.ai/api/v1")
23
+
24
+ # --- Logger ---
25
+ log_filename = "rating_log.txt"
26
+ if not os.path.exists(log_filename):
27
+ with open(log_filename, "w", encoding="utf-8") as f:
28
+ f.write("=== Rating Log Initialized ===\n")
29
+
30
+ # --- Exadata Specs ---
31
+ exadata_specs = {
32
+ "X7": {"Quarter Rack": {"max_iops": 350000, "max_throughput": 25},
33
+ "Half Rack": {"max_iops": 700000, "max_throughput": 50},
34
+ "Full Rack": {"max_iops": 1400000, "max_throughput": 100}},
35
+ "X8": {"Quarter Rack": {"max_iops": 380000, "max_throughput": 28},
36
+ "Half Rack": {"max_iops": 760000, "max_throughput": 56},
37
+ "Full Rack": {"max_iops": 1520000, "max_throughput": 112}},
38
+ "X9": {"Quarter Rack": {"max_iops": 450000, "max_throughput": 30},
39
+ "Half Rack": {"max_iops": 900000, "max_throughput": 60},
40
+ "Full Rack": {"max_iops": 1800000, "max_throughput": 120}},
41
+ "X10": {"Quarter Rack": {"max_iops": 500000, "max_throughput": 35},
42
+ "Half Rack": {"max_iops": 1000000, "max_throughput": 70},
43
+ "Full Rack": {"max_iops": 2000000, "max_throughput": 140}},
44
+ "X11M": {"Quarter Rack": {"max_iops": 600000, "max_throughput": 40},
45
+ "Half Rack": {"max_iops": 1200000, "max_throughput": 80},
46
+ "Full Rack": {"max_iops": 2400000, "max_throughput": 160}},
47
+ }
48
+
49
+ # --- Preprocessor ---
50
+ def clean_awr_content(content):
51
+ if "<html" in content.lower():
52
+ soup = BeautifulSoup(content, "html.parser")
53
+ text = soup.get_text()
54
+ else:
55
+ text = content
56
+ cleaned = "\n".join([line.strip() for line in text.splitlines() if line.strip()])
57
+ return cleaned
58
+
59
+ # --- AWR Analyzer ---
60
+ def analyze_awr(content, performance_test_mode, exadata_model, rack_size):
61
+ cleaned_content = clean_awr_content(content)
62
+ max_chars = 128000
63
+ if len(cleaned_content) > max_chars:
64
+ cleaned_content = cleaned_content[:max_chars] + "\n\n[TRUNCATED]..."
65
+
66
+ # Build prompt
67
+ prompt = f"""You are an expert Oracle Database performance analyst with deep knowledge of AWR reports and the Time Scale Methodology.
68
+
69
+ Analyze the following AWR Report:
70
+
71
+ ======== AWR REPORT START ========
72
+ {cleaned_content}
73
+ ======== AWR REPORT END ========
74
+
75
+ Please provide:
76
+ - Performance Summary
77
+ - Detailed Analysis of Bottlenecks and/or Degradation Risks
78
+ - Performance Forecast and Predictions
79
+ - Specific recommendations for Monitoring relative to bottlenecks or degradation risks
80
+ - Provide a separate Exadata Statistics Performance Summary IO, Flash Cache, and Smart Scan utilization
81
+ """
82
+
83
+ # Add Exadata comparison if performance test mode
84
+ if performance_test_mode and exadata_model and rack_size:
85
+ specs = exadata_specs.get(exadata_model, {}).get(rack_size, {})
86
+ if specs:
87
+ prompt += f"""
88
+
89
+ This was a PERFORMANCE TEST on Oracle Exadata {exadata_model} {rack_size}.
90
+ Theoretical Max:
91
+ - Max IOPS: {specs['max_iops']}
92
+ - Max Throughput: {specs['max_throughput']} GB/s
93
+
94
+ Show actual vs theoretical and generate Recommended Next Steps to Bridge Performance Gap.
95
+ """
96
+
97
+ # --- Call GPT-4o (or turbo) ---
98
+ MODEL = "gpt-4-turbo" # BEST (or change to gpt-4-turbo if needed)
99
+
100
+ response = client.chat.completions.create(
101
+ model=MODEL,
102
+ messages=[
103
+ {"role": "system", "content": "You are an expert Oracle Database performance analyst."},
104
+ {"role": "user", "content": prompt}
105
+ ]
106
+ )
107
+
108
+ return response.choices[0].message.content.strip()
109
+
110
+
111
+
112
+ # --- Rater ---
113
+ def rate_answer_rater(question, final_answer):
114
+ prompt = f"Rate this answer 1-5 stars with explanation:\n\n{final_answer}"
115
+ response = openai_rater.chat.completions.create(
116
+ model="mistral/ministral-8b",
117
+ messages=[{"role": "user", "content": prompt}]
118
+ )
119
+ return response.choices[0].message.content.strip()
120
+
121
+ # --- Main Logic ---
122
+ def process_awr(awr_text, correctness_threshold, performance_test_mode, exadata_model, rack_size):
123
+ if not awr_text.strip():
124
+ return "No AWR report provided.", "", ""
125
+
126
+ answer = analyze_awr(awr_text, performance_test_mode, exadata_model, rack_size)
127
+ rating_text = rate_answer_rater("AWR Analysis", answer)
128
+
129
+ stars = 0
130
+ match = re.search(r"(\d+)", rating_text)
131
+ if match:
132
+ stars = int(match.group(1))
133
+
134
+ if stars < correctness_threshold:
135
+ answer_retry = analyze_awr(awr_text, performance_test_mode, exadata_model, rack_size)
136
+ rating_text_retry = rate_answer_rater("AWR Analysis (Retry)", answer_retry)
137
+
138
+ with open(log_filename, "a", encoding="utf-8") as log_file:
139
+ log_file.write(f"\n---\n{datetime.now()} RETRY\nOriginal: {answer}\nRating: {rating_text}\nRetry: {answer_retry}\nRetry Rating: {rating_text_retry}\n")
140
+
141
+ return answer_retry, rating_text_retry, "✅ Retry Occurred (rating below threshold)"
142
+ else:
143
+ with open(log_filename, "a", encoding="utf-8") as log_file:
144
+ log_file.write(f"\n---\n{datetime.now()} SUCCESS\nAnswer: {answer}\nRating: {rating_text}\n")
145
+
146
+ return answer, rating_text, "✅ Accepted on first try"
147
+
148
+ # --- Gradio UI ---
149
+ with gr.Blocks() as demo:
150
+ gr.Markdown("## 📊 Oracle AWR Analyzer (AI + Rating + Retry + Exadata Gap Analysis)")
151
+
152
+ awr_text = gr.Textbox(label="Paste AWR Report (HTML or TXT)", lines=30, placeholder="Paste full AWR here...")
153
+ threshold = gr.Slider(0, 5, value=3, step=1, label="Correctness Threshold (Stars for Retry)")
154
+ performance_test_mode = gr.Checkbox(label="Performance Test Mode")
155
+ exadata_model = gr.Dropdown(choices=["X7", "X8", "X9", "X10", "X11M"], label="Exadata Model", visible=False)
156
+ rack_size = gr.Dropdown(choices=["Quarter Rack", "Half Rack", "Full Rack"], label="Rack Size", visible=False)
157
+
158
+ def toggle_visibility(mode):
159
+ return gr.update(visible=mode), gr.update(visible=mode)
160
+
161
+ performance_test_mode.change(toggle_visibility, inputs=performance_test_mode, outputs=[exadata_model, rack_size])
162
+
163
+ analyze_btn = gr.Button("Analyze AWR")
164
+ output = gr.Textbox(label="AWR Analysis Result", lines=15)
165
+ rating = gr.Textbox(label="Rater Rating + Explanation", lines=4)
166
+ retry_status = gr.Textbox(label="Retry Status")
167
+
168
+ analyze_btn.click(process_awr, inputs=[awr_text, threshold, performance_test_mode, exadata_model, rack_size], outputs=[output, rating, retry_status])
169
+
170
+ demo.launch(debug=True)