| """ |
| Kuwaiti Arabic Translator - Streamlit Frontend |
| For Hugging Face Spaces deployment |
| """ |
|
|
| import streamlit as st |
| import google.generativeai as genai |
| import requests |
| import os |
| from dotenv import load_dotenv |
| import io |
| import base64 |
|
|
| |
| load_dotenv() |
|
|
| |
| |
| |
|
|
| st.set_page_config( |
| page_title="Kuwaiti Arabic Translator", |
| page_icon="π°πΌ", |
| layout="wide", |
| initial_sidebar_state="expanded" |
| ) |
|
|
| |
| |
| |
|
|
| GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") |
| ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY") |
|
|
| genai.configure(api_key=GEMINI_API_KEY) |
| gemini_model = genai.GenerativeModel("gemini-2.5-flash") |
|
|
| |
| |
| |
|
|
| if "translation_history" not in st.session_state: |
| st.session_state.translation_history = [] |
|
|
| if "current_kuwaiti" not in st.session_state: |
| st.session_state.current_kuwaiti = None |
|
|
| if "current_audio" not in st.session_state: |
| st.session_state.current_audio = None |
|
|
| |
| |
| |
|
|
| def translate_to_kuwaiti(english_text: str) -> str: |
| """ |
| Translate English to Kuwaiti Arabic dialect using Gemini 2.5 Flash |
| """ |
| system_prompt = """You are a native Kuwaiti Arabic speaker and dialect expert. |
| Translate the following English text into natural Kuwaiti Arabic dialect. |
| |
| IMPORTANT RULES: |
| - DO NOT use Modern Standard Arabic (MSA) |
| - Use casual, conversational Kuwaiti style |
| - Write as if for social media and daily speech |
| - Include Kuwaiti colloquialisms and expressions |
| - Keep it authentic and natural sounding |
| |
| Return ONLY the translated text. No explanations.""" |
| |
| response = gemini_model.generate_content( |
| f"{system_prompt}\n\nEnglish text: {english_text}" |
| ) |
| return response.text.strip() |
|
|
|
|
| def generate_kuwaiti_voice(arabic_text: str) -> bytes: |
| """ |
| Generate Kuwaiti Arabic voice using ElevenLabs REST API |
| """ |
| url = f"https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnSDxMaL" |
| |
| headers = { |
| "xi-api-key": ELEVENLABS_API_KEY, |
| "Content-Type": "application/json" |
| } |
| |
| payload = { |
| "text": arabic_text, |
| "voice_settings": { |
| "stability": 0.5, |
| "similarity_boost": 0.75 |
| } |
| } |
| |
| response = requests.post(url, json=payload, headers=headers) |
| |
| if response.status_code != 200: |
| raise Exception(f"ElevenLabs API error: {response.status_code} - {response.text}") |
| |
| return response.content |
|
|
|
|
| def add_to_history(english: str, kuwaiti: str): |
| """Add translation to history""" |
| st.session_state.translation_history.append({ |
| "english": english, |
| "kuwaiti": kuwaiti |
| }) |
|
|
|
|
| |
| |
| |
|
|
| with st.sidebar: |
| st.header("βοΈ Settings") |
| |
| st.subheader("About") |
| st.markdown(""" |
| π°πΌ **Kuwaiti Arabic Translator** |
| |
| Convert English text to natural Kuwaiti Arabic dialect |
| with authentic voice generation. |
| |
| **Features:** |
| - English β Kuwaiti dialect (Gemini 2.5 Flash) |
| - Natural Arabic voice (ElevenLabs) |
| - MP3 download support |
| - Translation history |
| |
| **Note:** This is an educational tool and dialect |
| representation may vary by user. |
| """) |
| |
| st.divider() |
| |
| st.subheader("π Statistics") |
| st.metric("Translations Made", len(st.session_state.translation_history)) |
| |
| st.divider() |
| |
| if st.button("ποΈ Clear History"): |
| st.session_state.translation_history = [] |
| st.session_state.current_kuwaiti = None |
| st.session_state.current_audio = None |
| st.rerun() |
|
|
|
|
| |
| |
| |
|
|
| st.title("π°πΌ Kuwaiti Arabic Translator") |
| st.markdown("*Convert English to Kuwaiti dialect with natural voice*") |
|
|
| st.info(""" |
| π‘ **How to use:** |
| 1. Type or paste English text |
| 2. Click "β¨ Generate Kuwaiti Text" |
| 3. Click "π Generate Voice" to create speech |
| 4. Listen and download MP3 |
| """) |
|
|
| |
| col1, col2 = st.columns([3, 1]) |
|
|
| with col1: |
| english_text = st.text_area( |
| "π English Text", |
| placeholder="Type English text here...", |
| height=120, |
| label_visibility="collapsed" |
| ) |
|
|
| with col2: |
| st.markdown("") |
| if st.button("β¨ Generate\nKuwaiti Text", use_container_width=True, type="primary"): |
| if english_text.strip(): |
| with st.spinner("π Translating to Kuwaiti..."): |
| try: |
| kuwaiti_text = translate_to_kuwaiti(english_text) |
| st.session_state.current_kuwaiti = kuwaiti_text |
| add_to_history(english_text, kuwaiti_text) |
| st.success("β
Translation complete!") |
| except Exception as e: |
| st.error(f"β Translation error: {str(e)}") |
| else: |
| st.warning("β οΈ Please enter English text first") |
|
|
| |
| if st.session_state.current_kuwaiti: |
| st.markdown("---") |
| |
| col1, col2 = st.columns([3, 1]) |
| |
| with col1: |
| st.markdown("### π£οΈ Kuwaiti Arabic Dialect") |
| st.markdown(f""" |
| <div style=" |
| background: #f5f5f5; |
| border: 2px solid #667eea; |
| border-radius: 8px; |
| padding: 20px; |
| direction: rtl; |
| text-align: right; |
| font-size: 1.2em; |
| line-height: 1.6; |
| "> |
| {st.session_state.current_kuwaiti} |
| </div> |
| """, unsafe_allow_html=True) |
| |
| with col2: |
| st.markdown("") |
| if st.button("π Generate\nVoice", use_container_width=True, type="secondary"): |
| with st.spinner("π΅ Generating voice..."): |
| try: |
| audio_bytes = generate_kuwaiti_voice(st.session_state.current_kuwaiti) |
| st.session_state.current_audio = audio_bytes |
| st.success("β
Voice generated!") |
| except Exception as e: |
| st.error(f"β Voice error: {str(e)}") |
|
|
| |
| if st.session_state.current_audio: |
| st.markdown("---") |
| st.markdown("### π΅ Listen to Kuwaiti Voice") |
| |
| col1, col2 = st.columns([3, 1]) |
| |
| with col1: |
| st.audio(st.session_state.current_audio, format="audio/mp3") |
| |
| with col2: |
| st.download_button( |
| label="π₯ Download\nMP3", |
| data=st.session_state.current_audio, |
| file_name="kuwaiti_translation.mp3", |
| mime="audio/mp3", |
| use_container_width=True |
| ) |
|
|
| |
| if st.session_state.translation_history: |
| st.markdown("---") |
| st.markdown("## π Translation History") |
| |
| for idx, item in enumerate(st.session_state.translation_history[-5:], 1): |
| with st.expander(f"π Translation {idx}: {item['english'][:50]}..."): |
| col1, col2 = st.columns(2) |
| |
| with col1: |
| st.markdown("**English:**") |
| st.text(item['english']) |
| |
| with col2: |
| st.markdown("**Kuwaiti:**") |
| st.markdown(f"<div dir='rtl' style='text-align: right;'>{item['kuwaiti']}</div>", |
| unsafe_allow_html=True) |
|
|
| |
| st.markdown("---") |
| st.caption("π Kuwaiti Arabic Translator | Powered by Gemini 2.5 Flash + ElevenLabs | Deployed on Hugging Face Spaces") |
|
|