PeterPinetree's picture
Update app.py
f926061 verified
raw
history blame
5.91 kB
import streamlit as st
from streamlit.components.v1 import html
import requests
import os
import base64
import tempfile
import io
from audiorecorder import audiorecorder
import streamlit.components.v1 as components
from PIL import Image
# Hugging Face API Keys
HF_API_KEY = os.getenv("HF_API_KEY")
HEADERS = {"Authorization": f"Bearer {HF_API_KEY}"}
# Hugging Face API Endpoints
HF_SPEECH_TO_TEXT_API = "https://api-inference.huggingface.co/models/openai/whisper-small"
HF_CHATBOT_API = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct"
HF_TEXT_TO_SPEECH_API = "https://api-inference.huggingface.co/models/facebook/mms-tts-eng"
# Avatars and their personalities
avatars = {
"rat": {"desc": "Clever and resourceful. Loves puzzles and word games.", "voice": "Hello! Let's solve some fun puzzles together!"},
"ox": {"desc": "Steady and dependable. Encourages patience in learning.", "voice": "Consistency is key! Let's learn step by step."},
"tiger": {"desc": "Bold and adventurous. Loves dynamic conversations.", "voice": "Let's jump into an exciting conversation!"},
"rabbit": {"desc": "Gentle and kind. A patient and encouraging teacher.", "voice": "Take your time. Learning should be fun!"},
"dragon": {"desc": "Wise and powerful. Inspires confidence in learning.", "voice": "Believe in yourself! You can do this!"},
"snake": {"desc": "Calm and analytical. Gives insightful explanations.", "voice": "Let's explore the beauty of language together."},
"horse": {"desc": "Energetic and friendly. Encourages active learning.", "voice": "Let's have fun while we learn!"},
"goat": {"desc": "Gentle and artistic. Uses creativity to teach.", "voice": "Imagine and express yourself freely!"},
"monkey": {"desc": "Playful and clever. Loves challenges and fun exercises.", "voice": "I love games! Let's play with words!"},
"rooster": {"desc": "Confident and expressive. Loves discussions.", "voice": "Speak up! Let's share ideas together."},
"dog": {"desc": "Loyal and friendly. Encourages persistence.", "voice": "I'll always be here to help you practice!"},
"pig": {"desc": "Warm and cheerful. Creates a positive learning atmosphere.", "voice": "Learning is fun! Let's enjoy this together!"},
}
# Load the Swiper component
swiper_code = """
<script type="module">
import React from "react";
import ReactDOM from "react-dom";
import SwiperComponent from "./Swipercomponent.js";
function App() {
return <SwiperComponent />;
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>
"""
st.components.v1.html(swiper_code, height=400)
# Function to process speech-to-text
def speech_to_text(audio_bytes):
files = {"file": ("audio.wav", audio_bytes, "audio/wav")}
response = requests.post(HF_SPEECH_TO_TEXT_API, headers=HEADERS, files=files)
text = response.json().get("text", "Sorry, could not transcribe audio.")
return text
# Function to get chatbot response
def chatbot_response(user_input):
payload = {"inputs": f"You are a friendly AI coach for English learners. Help them practice speaking naturally with supportive feedback.\nUser: {user_input}\nAI:"}
response = requests.post(HF_CHATBOT_API, headers=HEADERS, json=payload)
ai_reply = response.json().get("generated_text", "I'm here to help! Keep practicing.")
return ai_reply
# Function for text-to-speech
def text_to_speech(text):
payload = {"inputs": text}
response = requests.post(HF_TEXT_TO_SPEECH_API, headers=HEADERS, json=payload)
return response.content
# Streamlit UI
st.title("πŸŽ™οΈ AI Speaking Pal")
st.write("Press the button and chat with your pal!")
# Audio Recording Component
audio_input = st.audio_input("Let's talk!")
if audio_input is not None:
# Read audio data
audio_bytes = audio_input.read()
# Process speech-to-text
user_text = speech_to_text(audio_bytes)
st.write(f"**You:** {user_text}")
# Get AI response
ai_reply = chatbot_response(user_text)
st.write(f"**AI:** {ai_reply}")
# Convert AI response to speech
speech_audio = text_to_speech(ai_reply)
st.audio(speech_audio, format="audio/wav")
# Swiper Carousel Component
avatar_list = list(avatars.keys())
selected_index = st.slider("Pick your pal:", 0, len(avatar_list) - 1, 0)
selected_avatar = avatar_list[selected_index]
avatar_info = avatars[selected_avatar]
# Display Avatar Image
avatar_img = Image.open(f"images/{selected_avatar}.png")
st.image(avatar_img, caption=f"{selected_avatar.capitalize()} - {avatar_info['desc']}", use_column_width=True)
# Play avatar's sample voice
if st.button("Hear Sample"):
audio_bytes = text_to_speech(avatar_info["voice"])
st.audio(io.BytesIO(audio_bytes), format="audio/wav")
# Start/Stop Conversation Button
if "conversation_active" not in st.session_state:
st.session_state.conversation_active = False
def toggle_conversation():
st.session_state.conversation_active = not st.session_state.conversation_active
st.button("🎀 Start/Stop Conversation", on_click=toggle_conversation)
# Conversation Text Box
show_text = st.checkbox("Show conversation text")
if show_text:
conversation_box = st.text_area("Conversation:", height=200)
# Handle microphone input
if st.session_state.conversation_active:
audio = audiorecorder("Click to Speak", "Stop recording")
if len(audio) > 0:
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmpfile:
tmpfile.write(audio)
user_text = speech_to_text(tmpfile.name)
st.write(f"**You:** {user_text}")
ai_reply = chatbot_response(user_text)
st.write(f"**{selected_avatar.capitalize()}:** {ai_reply}")
speech_audio = text_to_speech(ai_reply)
st.audio(io.BytesIO(speech_audio), format="audio/wav")
st.write("Have fun learning English with your AI pal!")