text-translate / app.py
vineet124jig's picture
Update app.py
5d6b767 verified
import gradio as gr
import requests
import json
import os
import time
from collections import defaultdict
from PIL import Image
import io
BASE_URL = "https://api.jigsawstack.com/v1"
headers = {
"x-api-key": os.getenv("JIGSAWSTACK_API_KEY")
}
# Rate limiting configuration
request_times = defaultdict(list)
MAX_REQUESTS = 20 # Maximum requests per time window
TIME_WINDOW = 3600 # Time window in seconds (1 hour)
def get_real_ip(request: gr.Request):
"""Extract real IP address using x-forwarded-for header or fallback"""
if not request:
return "unknown"
forwarded = request.headers.get("x-forwarded-for")
if forwarded:
ip = forwarded.split(",")[0].strip() # First IP in the list is the client's
else:
ip = request.client.host # fallback
return ip
def check_rate_limit(request: gr.Request):
"""Check if the current request exceeds rate limits"""
if not request:
return True, "Rate limit check failed - no request info"
ip = get_real_ip(request)
now = time.time()
# Clean up old timestamps outside the time window
request_times[ip] = [t for t in request_times[ip] if now - t < TIME_WINDOW]
# Check if rate limit exceeded
if len(request_times[ip]) >= MAX_REQUESTS:
time_remaining = int(TIME_WINDOW - (now - request_times[ip][0]))
time_remaining_minutes = round(time_remaining / 60, 1)
time_window_minutes = round(TIME_WINDOW / 60, 1)
return False, f"Rate limit exceeded. You can make {MAX_REQUESTS} requests per {time_window_minutes} minutes. Try again in {time_remaining_minutes} minutes."
# Add current request timestamp
request_times[ip].append(now)
return True, ""
# ----------------- JigsawStack API Wrappers ------------------
def translate_text(text_input, target_lang, request: gr.Request):
# Check rate limit first
rate_limit_ok, rate_limit_msg = check_rate_limit(request)
if not rate_limit_ok:
return {"error": "Rate limit exceeded", "message": rate_limit_msg}
# Validate required inputs
if not text_input or not text_input.strip():
return {"error": "Text input is required"}
if not target_lang or not target_lang.strip():
return {"error": "Target language code is required"}
# Handle both single string and comma-separated multiple phrases
if "," in text_input and not text_input.strip().startswith("["):
text_payload = [t.strip() for t in text_input.split(",") if t.strip()]
else:
text_payload = text_input.strip()
payload = {
"text": text_payload,
"target_language": target_lang.strip()
}
try:
r = requests.post(f"{BASE_URL}/ai/translate", headers=headers, json=payload)
r.raise_for_status()
data = r.json()
if not data.get("success"):
return {"error": "Translation failed", "response": data}
# Return a more comprehensive result matching the API response
result = {
"success": True,
"translated_text": data.get("translated_text")
}
return result
except requests.exceptions.RequestException as req_err:
return {"error": "Request failed", "message": str(req_err)}
except Exception as e:
return {"error": "Unexpected error", "message": str(e)}
# ----------------- Gradio UI ------------------
with gr.Blocks() as demo:
gr.Markdown("""
<div style='text-align: center; margin-bottom: 24px;'>
<h1 style='font-size:2.2em; margin-bottom: 0.2em;'>๐Ÿงฉ Text Translation</h1>
<p style='font-size:1.2em; margin-top: 0;'>Translate text from one language to another with support for multiple text formats.</p>
<p style='font-size:1em; margin-top: 0.5em;'>For more details and API usage, see the <a href='https://jigsawstack.com/docs/api-reference/ai/translate/translate' target='_blank'>documentation</a>.</p>
</div>
""")
with gr.Row():
# Left Column: Inputs and Examples
with gr.Column(scale=2):
gr.Markdown("#### Input")
text_input = gr.Textbox(
label="Text to Translate",
lines=4,
placeholder="Enter text to translate (use commas to separate multiple phrases for batch translation)"
)
gr.Markdown("#### Translation Options")
target_lang = gr.Textbox(
label="Target Language Code",
placeholder="es (Spanish), fr (French), de (German), etc.",
info="Common codes: es, fr, de, hi, ja, ko, zh, ar, ru, pt"
)
gr.Markdown("#### Quick Examples")
gr.Markdown("Click any example below to auto-fill the fields:")
with gr.Row():
example_btn1 = gr.Button("๐Ÿ‡ช๐Ÿ‡ธ Hello World โ†’ Spanish", size="sm")
example_btn2 = gr.Button("๐Ÿ‡ซ๐Ÿ‡ท Good morning โ†’ French", size="sm")
example_btn3 = gr.Button("๐Ÿ‡ฉ๐Ÿ‡ช Thank you โ†’ German", size="sm")
with gr.Row():
example_btn4 = gr.Button("๐Ÿ‡ฏ๐Ÿ‡ต How are you? โ†’ Japanese", size="sm")
example_btn5 = gr.Button("๐Ÿ‡จ๐Ÿ‡ณ Welcome โ†’ Chinese", size="sm")
example_btn6 = gr.Button("๐Ÿ‡ฐ๐Ÿ‡ท Goodbye โ†’ Korean", size="sm")
with gr.Row():
example_btn7 = gr.Button("๐Ÿ‡ฎ๐Ÿ‡ณ Batch: Hello, Goodbye, Thank you โ†’ Hindi", size="sm")
example_btn8 = gr.Button("๐Ÿ‡ท๐Ÿ‡บ Business: Meeting, Project, Deadline โ†’ Russian", size="sm")
gr.Markdown("") # Spacer
translate_btn = gr.Button("Translate", variant="primary")
# Middle Column: Supported Languages
with gr.Column(scale=1):
gr.Markdown("#### Supported Languages")
gr.Markdown("""
**Common Language Codes:**
- `es` - Spanish
- `fr` - French
- `de` - German
- `hi` - Hindi
- `ja` - Japanese
- `ko` - Korean
- `zh` - Chinese
- `ar` - Arabic
- `ru` - Russian
- `pt` - Portuguese
- `tr` - Turkish
- `bn` - Bengali
- `fi` - Finnish
- `sw` - Swahili
*For a complete list of 162+ supported languages, visit the [Language Codes Reference](https://jigsawstack.com/docs/additional-resources/languages)*
""")
# Example functions to auto-fill fields
def fill_example_1():
return "Hello World", "es"
def fill_example_2():
return "Good morning", "fr"
def fill_example_3():
return "Thank you", "de"
def fill_example_4():
return "How are you?", "ja"
def fill_example_5():
return "Welcome", "zh"
def fill_example_6():
return "Goodbye", "ko"
def fill_example_7():
return "Hello, Goodbye, Thank you", "hi"
def fill_example_8():
return "Meeting, Project, Deadline", "ru"
# Connect example buttons to auto-fill functions
example_btn1.click(fill_example_1, outputs=[text_input, target_lang])
example_btn2.click(fill_example_2, outputs=[text_input, target_lang])
example_btn3.click(fill_example_3, outputs=[text_input, target_lang])
example_btn4.click(fill_example_4, outputs=[text_input, target_lang])
example_btn5.click(fill_example_5, outputs=[text_input, target_lang])
example_btn6.click(fill_example_6, outputs=[text_input, target_lang])
example_btn7.click(fill_example_7, outputs=[text_input, target_lang])
example_btn8.click(fill_example_8, outputs=[text_input, target_lang])
gr.Markdown("#### Translation Result")
translate_result = gr.JSON()
translate_btn.click(
translate_text,
inputs=[text_input, target_lang],
outputs=translate_result,
)
demo.launch()