iisadia commited on
Commit
ccb31be
·
verified ·
1 Parent(s): fb304aa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -159
app.py CHANGED
@@ -1,164 +1,63 @@
 
1
  import streamlit as st
2
  import requests
3
  from fpdf import FPDF
4
  import os
5
  import time
6
  from datetime import datetime
7
- import unittest
8
-
9
- # Mistral API key (replace with your key or use environment variable)
10
- api_key = os.getenv("MISTRAL_API_KEY", "gz6lDXokxgR6cLY72oomALWcm7vhjRzQ")
11
 
12
- # Function to call Mistral API with rate limit handling
13
  def call_mistral_api(prompt):
14
- url = "https://api.mistral.ai/v1/chat/completions"
15
- headers = {
16
- "Authorization": f"Bearer {api_key}",
17
- "Content-Type": "application/json"
18
- }
19
- payload = {
20
- "model": "mistral-medium",
21
- "messages": [
22
- {"role": "user", "content": prompt}
23
- ]
24
- }
25
- try:
26
- response = requests.post(url, headers=headers, json=payload)
27
- response.raise_for_status() # Raise an error for bad status codes
28
- return response.json()['choices'][0]['message']['content']
29
- except requests.exceptions.HTTPError as err:
30
- if response.status_code == 429: # Rate limit exceeded
31
- st.warning("Rate limit exceeded. Please wait a few seconds and try again.")
32
- time.sleep(5) # Wait for 5 seconds before retrying
33
- return call_mistral_api(prompt) # Retry the request
34
- return f"HTTP Error: {err}"
35
- except Exception as err:
36
- return f"Error: {err}"
37
-
38
- # Function to analyze a single requirement
39
- def analyze_requirement(requirement):
40
- # Detect requirement type
41
- type_prompt = f"Classify the following requirement as Functional or Non-Functional:\n\n{requirement}\n\nType:"
42
- req_type = call_mistral_api(type_prompt)
43
-
44
- # Identify stakeholders
45
- stakeholders_prompt = f"Identify the stakeholders for the following requirement:\n\n{requirement}\n\nStakeholders:"
46
- stakeholders = call_mistral_api(stakeholders_prompt)
47
-
48
- # Classify domain
49
- domain_prompt = f"Classify the domain for the following requirement (e.g., Bank, Healthcare, etc.):\n\n{requirement}\n\nDomain:"
50
- domain = call_mistral_api(domain_prompt)
51
-
52
- # Detect defects
53
- defects_prompt = f"""Analyze the following requirement and identify ONLY MAJOR defects (e.g., Ambiguity, Incompleteness, etc.).
54
- If the requirement is clear and complete, respond with 'No defects.'
55
- Requirement: {requirement}
56
- Defects:"""
57
- defects = call_mistral_api(defects_prompt)
58
-
59
- # Rewrite requirement
60
- rewritten = rewrite_requirement(requirement, defects)
61
-
62
- return {
63
- "Requirement": requirement,
64
- "Type": req_type,
65
- "Stakeholders": stakeholders,
66
- "Domain": domain,
67
- "Defects": defects,
68
- "Rewritten": rewritten
69
- }
70
-
71
- # Function to rewrite requirement concisely
72
- def rewrite_requirement(requirement, defects):
73
- if "no defects" in defects.lower():
74
- return "No modification needed."
75
-
76
- # If defects are found, generate a concise and clear rewritten requirement
77
- prompt = f"""Rewrite the following requirement to address the defects listed below. Ensure the rewritten requirement is clear, concise, and free of defects. It should be no more than 1-2 sentences.
78
-
79
- Original Requirement: {requirement}
80
-
81
- Defects: {defects}
82
-
83
- Rewritten Requirement:"""
84
- response = call_mistral_api(prompt)
85
- return response.strip()
86
-
87
- # Function to generate a PDF report with professional formatting
88
- def generate_pdf_report(results):
89
- pdf = FPDF()
90
- pdf.add_page()
91
- pdf.set_font("Arial", size=12)
92
-
93
- # Add watermark
94
- pdf.set_font("Arial", 'B', 50)
95
- pdf.set_text_color(230, 230, 230) # Light gray color for watermark
96
- pdf.rotate(45) # Rotate the text for watermark effect
97
- pdf.text(60, 150, "AI Powered Requirement Analysis")
98
- pdf.rotate(0) # Reset rotation
99
-
100
- # Add title and date/time
101
- pdf.set_font("Arial", 'B', 16)
102
- pdf.set_text_color(0, 0, 0) # Black color for title
103
- pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection using LLM Model Mistral", ln=True, align='C')
104
- pdf.set_font("Arial", size=12)
105
- pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
106
- pdf.ln(10) # Add some space
107
-
108
- # Add requirements analysis
109
- pdf.set_font("Arial", size=12)
110
- for i, result in enumerate(results, start=1):
111
- # Check if we need a new page
112
- if pdf.get_y() > 250: # If the content is near the bottom of the page
113
- pdf.add_page() # Add a new page
114
- pdf.set_font("Arial", 'B', 16)
115
- pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection using LLM Model Mistral", ln=True, align='C')
116
- pdf.set_font("Arial", size=12)
117
- pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
118
- pdf.ln(10) # Add some space
119
-
120
- # Add requirement details
121
- pdf.set_font("Arial", 'B', 14)
122
- pdf.multi_cell(200, 10, txt=f"Requirement R{i}: {result['Requirement']}", align='L')
123
- pdf.set_font("Arial", size=12)
124
- pdf.multi_cell(200, 10, txt=f"Type: {result['Type']}", align='L')
125
- pdf.multi_cell(200, 10, txt=f"Stakeholders: {result['Stakeholders']}", align='L')
126
- pdf.multi_cell(200, 10, txt=f"Domain: {result['Domain']}", align='L')
127
- pdf.multi_cell(200, 10, txt=f"Defects: {result['Defects']}", align='L')
128
- pdf.multi_cell(200, 10, txt=f"Rewritten: {result['Rewritten']}", align='L')
129
- pdf.multi_cell(200, 10, txt="-" * 50, align='L')
130
- pdf.ln(5) # Add some space between requirements
131
-
132
- pdf_output = "requirements_report.pdf"
133
- pdf.output(pdf_output)
134
- return pdf_output
135
-
136
- # Unit testing section
137
- class TestRequirementAnalysis(unittest.TestCase):
138
-
139
- def test_analyze_requirement(self):
140
- requirement = "The system must allow users to log in using email and password."
141
- result = analyze_requirement(requirement)
142
- self.assertIn("Requirement", result)
143
- self.assertIn("Type", result)
144
- self.assertIn("Stakeholders", result)
145
- self.assertIn("Domain", result)
146
- self.assertIn("Defects", result)
147
- self.assertIn("Rewritten", result)
148
-
149
- def test_rewrite_requirement_no_defects(self):
150
- requirement = "The system should send an email notification when a user signs up."
151
- defects = "No defects."
152
- result = rewrite_requirement(requirement, defects)
153
- self.assertEqual(result, "No modification needed.")
154
-
155
- def test_generate_pdf_report(self):
156
- results = [
157
- {"Requirement": "The system should be scalable.", "Type": "Functional", "Stakeholders": "Developers", "Domain": "IT", "Defects": "No defects", "Rewritten": "No modification needed."}
158
- ]
159
- report = generate_pdf_report(results)
160
- self.assertTrue(os.path.exists(report))
161
-
162
  # Streamlit app
163
  def main():
164
  st.title("AI Powered Requirement Analysis and Defect Detection using Large Language Model Mistral")
@@ -172,7 +71,7 @@ def main():
172
  # Split by periods or newlines
173
  requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()]
174
 
175
- # Analyze requirements
176
  if st.button("Analyze Requirements"):
177
  if not requirements:
178
  st.warning("Please enter requirements.")
@@ -203,11 +102,11 @@ def main():
203
  mime="application/pdf"
204
  )
205
 
206
- # Display test results
207
- st.subheader("Unit Test Results")
208
- test_suite = unittest.TextTestRunner()
209
- test_results = test_suite.run(unittest.TestLoader().loadTestsFromTestCase(TestRequirementAnalysis))
210
- st.write(test_results)
211
 
212
  # Run the app
213
  if __name__ == "__main__":
 
1
+ import unittest
2
  import streamlit as st
3
  import requests
4
  from fpdf import FPDF
5
  import os
6
  import time
7
  from datetime import datetime
 
 
 
 
8
 
9
+ # Mock function to call Mistral API (replace with real call for actual usage)
10
  def call_mistral_api(prompt):
11
+ return "Functional" # Mock response for testing
12
+
13
+ # Test case class to check requirement analysis functionality
14
+ class RequirementTestCase(unittest.TestCase):
15
+
16
+ def test_requirement_type(self):
17
+ requirement = "The system shall allow users to login."
18
+ expected = "Functional"
19
+ actual = call_mistral_api(f"Classify the following requirement as Functional or Non-Functional:\n\n{requirement}\n\nType:")
20
+ self.assertEqual(actual, expected, f"Test failed for requirement type. Expected: {expected}, but got: {actual}")
21
+
22
+ def test_stakeholders_identification(self):
23
+ requirement = "The system shall allow users to login."
24
+ expected = "User, System Administrator"
25
+ actual = call_mistral_api(f"Identify the stakeholders for the following requirement:\n\n{requirement}\n\nStakeholders:")
26
+ self.assertEqual(actual, expected, f"Test failed for stakeholders. Expected: {expected}, but got: {actual}")
27
+
28
+ def test_defects_identification(self):
29
+ requirement = "The system shall allow users to login."
30
+ expected = "No defects"
31
+ actual = call_mistral_api(f"Analyze the following requirement and identify ONLY MAJOR defects:\n\n{requirement}\n\nDefects:")
32
+ self.assertEqual(actual, expected, f"Test failed for defects. Expected: {expected}, but got: {actual}")
33
+
34
+ # Add more test cases as needed...
35
+
36
+ # Custom runner to display detailed results
37
+ class DetailedTextTestRunner(unittest.TextTestRunner):
38
+ def getDescription(self, test):
39
+ return f"{test.__class__.__name__} ({test._testMethodName})"
40
+
41
+ def run(self, test):
42
+ result = super().run(test)
43
+ self.display_results(result)
44
+ return result
45
+
46
+ def display_results(self, result):
47
+ if result.errors or result.failures:
48
+ st.subheader("Test Results")
49
+ for test, traceback in result.errors + result.failures:
50
+ st.write(f"**Test Case:** {test}")
51
+ st.write(f"**Error/Failure:** {traceback}")
52
+ else:
53
+ st.success("All tests passed successfully!")
54
+
55
+ st.subheader("Test Summary")
56
+ st.write(f"Total Tests Run: {result.testsRun}")
57
+ st.write(f"Failures: {len(result.failures)}")
58
+ st.write(f"Errors: {len(result.errors)}")
59
+ st.write(f"Skipped: {len(result.skipped)}")
60
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  # Streamlit app
62
  def main():
63
  st.title("AI Powered Requirement Analysis and Defect Detection using Large Language Model Mistral")
 
71
  # Split by periods or newlines
72
  requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()]
73
 
74
+ # Analyze requirements and display results
75
  if st.button("Analyze Requirements"):
76
  if not requirements:
77
  st.warning("Please enter requirements.")
 
102
  mime="application/pdf"
103
  )
104
 
105
+ # Run the unit tests
106
+ st.subheader("Running Unit Tests...")
107
+ test_suite = unittest.defaultTestLoader.loadTestsFromTestCase(RequirementTestCase)
108
+ test_runner = DetailedTextTestRunner(verbosity=2)
109
+ test_runner.run(test_suite)
110
 
111
  # Run the app
112
  if __name__ == "__main__":