Hackathon / app.py
SameerArz's picture
Update app.py
28aa36f verified
raw
history blame
6.9 kB
#!/usr/bin/env python3
import streamlit as st
from gradio_client import Client
from groq import Groq
from PIL import Image
import moviepy.editor as mp
from natsort import natsorted
import os
from dotenv import load_dotenv
import json
# Load environment variables
load_dotenv()
# Constants
HF_TOKEN = os.getenv("HF_TOKEN")
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
IMAGE_GENERATION_SPACE_NAME = "stabilityai/stable-diffusion-3.5-large-turbo"
# Initialize Groq client with minimal parameters
try:
groq_client = Groq(api_key=GROQ_API_KEY)
except Exception as e:
st.error(f"Failed to initialize Groq client: {e}")
groq_client = None
# LLM Models (free options)
LLM_MODELS = {
"Mixtral 8x7B (Groq)": "mixtral-8x7b-32768",
"Mistral 7B (HF)": "mistralai/Mixtral-7B-Instruct-v0.1",
"LLaMA 13B (HF)": "meta-llama/Llama-13b-hf" # Note: May require approval; replace if needed
}
# Utility Functions
def generate_tutor_output(subject, difficulty, student_input, model):
prompt = f"""
You are an expert tutor in {subject} at the {difficulty} level.
The student has provided the following input: "{student_input}"
Please generate:
1. A brief, engaging lesson on the topic (2-3 paragraphs)
2. A thought-provoking question to check understanding
3. Constructive feedback on the student's input
Format your response as a JSON object with keys: "lesson", "question", "feedback"
"""
if model.startswith("mixtral") and groq_client: # Groq model
try:
completion = groq_client.chat.completions.create(
messages=[{
"role": "system",
"content": f"You are the world's best AI tutor for {subject}, renowned for clear, engaging explanations."
}, {
"role": "user",
"content": prompt
}],
model=model,
max_tokens=1000
)
return json.loads(completion.choices[0].message.content)
except Exception as e:
st.error(f"Groq error: {e}")
return {"lesson": "Error generating lesson", "question": "N/A", "feedback": "N/A"}
else: # Hugging Face models
try:
client = Client("https://api-inference.huggingface.co/models/" + model, hf_token=HF_TOKEN)
response = client.predict(prompt, api_name="/generate")
return json.loads(response)
except:
st.warning(f"HF model {model} failed, falling back to Mixtral.")
if groq_client:
return generate_tutor_output(subject, difficulty, student_input, "mixtral-8x7b-32768")
return {"lesson": "Error generating lesson", "question": "N/A", "feedback": "N/A"}
def generate_image(prompt, path='temp_image.png'):
try:
client = Client(IMAGE_GENERATION_SPACE_NAME, hf_token=HF_TOKEN)
result = client.predict(
prompt=prompt,
width=512,
height=512,
api_name="/predict"
)
image = Image.open(result)
image.save(path)
return path
except Exception as e:
st.error(f"Error generating image: {e}")
return None
def generate_video(images, audio_text, language, speaker, path='temp_video.mp4'):
try:
audio_client = Client("habib926653/Multilingual-TTS")
audio_result = audio_client.predict(
text=audio_text,
language_code=language,
speaker=speaker,
api_name="/text_to_speech_edge"
)
audio_file = audio_result[1]
with open(audio_file, 'rb') as f:
audio_bytes = f.read()
audio_path = "temp_audio.mp3"
with open(audio_path, 'wb') as f:
f.write(audio_bytes)
audio_clip = mp.AudioFileClip(audio_path)
duration_per_image = audio_clip.duration / len(images)
image_clips = [mp.ImageClip(img).set_duration(duration_per_image) for img in images if img]
video = mp.concatenate_videoclips(image_clips, method="compose").set_audio(audio_clip)
video.write_videofile(path, fps=24, codec='libx264')
return path
except Exception as e:
st.error(f"Error generating video: {e}")
return None
# Streamlit App
def main():
st.markdown("<h1 style='text-align: center;'>EduAI: Your Interactive Tutor</h1>", unsafe_allow_html=True)
st.markdown("<p style='text-align: center;'>Learn, Ask, Visualize! ❤️</p>", unsafe_allow_html=True)
subject = st.selectbox("Choose Subject:", ["Math", "Science", "History", "Literature", "Code", "AI"])
difficulty = st.selectbox("Difficulty Level:", ["Beginner", "Intermediate", "Advanced"])
model = st.selectbox("Choose LLM Model:", list(LLM_MODELS.keys()))
student_input = st.text_area("Your Question/Input (max 1500 chars):", max_chars=1500)
if 'tutor_response' not in st.session_state:
st.session_state.tutor_response = None
if st.button("Generate Answer & Question"):
if student_input:
with st.spinner("Generating your lesson..."):
response = generate_tutor_output(subject, difficulty, student_input, LLM_MODELS[model])
st.session_state.tutor_response = response
else:
st.warning("Please provide an input!")
if st.session_state.tutor_response:
st.markdown("### Lesson")
st.write(st.session_state.tutor_response["lesson"])
st.markdown("### Comprehension Question")
st.write(st.session_state.tutor_response["question"])
st.markdown("### Feedback")
st.write(st.session_state.tutor_response["feedback"])
col1, col2 = st.columns(2)
with col1:
if st.button("Generate Image"):
with st.spinner("Creating image..."):
image_path = generate_image(st.session_state.tutor_response["lesson"])
if image_path:
st.image(image_path, caption="Visual of your lesson")
with col2:
if st.button("Generate Video"):
with st.spinner("Creating video..."):
audio_client = Client("habib926653/Multilingual-TTS")
speakers_response = audio_client.predict(language="English", api_name="/get_speakers")
speaker = speakers_response["choices"][0][0]
images = [generate_image(st.session_state.tutor_response["lesson"])]
video_path = generate_video(images, st.session_state.tutor_response["lesson"], "English", speaker)
if video_path:
st.video(video_path)
st.markdown("---")
st.markdown("<p style='text-align: center;'>Built for learning, powered by AI!</p>", unsafe_allow_html=True)
if __name__ == "__main__":
main()