Spaces:
Sleeping
Sleeping
File size: 7,086 Bytes
b08909a 1ccd69b b08909a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
import streamlit as st
import requests
import os
from dotenv import load_dotenv
# --- Configuration ---
# Attempt to load .env file.
# Assumes .env is in the parent directory of this script's location (e.g., ../.env)
# If your app.py is in the root of your project (where .env also is),
# load_dotenv() without arguments might work.
# For Hugging Face Spaces, you'll set secrets directly in the Space settings.
dotenv_path = os.path.join(
os.path.dirname(__file__), "..", ".env"
) # Path to .env in parent directory
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path=dotenv_path)
else:
# Fallback if .env is in the current directory (less likely for multi-project setup)
load_dotenv()
API_TOKEN = os.getenv("HF_TOKEN")
API_URL_BASE = "https://api-inference.huggingface.co/models/"
HEADERS = {"Authorization": f"Bearer {API_TOKEN}"}
# Define available models (user-friendly name: model_id)
# You can find more models at https://huggingface.co/models?pipeline_tag=translation
# Filter by source language and target language.
TRANSLATION_MODELS = {
"English to Spanish": "Helsinki-NLP/opus-mt-en-es",
"English to French": "Helsinki-NLP/opus-mt-en-fr",
"English to German": "Helsinki-NLP/opus-mt-en-de",
"English to Chinese (Simplified)": "Helsinki-NLP/opus-mt-en-zh",
"English to Japanese": "Helsinki-NLP/opus-mt-en-jap", # Check model hub for exact ID if this doesn't work
"Spanish to English": "Helsinki-NLP/opus-mt-es-en",
"French to English": "Helsinki-NLP/opus-mt-fr-en",
# Add more models/languages as desired
}
# --- Hugging Face API Call Function ---
def query_translation(text_to_translate, model_id):
"""
Sends a request to the Hugging Face Inference API for translation.
"""
if not API_TOKEN: # Check if token was loaded
st.error(
"Hugging Face API Token not found. Please configure it in your .env file or Space secrets."
)
return None
api_url = API_URL_BASE + model_id
payload = {"inputs": text_to_translate}
try:
response = requests.post(
api_url, headers=HEADERS, json=payload, timeout=30
) # Added timeout
response.raise_for_status() # Raises an HTTPError for bad responses (4XX or 5XX)
return response.json()
except requests.exceptions.HTTPError as errh:
st.error(f"Translation API HTTP Error: {errh}")
error_details = "No additional details from API."
try:
error_details = response.json().get("error", response.text)
except ValueError: # If response.text is not JSON
error_details = response.text
st.info(f"Details: {error_details}")
return None
except requests.exceptions.ConnectionError as errc:
st.error(f"Translation API Connection Error: {errc}")
return None
except requests.exceptions.Timeout as errt:
st.error(f"Translation API Timeout Error: {errt}")
return None
except requests.exceptions.RequestException as err:
st.error(f"Translation API Request Error: {err}")
return None
except (
ValueError
): # If response is not JSON (should be caught by response.json() above but good to have)
st.error("Error: Received non-JSON response from translation API.")
st.info(
f"Raw Response: {response.text if 'response' in locals() else 'No response object'}"
)
return None
# --- Streamlit UI ---
st.set_page_config(page_title="π Text Translator", layout="wide")
st.title("π Text Translation Tool")
st.markdown(
"Translate text into various languages using Hugging Face's Inference API. "
"This app demonstrates API integration for NLP tasks."
)
# Check for API token at the beginning of UI rendering
if not API_TOKEN:
st.error("Hugging Face API Token not configured. The application cannot function.")
st.markdown(
"Please ensure your `HUGGING_FACE_API_TOKEN` is set in a `.env` file "
"in the root of your `ai-portfolio` project or as a secret if deploying on Hugging Face Spaces."
)
st.stop() # Stop further execution of the script if token is missing
# Layout columns
col1, col2 = st.columns([2, 1]) # Text area takes 2/3, selectbox takes 1/3
with col1:
text_input = st.text_area(
"Enter text to translate:",
height=200,
key="text_input_translate",
placeholder="Type or paste your text here...",
)
with col2:
selected_language_name = st.selectbox(
"Select target language:",
options=list(TRANSLATION_MODELS.keys()),
index=0, # Default to the first language in the list
key="lang_select",
)
model_id_to_use = TRANSLATION_MODELS[selected_language_name]
st.caption(f"Using model: `{model_id_to_use}`")
if st.button("Translate Text", key="translate_button", type="primary"):
if text_input:
if not API_TOKEN: # Redundant check, but good for safety
st.error("API Token is missing. Cannot proceed.")
else:
with st.spinner(f"Translating to {selected_language_name}... Please wait."):
translation_result = query_translation(text_input, model_id_to_use)
if translation_result:
# The API returns a list with a dictionary inside
if (
isinstance(translation_result, list)
and len(translation_result) > 0
and "translation_text" in translation_result[0]
):
translated_text = translation_result[0]["translation_text"]
st.subheader("π Translation:")
st.success(translated_text)
# Sometimes the API might return a dictionary directly with an error
elif isinstance(translation_result, dict) and translation_result.get(
"error"
):
# Error is already displayed by the query_translation function
st.warning("Translation failed. See error message above.")
else:
st.error(
"Translation failed or the API returned an unexpected format."
)
st.json(translation_result) # Show the raw response for debugging
# If translation_result is None, query_translation already showed an error
else:
st.warning("Please enter some text to translate.")
st.divider()
st.sidebar.header("βΉοΈ About This App")
st.sidebar.info(
"This tool demonstrates the use of the Hugging Face Inference API "
"for text translation. It allows users to input text and select a target "
"language, then displays the translated output."
"\n\n**Key Skills Showcased:**"
"\n- Python & Streamlit for UI"
"\n- Hugging Face API Integration"
"\n- Handling API responses & errors"
"\n- Basic NLP application"
)
st.sidebar.markdown("---")
st.sidebar.markdown("Project for **AI Project Portfolio (4 Weeks)**")
|