import gradio as gr import requests import html import os # LibreTranslate instance API_URL = "https://imsidag-community-libretranslate-kabyle.hf.space/translate" API_KEY = os.environ["API_KEY"] # Language codes langs = { "English": "en", "French": "fr", "Italian": "it", "Occitan (26000)": "oc_comp2", "Taqbaylit (LTCommunity)": "kab", "Taqbaylit (Tasenselkimt)": "kab_comp", "Taqbaylit (51000)": "kab_comp2", "Taqbaylit (OS)": "kab_os", "Taqbaylit (Google)": "google", "Taqbaylit (All Variants)": "kab_all" } kabyle_variants = { "Taqbaylit (LTCommunity)": "kab", "Taqbaylit (Tasenselkimt)": "kab_comp", "Taqbaylit (51000)": "kab_comp2", "Taqbaylit (OS)": "kab_os", "Taqbaylit (Google)": "google" } def highlight_differences(translations_dict): token_lists = {k: v.split() for k, v in translations_dict.items()} max_len = max(len(tokens) for tokens in token_lists.values()) aligned = {k: [] for k in token_lists.keys()} for i in range(max_len): words_at_i = [token_lists[k][i] if i < len(token_lists[k]) else "" for k in token_lists] if len(set(words_at_i)) == 1: for k in token_lists: aligned[k].append(words_at_i[0]) else: for k in token_lists: word = token_lists[k][i] if i < len(token_lists[k]) else "" # Use gold color for highlights that works in both themes highlighted = f"{word}" aligned[k].append(highlighted) return {k: " ".join(tokens) for k, tokens in aligned.items()} def translate(text, source_lang, target_lang): source_code = langs.get(source_lang, "en") target_code = langs.get(target_lang) if target_code == "kab_all": # Escape and format the original text with dark-theme friendly styling escaped_text = html.escape(text).replace('\n', '
') header = f"""
ORIGINAL TEXT
{escaped_text}
From: {source_lang} → To: {target_lang}
""" translations_dict = {} alternatives_dict = {} for name, code in kabyle_variants.items(): if code == "google": # Fallback source for Google google_source = source_code if source_code in ["en", "fr", "it", "es"] else "fr" params = { "engine": "google", "from": google_source, "to": "ber-Latn", "text": text } try: response = requests.get("https://mozhi.pussthecat.org/api/translate", params=params) result = response.json() translations_dict[name] = result.get("translated-text", "No result") alternatives_dict[name] = "" except Exception as e: translations_dict[name] = f"Google Error: {str(e)}" alternatives_dict[name] = "" else: data = { "q": text, "source": source_code, "target": code, "format": "text", "alternatives": 3, "api_key": API_KEY } try: response = requests.post(API_URL, data=data, headers={"Content-Type": "application/x-www-form-urlencoded"}) result = response.json() if "translatedText" in result: translations_dict[name] = result["translatedText"] alternatives_dict[name] = ", ".join(result.get("alternatives", [])) elif "error" in result: translations_dict[name] = f"API Error: {result['error']}" alternatives_dict[name] = "" else: translations_dict[name] = "Unexpected response" alternatives_dict[name] = "" except Exception as e: translations_dict[name] = f"Exception: {str(e)}" alternatives_dict[name] = "" highlighted = highlight_differences(translations_dict) outputs = [] for name in kabyle_variants: output = f"
{name}:
Translation: {highlighted[name]}" if alternatives_dict.get(name): output += f"
Alternatives: {alternatives_dict[name]}" output += "
" outputs.append(output) return header + "".join(outputs) elif target_code == "google": google_source = source_code if source_code in ["en", "fr", "it", "es"] else "fr" params = { "engine": "google", "from": google_source, "to": "ber-Latn", "text": text } try: response = requests.get("https://mozhi.pussthecat.org/api/translate", params=params) result = response.json() return f"Translation: {result.get('translated-text', 'No result')}" except Exception as e: return f"Google Error: {str(e)}" else: data = { "q": text, "source": source_code, "target": target_code, "format": "text", "alternatives": 3, "api_key": API_KEY } try: response = requests.post(API_URL, data=data, headers={"Content-Type": "application/x-www-form-urlencoded"}) result = response.json() if "translatedText" in result: output = f"Translation: {result['translatedText']}" if result.get("alternatives"): alt = ", ".join(result["alternatives"]) output += f"
Alternatives: {alt}" return output elif "error" in result: return f"API Error: {result['error']}" else: return f"Unexpected response: {result}" except Exception as e: return f"Exception: {str(e)}" # Gradio UI with dark theme friendly styling with gr.Blocks(theme=gr.themes.Default()) as demo: gr.Markdown("# Kabyle Translator") gr.Markdown("Compare Kabyle translations from LibreTranslate (variants) and Google Translate via Mozhi. Differences are highlighted.") with gr.Row(): with gr.Column(): input_text = gr.Textbox(label="Enter text to translate", lines=3) source_lang = gr.Dropdown(choices=list(langs.keys()), label="From language", value="English") target_lang = gr.Dropdown(choices=list(langs.keys()), label="To language", value="Taqbaylit (All Variants)") submit_btn = gr.Button("Translate") with gr.Column(): output = gr.HTML(label="Translation Results") submit_btn.click( fn=translate, inputs=[input_text, source_lang, target_lang], outputs=output ) demo.launch()