Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 14 additions & 28 deletions frontend/my_pages/6_translate_UI.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import asyncio
import httpx
import os
import base64
from httpx import Cookies

PDF_PROCESSOR_URL = os.environ["PDF_PROCESSOR_URL"]
Expand All @@ -16,12 +15,10 @@
if "httpx_cookies" not in st.session_state:
st.session_state.httpx_cookies = Cookies()

client = httpx.AsyncClient(cookies=st.session_state.httpx_cookies, timeout=300.0)

st.header("🌐 Translation")


async def get_translation_status(doc_id: str) -> dict:
async def get_translation_status(doc_id: str, client: httpx.AsyncClient) -> dict:
"""Get translation status for a document."""
try:
response = await client.get(f"{PDF_PROCESSOR_URL}/translation/{doc_id}")
Expand All @@ -36,7 +33,7 @@ async def get_translation_status(doc_id: str) -> dict:
return {"status": "error", "error": str(e)}


async def get_renderer_status(doc_id: str) -> dict:
async def get_renderer_status(doc_id: str, client: httpx.AsyncClient) -> dict:
"""Get renderer status for a document."""
try:
response = await client.get(f"{PDF_PROCESSOR_URL}/renderer/{doc_id}")
Expand All @@ -51,7 +48,7 @@ async def get_renderer_status(doc_id: str) -> dict:
return {"status": "error", "error": str(e)}


async def trigger_renderer(doc_id: str) -> dict:
async def trigger_renderer(doc_id: str, client: httpx.AsyncClient) -> dict:
"""Trigger rendering for a translated document."""
try:
response = await client.post(f"{PDF_PROCESSOR_URL}/renderer/{doc_id}")
Expand Down Expand Up @@ -82,18 +79,14 @@ def display_translation_info(translation_data: dict):
st.metric("Images", len(result.get("pictures", [])))


def display_rendered_pdf(doc_id: str, filename: str, runner: asyncio.Runner):
"""Display rendered PDF with download and preview options."""
def display_rendered_pdf(doc_id: str, filename: str, runner: asyncio.Runner, client: httpx.AsyncClient):
"""Display download button for rendered PDF."""
# Server-side URL for fetching PDF (internal service communication)
server_pdf_url = f"{PDF_PROCESSOR_URL}/renderer/{doc_id}/rendered.pdf"

# Client-side URL for browser downloads (through nginx gateway)
client_pdf_url = f"/pdf_processor/renderer/{doc_id}/rendered.pdf"

try:
pdf_response = runner.run(client.get(server_pdf_url))
if pdf_response.status_code == 200:
# Download button at the top
st.download_button(
label="📥 Download Translated PDF",
data=pdf_response.content,
Expand All @@ -102,30 +95,22 @@ def display_rendered_pdf(doc_id: str, filename: str, runner: asyncio.Runner):
key=f"download_{doc_id}",
use_container_width=True
)

# Preview section
with st.expander("👁️ Preview PDF", expanded=False):
base64_pdf = base64.b64encode(pdf_response.content).decode('utf-8')
pdf_display = f'<iframe src="data:application/pdf;base64,{base64_pdf}" width="100%" height="600px" type="application/pdf"></iframe>'
st.markdown(pdf_display, unsafe_allow_html=True)
else:
st.error(f"Failed to load PDF (HTTP {pdf_response.status_code})")
st.markdown(f"[Try direct download]({client_pdf_url})")
except Exception as e:
logger.error(f"Error fetching rendered PDF: {e}")
st.error("Error loading PDF. Try the download link below:")
st.markdown(f"[Download Translated PDF]({client_pdf_url})")
st.error("An error occurred while trying to load the PDF.")


def display_renderer_section(doc_id: str, filename: str, renderer_data: dict, runner: asyncio.Runner):
def display_renderer_section(doc_id: str, filename: str, renderer_data: dict, runner: asyncio.Runner, client: httpx.AsyncClient):
"""Display renderer status and controls."""
status = renderer_data.get("status")

if status == "not_found":
st.info("💡 Generate a translated PDF with the translated text overlaid on the original document.")
if st.button("🎨 Generate Translated PDF", key=f"render_{doc_id}", use_container_width=True):
with st.spinner("Generating translated PDF..."):
trigger_result = runner.run(trigger_renderer(doc_id))
trigger_result = runner.run(trigger_renderer(doc_id, client))
if trigger_result.get("status") == "success":
st.success("✅ Generation started! Refreshing...")
st.rerun()
Expand All @@ -138,13 +123,13 @@ def display_renderer_section(doc_id: str, filename: str, renderer_data: dict, ru
st.rerun()

elif status == "completed":
display_rendered_pdf(doc_id, filename, runner)
display_rendered_pdf(doc_id, filename, runner, client)

elif status == "failed":
st.error("❌ PDF generation failed")
if st.button("🔄 Retry", key=f"retry_{doc_id}"):
with st.spinner("Retrying..."):
trigger_result = runner.run(trigger_renderer(doc_id))
trigger_result = runner.run(trigger_renderer(doc_id, client))
if trigger_result.get("status") == "success":
st.success("✅ Restarted! Refreshing...")
st.rerun()
Expand All @@ -165,7 +150,8 @@ def display_renderer_section(doc_id: str, filename: str, renderer_data: dict, ru
for doc_id, data in response_lst:
with st.expander(f"📄 {data['uploaded_filename']}", expanded=True):
runner = asyncio.Runner()
translation_data = runner.run(get_translation_status(doc_id))
client = httpx.AsyncClient(cookies=st.session_state.httpx_cookies, timeout=300.0)
translation_data = runner.run(get_translation_status(doc_id, client))

status = translation_data.get("status")

Expand All @@ -183,8 +169,8 @@ def display_renderer_section(doc_id: str, filename: str, renderer_data: dict, ru
display_translation_info(translation_data)

# Check and display renderer section
renderer_data = runner.run(get_renderer_status(doc_id))
display_renderer_section(doc_id, data['uploaded_filename'], renderer_data, runner)
renderer_data = runner.run(get_renderer_status(doc_id, client))
display_renderer_section(doc_id, data['uploaded_filename'], renderer_data, runner, client)

elif status == "failed":
st.error("❌ Translation failed")
Expand Down