Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,47 +1,119 @@
|
|
|
|
1 |
import streamlit as st
|
2 |
import requests
|
|
|
|
|
3 |
|
4 |
-
#
|
5 |
-
API_KEY = "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" # π Replace with your key
|
6 |
API_URL = "https://openrouter.ai/api/v1/chat/completions"
|
|
|
|
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
}
|
12 |
-
|
13 |
-
|
14 |
data = {
|
15 |
-
"model":
|
16 |
-
"messages": [
|
17 |
-
|
18 |
-
{"role": "user", "content": prompt}
|
19 |
-
]
|
20 |
}
|
21 |
-
|
22 |
try:
|
23 |
-
response = requests.post(API_URL, headers=
|
24 |
-
|
25 |
-
return
|
26 |
except Exception as e:
|
27 |
-
return f"β Error: {str(e)}"
|
28 |
|
29 |
-
#
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
st.title("π§ͺ Science Lab Assistant")
|
32 |
-
st.
|
|
|
|
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
st.
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
|
|
45 |
st.markdown("---")
|
46 |
-
st.
|
47 |
-
st.
|
|
|
|
|
|
1 |
+
# app.py
|
2 |
import streamlit as st
|
3 |
import requests
|
4 |
+
from datetime import datetime
|
5 |
+
from fpdf import FPDF
|
6 |
|
7 |
+
# Replace with your actual OpenRouter or Hugging Face endpoint and key
|
|
|
8 |
API_URL = "https://openrouter.ai/api/v1/chat/completions"
|
9 |
+
API_KEY = "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"
|
10 |
+
MODEL = "mistralai/mistral-7b-instruct"
|
11 |
|
12 |
+
# ------------------------- AI QUERY FUNCTION -------------------------
|
13 |
+
def query_ai(prompt):
|
14 |
+
headers = {
|
15 |
+
"Authorization": f"Bearer {API_KEY}",
|
16 |
+
"Content-Type": "application/json"
|
17 |
+
}
|
18 |
data = {
|
19 |
+
"model": MODEL,
|
20 |
+
"messages": [{"role": "user", "content": prompt}],
|
21 |
+
"temperature": 0.7
|
|
|
|
|
22 |
}
|
|
|
23 |
try:
|
24 |
+
response = requests.post(API_URL, headers=headers, json=data)
|
25 |
+
response.raise_for_status()
|
26 |
+
return response.json()['choices'][0]['message']['content']
|
27 |
except Exception as e:
|
28 |
+
return f"β API Error: {str(e)}"
|
29 |
|
30 |
+
# ---------------------- EXPERIMENT TEMPLATES ------------------------
|
31 |
+
experiments = {
|
32 |
+
"Vinegar + Baking Soda": {
|
33 |
+
"hypothesis": "Mixing vinegar and baking soda will produce bubbles due to a chemical reaction.",
|
34 |
+
"concept": "Acid-base reaction producing carbon dioxide."
|
35 |
+
},
|
36 |
+
"Floating Egg": {
|
37 |
+
"hypothesis": "An egg will float in salt water but sink in plain water.",
|
38 |
+
"concept": "Density difference between saltwater and freshwater."
|
39 |
+
},
|
40 |
+
"Lemon Battery": {
|
41 |
+
"hypothesis": "A lemon can produce electricity to power a small LED.",
|
42 |
+
"concept": "Chemical energy conversion to electrical energy."
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
# -------------------------- PDF REPORT ------------------------------
|
47 |
+
def generate_pdf_report(exp_name, hypo, explanation, result):
|
48 |
+
pdf = FPDF()
|
49 |
+
pdf.add_page()
|
50 |
+
pdf.set_font("Arial", size=12)
|
51 |
+
pdf.cell(200, 10, txt="Science Lab Report", ln=True, align='C')
|
52 |
+
pdf.ln(10)
|
53 |
+
pdf.multi_cell(0, 10, txt=f"Experiment: {exp_name}\n\nHypothesis: {hypo}\n\nAI Explanation: {explanation}\n\nExpected Result: {result}")
|
54 |
+
filename = f"report_{datetime.now().strftime('%Y%m%d%H%M%S')}.pdf"
|
55 |
+
pdf.output(filename)
|
56 |
+
return filename
|
57 |
+
|
58 |
+
# --------------------------- STREAMLIT UI ---------------------------
|
59 |
+
st.set_page_config(page_title="π§ͺ Science Lab Assistant", layout="centered")
|
60 |
st.title("π§ͺ Science Lab Assistant")
|
61 |
+
st.markdown("Helping students understand, hypothesize, and explain science experiments.")
|
62 |
+
|
63 |
+
exp_choice = st.selectbox("Choose an experiment or enter your own:", list(experiments.keys()) + ["Custom Experiment"])
|
64 |
|
65 |
+
if exp_choice != "Custom Experiment":
|
66 |
+
default_hypo = experiments[exp_choice]["hypothesis"]
|
67 |
+
concept = experiments[exp_choice]["concept"]
|
68 |
+
else:
|
69 |
+
default_hypo = ""
|
70 |
+
concept = ""
|
71 |
|
72 |
+
with st.form("experiment_form"):
|
73 |
+
exp_name = st.text_input("Experiment Name", value=exp_choice)
|
74 |
+
hypo = st.text_area("Your Hypothesis", value=default_hypo)
|
75 |
+
submit = st.form_submit_button("π Explain Experiment")
|
76 |
+
|
77 |
+
if submit:
|
78 |
+
with st.spinner("Thinking like a scientist..."):
|
79 |
+
prompt = f"Explain the following school science experiment clearly for a student.\n\nExperiment: {exp_name}\nHypothesis: {hypo}\nExplain what happens, why it happens, and what the expected result is."
|
80 |
+
explanation = query_ai(prompt)
|
81 |
+
|
82 |
+
st.success("AI Explanation")
|
83 |
+
st.write(explanation)
|
84 |
+
|
85 |
+
# Generate expected result
|
86 |
+
with st.spinner("Predicting result..."):
|
87 |
+
result = query_ai(f"What is the expected result of this experiment: {exp_name}?")
|
88 |
+
st.info(f"**Expected Result:** {result}")
|
89 |
+
|
90 |
+
# Conceptual Science
|
91 |
+
if concept:
|
92 |
+
st.caption(f"π§ Science Concept: {concept}")
|
93 |
+
|
94 |
+
# PDF Download
|
95 |
+
pdf_file = generate_pdf_report(exp_name, hypo, explanation, result)
|
96 |
+
with open(pdf_file, "rb") as file:
|
97 |
+
st.download_button("π Download Lab Report (PDF)", file, file_name=pdf_file)
|
98 |
+
|
99 |
+
# --------------------- OPTIONAL FILE UPLOAD -------------------------
|
100 |
+
st.markdown("---")
|
101 |
+
st.subheader("πΈ Upload Your Lab Report Image (optional)")
|
102 |
+
uploaded_file = st.file_uploader("Upload an image for feedback", type=["jpg", "png", "jpeg"])
|
103 |
+
if uploaded_file:
|
104 |
+
st.image(uploaded_file, caption="Uploaded Report", use_column_width=True)
|
105 |
+
st.markdown("β
Received. AI feedback coming soon (future feature).")
|
106 |
+
|
107 |
+
# ------------------------ GLOSSARY HELPER ---------------------------
|
108 |
+
st.markdown("---")
|
109 |
+
st.subheader("π Ask About a Science Term")
|
110 |
+
term = st.text_input("Enter a science term (e.g., osmosis, catalyst)")
|
111 |
+
if term:
|
112 |
+
st.write(query_ai(f"Explain the term '{term}' in simple words for a student."))
|
113 |
|
114 |
+
# ---------------------- FEEDBACK SECTION ----------------------------
|
115 |
st.markdown("---")
|
116 |
+
st.subheader("π¬ Feedback")
|
117 |
+
user_feedback = st.text_area("What can we improve in this app?")
|
118 |
+
if user_feedback:
|
119 |
+
st.success("Thanks! Your feedback was recorded (simulated). π¨")
|