iisadia's picture
Update app.py
f004bde verified
raw
history blame
8.65 kB
import streamlit as st
import requests
from fpdf import FPDF
import os
import time
from datetime import datetime
import groq
import pandas as pd
import matplotlib.pyplot as plt
# API keys (replace with your keys or use environment variables)
mistral_api_key = os.getenv("MISTRAL_API_KEY", "gz6lDXokxgR6cLY72oomALWcm7vhjRzQ")
groq_api_key = os.getenv("GROQ_API_KEY", "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")
# Initialize Groq client
groq_client = groq.Client(api_key=groq_api_key)
# Function to call Mistral API
def call_mistral_api(prompt):
start_time = time.time()
url = "https://api.mistral.ai/v1/chat/completions"
headers = {
"Authorization": f"Bearer {mistral_api_key}",
"Content-Type": "application/json"
}
payload = {
"model": "mistral-medium",
"messages": [
{"role": "user", "content": prompt}
]
}
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status() # Raise an error for bad status codes
end_time = time.time()
speed = end_time - start_time
content = response.json()['choices'][0]['message']['content']
return content, speed
except requests.exceptions.HTTPError as err:
if response.status_code == 429: # Rate limit exceeded
st.warning("Rate limit exceeded. Please wait a few seconds and try again.")
time.sleep(5) # Wait for 5 seconds before retrying
return call_mistral_api(prompt) # Retry the request
return f"HTTP Error: {err}", 0
except Exception as err:
return f"Error: {err}", 0
# Function to call Groq API
def call_groq_api(prompt):
start_time = time.time()
try:
response = groq_client.chat.completions.create(
model="llama-3.3-70b-versatile", # Correct model name
messages=[
{"role": "user", "content": prompt}
]
)
end_time = time.time()
speed = end_time - start_time
content = response.choices[0].message.content
return content, speed
except Exception as err:
st.error(f"Error: {err}")
return f"Error: {err}", 0
# Function to analyze a single requirement using both models
def analyze_requirement(requirement):
# Use Mistral for classification and domain identification
type_prompt = f"Classify the following requirement as Functional or Non-Functional in one word:\n\n{requirement}\n\nType:"
req_type, type_speed = call_mistral_api(type_prompt)
req_type = req_type.strip()
domain_prompt = f"Classify the domain for the following requirement in one word (e.g., E-commerce, Education, etc.):\n\n{requirement}\n\nDomain:"
domain, domain_speed = call_mistral_api(domain_prompt)
domain = domain.strip()
# Use Groq for defect analysis and rewriting
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:"""
defects, defects_speed = call_groq_api(defects_prompt)
defects = defects.strip()
rewritten_prompt = f"""Rewrite the following requirement in 1-2 sentences to address the defects:\n\n{requirement}\n\nRewritten:"""
rewritten, rewritten_speed = call_groq_api(rewritten_prompt)
rewritten = rewritten.strip()
# Calculate total speed for this requirement
total_speed = type_speed + domain_speed + defects_speed + rewritten_speed
return {
"Requirement": requirement,
"Type": req_type,
"Domain": domain,
"Defects": defects,
"Rewritten": rewritten,
"Total_Speed": total_speed
}
# Function to calculate accuracy (placeholder logic)
def calculate_accuracy(results):
# Placeholder logic: Assume 80% accuracy for demonstration
# Replace this with actual logic if you have correct answers
return 80.0 # Return accuracy as a percentage
# Function to generate a PDF report
def generate_pdf_report(results):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
# Add watermark
pdf.set_font("Arial", 'B', 50)
pdf.set_text_color(230, 230, 230) # Light gray color for watermark
pdf.rotate(45) # Rotate the text for watermark effect
pdf.text(60, 150, "AI Powered Requirement Analysis")
pdf.rotate(0) # Reset rotation
# Add title and date/time
pdf.set_font("Arial", 'B', 16)
pdf.set_text_color(0, 0, 0) # Black color for title
pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
pdf.ln(10) # Add some space
# Add requirements analysis
pdf.set_font("Arial", size=12)
for i, result in enumerate(results, start=1):
if pdf.get_y() > 250: # If the content is near the bottom of the page
pdf.add_page() # Add a new page
pdf.set_font("Arial", 'B', 16)
pdf.cell(200, 10, txt="AI Powered Requirement Analysis and Defect Detection", ln=True, align='C')
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt=f"Report Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align='C')
pdf.ln(10) # Add some space
# Add requirement details
pdf.set_font("Arial", 'B', 14)
pdf.multi_cell(200, 10, txt=f"Requirement R{i}: {result['Requirement']}", align='L')
pdf.set_font("Arial", size=12)
pdf.multi_cell(200, 10, txt=f"Type: {result['Type']}", align='L')
pdf.multi_cell(200, 10, txt=f"Domain: {result['Domain']}", align='L')
pdf.multi_cell(200, 10, txt=f"Defects: {result['Defects']}", align='L')
pdf.multi_cell(200, 10, txt=f"Rewritten: {result['Rewritten']}", align='L')
pdf.multi_cell(200, 10, txt=f"Total Speed: {result['Total_Speed']:.2f}s", align='L')
pdf.multi_cell(200, 10, txt="-" * 50, align='L')
pdf.ln(5) # Add some space between requirements
pdf_output = "requirements_report.pdf"
pdf.output(pdf_output)
return pdf_output
# Streamlit app
def main():
st.title("AI Powered Requirement Analysis and Defect Detection")
st.markdown("**Team Name:** Sadia, Areeba, Rabbia, Tesmia")
st.markdown("**Models:** Mistral (Classification & Domain) + Groq (Defects & Rewriting)")
# Input requirements manually
input_text = st.text_area("Enter your requirements (one per line or separated by periods):")
requirements = []
if input_text:
requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()]
# Analyze requirements
if st.button("Analyze Requirements"):
if not requirements:
st.warning("Please enter requirements.")
else:
results = []
total_speed = 0
for req in requirements:
if req.strip(): # Ignore empty lines
result = analyze_requirement(req.strip())
results.append(result)
total_speed += result["Total_Speed"]
# Calculate accuracy (placeholder logic)
accuracy = calculate_accuracy(results)
# Display total speed and accuracy
st.subheader("Performance Metrics")
col1, col2 = st.columns(2)
with col1:
st.metric("Total Speed", f"{total_speed:.2f} seconds")
with col2:
st.metric("Accuracy", f"{accuracy:.2f}%")
# Visualize metrics
st.subheader("Visualization")
metrics_data = {
"Metric": ["Total Speed", "Accuracy"],
"Value": [total_speed, accuracy]
}
df = pd.DataFrame(metrics_data)
# Bar chart
fig, ax = plt.subplots()
ax.bar(df["Metric"], df["Value"], color=["blue", "green"])
ax.set_ylabel("Value")
ax.set_title("Performance Metrics")
st.pyplot(fig)
# Table
st.table(df)
# Generate and download PDF report
pdf_report = generate_pdf_report(results)
with open(pdf_report, "rb") as f:
st.download_button(
label="Download PDF Report",
data=f,
file_name="requirements_report.pdf",
mime="application/pdf"
)
# Run the app
if __name__ == "__main__":
main()