""" Netra Translate — Streamlit demo for the netra-nmt English ↔ Khmer model. A two-pane translation UI (mirroring the bundled FastAPI web app) intended for deployment on Hugging Face Spaces. All inference is delegated to the ``NetraTranslator`` class from the installed ``netra-nmt`` package. """ from __future__ import annotations from pathlib import Path import streamlit as st # --------------------------------------------------------------------------- # Page config + branding # --------------------------------------------------------------------------- _ASSETS = Path(__file__).resolve().parent / "assets" _WORDMARK = _ASSETS / "netra-wordmark-orange.png" st.set_page_config( page_title="Netra Translate", page_icon="🪔", layout="wide", ) LABELS = {"en": "English", "km": "Khmer"} # Netra palette + Khmer webfont, adapted from netra_nmt/static/index.html. st.markdown( """ """, unsafe_allow_html=True, ) # --------------------------------------------------------------------------- # Model (loaded once per Space process) # --------------------------------------------------------------------------- @st.cache_resource(show_spinner="Loading Netra model… (first run downloads weights)") def get_translator(): from netra_nmt import NetraTranslator # Spaces free tier is CPU-only; this also works locally on a GPU box. return NetraTranslator(device="cpu") # --------------------------------------------------------------------------- # Session state # --------------------------------------------------------------------------- if "direction" not in st.session_state: st.session_state.direction = "en2km" if "source" not in st.session_state: st.session_state.source = "" if "output" not in st.session_state: st.session_state.output = "" def _src_tgt() -> tuple[str, str]: return ("en", "km") if st.session_state.direction == "en2km" else ("km", "en") def _swap() -> None: """Flip the direction and carry the previous output into the input box.""" st.session_state.direction = ( "km2en" if st.session_state.direction == "en2km" else "en2km" ) prev = st.session_state.output st.session_state.source = prev st.session_state.output = "" def _clear() -> None: st.session_state.source = "" st.session_state.output = "" # --------------------------------------------------------------------------- # Header # --------------------------------------------------------------------------- head_left, head_right = st.columns([3, 2], vertical_alignment="center") with head_left: if _WORDMARK.exists(): st.image(str(_WORDMARK), width=170) else: # pragma: no cover - asset is shipped alongside the app st.markdown("### netra") st.caption("English ↔ Khmer neural machine translation") st.divider() # --------------------------------------------------------------------------- # Language bar + swap # --------------------------------------------------------------------------- src, tgt = _src_tgt() lang_l, lang_mid, lang_r = st.columns([5, 1, 5], vertical_alignment="center") with lang_l: st.markdown(f"{LABELS[src]}", unsafe_allow_html=True) with lang_mid: st.button("⇄", on_click=_swap, help="Swap languages", use_container_width=True) with lang_r: st.markdown( f"