Spaces:
No application file
No application file
translator
Browse filessmall translator
- translator +105 -0
translator
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import gradio as gr
|
| 3 |
+
from google import genai
|
| 4 |
+
|
| 5 |
+
# Initialize Gemini client (reads GEMINI_API_KEY from environment)
|
| 6 |
+
API_KEY = os.getenv("GEMINI_API_KEY")
|
| 7 |
+
if not API_KEY:
|
| 8 |
+
raise RuntimeError("Please set the GEMINI_API_KEY environment variable.")
|
| 9 |
+
|
| 10 |
+
client = genai.Client(api_key=API_KEY)
|
| 11 |
+
|
| 12 |
+
# List of common languages for dropdown
|
| 13 |
+
LANGUAGES = [
|
| 14 |
+
"Auto-detect",
|
| 15 |
+
"Arabic", "Bengali", "Chinese (Simplified)", "Chinese (Traditional)",
|
| 16 |
+
"Dutch", "English", "French", "German", "Hindi", "Indonesian",
|
| 17 |
+
"Italian", "Japanese", "Korean", "Malay", "Portuguese",
|
| 18 |
+
"Punjabi", "Russian", "Spanish", "Swahili", "Turkish", "Urdu", "Vietnamese"
|
| 19 |
+
]
|
| 20 |
+
|
| 21 |
+
def build_prompt(text: str, src_lang: str, tgt_lang: str, tone: str, preserve_entities: bool):
|
| 22 |
+
"""
|
| 23 |
+
Build translation prompt for Gemini.
|
| 24 |
+
"""
|
| 25 |
+
preserve_text = (
|
| 26 |
+
"Preserve named entities (names, places, numbers, dates) exactly where possible."
|
| 27 |
+
if preserve_entities else ""
|
| 28 |
+
)
|
| 29 |
+
if src_lang == "Auto-detect":
|
| 30 |
+
src_instruction = "Auto-detect the source language."
|
| 31 |
+
else:
|
| 32 |
+
src_instruction = f"The source language is {src_lang}."
|
| 33 |
+
prompt = f"""
|
| 34 |
+
You are a professional translator assistant.
|
| 35 |
+
{src_instruction}
|
| 36 |
+
Translate the following text into {tgt_lang}. Maintain the original meaning and {tone} tone. {preserve_text}
|
| 37 |
+
If the text contains formatting (bullets, lists, newlines), keep the structure in the translation.
|
| 38 |
+
Respond ONLY with the translated text (no extra commentary).
|
| 39 |
+
-----
|
| 40 |
+
Text to translate:
|
| 41 |
+
\"\"\"{text}\"\"\"
|
| 42 |
+
"""
|
| 43 |
+
return prompt.strip()
|
| 44 |
+
|
| 45 |
+
def translate_text(text: str, src_lang: str, tgt_lang: str, tone: str, preserve_entities: bool):
|
| 46 |
+
if not text or not text.strip():
|
| 47 |
+
return "⚠️ Please enter text to translate."
|
| 48 |
+
if src_lang == tgt_lang:
|
| 49 |
+
return "⚠️ Source and target languages are the same — choose a different target language."
|
| 50 |
+
|
| 51 |
+
prompt = build_prompt(text, src_lang, tgt_lang, tone, preserve_entities)
|
| 52 |
+
|
| 53 |
+
try:
|
| 54 |
+
response = client.models.generate_content(
|
| 55 |
+
model="gemini-2.5-flash",
|
| 56 |
+
contents=prompt,
|
| 57 |
+
)
|
| 58 |
+
translated = response.text.strip()
|
| 59 |
+
|
| 60 |
+
detected_note = ""
|
| 61 |
+
if src_lang == "Auto-detect":
|
| 62 |
+
detect_prompt = f"Detect the language of the following text and reply with a single word (language name):\n\n\"\"\"{text}\"\"\""
|
| 63 |
+
try:
|
| 64 |
+
detect_resp = client.models.generate_content(
|
| 65 |
+
model="gemini-2.5-flash",
|
| 66 |
+
contents=detect_prompt,
|
| 67 |
+
)
|
| 68 |
+
detected_lang = detect_resp.text.strip().splitlines()[0]
|
| 69 |
+
detected_note = f"\n\nDetected source language: {detected_lang}"
|
| 70 |
+
except Exception:
|
| 71 |
+
detected_note = ""
|
| 72 |
+
return translated + detected_note
|
| 73 |
+
except Exception as e:
|
| 74 |
+
return f"❌ Error calling Gemini API: {str(e)}"
|
| 75 |
+
|
| 76 |
+
# ---------- Gradio UI ----------
|
| 77 |
+
with gr.Blocks(theme=gr.themes.Default()) as demo:
|
| 78 |
+
gr.Markdown("## 🌍 Simple Translator App\nTranslate text between multiple languages with tone control and entity preservation using Google Gemini.")
|
| 79 |
+
with gr.Row():
|
| 80 |
+
with gr.Column(scale=3):
|
| 81 |
+
txt = gr.Textbox(lines=6, placeholder="Enter text here...", label="Input text")
|
| 82 |
+
preserve = gr.Checkbox(label="Preserve names, places, and numbers", value=True)
|
| 83 |
+
with gr.Column(scale=1):
|
| 84 |
+
src = gr.Dropdown(choices=LANGUAGES, value="Auto-detect", label="Source language")
|
| 85 |
+
tgt = gr.Dropdown(choices=[l for l in LANGUAGES if l != "Auto-detect"], value="English", label="Target language")
|
| 86 |
+
tone = gr.Radio(choices=["neutral", "formal", "informal", "friendly", "professional"], value="neutral", label="Tone")
|
| 87 |
+
translate_btn = gr.Button("Translate")
|
| 88 |
+
output = gr.Textbox(lines=8, label="Translated text")
|
| 89 |
+
|
| 90 |
+
examples = [
|
| 91 |
+
["Hello, how are you?", "Auto-detect", "Urdu", "friendly", True],
|
| 92 |
+
["Explain gravity in one sentence.", "English", "Spanish", "neutral", False],
|
| 93 |
+
["مرحبا كيف حالك", "Auto-detect", "English", "friendly", True]
|
| 94 |
+
]
|
| 95 |
+
gr.Examples(examples=examples, inputs=[txt, src, tgt, tone, preserve])
|
| 96 |
+
|
| 97 |
+
def run_translate(text, src_lang, tgt_lang, tone, preserve_entities):
|
| 98 |
+
return translate_text(text, src_lang, tgt_lang, tone, preserve_entities)
|
| 99 |
+
|
| 100 |
+
translate_btn.click(fn=run_translate, inputs=[txt, src, tgt, tone, preserve], outputs=output)
|
| 101 |
+
|
| 102 |
+
gr.Markdown("**Note:** This app uses the `GEMINI_API_KEY` from environment variables. Add it in *Settings → Secrets* when deploying on Hugging Face Spaces.")
|
| 103 |
+
|
| 104 |
+
if __name__ == "__main__":
|
| 105 |
+
demo.launch()
|