Files
office_translator/services/providers/README.md
2026-03-07 11:42:58 +01:00

283 lines
8.7 KiB
Markdown

# Translation Providers
This directory contains translation provider implementations for the office_translator service.
## Available Providers
### Google Translate (`google_provider.py`)
Production-ready Google Translate provider with:
- Robust error handling with specific error codes
- Retry logic with exponential backoff
- Health check with result caching (60s TTL)
- Usage metrics logging
**Configuration:**
```bash
GOOGLE_TRANSLATE_ENABLED=true
GOOGLE_TRANSLATE_TIMEOUT=30
GOOGLE_TRANSLATE_MAX_RETRIES=3
GOOGLE_TRANSLATE_RETRY_DELAY=1
```
**API Usage:**
- Free tier: 500,000 characters/month
- 5,000 characters max per request
- Cost: ~$20 per million characters (paid tier)
**Error Codes:**
| Code | Description |
|------|-------------|
| `GOOGLE_QUOTA_EXCEEDED` | API quota exceeded (429) |
| `GOOGLE_INVALID_KEY` | Invalid API key (401/403) |
| `GOOGLE_NETWORK_ERROR` | Network/timeout error (502) |
| `GOOGLE_UNSUPPORTED_LANGUAGE` | Language not supported (400) |
| `GOOGLE_TEXT_TOO_LONG` | Text exceeds 5000 chars (413) |
### DeepL (`deepl_provider.py`)
Production-ready DeepL provider with:
- Automatic Free/Pro endpoint detection based on API key format
- Robust error handling with specific error codes
- Retry logic with exponential backoff
- Health check with result caching (60s TTL)
- Language code normalization for DeepL compatibility
**Configuration:**
```bash
DEEPL_ENABLED=true
DEEPL_API_KEY=your_deepl_api_key_here # Free keys end with :fx
DEEPL_TIMEOUT=30
DEEPL_MAX_RETRIES=3
DEEPL_RETRY_DELAY=1
```
**Free vs Pro API Keys:**
| Type | Key Format | Endpoint |
|------|------------|----------|
| Free | Ends with `:fx` | `https://api-free.deepl.com/v2/translate` |
| Pro | Does NOT end with `:fx` | `https://api.deepl.com/v2/translate` |
**API Usage:**
- Free tier: 500,000 characters/month
- Pro tier: ~€25 per million characters
- 128KB max per request
- Higher quality for European languages
**Supported Languages:**
BG, CS, DA, DE, EL, EN-GB, EN-US, ES, ET, FI, FR, HU, ID, IT, JA, KO, LT, LV, NB, NL, PL, PT-BR, PT-PT, RO, RU, SK, SL, SV, TR, UK, ZH
**Language Notes:**
- English has two variants: EN-GB, EN-US (defaults to EN-US)
- Portuguese has two variants: PT-BR, PT-PT (defaults to PT-BR)
- Language codes are case-sensitive (uppercase)
- Auto-detect uses `auto` (like Google)
**Error Codes:**
| Code | HTTP | Description |
|------|------|-------------|
| `DEEPL_QUOTA_EXCEEDED` | 429 | Character quota exceeded |
| `DEEPL_INVALID_KEY` | 401 | Invalid API key |
| `DEEPL_NETWORK_ERROR` | 502 | Network/timeout error |
| `DEEPL_UNSUPPORTED_LANGUAGE` | 400 | Language not supported |
| `DEEPL_TEXT_TOO_LONG` | 413 | Text exceeds 128KB |
### OpenAI (`openai_provider.py`)
Cloud LLM translation provider with:
- GPT-4/GPT-4o/GPT-4o-mini model support
- Custom system prompt support for translation context
- Robust error handling with specific error codes
- Retry logic with exponential backoff
- Fast timeout for cloud API (default 60s)
- Health check with result caching (60s TTL)
**Configuration:**
```bash
OPENAI_ENABLED=true
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxx
OPENAI_MODEL=gpt-4o-mini
OPENAI_TIMEOUT=60
OPENAI_MAX_RETRIES=3
OPENAI_RETRY_DELAY=1.0
# OPENAI_BASE_URL=https://api.openai.com/v1 # Optional: for Azure OpenAI or proxies
```
**Prerequisites:**
- OpenAI API key from https://platform.openai.com/api-keys
- Valid billing method on your OpenAI account
**Recommended Models for Translation:**
| Model | Cost | Speed | Quality | Best For |
|-------|------|-------|---------|----------|
| `gpt-4o-mini` | $0.15/M tokens | Fast | Good | Default choice, cost-effective |
| `gpt-4o` | $2.50/M tokens | Medium | Excellent | High-quality requirements |
| `gpt-4` | $30/M tokens | Slower | Excellent | Critical translations |
| `gpt-3.5-turbo` | $0.50/M tokens | Fastest | Good | Speed priority |
**Custom System Prompt:**
```python
request = TranslationRequest(
text="Hello",
target_language="fr",
metadata={"custom_prompt": "Translate formally for business context"}
)
```
**Rate Limiting:**
- OpenAI has strict rate limits per tier
- The provider automatically handles 429 errors with retry
- Retry-After header is respected when available
- Exponential backoff for transient errors
**Error Codes:**
| Code | HTTP | Description |
|------|------|-------------|
| `OPENAI_RATE_LIMITED` | 429 | Rate limit hit, retry suggested |
| `OPENAI_INVALID_KEY` | 401 | Invalid API key |
| `OPENAI_QUOTA_EXCEEDED` | 429 | Billing quota exceeded |
| `OPENAI_TIMEOUT` | 502 | Request timeout |
| `OPENAI_SERVICE_ERROR` | 502 | OpenAI server error |
| `OPENAI_CONTEXT_TOO_LONG` | 413 | Text exceeds model limit |
### Ollama (`ollama_provider.py`)
Local LLM translation provider with:
- Custom system prompt support for translation context
- Automatic model availability checking
- Robust error handling with specific error codes
- Retry logic with exponential backoff
- Longer timeout for LLM operations (default 120s)
- Health check with result caching (60s TTL)
**Configuration:**
```bash
OLLAMA_ENABLED=true
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3
OLLAMA_VISION_MODEL=llava
OLLAMA_TIMEOUT=120
OLLAMA_MAX_RETRIES=2
OLLAMA_RETRY_DELAY=2
```
**Prerequisites:**
- Ollama must be installed and running: `ollama serve`
- Model must be pulled before use: `ollama pull llama3`
**Recommended Models for Translation:**
| Model | Size | Best For |
|-------|------|----------|
| `llama3` | 8B | General translation, good balance |
| `llama3:70b` | 70B | High-quality translation |
| `mistral` | 7B | Fast translation |
| `qwen2` | 7B | Strong non-English support |
**Custom System Prompt:**
```python
request = TranslationRequest(
text="Hello",
target_language="fr",
metadata={"custom_prompt": "Translate formally for business context"}
)
```
**Error Codes:**
| Code | HTTP | Description |
|------|------|-------------|
| `OLLAMA_UNAVAILABLE` | 502 | Ollama service not reachable |
| `OLLAMA_MODEL_NOT_FOUND` | 400 | Model not pulled |
| `OLLAMA_TIMEOUT` | 502 | Request timeout |
| `OLLAMA_GENERATION_ERROR` | 502 | LLM generation failed |
| `OLLAMA_CONTEXT_TOO_LONG` | 413 | Text exceeds model limit |
## Usage
```python
from services.providers.google_provider import GoogleTranslationProvider
from services.providers.deepl_provider import DeepLTranslationProvider
from services.providers.openai_provider import OpenAITranslationProvider
from services.providers.ollama_provider import OllamaTranslationProvider
from services.providers.schemas import TranslationRequest
# Google provider
google_provider = GoogleTranslationProvider()
request = TranslationRequest(text="Hello", target_language="fr")
response = google_provider.translate_text(request)
# DeepL provider (requires API key)
deepl_provider = DeepLTranslationProvider(api_key="your-key:fx")
request = TranslationRequest(text="Hello", target_language="fr")
response = deepl_provider.translate_text(request)
# OpenAI provider (requires API key)
openai_provider = OpenAITranslationProvider(
api_key="sk-...",
model="gpt-4o-mini"
)
request = TranslationRequest(text="Hello", target_language="fr")
response = openai_provider.translate_text(request)
# OpenAI with custom prompt
request = TranslationRequest(
text="Hello",
target_language="fr",
metadata={"custom_prompt": "Translate formally for business context"}
)
response = openai_provider.translate_text(request)
# Ollama provider (requires local Ollama running)
ollama_provider = OllamaTranslationProvider(
base_url="http://localhost:11434",
model="llama3"
)
request = TranslationRequest(text="Hello", target_language="fr")
response = ollama_provider.translate_text(request)
# Ollama with custom prompt
request = TranslationRequest(
text="Hello",
target_language="fr",
metadata={"custom_prompt": "Translate formally"}
)
response = ollama_provider.translate_text(request)
if response.success:
print(response.translated_text)
else:
print(f"Error: {response.error_code} - {response.error}")
```
## Registry Usage
```python
from services.providers import registry
# List all providers
print(registry.list_all())
# Get first available from fallback chain
provider = registry.get_first_available(["google", "deepl", "openai", "ollama"])
# Check if provider is available
print(registry.list_available())
```
## Health Check
```python
status = provider.health_check()
print(f"Available: {status.available}")
print(f"Latency: {status.latency_ms}ms")
print(f"Last Check: {status.last_check}")
```
## Architecture
All providers extend `TranslationProvider` base class and implement:
- `translate_text(request: TranslationRequest) -> TranslationResponse`
- `translate_batch(requests: List[TranslationRequest]) -> List[TranslationResponse]`
- `is_available() -> bool`
- `health_check() -> ProviderHealthStatus`
- `get_name() -> str`