Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Upload folder using huggingface_hub
Browse files- modules/languages/models.py +6 -0
- modules/languages/translator.py +51 -0
- server.py +4 -51
modules/languages/models.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pydantic import BaseModel
|
| 2 |
+
|
| 3 |
+
class TranslationRequest(BaseModel):
|
| 4 |
+
context : str
|
| 5 |
+
text: str
|
| 6 |
+
target_lang: str
|
modules/languages/translator.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import HTTPException, Request
|
| 2 |
+
from modules.languages.models import TranslationRequest
|
| 3 |
+
from openai import OpenAI
|
| 4 |
+
from dotenv import load_dotenv
|
| 5 |
+
|
| 6 |
+
load_dotenv()
|
| 7 |
+
|
| 8 |
+
client = OpenAI()
|
| 9 |
+
|
| 10 |
+
async def svc_translate_text(request: Request, body: TranslationRequest):
|
| 11 |
+
"""
|
| 12 |
+
Translate text from any language (auto-detected) to the target language.
|
| 13 |
+
"""
|
| 14 |
+
try:
|
| 15 |
+
prompt = f"""
|
| 16 |
+
You are a professional translation engine that performs **literal, direct translations** β not summaries or interpretations.
|
| 17 |
+
|
| 18 |
+
Your objectives:
|
| 19 |
+
1. **Detect the source language and script automatically.**
|
| 20 |
+
2. If the source and target languages are the same ({body.target_lang}), return the original text unchanged.
|
| 21 |
+
3. Translate **each sentence or line** in a one-to-one manner, preserving structure, order, and approximate length.
|
| 22 |
+
4. Do **not infer**, **do not summarize**, and **do not paraphrase** β translate only what is written.
|
| 23 |
+
5. Maintain every phrase and symbol; do not omit or merge content.
|
| 24 |
+
6. If the input text appears to be **transliterated** (for example, Indic or Dravidian language text written in Latin characters), internally interpret it as its likely original language (e.g., Sanskrit, Tamil, Telugu, etc.) before translating to {body.target_lang}.
|
| 25 |
+
7. When the target language uses a non-Latin script, **output in that native script** (not in transliteration).
|
| 26 |
+
8. Use the provided context only to resolve ambiguity β never to alter, shorten, or elaborate the meaning.
|
| 27 |
+
9. Respond with **only the translated text** β no commentary, explanations, transliterations, or formatting.
|
| 28 |
+
10. NEVER return the context back.
|
| 29 |
+
|
| 30 |
+
Context (for disambiguation only):
|
| 31 |
+
{body.context}
|
| 32 |
+
|
| 33 |
+
Text to translate:
|
| 34 |
+
{body.text}
|
| 35 |
+
"""
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
print(f"prompt = {prompt}")
|
| 40 |
+
|
| 41 |
+
response = client.chat.completions.create(
|
| 42 |
+
model="gpt-4o-mini",
|
| 43 |
+
messages=[{"role": "user", "content": prompt}],
|
| 44 |
+
temperature=0.2,
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
translation = response.choices[0].message.content.strip()
|
| 48 |
+
return {"translated_text": translation}
|
| 49 |
+
|
| 50 |
+
except Exception as e:
|
| 51 |
+
raise HTTPException(status_code=500, detail=str(e))
|
server.py
CHANGED
|
@@ -22,8 +22,8 @@ from modules.quiz.quiz_helper import generate_question
|
|
| 22 |
import logging
|
| 23 |
from modules.video.model import VideoRequest
|
| 24 |
from modules.video.service import svc_get_video_urls
|
| 25 |
-
from
|
| 26 |
-
from
|
| 27 |
from slowapi.util import get_remote_address
|
| 28 |
from slowapi import Limiter
|
| 29 |
from slowapi.errors import RateLimitExceeded
|
|
@@ -31,8 +31,6 @@ from slowapi.errors import RateLimitExceeded
|
|
| 31 |
router = APIRouter()
|
| 32 |
limiter = Limiter(key_func=get_remote_address)
|
| 33 |
|
| 34 |
-
load_dotenv()
|
| 35 |
-
|
| 36 |
logging.basicConfig()
|
| 37 |
logger = logging.getLogger(__name__)
|
| 38 |
logger.setLevel(logging.INFO)
|
|
@@ -637,53 +635,8 @@ async def get_discourse_detail(topic_id: int):
|
|
| 637 |
raise HTTPException(status_code=404, detail="Discourse topic not found")
|
| 638 |
return topic
|
| 639 |
|
| 640 |
-
class TranslationRequest(BaseModel):
|
| 641 |
-
context : str
|
| 642 |
-
text: str
|
| 643 |
-
target_lang: str
|
| 644 |
-
|
| 645 |
-
client = OpenAI()
|
| 646 |
-
|
| 647 |
@router.post("/translate")
|
| 648 |
@limiter.limit("5/minute")
|
| 649 |
async def translate_text(request: Request, body: TranslationRequest):
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
"""
|
| 653 |
-
try:
|
| 654 |
-
prompt = f"""
|
| 655 |
-
You are a professional translation engine that performs **literal, direct translations** β not summaries or interpretations.
|
| 656 |
-
|
| 657 |
-
Your objectives:
|
| 658 |
-
1. **Detect the source language and script automatically.**
|
| 659 |
-
2. If the source and target languages are the same ({body.target_lang}), return the original text unchanged.
|
| 660 |
-
3. Translate **each sentence or line** in a one-to-one manner, preserving structure, order, and approximate length.
|
| 661 |
-
4. Do **not infer**, **do not summarize**, and **do not paraphrase** β translate only what is written.
|
| 662 |
-
5. Maintain every phrase and symbol; do not omit or merge content.
|
| 663 |
-
6. If the input text appears to be **transliterated** (for example, Indic or Dravidian language text written in Latin characters), internally interpret it as its likely original language (e.g., Sanskrit, Tamil, Telugu, etc.) before translating to {body.target_lang}.
|
| 664 |
-
7. When the target language uses a non-Latin script, **output in that native script** (not in transliteration).
|
| 665 |
-
8. Use the provided context only to resolve ambiguity β never to alter, shorten, or elaborate the meaning.
|
| 666 |
-
9. Respond with **only the translated text** β no commentary, explanations, transliterations, or formatting.
|
| 667 |
-
|
| 668 |
-
Context (for disambiguation only):
|
| 669 |
-
{body.context}
|
| 670 |
-
|
| 671 |
-
Text to translate:
|
| 672 |
-
{body.text}
|
| 673 |
-
"""
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
print(f"prompt = {prompt}")
|
| 678 |
-
|
| 679 |
-
response = client.chat.completions.create(
|
| 680 |
-
model="gpt-4o-mini",
|
| 681 |
-
messages=[{"role": "user", "content": prompt}],
|
| 682 |
-
temperature=0.2,
|
| 683 |
-
)
|
| 684 |
-
|
| 685 |
-
translation = response.choices[0].message.content.strip()
|
| 686 |
-
return {"translated_text": translation}
|
| 687 |
-
|
| 688 |
-
except Exception as e:
|
| 689 |
-
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
| 22 |
import logging
|
| 23 |
from modules.video.model import VideoRequest
|
| 24 |
from modules.video.service import svc_get_video_urls
|
| 25 |
+
from modules.languages.models import TranslationRequest
|
| 26 |
+
from modules.languages.translator import svc_translate_text
|
| 27 |
from slowapi.util import get_remote_address
|
| 28 |
from slowapi import Limiter
|
| 29 |
from slowapi.errors import RateLimitExceeded
|
|
|
|
| 31 |
router = APIRouter()
|
| 32 |
limiter = Limiter(key_func=get_remote_address)
|
| 33 |
|
|
|
|
|
|
|
| 34 |
logging.basicConfig()
|
| 35 |
logger = logging.getLogger(__name__)
|
| 36 |
logger.setLevel(logging.INFO)
|
|
|
|
| 635 |
raise HTTPException(status_code=404, detail="Discourse topic not found")
|
| 636 |
return topic
|
| 637 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 638 |
@router.post("/translate")
|
| 639 |
@limiter.limit("5/minute")
|
| 640 |
async def translate_text(request: Request, body: TranslationRequest):
|
| 641 |
+
resp = await svc_translate_text(request, body)
|
| 642 |
+
return resp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|