iisadia commited on
Commit
c87b45b
Β·
verified Β·
1 Parent(s): b09438d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -77
app.py CHANGED
@@ -6,11 +6,6 @@ import time
6
  from datetime import datetime
7
  import groq
8
 
9
- # Load custom CSS
10
- def local_css(file_name):
11
- with open(file_name) as f:
12
- st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
13
-
14
  # API keys (replace with your keys or use environment variables)
15
  mistral_api_key = os.getenv("MISTRAL_API_KEY", "gz6lDXokxgR6cLY72oomALWcm7vhjRzQ")
16
  groq_api_key = os.getenv("GROQ_API_KEY", "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")
@@ -33,13 +28,13 @@ def call_mistral_api(prompt):
33
  }
34
  try:
35
  response = requests.post(url, headers=headers, json=payload)
36
- response.raise_for_status() # Raise an error for bad status codes
37
  return response.json()['choices'][0]['message']['content']
38
  except requests.exceptions.HTTPError as err:
39
- if response.status_code == 429: # Rate limit exceeded
40
  st.warning("Rate limit exceeded. Please wait a few seconds and try again.")
41
- time.sleep(5) # Wait for 5 seconds before retrying
42
- return call_mistral_api(prompt) # Retry the request
43
  return f"HTTP Error: {err}"
44
  except Exception as err:
45
  return f"Error: {err}"
@@ -48,7 +43,7 @@ def call_mistral_api(prompt):
48
  def call_groq_api(prompt):
49
  try:
50
  response = groq_client.chat.completions.create(
51
- model="llama-3.3-70b-versatile", # Correct model name
52
  messages=[
53
  {"role": "user", "content": prompt}
54
  ]
@@ -58,16 +53,14 @@ def call_groq_api(prompt):
58
  st.error(f"Error: {err}")
59
  return f"Error: {err}"
60
 
61
- # Function to analyze a single requirement using both models
62
  def analyze_requirement(requirement):
63
- # Use Mistral for classification and domain identification
64
  type_prompt = f"Classify the following requirement as Functional or Non-Functional in one word:\n\n{requirement}\n\nType:"
65
  req_type = call_mistral_api(type_prompt).strip()
66
 
67
  domain_prompt = f"Classify the domain for the following requirement in one word (e.g., E-commerce, Education, etc.):\n\n{requirement}\n\nDomain:"
68
  domain = call_mistral_api(domain_prompt).strip()
69
 
70
- # Use Groq for defect analysis and rewriting
71
  defects_prompt = f"""List ONLY the major defects in the following requirement (e.g., Ambiguity, Incompleteness, etc.) in 1-2 words each:\n\n{requirement}\n\nDefects:"""
72
  defects = call_groq_api(defects_prompt).strip()
73
 
@@ -82,39 +75,35 @@ def analyze_requirement(requirement):
82
  "Rewritten": rewritten
83
  }
84
 
85
- # Function to generate a PDF report
86
  def generate_pdf_report(results):
87
  pdf = FPDF()
88
  pdf.add_page()
89
  pdf.set_font("Arial", size=12)
90
 
91
- # Add watermark
92
  pdf.set_font("Arial", 'B', 50)
93
- pdf.set_text_color(230, 230, 230) # Light gray color for watermark
94
- pdf.rotate(45) # Rotate the text for watermark effect
95
  pdf.text(60, 150, "AI Powered Requirement Analysis")
96
- pdf.rotate(0) # Reset rotation
97
 
98
- # Add title and date/time
99
  pdf.set_font("Arial", 'B', 16)
100
- pdf.set_text_color(0, 0, 0) # Black color for title
101
  pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
102
  pdf.set_font("Arial", size=12)
103
  pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
104
- pdf.ln(10) # Add some space
105
 
106
- # Add requirements analysis
107
  pdf.set_font("Arial", size=12)
108
  for i, result in enumerate(results, start=1):
109
- if pdf.get_y() > 250: # If the content is near the bottom of the page
110
- pdf.add_page() # Add a new page
111
  pdf.set_font("Arial", 'B', 16)
112
  pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
113
  pdf.set_font("Arial", size=12)
114
  pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
115
- pdf.ln(10) # Add some space
116
 
117
- # Add requirement details
118
  pdf.set_font("Arial", 'B', 14)
119
  pdf.multi_cell(200, 10, txt=f"Requirement R{i}: {result['Requirement']}", align='L')
120
  pdf.set_font("Arial", size=12)
@@ -123,61 +112,116 @@ def generate_pdf_report(results):
123
  pdf.multi_cell(200, 10, txt=f"Defects: {result['Defects']}", align='L')
124
  pdf.multi_cell(200, 10, txt=f"Rewritten: {result['Rewritten']}", align='L')
125
  pdf.multi_cell(200, 10, txt="-" * 50, align='L')
126
- pdf.ln(5) # Add some space between requirements
127
 
128
  pdf_output = "requirements_report.pdf"
129
  pdf.output(pdf_output)
130
  return pdf_output
131
 
132
- # Streamlit app
133
  def main():
134
- # Load custom CSS
135
- local_css("style.css")
136
-
137
- st.title("AI Powered Requirement Analysis and Defect Detection")
138
- st.markdown("**Team Name:** Sadia, Areeba, Rabbia, Tesmia")
139
- st.markdown("**Models:** Mistral (Classification & Domain) + Groq (Defects & Rewriting)")
140
-
141
- # Input requirements manually
142
- with st.container():
143
- st.subheader("Enter Requirements")
144
- input_text = st.text_area("Enter your requirements (one per line or separated by periods):", height=200)
145
- requirements = []
146
- if input_text:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()]
148
-
149
- # Analyze requirements
150
- with st.container():
151
- col1, col2 = st.columns([2, 1])
152
- with col1:
153
- if st.button("Analyze Requirements"):
154
- if not requirements:
155
- st.warning("Please enter requirements.")
156
- else:
157
- with st.spinner("Analyzing requirements..."):
158
- results = []
159
- for req in requirements:
160
- if req.strip(): # Ignore empty lines
161
- results.append(analyze_requirement(req.strip()))
162
-
163
- # Display results
164
- st.subheader("Analysis Results")
165
- for i, result in enumerate(results, start=1):
166
- st.write(f"### Requirement R{i}: {result['Requirement']}")
167
- st.write(f"**Type:** {result['Type']}")
168
- st.write(f"**Domain:** {result['Domain']}")
169
- st.write(f"**Defects:** {result['Defects']}")
170
- st.write(f"**Rewritten:** {result['Rewritten']}")
171
- st.write("---")
172
-
173
- # Generate and download PDF report
174
- pdf_report = generate_pdf_report(results)
175
- with open(pdf_report, "rb") as f:
176
- st.download_button(
177
- label="Download PDF Report",
178
- data=f,
179
- file_name="requirements_report.pdf",
180
- mime="application/pdf"
181
- )
182
- with col2:
183
- st.image
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  from datetime import datetime
7
  import groq
8
 
 
 
 
 
 
9
  # API keys (replace with your keys or use environment variables)
10
  mistral_api_key = os.getenv("MISTRAL_API_KEY", "gz6lDXokxgR6cLY72oomALWcm7vhjRzQ")
11
  groq_api_key = os.getenv("GROQ_API_KEY", "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")
 
28
  }
29
  try:
30
  response = requests.post(url, headers=headers, json=payload)
31
+ response.raise_for_status()
32
  return response.json()['choices'][0]['message']['content']
33
  except requests.exceptions.HTTPError as err:
34
+ if response.status_code == 429:
35
  st.warning("Rate limit exceeded. Please wait a few seconds and try again.")
36
+ time.sleep(5)
37
+ return call_mistral_api(prompt)
38
  return f"HTTP Error: {err}"
39
  except Exception as err:
40
  return f"Error: {err}"
 
43
  def call_groq_api(prompt):
44
  try:
45
  response = groq_client.chat.completions.create(
46
+ model="llama-3.3-70b-versatile",
47
  messages=[
48
  {"role": "user", "content": prompt}
49
  ]
 
53
  st.error(f"Error: {err}")
54
  return f"Error: {err}"
55
 
56
+ # Function to analyze requirement
57
  def analyze_requirement(requirement):
 
58
  type_prompt = f"Classify the following requirement as Functional or Non-Functional in one word:\n\n{requirement}\n\nType:"
59
  req_type = call_mistral_api(type_prompt).strip()
60
 
61
  domain_prompt = f"Classify the domain for the following requirement in one word (e.g., E-commerce, Education, etc.):\n\n{requirement}\n\nDomain:"
62
  domain = call_mistral_api(domain_prompt).strip()
63
 
 
64
  defects_prompt = f"""List ONLY the major defects in the following requirement (e.g., Ambiguity, Incompleteness, etc.) in 1-2 words each:\n\n{requirement}\n\nDefects:"""
65
  defects = call_groq_api(defects_prompt).strip()
66
 
 
75
  "Rewritten": rewritten
76
  }
77
 
78
+ # Function to generate PDF report
79
  def generate_pdf_report(results):
80
  pdf = FPDF()
81
  pdf.add_page()
82
  pdf.set_font("Arial", size=12)
83
 
 
84
  pdf.set_font("Arial", 'B', 50)
85
+ pdf.set_text_color(230, 230, 230)
86
+ pdf.rotate(45)
87
  pdf.text(60, 150, "AI Powered Requirement Analysis")
88
+ pdf.rotate(0)
89
 
 
90
  pdf.set_font("Arial", 'B', 16)
91
+ pdf.set_text_color(0, 0, 0)
92
  pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
93
  pdf.set_font("Arial", size=12)
94
  pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
95
+ pdf.ln(10)
96
 
 
97
  pdf.set_font("Arial", size=12)
98
  for i, result in enumerate(results, start=1):
99
+ if pdf.get_y() > 250:
100
+ pdf.add_page()
101
  pdf.set_font("Arial", 'B', 16)
102
  pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
103
  pdf.set_font("Arial", size=12)
104
  pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
105
+ pdf.ln(10)
106
 
 
107
  pdf.set_font("Arial", 'B', 14)
108
  pdf.multi_cell(200, 10, txt=f"Requirement R{i}: {result['Requirement']}", align='L')
109
  pdf.set_font("Arial", size=12)
 
112
  pdf.multi_cell(200, 10, txt=f"Defects: {result['Defects']}", align='L')
113
  pdf.multi_cell(200, 10, txt=f"Rewritten: {result['Rewritten']}", align='L')
114
  pdf.multi_cell(200, 10, txt="-" * 50, align='L')
115
+ pdf.ln(5)
116
 
117
  pdf_output = "requirements_report.pdf"
118
  pdf.output(pdf_output)
119
  return pdf_output
120
 
121
+ # Streamlit UI
122
  def main():
123
+ st.markdown("""
124
+ <style>
125
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap');
126
+ * { font-family: 'Poppins', sans-serif; }
127
+ .main-container { max-width: 800px; margin: 0 auto; padding: 2rem; }
128
+ .gradient-header { background: linear-gradient(45deg, #4F46E5, #1E40AF);
129
+ color: white; padding: 2rem; border-radius: 15px; }
130
+ .team-card { background: #f8f9fa; padding: 1.5rem; border-radius: 15px;
131
+ margin: 1rem 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
132
+ .styled-input { border: 2px solid #e0e0e0 !important; border-radius: 10px !important;
133
+ padding: 1rem !important; margin: 1rem 0; }
134
+ .result-card { background: white; padding: 1.5rem; border-radius: 15px;
135
+ margin: 1rem 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
136
+ .badge { padding: 0.3rem 1rem; border-radius: 20px; font-size: 0.9rem;
137
+ margin-right: 0.5rem; display: inline-block; }
138
+ .type-badge { background: #4F46E510; color: #4F46E5; }
139
+ .domain-badge { background: #10B98110; color: #10B981; }
140
+ .defect-badge { background: #EF444410; color: #EF4444; }
141
+ .animate-hover { transition: transform 0.2s; }
142
+ .animate-hover:hover { transform: translateY(-2px); }
143
+ </style>
144
+ """, unsafe_allow_html=True)
145
+
146
+ st.markdown("""
147
+ <div class="main-container">
148
+ <div class="gradient-header">
149
+ <h1 style="margin: 0; font-weight: 600;">🧠 AI Requirement Analyzer</h1>
150
+ <p style="margin: 0.5rem 0 0; opacity: 0.9;">Smart Analysis & Quality Enhancement System</p>
151
+ </div>
152
+
153
+ <div class="team-card">
154
+ <h3 style="margin: 0 0 1rem;">πŸ‘₯ Team Members</h3>
155
+ <div style="display: flex; gap: 1rem;">
156
+ <div style="flex: 1; text-align: center;">
157
+ <div style="background: #4F46E510; padding: 0.5rem; border-radius: 10px;">
158
+ <p style="margin: 0; color: #4F46E5;">Sadia</p>
159
+ </div>
160
+ </div>
161
+ <!-- Repeat similar blocks for other team members -->
162
+ </div>
163
+ </div>
164
+ """, unsafe_allow_html=True)
165
+
166
+ st.markdown("""
167
+ <div style="margin: 2rem 0;">
168
+ <h2>πŸ“₯ Input Requirements</h2>
169
+ <p style="opacity: 0.8;">Enter multiple requirements separated by new lines or periods</p>
170
+ """, unsafe_allow_html=True)
171
+
172
+ input_text = st.text_area("", height=200, key="input_area",
173
+ help="Example:\n1. The system must handle 1000 users\n2. User interface should be responsive")
174
+
175
+ if st.button("πŸš€ Start Analysis", key="analyze_btn", use_container_width=True):
176
+ if not input_text.strip():
177
+ st.warning("⚠️ Please enter requirements to analyze")
178
+ else:
179
  requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()]
180
+ results = []
181
+ progress_bar = st.progress(0)
182
+
183
+ with st.spinner("πŸ” Analyzing requirements..."):
184
+ for i, req in enumerate(requirements):
185
+ results.append(analyze_requirement(req))
186
+ progress_bar.progress((i+1)/len(requirements))
187
+ time.sleep(0.1)
188
+
189
+ st.success("βœ… Analysis completed!")
190
+ st.markdown("---")
191
+
192
+ for i, result in enumerate(results, 1):
193
+ st.markdown(f"""
194
+ <div class="result-card animate-hover">
195
+ <h3 style="margin: 0 0 1rem;">πŸ”– Requirement R{i}</h3>
196
+ <p style="font-size: 1.1rem; margin-bottom: 1.5rem;">{result['Requirement']}</p>
197
+
198
+ <div style="display: flex; gap: 1rem; margin-bottom: 1rem;">
199
+ <span class="badge type-badge">πŸ“ {result['Type']}</span>
200
+ <span class="badge domain-badge">🌍 {result['Domain']}</span>
201
+ <span class="badge defect-badge">⚠️ {result['Defects']}</span>
202
+ </div>
203
+
204
+ <div style="background: #f8f9fa; padding: 1rem; border-radius: 10px;">
205
+ <p style="margin: 0; color: #3B82F6;">✏️ Optimized Version:</p>
206
+ <p style="margin: 0.5rem 0 0; font-weight: 500;">{result['Rewritten']}</p>
207
+ </div>
208
+ </div>
209
+ """, unsafe_allow_html=True)
210
+
211
+ st.markdown("---")
212
+ st.markdown("### πŸ“„ Generate Report")
213
+ pdf_report = generate_pdf_report(results)
214
+ with open(pdf_report, "rb") as f:
215
+ st.download_button(
216
+ label="πŸ“₯ Download PDF Report",
217
+ data=f,
218
+ file_name="requirements_analysis.pdf",
219
+ mime="application/pdf",
220
+ use_container_width=True,
221
+ key="download_btn"
222
+ )
223
+
224
+ st.markdown("</div>", unsafe_allow_html=True)
225
+
226
+ if __name__ == "__main__":
227
+ main()