Ahmad-01 commited on
Commit
64664c6
Β·
verified Β·
1 Parent(s): f727893

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +208 -33
src/streamlit_app.py CHANGED
@@ -1,40 +1,215 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  """
7
- # Welcome to Streamlit!
 
 
 
 
 
 
 
 
 
 
8
 
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
 
 
 
12
 
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
1
+ %%writefile app.py
2
+ import os
 
3
  import streamlit as st
4
+ from groq import Groq
5
+
6
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
7
+ from langchain_community.vectorstores import FAISS
8
+ from langchain_community.embeddings import HuggingFaceEmbeddings
9
+
10
+ import pandas as pd
11
+ import docx
12
+ from pypdf import PdfReader
13
+
14
+ from reportlab.platypus import SimpleDocTemplate, Paragraph
15
+ from reportlab.lib.styles import getSampleStyleSheet
16
+ import tempfile
17
+
18
+ # -----------------------------
19
+ # GROQ CLIENT
20
+ # -----------------------------
21
+ client = Groq(api_key=os.environ.get("GROQ_API_KEY"))
22
+
23
+ # -----------------------------
24
+ # PAGE CONFIG
25
+ # -----------------------------
26
+ st.set_page_config(
27
+ page_title="AI Study Assistant πŸ“š",
28
+ page_icon="πŸŽ“",
29
+ layout="wide",
30
+ initial_sidebar_state="expanded"
31
+ )
32
+
33
+ # -----------------------------
34
+ # SIDEBAR
35
+ # -----------------------------
36
+ st.sidebar.title("πŸ“Œ Settings")
37
+ education_level = st.sidebar.selectbox(
38
+ "Select Education Level",
39
+ ["Primary School", "Middle School", "Secondary School", "High School", "Undergraduate", "Graduate"]
40
+ )
41
+ st.sidebar.markdown("---")
42
+ st.sidebar.write("Developed by **Ahmad Bilal** | Fiverr Portfolio Demo")
43
+
44
+ # -----------------------------
45
+ # HEADER
46
+ # -----------------------------
47
+ st.markdown(
48
+ """
49
+ <div style='text-align:center; padding:10px; background-color:#f0f2f6; border-radius:10px'>
50
+ <h1 style='color:#0f4c81'>πŸŽ“ AI Study Assistant</h1>
51
+ <p style='font-size:18px; color:#333'>Upload your study material and ask questions. Get answers & summaries instantly!</p>
52
+ </div>
53
+ """,
54
+ unsafe_allow_html=True
55
+ )
56
+
57
+ # -----------------------------
58
+ # FILE UPLOADER (CENTER)
59
+ # -----------------------------
60
+ st.markdown("### πŸ“‚ Upload Your Study Materials")
61
+ uploaded_files = st.file_uploader(
62
+ "",
63
+ type=["pdf","docx","txt","csv","xlsx"],
64
+ accept_multiple_files=True,
65
+ help="Upload PDFs, Word Docs, Excel, CSV, or TXT files."
66
+ )
67
+
68
+ # -----------------------------
69
+ # FILE PROCESSING
70
+ # -----------------------------
71
+ def load_pdf(file):
72
+ reader = PdfReader(file)
73
+ text=""
74
+ for page in reader.pages:
75
+ text+=page.extract_text()
76
+ return text
77
+
78
+ def load_docx(file):
79
+ doc=docx.Document(file)
80
+ return "\n".join([p.text for p in doc.paragraphs])
81
+
82
+ def load_csv(file):
83
+ df=pd.read_csv(file)
84
+ return df.to_string()
85
+
86
+ def load_xlsx(file):
87
+ df=pd.read_excel(file)
88
+ return df.to_string()
89
+
90
+ def load_txt(file):
91
+ return file.read().decode("utf-8")
92
 
93
+ def process_docs(files):
94
+ text=""
95
+ for file in files:
96
+ if file.type=="application/pdf":
97
+ text+=load_pdf(file)
98
+ elif file.type=="application/vnd.openxmlformats-officedocument.wordprocessingml.document":
99
+ text+=load_docx(file)
100
+ elif file.type=="text/csv":
101
+ text+=load_csv(file)
102
+ elif file.type=="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
103
+ text+=load_xlsx(file)
104
+ else:
105
+ text+=load_txt(file)
106
+ return text
107
+
108
+ # -----------------------------
109
+ # VECTOR STORE
110
+ # -----------------------------
111
+ @st.cache_resource
112
+ def create_vectorstore(text):
113
+ splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100)
114
+ chunks = splitter.split_text(text)
115
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
116
+ vectorstore = FAISS.from_texts(chunks, embeddings)
117
+ return vectorstore
118
+
119
+ # -----------------------------
120
+ # PROMPT BUILDER
121
+ # -----------------------------
122
+ def build_prompt(context, question, level):
123
+ style={
124
+ "Primary School":"Explain like teaching a 5 year old child using simple fun examples.",
125
+ "Middle School":"Explain using easy examples.",
126
+ "Secondary School":"Explain clearly using simple concepts.",
127
+ "High School":"Explain with reasoning and examples.",
128
+ "Undergraduate":"Explain in academic but easy language.",
129
+ "Graduate":"Provide detailed academic explanation."
130
+ }
131
+ prompt=f"""
132
+ Use the study material below to answer the question.
133
+
134
+ Study Material:
135
+ {context}
136
+
137
+ Question:
138
+ {question}
139
+
140
+ Explanation Style:
141
+ {style[level]}
142
  """
143
+ return prompt
144
+
145
+ # -----------------------------
146
+ # GROQ LLM CALL
147
+ # -----------------------------
148
+ def ask_llm(prompt):
149
+ chat_completion = client.chat.completions.create(
150
+ messages=[{"role":"user","content":prompt}],
151
+ model="llama-3.3-70b-versatile"
152
+ )
153
+ return chat_completion.choices[0].message.content
154
 
155
+ # -----------------------------
156
+ # SUMMARY GENERATOR
157
+ # -----------------------------
158
+ def generate_summary(text):
159
+ prompt=f"""
160
+ Create a short and easy summary of the following material.
161
 
162
+ {text}
163
  """
164
+ return ask_llm(prompt)
165
+
166
+ # -----------------------------
167
+ # PDF GENERATOR
168
+ # -----------------------------
169
+ def create_pdf(text):
170
+ temp_file=tempfile.NamedTemporaryFile(delete=False,suffix=".pdf")
171
+ styles=getSampleStyleSheet()
172
+ story=[Paragraph(text,styles["Normal"])]
173
+ doc=SimpleDocTemplate(temp_file.name)
174
+ doc.build(story)
175
+ return temp_file.name
176
+
177
+ # -----------------------------
178
+ # MAIN APP LOGIC
179
+ # -----------------------------
180
+ if uploaded_files:
181
+
182
+ raw_text=process_docs(uploaded_files)
183
+ vectorstore=create_vectorstore(raw_text)
184
+
185
+ st.markdown("---")
186
+ st.markdown("### ❓ Ask a Question")
187
+ question=st.text_input("Type your question here:")
188
+
189
+ if question:
190
+
191
+ # Use columns for nicer layout
192
+ col1, col2 = st.columns([2,1])
193
+
194
+ docs = vectorstore.similarity_search(question, k=3)
195
+ context = "\n".join([doc.page_content for doc in docs])
196
+ prompt = build_prompt(context, question, education_level)
197
+ answer = ask_llm(prompt)
198
+
199
+ with col1:
200
+ st.markdown("### πŸ“– Answer")
201
+ st.success(answer)
202
+
203
+ with col2:
204
+ st.markdown("### πŸ“ Generate Summary")
205
+ if st.button("Create Summary & Download"):
206
+ summary = generate_summary(context)
207
+ st.markdown("#### Summary")
208
+ st.info(summary)
209
+ st.download_button("Download Markdown", summary, file_name="summary.md")
210
+ pdf_file=create_pdf(summary)
211
+ with open(pdf_file,"rb") as f:
212
+ st.download_button("Download PDF", f, file_name="summary.pdf")
213
 
214
+ else:
215
+ st.markdown("⚠️ Please upload at least one study document to start.")