Download app.py from sameernotes/translation_prediction_space: direct link, hf CLI and curl.
- Browser
- Download file 6.93 kB
-
https://huggingface.co/spaces/sameernotes/translation_prediction_space/resolve/main/app.py
- Command line
-
hf download hf://spaces/sameernotes/translation_prediction_space/app.py
-
curl -L -o app.py https://huggingface.co/spaces/sameernotes/translation_prediction_space/resolve/main/app.py
6.93 kB
| import os | |
| import re # Import the regular expression module | |
| from typing import List | |
| from fastapi import FastAPI, HTTPException, status | |
| from pydantic import BaseModel | |
| import requests | |
| from fastapi.responses import HTMLResponse | |
| app = FastAPI() | |
| GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") | |
| if not GEMINI_API_KEY: | |
| raise ValueError("The GEMINI_API_KEY environment variable is not set.") | |
| GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key=" + GEMINI_API_KEY | |
| class TranslationRequest(BaseModel): | |
| text: str | |
| target_language: str | |
| source_language: str = None | |
| class TranslationResponse(BaseModel): # For /detect_language | |
| translated_text: str | |
| source_language: str | |
| target_language: str | |
| # --- Helper Functions --- | |
| def detect_language_and_options(text: str): | |
| """Detects the language and provides translation options.""" | |
| prompt = f"""Please identify the language of the text provided and then offer translation options as numbered choices (1-5). Use this format: "The text is in [Language]. Choose a language to translate to: 1. [Option 1], 2. [Option 2], 3. [Option 3], 4. [Option 4], 5. [Option 5]" | |
| Input Text: {text}""" | |
| request_data = { | |
| "contents": [{ | |
| "role": "user", | |
| "parts": [{"text": prompt}] | |
| }] | |
| } | |
| try: | |
| response = requests.post(GEMINI_API_URL, json=request_data) | |
| response.raise_for_status() | |
| response_json = response.json() | |
| try: | |
| response_text = response_json['candidates'][0]['content']['parts'][0]['text'] | |
| source_language = response_text.split("The text is in ")[1].split(".")[0].strip() | |
| options_str = response_text.split("Choose a language to translate to:")[1].strip() | |
| options_list = [opt.split(". ")[1].strip() for opt in options_str.split(", ")] | |
| while len(options_list) < 5: | |
| options_list.append("Option Not Available") | |
| options_list = options_list[:5] | |
| options = {str(i + 1): lang for i, lang in enumerate(options_list)} | |
| return source_language, options | |
| except (KeyError, IndexError, AttributeError) as e: | |
| raise HTTPException(status_code=500, detail=f"Error parsing Gemini API response: {e}") | |
| except requests.exceptions.RequestException as e: | |
| raise HTTPException(status_code=500, detail=f"Error communicating with Gemini API: {e}") | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {e}") | |
| def translate_with_gemini(text: str, source_language: str, target_language: str) -> str: | |
| """Translates text, requesting HTML, and removes Markdown code blocks.""" | |
| prompt = f"""Translate the following text from {source_language} to {target_language}. Return *only* the translated text. Format the response as HTML. If any part of the translated text should be emphasized (like an example or key phrase), use `<strong>` tags around that part. Do not include ANY additional text like 'Here is the translation:' or similar. Only the translated text, formatted as HTML. | |
| Text: | |
| {text}""" | |
| request_data = { | |
| "contents": [{ | |
| "role": "user", | |
| "parts": [{"text": prompt}] | |
| }] | |
| } | |
| try: | |
| response = requests.post(GEMINI_API_URL, json=request_data) | |
| response.raise_for_status() | |
| response_json = response.json() | |
| try: | |
| translated_text = response_json['candidates'][0]['content']['parts'][0]['text'] | |
| # Remove Markdown code blocks (```html ... ```) | |
| translated_text = re.sub(r"```html\n?([\s\S]*?)\n?```", r"\1", translated_text).strip() | |
| translated_text = re.sub(r"```([\s\S]*?)```", r"\1", translated_text).strip() # Remove plain ``` ... ``` | |
| return translated_text | |
| except (KeyError, IndexError) as e: | |
| raise HTTPException(status_code=500, detail=f"Error parsing Gemini API response: {e}") | |
| except requests.exceptions.RequestException as e: | |
| raise HTTPException(status_code=500, detail=f"Error communicating with Gemini API: {e}") | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {e}") | |
| async def translate(request: TranslationRequest): | |
| """Translates text, returning HTML.""" | |
| if not request.text: | |
| raise HTTPException(status_code=400, detail="Text to translate cannot be empty.") | |
| if not request.target_language: | |
| raise HTTPException(status_code=400, detail="Target language must be provided.") | |
| if request.source_language: | |
| source_language = request.source_language | |
| else: | |
| try: | |
| source_language, _ = detect_language_and_options(request.text) | |
| except HTTPException as e: | |
| raise e | |
| supported_languages = ["Afrikaans", "Arabic", "Armenian", "Azerbaijani", "Belarusian", "Bosnian", "Bulgarian", | |
| "Catalan", "Chinese", "Croatian", "Czech", "Danish", "Dutch", "English", "Estonian", | |
| "Finnish", "French", "Galician", "German", "Greek", "Hebrew", "Hindi", "Hungarian", | |
| "Icelandic", "Indonesian", "Italian", "Japanese", "Kannada", "Kazakh", "Korean", "Latvian", | |
| "Lithuanian", "Macedonian", "Malay", "Marathi", "Maori", "Nepali", "Norwegian", "Persian", | |
| "Polish", "Portuguese", "Romanian", "Russian", "Serbian", "Slovak", "Slovenian", "Spanish", | |
| "Swahili", "Swedish", "Tagalog", "Tamil", "Thai", "Turkish", "Ukrainian", "Urdu", | |
| "Vietnamese", "Welsh"] | |
| if request.target_language not in supported_languages: | |
| raise HTTPException(status_code=400, detail=f"Target language '{request.target_language}' is not supported.") | |
| try: | |
| translated_html = translate_with_gemini(request.text, source_language, request.target_language) | |
| return translated_html | |
| except HTTPException as e: | |
| raise e | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {e}") | |
| async def detect_language(text: str = ""): | |
| """Detects the language of the input text and provides translation options.""" | |
| if not text: | |
| raise HTTPException(status_code=400, detail="Text to detect cannot be empty.") | |
| try: | |
| source_language, options = detect_language_and_options(text) | |
| return {"source_language": source_language, "translation_options": options} | |
| except HTTPException as e: | |
| raise e | |
| except Exception as e: | |
| raise HTTPException(status_code=500,detail=f"An unexpected error occurred {e}") |