A lightweight FastAPI microservice for translation with language detection, caching, glossary support, and optional tone rewriting.
- 🌍 Multi-language Translation - Supports 25+ languages via NLLB-200 model
- 🔍 Language Detection - Automatic language detection with pycld3
- 💾 Smart Caching - SQLite-based translation cache for instant retrieval
- 📚 Glossary Support - Pre/post translation term replacement
- ✨ Tone Rewriting - Optional politeness adjustment via Ollama (Japanese/Korean)
- 🐳 Docker Ready - Full containerization with Docker Compose
- ⚡ Fast API - Built on FastAPI with automatic OpenAPI documentation
- Python 3.11
- Docker & Docker Compose (for containerized deployment)
- Ollama (optional, for tone rewriting)
The fastest way to get started:
# Clone or navigate to the project
cd STAN-Lingua
# Start the service
docker-compose up -d
# View logs
docker-compose logs -f stan-lingua
# Access the API
curl http://localhost:8000The service will be available at http://localhost:8000
The Docker setup includes:
- Port 8000 exposed for the API
- Model caching in
/modelsvolume (persistent across restarts) - Glossary mounting as read-only volume for easy updates
- Translation cache persisted in SQLite database
- Optional Ollama service for tone rewriting
To stop the service:
docker-compose downTo rebuild after code changes:
docker-compose up -d --build- Create a virtual environment:
python -m venv venv- Activate the virtual environment:
# Windows
venv\Scripts\activate
# Linux/Mac
source venv/bin/activate- Install dependencies:
pip install -r requirements.txt- Run the service:
uvicorn app.main:app --reloadDefine terms to replace before/after translation:
{
"pre": {
"API": "API (Application Programming Interface)"
},
"post": {
"GPU": "GPU(ジーピーユー)"
}
}Enable tone adjustment for Japanese/Korean:
{
"rewrite": {
"enabled": false,
"ollama_url": "http://localhost:11434",
"model": "phi3:mini",
"languages": ["ja", "ko"],
"tone": "polite"
}
}To enable rewriting:
- Start Ollama:
docker-compose up ollama -d - Pull a model:
docker exec -it stan-lingua-ollama ollama pull phi3:mini - Set
"enabled": trueinconfig.json
Once running, visit:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
Health check endpoint.
Response:
{
"message": "Welcome to STAN-Lingua translation service"
}Translate text between languages.
Request:
{
"text": "Hello, world!",
"source": "en",
"target": "es"
}Response:
{
"translation": "¡Hola, mundo!",
"source_lang": "en",
"target_lang": "es",
"model": "facebook/nllb-200-distilled-600M",
"cached": false
}Supported Languages:
- English (en), Spanish (es), French (fr), German (de)
- Italian (it), Portuguese (pt), Dutch (nl), Russian (ru)
- Chinese (zh), Japanese (ja), Korean (ko), Arabic (ar)
- Hindi (hi), Turkish (tr), Polish (pl), Ukrainian (uk)
- Vietnamese (vi), Thai (th), Czech (cs), Romanian (ro)
- Swedish (sv), Greek (el), Hebrew (he), Persian (fa)
- Indonesian (id), Malay (ms), Bengali (bn)
Run the test suite:
# All tests
pytest tests/ -v
# Exclude slow tests
pytest tests/ -v -m "not slow"
# End-to-end test
python e2e_test.py- Translation API on port 8000
- Automatic model downloading
- Persistent cache and models
- LLM service on port 11434
- For tone rewriting functionality
- Supports phi3:mini, llama3:8b, etc.
models_cache- Hugging Face models (persistent)ollama_data- Ollama models (persistent)./glossary.json- Mounted read-only for easy updates./config.json- Mounted read-only for configuration./translation_cache.db- SQLite cache database
Set in docker-compose.yml or .env:
TRANSFORMERS_CACHE=/models- Model cache directoryHF_HOME=/models- Hugging Face home directoryHF_TOKEN- Hugging Face token (for private models)LOG_LEVEL=INFO- Logging level
┌─────────────┐
│ Client │
└──────┬──────┘
│
▼
┌─────────────────────────────────────┐
│ FastAPI Service │
│ ┌──────────────────────────────┐ │
│ │ 1. Language Detection │ │
│ │ (pycld3) │ │
│ └──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ 2. Check Cache │ │
│ │ (SQLite) │◄──┼── Cache Hit? → Return
│ └──────────────────────────────┘ │
│ │ │
│ ▼ (Cache Miss) │
│ ┌──────────────────────────────┐ │
│ │ 3. Apply Pre-Glossary │ │
│ └──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ 4. Translate (NLLB-200) │ │
│ └──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ 5. Apply Post-Glossary │ │
│ └──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ 6. Rewrite Tone (Ollama) │ │
│ │ [Optional] │ │
│ └──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────┐ │
│ │ 7. Store in Cache │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘
- First translation: 1-5 seconds (model loading + inference)
- Subsequent translations: 500-2000ms (inference only)
- Cached translations: <100ms (database lookup)
- Language detection: <50ms
MIT
Contributions welcome! Please feel free to submit a Pull Request.