Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,8 +7,6 @@ from io import BytesIO
|
|
| 7 |
import os
|
| 8 |
from dotenv import load_dotenv
|
| 9 |
from groq import Groq
|
| 10 |
-
import requests
|
| 11 |
-
from bs4 import BeautifulSoup
|
| 12 |
|
| 13 |
# Load API key
|
| 14 |
load_dotenv()
|
|
@@ -21,7 +19,7 @@ except Exception as e:
|
|
| 21 |
st.error(f"Failed to initialize Groq client: {str(e)}")
|
| 22 |
client = None
|
| 23 |
|
| 24 |
-
# Extract
|
| 25 |
def extract_text(file):
|
| 26 |
if file.name.endswith(".pdf"):
|
| 27 |
try:
|
|
@@ -36,34 +34,25 @@ def extract_text(file):
|
|
| 36 |
st.error(f"DOCX error: {e}")
|
| 37 |
return None
|
| 38 |
|
| 39 |
-
#
|
| 40 |
-
def extract_from_url(url):
|
| 41 |
-
try:
|
| 42 |
-
response = requests.get(url, headers={"User-Agent": "Mozilla"}, timeout=10)
|
| 43 |
-
soup = BeautifulSoup(response.text, "html.parser")
|
| 44 |
-
for tag in soup(["script", "style"]):
|
| 45 |
-
tag.decompose()
|
| 46 |
-
return " ".join(soup.stripped_strings)
|
| 47 |
-
except Exception as e:
|
| 48 |
-
st.error(f"URL extract error: {e}")
|
| 49 |
-
return None
|
| 50 |
-
|
| 51 |
-
# AI using llama3 (replaces broken deepseek)
|
| 52 |
def analyze_with_ai(prompt):
|
| 53 |
if not client:
|
| 54 |
return "Missing API key"
|
| 55 |
try:
|
| 56 |
-
|
| 57 |
model="llama3-70b-8192",
|
| 58 |
messages=[{"role": "user", "content": prompt}],
|
| 59 |
-
temperature=0.
|
| 60 |
-
max_tokens=
|
|
|
|
|
|
|
|
|
|
| 61 |
)
|
| 62 |
-
return
|
| 63 |
except Exception as e:
|
| 64 |
return f"AI Error: {e}"
|
| 65 |
|
| 66 |
-
# Save text as
|
| 67 |
def text_to_docx(text):
|
| 68 |
doc = Document()
|
| 69 |
for p in text.split("\n"):
|
|
@@ -74,82 +63,89 @@ def text_to_docx(text):
|
|
| 74 |
buffer.seek(0)
|
| 75 |
return buffer
|
| 76 |
|
| 77 |
-
# UI
|
| 78 |
-
st.set_page_config(page_title="AI
|
| 79 |
-
st.title("
|
| 80 |
-
st.write("Upload your
|
| 81 |
|
| 82 |
with st.sidebar:
|
| 83 |
st.markdown("### Instructions")
|
| 84 |
-
st.markdown("1. Upload
|
| 85 |
-
st.markdown("2.
|
| 86 |
-
st.markdown("3. Click 'Analyze'")
|
| 87 |
-
st.markdown("4. Download
|
| 88 |
|
| 89 |
# Inputs
|
| 90 |
col1, col2 = st.columns(2)
|
| 91 |
with col1:
|
| 92 |
-
|
| 93 |
with col2:
|
| 94 |
-
|
|
|
|
| 95 |
|
| 96 |
if st.button("🔍 Analyze and Generate"):
|
| 97 |
-
if
|
| 98 |
-
with st.spinner("
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
st.error("Resume or job description could not be processed.")
|
| 104 |
st.stop()
|
| 105 |
|
| 106 |
-
prompt
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
"""
|
| 122 |
|
| 123 |
ai_response = analyze_with_ai(prompt)
|
| 124 |
|
| 125 |
-
if "###
|
| 126 |
-
|
| 127 |
-
|
| 128 |
else:
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
st.warning("Unexpected format. Showing full response as
|
| 132 |
-
|
| 133 |
-
#
|
| 134 |
-
st.success("✅
|
| 135 |
-
st.subheader("
|
| 136 |
-
st.markdown(
|
| 137 |
-
st.download_button("⬇ Download
|
| 138 |
-
|
| 139 |
-
#
|
| 140 |
-
if
|
| 141 |
-
st.subheader("
|
| 142 |
-
st.markdown(
|
| 143 |
-
st.download_button("⬇ Download
|
| 144 |
else:
|
| 145 |
-
st.info("No
|
| 146 |
else:
|
| 147 |
-
st.warning("Please upload
|
| 148 |
|
| 149 |
# Footer
|
| 150 |
st.markdown("---")
|
| 151 |
st.markdown("""
|
| 152 |
<div style='text-align:center; font-size:0.85em; color:gray'>
|
| 153 |
-
AI
|
| 154 |
</div>
|
| 155 |
-
""", unsafe_allow_html=True)
|
|
|
|
| 7 |
import os
|
| 8 |
from dotenv import load_dotenv
|
| 9 |
from groq import Groq
|
|
|
|
|
|
|
| 10 |
|
| 11 |
# Load API key
|
| 12 |
load_dotenv()
|
|
|
|
| 19 |
st.error(f"Failed to initialize Groq client: {str(e)}")
|
| 20 |
client = None
|
| 21 |
|
| 22 |
+
# Extract text from uploaded file
|
| 23 |
def extract_text(file):
|
| 24 |
if file.name.endswith(".pdf"):
|
| 25 |
try:
|
|
|
|
| 34 |
st.error(f"DOCX error: {e}")
|
| 35 |
return None
|
| 36 |
|
| 37 |
+
# Analyze with Groq API
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
def analyze_with_ai(prompt):
|
| 39 |
if not client:
|
| 40 |
return "Missing API key"
|
| 41 |
try:
|
| 42 |
+
completion = client.chat.completions.create(
|
| 43 |
model="llama3-70b-8192",
|
| 44 |
messages=[{"role": "user", "content": prompt}],
|
| 45 |
+
temperature=0.7, # Balanced creativity for feedback
|
| 46 |
+
max_tokens=4096, # Adjusted for detailed feedback
|
| 47 |
+
top_p=1,
|
| 48 |
+
stream=False,
|
| 49 |
+
stop=None
|
| 50 |
)
|
| 51 |
+
return completion.choices[0].message.content
|
| 52 |
except Exception as e:
|
| 53 |
return f"AI Error: {e}"
|
| 54 |
|
| 55 |
+
# Save text as DOCX
|
| 56 |
def text_to_docx(text):
|
| 57 |
doc = Document()
|
| 58 |
for p in text.split("\n"):
|
|
|
|
| 63 |
buffer.seek(0)
|
| 64 |
return buffer
|
| 65 |
|
| 66 |
+
# Streamlit UI
|
| 67 |
+
st.set_page_config(page_title="AI IELTS Preparation Assistant", layout="wide")
|
| 68 |
+
st.title("📚 AI IELTS Preparation Assistant")
|
| 69 |
+
st.write("Upload your IELTS essay or input text to get feedback and practice questions for Writing and Speaking.")
|
| 70 |
|
| 71 |
with st.sidebar:
|
| 72 |
st.markdown("### Instructions")
|
| 73 |
+
st.markdown("1. Upload an essay (PDF or DOCX) or enter text.")
|
| 74 |
+
st.markdown("2. Select the IELTS section (Writing/Speaking).")
|
| 75 |
+
st.markdown("3. Click 'Analyze' for feedback and practice questions.")
|
| 76 |
+
st.markdown("4. Download feedback and practice materials.")
|
| 77 |
|
| 78 |
# Inputs
|
| 79 |
col1, col2 = st.columns(2)
|
| 80 |
with col1:
|
| 81 |
+
essay_file = st.file_uploader("Upload Essay (Optional)", type=["pdf", "docx"])
|
| 82 |
with col2:
|
| 83 |
+
essay_text = st.text_area("Or Enter Essay Text", height=200)
|
| 84 |
+
ielts_section = st.selectbox("IELTS Section", ["Writing Task 1", "Writing Task 2", "Speaking"])
|
| 85 |
|
| 86 |
if st.button("🔍 Analyze and Generate"):
|
| 87 |
+
if essay_file or essay_text:
|
| 88 |
+
with st.spinner("Analyzing your input..."):
|
| 89 |
+
# Extract text from file or use direct input
|
| 90 |
+
input_text = extract_text(essay_file) if essay_file else essay_text
|
| 91 |
+
if not input_text:
|
| 92 |
+
st.error("No text provided or extraction failed.")
|
|
|
|
| 93 |
st.stop()
|
| 94 |
|
| 95 |
+
# Define prompt based on IELTS section
|
| 96 |
+
if ielts_section.startswith("Writing"):
|
| 97 |
+
prompt = f"""
|
| 98 |
+
You are an IELTS examiner. Analyze the following {ielts_section} essay for grammar, vocabulary, coherence, and task response. Provide detailed feedback, including strengths, weaknesses, and suggestions for improvement (aligned with IELTS band descriptors). Also, generate 3 practice questions for {ielts_section}.
|
| 99 |
+
ESSAY:
|
| 100 |
+
{input_text[:3000]}
|
| 101 |
+
Respond in this format:
|
| 102 |
+
### Feedback:
|
| 103 |
+
<Detailed feedback>
|
| 104 |
+
### Practice Questions:
|
| 105 |
+
<Three practice questions>
|
| 106 |
+
"""
|
| 107 |
+
else: # Speaking
|
| 108 |
+
prompt = f"""
|
| 109 |
+
You are an IELTS examiner. Analyze the following IELTS Speaking response for fluency, vocabulary, grammar, and pronunciation. Provide detailed feedback, including strengths, weaknesses, and suggestions for improvement (aligned with IELTS band descriptors). Also, generate 3 practice questions for IELTS Speaking.
|
| 110 |
+
RESPONSE:
|
| 111 |
+
{input_text[:3000]}
|
| 112 |
+
Respond in this format:
|
| 113 |
+
### Feedback:
|
| 114 |
+
<Detailed feedback>
|
| 115 |
+
### Practice Questions:
|
| 116 |
+
<Three practice questions>
|
| 117 |
"""
|
| 118 |
|
| 119 |
ai_response = analyze_with_ai(prompt)
|
| 120 |
|
| 121 |
+
if "### Feedback:" in ai_response and "### Practice Questions:" in ai_response:
|
| 122 |
+
feedback_part = ai_response.split("### Practice Questions:")[0].replace("### Feedback:", "").strip()
|
| 123 |
+
questions_part = ai_response.split("### Practice Questions:")[1].strip()
|
| 124 |
else:
|
| 125 |
+
feedback_part = ai_response.strip()
|
| 126 |
+
questions_part = ""
|
| 127 |
+
st.warning("Unexpected response format. Showing full response as feedback.")
|
| 128 |
+
|
| 129 |
+
# Display and download feedback
|
| 130 |
+
st.success("✅ Analysis complete!")
|
| 131 |
+
st.subheader("📝 Feedback")
|
| 132 |
+
st.markdown(feedback_part)
|
| 133 |
+
st.download_button("⬇ Download Feedback", data=text_to_docx(feedback_part), file_name="ielts_feedback.docx")
|
| 134 |
+
|
| 135 |
+
# Display and download practice questions
|
| 136 |
+
if questions_part:
|
| 137 |
+
st.subheader("❓ Practice Questions")
|
| 138 |
+
st.markdown(questions_part)
|
| 139 |
+
st.download_button("⬇ Download Practice Questions", data=text_to_docx(questions_part), file_name="practice_questions.docx")
|
| 140 |
else:
|
| 141 |
+
st.info("No practice questions generated.")
|
| 142 |
else:
|
| 143 |
+
st.warning("Please upload an essay or enter text.")
|
| 144 |
|
| 145 |
# Footer
|
| 146 |
st.markdown("---")
|
| 147 |
st.markdown("""
|
| 148 |
<div style='text-align:center; font-size:0.85em; color:gray'>
|
| 149 |
+
AI IELTS Assistant · Powered by Groq LLaMA3 · Built with ❤️ in Streamlit
|
| 150 |
</div>
|
| 151 |
+
""", unsafe_allow_html=True)
|