RohitHiwal's picture
Update main.py
7a52770 verified
import os
import html
import json
from fastapi import FastAPI, UploadFile, File, Form
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from google.cloud import vision
from google.cloud import translate_v2 as translate
from ddgs import DDGS
from google.oauth2 import service_account
# --- AUTHENTICATION ---
creds_json_str = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")
vision_client = None
translate_client = None
print("Initializing Google Cloud Clients...")
try:
if creds_json_str:
# --- PRODUCTION (Hugging Face) ---
print("Found GOOGLE_APPLICATION_CREDENTIALS secret. Parsing JSON...")
try:
creds_dict = json.loads(creds_json_str)
credentials = service_account.Credentials.from_service_account_info(creds_dict)
# PASS CREDENTIALS DIRECTLY TO CLIENTS
vision_client = vision.ImageAnnotatorClient(credentials=credentials)
translate_client = translate.Client(credentials=credentials)
print("SUCCESS: Google Clients initialized with Secret.")
except json.JSONDecodeError as e:
print(f"CRITICAL ERROR: Invalid JSON in GOOGLE_APPLICATION_CREDENTIALS secret. {e}")
else:
# --- LOCAL FALLBACK ---
print("No Secret found. Looking for local 'credentials.json' file...")
if os.path.exists('credentials.json'):
os.environ['GOOGLE_CREDENTIALS'] = 'credentials.json'
print("No such local file exist")
vision_client = vision.ImageAnnotatorClient()
translate_client = translate.Client()
print("SUCCESS: Google Clients initialized with local file.")
else:
print("CRITICAL ERROR: No credentials found (Env var or local file missing).")
except Exception as e:
print(f"CRITICAL ERROR Initializing Clients: {e}")
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# --- HELPER: Web Search ---
def get_english_definition(term):
"""
Searches for the dictionary definition of an English word.
e.g. term="Year" -> returns "Time taken by the earth to orbit the sun..."
"""
queries = [
f"define {term} dictionary",
f"meaning of {term} in english",
f"what is a {term}"
]
try:
with DDGS() as ddgs:
for q in queries:
results = list(ddgs.text(q, max_results=1))
if results:
return results[0]['body']
except: pass
return None
@app.post("/translate/")
async def translate_image(
file: UploadFile = File(...),
target_lang: str = Form("en")
):
try:
contents = await file.read()
image = vision.Image(content=contents)
response = vision_client.document_text_detection(image=image)
processed_results = []
word_data = []
for page in response.full_text_annotation.pages:
for block in page.blocks:
for paragraph in block.paragraphs:
paragraph_text = ""
for word in paragraph.words:
word_text = "".join([symbol.text for symbol in word.symbols])
paragraph_text += word_text + " "
w_verts = word.bounding_box.vertices
word_data.append({
"text": word_text,
"tl": [w_verts[0].x, w_verts[0].y],
"br": [w_verts[2].x, w_verts[2].y]
})
paragraph_text = paragraph_text.strip()
if len(paragraph_text) < 2: continue
translated_text = "[Error]"
try:
translation = translate_client.translate(
paragraph_text,
target_language=target_lang,
model="nmt"
)
translated_text = html.unescape(translation['translatedText'])
except: pass
vertices = paragraph.bounding_box.vertices
processed_results.append({
"tl": [vertices[0].x, vertices[0].y],
"br": [vertices[2].x, vertices[2].y],
"text": translated_text
})
return { "translations": processed_results, "words": word_data }
except Exception as e:
return {"error": str(e)}
@app.get("/define/")
async def define_word(word: str, target_lang: str = "en", source_lang: str = "auto"):
# Just remove whitespace.
clean_word = word.strip()
# 1. Language Setup
lang_map = {'en': 'English', 'hi': 'Hindi', 'es': 'Spanish', 'fr': 'French'}
source_name = lang_map.get(source_lang, 'Foreign Language')
target_name = lang_map.get(target_lang, 'English')
print(f"Processing: {clean_word} ({source_name} -> {target_name})")
# 2. STEP 1: Translate
translated_word = clean_word
english_meaning = ""
try:
# Get English meaning first (The "Bridge")
trans = translate_client.translate(
clean_word,
target_language='en',
source_language=source_lang if source_lang != 'auto' else None
)
english_meaning = html.unescape(trans['translatedText'])
# If user wants target lang (e.g. Spanish), translate "Year" -> "Año"
if target_lang != 'en':
trans_target = translate_client.translate(english_meaning, target_language=target_lang)
translated_word = html.unescape(trans_target['translatedText'])
else:
translated_word = english_meaning
except Exception as e:
print(f"Translation Error: {e}")
return {"word": clean_word, "definition": "Could not translate."}
# 3. STEP 2: Search Definition
definition_text = get_english_definition(english_meaning)
if not definition_text:
# Fallback: If English search fails, try the original word
definition_text = get_english_definition(clean_word)
# Translate definition if needed
if definition_text and target_lang != 'en':
try:
t_def = translate_client.translate(definition_text, target_language=target_lang)
definition_text = html.unescape(t_def['translatedText'])
except: pass
# 4. STEP 3: Format Output
# Format: "The Hindi word 'साल' translates to 'Year'..."
final_output = f"{translated_word}\n\n{definition_text or 'Definition not found.'}"
if english_meaning.lower() != clean_word.lower():
final_output = (
f"The {source_name} word '{clean_word}' translates to "
f"'{translated_word}' in {target_name}.\n\n"
f"{translated_word}: {definition_text or 'Definition not found.'}"
)
return {
"word": translated_word,
"definition": final_output
}
@app.get("/", response_class=HTMLResponse)
async def get_frontend():
try:
with open("index.html", "r", encoding="utf-8") as f:
return HTMLResponse(content=f.read())
except FileNotFoundError:
return HTMLResponse(content="<h1>Error: index.html missing</h1>", status_code=404)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=7860)