|
import streamlit as st |
|
import requests |
|
from fpdf import FPDF |
|
import os |
|
import time |
|
from datetime import datetime |
|
import groq |
|
|
|
|
|
mistral_api_key = os.getenv("MISTRAL_API_KEY", "your_mistral_key_here") |
|
groq_api_key = os.getenv("GROQ_API_KEY", "your_groq_key_here") |
|
|
|
|
|
groq_client = groq.Client(api_key=groq_api_key) |
|
|
|
def call_mistral_api(prompt): |
|
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() |
|
return response.json()['choices'][0]['message']['content'] |
|
except Exception as err: |
|
return f"Error: {err}" |
|
|
|
def call_groq_api(prompt): |
|
try: |
|
response = groq_client.chat.completions.create( |
|
model="llama-3.3-70b-versatile", |
|
messages=[{"role": "user", "content": prompt}] |
|
) |
|
return response.choices[0].message.content |
|
except Exception as err: |
|
return f"Error: {err}" |
|
|
|
def analyze_requirement(requirement): |
|
type_prompt = f"Classify as Functional or Non-Functional in one word:\n{requirement}\nType:" |
|
req_type = call_mistral_api(type_prompt).strip() |
|
|
|
domain_prompt = f"Classify domain in one word:\n{requirement}\nDomain:" |
|
domain = call_mistral_api(domain_prompt).strip() |
|
|
|
defects_prompt = f"List major defects (1-2 words each):\n{requirement}\nDefects:" |
|
defects = call_groq_api(defects_prompt).strip() |
|
|
|
rewritten_prompt = f"Rewrite to address defects:\n{requirement}\nRewritten:" |
|
rewritten = call_groq_api(rewritten_prompt).strip() |
|
|
|
return { |
|
"Requirement": requirement, |
|
"Type": req_type, |
|
"Domain": domain, |
|
"Defects": defects, |
|
"Rewritten": rewritten |
|
} |
|
|
|
def generate_pdf_report(results): |
|
pdf = FPDF() |
|
pdf.add_page() |
|
pdf.set_font("Arial", size=12) |
|
|
|
|
|
|
|
|
|
pdf_output = "requirements_report.pdf" |
|
pdf.output(pdf_output) |
|
return pdf_output |
|
|
|
def main(): |
|
st.markdown(""" |
|
<style> |
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap'); |
|
* { font-family: 'Poppins', sans-serif; } |
|
.main-container { max-width: 800px; margin: 0 auto; padding: 2rem; } |
|
.gradient-header { |
|
background: linear-gradient(45deg, #4F46E5, #1E40AF); |
|
color: white; |
|
padding: 2rem; |
|
border-radius: 15px; |
|
margin-bottom: 2rem; |
|
} |
|
.team-card { |
|
background: #f8f9fa; |
|
padding: 1.5rem; |
|
border-radius: 15px; |
|
margin: 1rem 0; |
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
|
} |
|
.result-card { |
|
background: white; |
|
padding: 1.5rem; |
|
border-radius: 15px; |
|
margin: 1rem 0; |
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1); |
|
} |
|
.badge { |
|
padding: 0.5rem 1rem; |
|
border-radius: 20px; |
|
font-size: 0.9rem; |
|
margin-right: 0.5rem; |
|
display: inline-block; |
|
} |
|
.type-badge { background: #4F46E510; color: #4F46E5; } |
|
.domain-badge { background: #10B98110; color: #10B981; } |
|
.defect-badge { background: #EF444410; color: #EF4444; } |
|
.animate-hover { transition: transform 0.2s; } |
|
.animate-hover:hover { transform: translateY(-2px); } |
|
.styled-textarea { |
|
border: 2px solid #e0e0e0 !important; |
|
border-radius: 10px !important; |
|
padding: 1rem !important; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
st.markdown(""" |
|
<div class="main-container"> |
|
<div class="gradient-header"> |
|
<h1 style="margin: 0; font-weight: 600;">π§ AI Requirement Analyzer</h1> |
|
<p style="margin: 0.5rem 0 0; opacity: 0.9;">Smart Analysis & Quality Enhancement System</p> |
|
</div> |
|
|
|
<div class="team-card"> |
|
<h3 style="margin: 0 0 1rem;">π₯ Team Members</h3> |
|
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem;"> |
|
<div style="background: #4F46E510; padding: 0.5rem; border-radius: 10px;"> |
|
<p style="margin: 0; color: #4F46E5;">Sadia</p> |
|
</div> |
|
<div style="background: #10B98110; padding: 0.5rem; border-radius: 10px;"> |
|
<p style="margin: 0; color: #10B981;">Areeba</p> |
|
</div> |
|
<div style="background: #EF444410; padding: 0.5rem; border-radius: 10px;"> |
|
<p style="margin: 0; color: #EF4444;">Rabbia</p> |
|
</div> |
|
<div style="background: #3B82F610; padding: 0.5rem; border-radius: 10px;"> |
|
<p style="margin: 0; color: #3B82F6;">Tesmia</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div style="margin: 2rem 0;"> |
|
<h2>π₯ Input Requirements</h2> |
|
<p style="opacity: 0.8;">Enter multiple requirements separated by new lines or periods</p> |
|
""", unsafe_allow_html=True) |
|
|
|
input_text = st.text_area("", height=200, key="input_area", |
|
help="Example:\n1. The system must handle 1000 users\n2. User interface should be responsive") |
|
|
|
if st.button("π Start Analysis", key="analyze_btn", use_container_width=True): |
|
if not input_text.strip(): |
|
st.warning("β οΈ Please enter requirements to analyze") |
|
else: |
|
requirements = [req.strip() for req in input_text.replace("\n", ".").split(".") if req.strip()] |
|
results = [] |
|
progress_bar = st.progress(0) |
|
|
|
with st.spinner("π Analyzing requirements..."): |
|
for i, req in enumerate(requirements): |
|
results.append(analyze_requirement(req)) |
|
progress_bar.progress((i+1)/len(requirements)) |
|
time.sleep(0.1) |
|
|
|
st.success("β
Analysis completed!") |
|
st.markdown("---") |
|
|
|
for i, result in enumerate(results, 1): |
|
st.markdown(f""" |
|
<div class="result-card animate-hover"> |
|
<h3 style="margin: 0 0 1rem;">π Requirement R{i}</h3> |
|
<p style="font-size: 1.1rem; margin-bottom: 1.5rem;">{result['Requirement']}</p> |
|
|
|
<div style="display: flex; gap: 1rem; margin-bottom: 1rem;"> |
|
<span class="badge type-badge">π {result['Type']}</span> |
|
<span class="badge domain-badge">π {result['Domain']}</span> |
|
<span class="badge defect-badge">β οΈ {result['Defects']}</span> |
|
</div> |
|
|
|
<div style="background: #f8f9fa; padding: 1rem; border-radius: 10px;"> |
|
<p style="margin: 0; color: #3B82F6;">βοΈ Optimized Version:</p> |
|
<p style="margin: 0.5rem 0 0; font-weight: 500;">{result['Rewritten']}</p> |
|
</div> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
st.markdown("---") |
|
st.markdown("### π Generate 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_analysis.pdf", |
|
mime="application/pdf", |
|
use_container_width=True, |
|
key="download_btn" |
|
) |
|
|
|
st.markdown("</div>", unsafe_allow_html=True) |
|
|
|
if __name__ == "__main__": |
|
main() |