File size: 5,538 Bytes
acf8bfe
1fd0997
129257a
acf8bfe
129257a
56ffb39
fc58506
e8b7c49
 
5dc46ff
 
 
fc58506
acf8bfe
e8b7c49
acf8bfe
 
 
e8b7c49
1fd0997
a371d81
 
 
 
 
e8b7c49
 
a371d81
1fd0997
 
 
acf8bfe
e8b7c49
1fd0997
e8b7c49
 
 
1fd0997
e8b7c49
acf8bfe
e8b7c49
1fd0997
e8b7c49
acf8bfe
fc58506
e8b7c49
 
56ffb39
e8b7c49
56ffb39
e8b7c49
 
129257a
 
e8b7c49
56ffb39
 
e8b7c49
 
 
 
 
56ffb39
e8b7c49
 
 
 
56ffb39
 
 
129257a
56ffb39
129257a
 
e8b7c49
 
56ffb39
 
 
e8b7c49
 
fc58506
56ffb39
e8b7c49
 
56ffb39
e8b7c49
acf8bfe
e8b7c49
 
acf8bfe
56ffb39
 
 
 
 
 
 
e8b7c49
 
129257a
56ffb39
129257a
e8b7c49
 
1fd0997
e8b7c49
56ffb39
1fd0997
e8b7c49
 
 
 
 
 
 
56ffb39
a371d81
e8b7c49
 
 
 
 
 
 
acf8bfe
e8b7c49
 
129257a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from fastapi import FastAPI, HTTPException
from transformers import pipeline
import langdetect
import logging
import os
from typing import Optional # Import Optional untuk parameter di FastAPI

# Set environment variables for Hugging Face cache
# Ini penting agar model di-cache di lokasi yang benar di dalam container Hugging Face Space
os.environ["HF_HOME"] = "/app/cache"
os.environ["TRANSFORMERS_CACHE"] = "/app/cache"

app = FastAPI()

# Konfigurasi logging untuk melihat pesan debug di log Space kamu
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Peta model untuk setiap bahasa yang didukung
MODEL_MAP = {
    "id": "Helsinki-NLP/opus-mt-id-en",
    "th": "Helsinki-NLP/opus-mt-th-en",
    "fr": "Helsinki-NLP/opus-mt-fr-en",
    "es": "Helsinki-NLP/opus-mt-es-en",
    "ja": "Helsinki-NLP/opus-mt-ja-en",
    # Entri tunggal untuk Mandarin, kita akan normalisasi deteksi bahasanya
    "zh": "Helsinki-NLP/opus-mt-zh-en",
    "vi": "Helsinki-NLP/opus-mt-vi-en",
}

translators = {}
try:
    # Inisialisasi semua model saat aplikasi dimulai
    for lang, model_name in MODEL_MAP.items():
        logger.info(f"Loading model for {lang} from {model_name}...")
        # Pastikan kita menggunakan device="cpu" atau "cuda" jika GPU tersedia
        # Untuk Hugging Face Space gratis biasanya CPU, jadi lebih aman tidak specify device
        translators[lang] = pipeline("translation", model=model_name)
        logger.info(f"Model for {lang} loaded successfully.")
except Exception as e:
    # Tangani kegagalan inisialisasi model
    logger.error(f"Model initialization failed: {str(e)}")
    # Hentikan aplikasi jika model gagal dimuat, karena aplikasi tidak akan berfungsi
    raise Exception(f"Model initialization failed: {str(e)}")

---

## Fungsi Deteksi Bahasa yang Ditingkatkan (dengan Logging Detail)

Ini adalah bagian kunci perbaikannya dengan penambahan *logging* yang lebih informatif.

```python
def detect_language(text: str) -> str:
    try:
        detected_lang = langdetect.detect(text)
        # Log ini SANGAT PENTING untuk debugging! Ini menunjukkan hasil mentah dari langdetect.
        logger.info(f"langdetect raw result: '{detected_lang}' for text: '{text[:50]}...'")

        # Normalisasi untuk bahasa Mandarin:
        # Jika langdetect mengembalikan 'zh-cn', 'zh-tw', 'zh-hk', dll.,
        # kita paksa menjadi 'zh' agar sesuai dengan kunci di MODEL_MAP.
        if detected_lang.startswith('zh'):
            logger.info(f"Normalizing '{detected_lang}' to 'zh' for Mandarin.")
            return 'zh'

        # Jika bahasa terdeteksi ada di MODEL_MAP, gunakan itu.
        # Jika tidak, default ke 'en' (bahasa Inggris).
        final_lang = detected_lang if detected_lang in MODEL_MAP else "en"
        logger.info(f"Final determined language: '{final_lang}'. (Based on raw detected: '{detected_lang}')")
        return final_lang
    except Exception as e:
        logger.warning(f"Language detection FAILED for text: '{text[:50]}...'. Error: {str(e)}. Defaulting to English.")
        return "en"

---

## Endpoint API untuk Terjemahan (dengan Opsi Override Bahasa Sumber)

Ini adalah bagian kunci perbaikannya dengan penambahan parameter `source_lang_override`.

```python
@app.post("/translate")
async def translate(text: str, source_lang_override: Optional[str] = None):
    """
    Menerima teks dan mengembalikannya dalam bahasa Inggris.
    Secara otomatis mendeteksi bahasa sumber, atau bisa di-override oleh pengguna.
    """
    if not text:
        raise HTTPException(status_code=400, detail="Text input is required.")

    try:
        # Tentukan bahasa sumber: gunakan override jika diberikan dan valid, kalau tidak, deteksi otomatis.
        if source_lang_override and source_lang_override in MODEL_MAP:
            source_lang = source_lang_override
            logger.info(f"Source language overridden by user to: '{source_lang_override}'.")
        else:
            source_lang = detect_language(text)
            logger.info(f"Determined source language for translation: '{source_lang}'.")

        # Jika bahasa sumber sudah Bahasa Inggris, kembalikan teks aslinya
        if source_lang == "en":
            logger.info("Source language is English or unrecognized, returning original text.")
            return {"translated_text": text}

        # Dapatkan translator yang sesuai dari kamus translators
        translator = translators.get(source_lang)

        # Jika tidak ada translator yang mendukung bahasa yang terdeteksi/di-override
        if not translator:
            logger.error(f"No translator found for language: '{source_lang}'.")
            raise HTTPException(
                status_code=400,
                detail=f"Translation not supported for language: {source_lang}."
            )

        # Lakukan terjemahan
        logger.info(f"Translating text from '{source_lang}' to English...")
        result = translator(text)
        translated_text = result[0]["translation_text"]
        logger.info(f"Translation successful. Original: '{text[:50]}...', Translated: '{translated_text[:50]}...'")

        return {"translated_text": translated_text}
    except HTTPException as e:
        # Tangani HTTPExceptions yang sudah kita definisikan sebelumnya
        raise e
    except Exception as e:
        # Tangani error tak terduga lainnya
        logger.error(f"An unexpected error occurred during processing: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Processing failed: {str(e)}")