← Retour à l'accueil

📖 Wiki - Translator API

Documentation complète pour intégrer l'API de traduction

🚀 Démarrage rapide

Translator API est une alternative gratuite à Google Translate, accessible via une API REST simple. Pas de clé API requise, pas d'inscription nécessaire.

✨ Fonctionnalités

  • 🆓 Gratuit et sans limite de compte
  • ⚡ 30 requêtes/minute par IP
  • 🌍 100+ langues supportées
  • 🔒 Détection automatique de langue
  • 📊 Dashboard admin avec métriques temps réel
  • ⚖️ Architecture distribuée (Central + Workers)

URL de base

Remplacez VOTRE_HOTE par l'adresse de votre instance :

https://VOTRE_HOTE:7860

Test rapide

curl -X POST https://VOTRE_HOTE:7860/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Bonjour le monde", "source": "fr", "target": "en"}'

Réponse :

{
  "translatedText": "Hello world",
  "source": "fr",
  "target": "en",
  "duration": 245
}

🔌 Endpoints API

POST /translate

Traduit un texte d'une langue vers une autre.

Paramètres (JSON body)

ParamètreTypeRequisDescription
textstringOuiTexte à traduire (max 5000 caractères)
sourcestringNonLangue source (code ISO 639-1). Défaut: "auto" (détection auto)
targetstringNonLangue cible (code ISO 639-1). Défaut: "fr"

Réponse

ChampTypeDescription
translatedTextstringTexte traduit
sourcestringLangue source détectée/utilisée
targetstringLangue cible
durationnumberTemps de traitement en ms
GET /api/health

Vérifie l'état du service.

GET /admin

Panel d'administration (nécessite code d'accès via header x-admin-code ou paramètre admin_code).

Codes de langue supportés (exemples)

CodeLangueCodeLangue
frFrançaisenAnglais
esEspagnoldeAllemand
itItalienptPortugais
ruRussezhChinois
jaJaponaiskoCoréen
arArabeautoDétection auto

📜 JavaScript / TypeScript

Fetch API (Navigateur / Node 18+)

async function translate(text, source = 'auto', target = 'fr') {
  const response = await fetch('https://VOTRE_HOTE:7860/translate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text, source, target })
  });
  
  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error || 'Erreur de traduction');
  }
  
  return response.json();
}

// Utilisation
translate('Bonjour le monde', 'fr', 'en')
  .then(result => console.log(result.translatedText)) // "Hello world"
  .catch(err => console.error(err));
const axios = require('axios');

async function translate(text, source = 'auto', target = 'fr') {
  try {
    const { data } = await axios.post('https://VOTRE_HOTE:7860/translate', {
      text, source, target
    });
    return data;
  } catch (error) {
    throw new Error(error.response?.data?.error || error.message);
  }
}

// Utilisation
translate('Hello world', 'en', 'fr')
  .then(r => console.log(r.translatedText)); // "Bonjour le monde"
const https = require('https');

function translate(text, source = 'auto', target = 'fr') {
  return new Promise((resolve, reject) => {
    const postData = JSON.stringify({ text, source, target });
    
    const options = {
      hostname: 'VOTRE_HOTE',
      port: 7860,
      path: '/translate',
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    const req = https.request(options, (res) => {
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => {
        try {
          const result = JSON.parse(data);
          if (res.statusCode >= 400) reject(new Error(result.error));
          else resolve(result);
        } catch (e) {
          reject(new Error('Réponse invalide'));
        }
      });
    });
    
    req.on('error', reject);
    req.write(postData);
    req.end();
  });
}

Classe réutilisable (ES6)

class TranslatorAPI {
  constructor(baseUrl = 'https://VOTRE_HOTE:7860') {
    this.baseUrl = baseUrl;
  }
  
  async translate(text, source = 'auto', target = 'fr') {
    const res = await fetch(`${this.baseUrl}/translate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text, source, target })
    });
    
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error);
    }
    
    return res.json();
  }
  
  async detectLanguage(text) {
    const result = await this.translate(text, 'auto', 'en');
    return result.source;
  }
  
  async translateBatch(texts, source = 'auto', target = 'fr') {
    // Paralléliser avec Promise.all (respecter rate limit 30/min)
    const results = await Promise.all(
      texts.map(t => this.translate(t, source, target))
    );
    return results.map(r => r.translatedText);
  }
}

// Usage
const translator = new TranslatorAPI();
const result = await translator.translate('Bonjour', 'fr', 'es');
console.log(result.translatedText); // "Hola"

🐍 Python

import requests

def translate(text, source='auto', target='fr', base_url='https://VOTRE_HOTE:7860'):
    \"\"\"Traduit un texte via l'API Translator.\"\"\"
    response = requests.post(
        f'{base_url}/translate',
        json={'text': text, 'source': source, 'target': target},
        timeout=30
    )
    response.raise_for_status()
    return response.json()

# Utilisation simple
result = translate('Bonjour le monde', 'fr', 'en')
print(result['translatedText'])  # "Hello world"

# Avec gestion d'erreurs
try:
    result = translate('Hola', 'es', 'fr')
    print(f"Traduit: {result['translatedText']} (durée: {result['duration']}ms)")
except requests.HTTPError as e:
    if e.response.status_code == 429:
        print("Rate limit dépassé (30 req/min)")
    else:
        print(f"Erreur: {e.response.json().get('error')}")
import httpx
import asyncio

class TranslatorClient:
    def __init__(self, base_url='https://VOTRE_HOTE:7860'):
        self.base_url = base_url
        self.client = httpx.AsyncClient(timeout=30.0)
    
    async def translate(self, text, source='auto', target='fr'):
        response = await self.client.post(
            f'{self.base_url}/translate',
            json={'text': text, 'source': source, 'target': target}
        )
        response.raise_for_status()
        return response.json()
    
    async def translate_batch(self, texts, source='auto', target='fr', concurrency=5):
        \"\"\"Traduit plusieurs textes avec limite de concurrence.\"\"\"
        semaphore = asyncio.Semaphore(concurrency)
        
        async def limited_translate(text):
            async with semaphore:
                return await self.translate(text, source, target)
        
        tasks = [limited_translate(t) for t in texts]
        results = await asyncio.gather(*tasks, return_exceptions=True)
        return [r['translatedText'] if not isinstance(r, Exception) else str(r) for r in results]
    
    async def close(self):
        await self.client.aclose()

# Usage
async def main():
    client = TranslatorClient()
    try:
        result = await client.translate('Hello world', 'en', 'fr')
        print(result['translatedText'])
        
        # Batch
        texts = ['Hello', 'World', 'Python']
        translations = await client.translate_batch(texts, 'en', 'fr')
        print(translations)
    finally:
        await client.close()

asyncio.run(main())
import urllib.request
import json

def translate(text, source='auto', target='fr', base_url='https://VOTRE_HOTE:7860'):
    data = json.dumps({'text': text, 'source': source, 'target': target}).encode('utf-8')
    
    req = urllib.request.Request(
        f'{base_url}/translate',
        data=data,
        headers={'Content-Type': 'application/json'},
        method='POST'
    )
    
    with urllib.request.urlopen(req, timeout=30) as response:
        result = json.loads(response.read().decode('utf-8'))
        if response.status >= 400:
            raise Exception(result.get('error', 'Erreur inconnue'))
        return result

# Utilisation
try:
    result = translate('Bonjour', 'fr', 'de')
    print(result['translatedText'])  # "Hallo"
except Exception as e:
    print(f"Erreur: {e}")

☕ Java

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class TranslatorClient {
    private final HttpClient client;
    private final String baseUrl;
    private final Gson gson = new Gson();
    
    public TranslatorClient(String baseUrl) {
        this.baseUrl = baseUrl;
        this.client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(30))
            .build();
    }
    
    public TranslationResult translate(String text, String source, String target) 
            throws Exception {
        JsonObject requestBody = new JsonObject();
        requestBody.addProperty("text", text);
        requestBody.addProperty("source", source);
        requestBody.addProperty("target", target);
        
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/translate"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(gson.toJson(requestBody)))
            .build();
        
        HttpResponse response = client.send(request, 
            HttpResponse.BodyHandlers.ofString());
        
        if (response.statusCode() >= 400) {
            JsonObject error = gson.fromJson(response.body(), JsonObject.class);
            throw new RuntimeException(error.get("error").getAsString());
        }
        
        return gson.fromJson(response.body(), TranslationResult.class);
    }
    
    public static class TranslationResult {
        public String translatedText;
        public String source;
        public String target;
        public long duration;
    }
    
    // Usage
    public static void main(String[] args) throws Exception {
        TranslatorClient translator = new TranslatorClient("https://VOTRE_HOTE:7860");
        TranslationResult result = translator.translate("Bonjour", "fr", "en");
        System.out.println(result.translatedText); // "Hello"
    }
}
// Dependencies: OkHttp + Gson
// implementation "com.squareup.okhttp3:okhttp:4.12.0"
// implementation "com.google.code.gson:gson:2.10.1"

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import okhttp3.*;

public class TranslatorClient {
    private final OkHttpClient client;
    private final String baseUrl;
    private final Gson gson = new Gson();
    
    public TranslatorClient(String baseUrl) {
        this.baseUrl = baseUrl;
        this.client = new OkHttpClient.Builder()
            .connectTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
            .readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
            .build();
    }
    
    public TranslationResult translate(String text, String source, String target) 
            throws Exception {
        JsonObject json = new JsonObject();
        json.addProperty("text", text);
        json.addProperty("source", source);
        json.addProperty("target", target);
        
        RequestBody body = RequestBody.create(
            gson.toJson(json), 
            MediaType.get("application/json; charset=utf-8")
        );
        
        Request request = new Request.Builder()
            .url(baseUrl + "/translate")
            .post(body)
            .build();
        
        try (Response response = client.newCall(request).execute()) {
            String responseBody = response.body().string();
            
            if (!response.isSuccessful()) {
                JsonObject error = gson.fromJson(responseBody, JsonObject.class);
                throw new RuntimeException(error.get("error").getAsString());
            }
            
            return gson.fromJson(responseBody, TranslationResult.class);
        }
    }
    
    public static class TranslationResult {
        public String translatedText;
        public String source;
        public String target;
        public long duration;
    }
}
// Spring Boot RestTemplate
// implementation 'org.springframework.boot:spring-boot-starter-web'

import org.springframework.web.client.RestTemplate;
import org.springframework.http.*;
import java.util.Map;

public class TranslatorClient {
    private final RestTemplate restTemplate = new RestTemplate();
    private final String baseUrl;
    
    public TranslatorClient(String baseUrl) {
        this.baseUrl = baseUrl;
    }
    
    public TranslationResult translate(String text, String source, String target) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        
        Map body = Map.of(
            "text", text,
            "source", source,
            "target", target
        );
        
        HttpEntity> request = new HttpEntity<>(body, headers);
        
        try {
            ResponseEntity response = restTemplate.postForEntity(
                baseUrl + "/translate", request, TranslationResult.class);
            
            if (!response.getStatusCode().is2xxSuccessful()) {
                throw new RuntimeException("Erreur HTTP: " + response.getStatusCode());
            }
            
            return response.getBody();
        } catch (Exception e) {
            throw new RuntimeException("Erreur traduction: " + e.getMessage());
        }
    }
    
    public static class TranslationResult {
        private String translatedText;
        private String source;
        private String target;
        private long duration;
        
        // Getters/Setters
        public String getTranslatedText() { return translatedText; }
        public void setTranslatedText(String translatedText) { this.translatedText = translatedText; }
        public String getSource() { return source; }
        public void setSource(String source) { this.source = source; }
        public String getTarget() { return target; }
        public void setTarget(String target) { this.target = target; }
        public long getDuration() { return duration; }
        public void setDuration(long duration) { this.duration = duration; }
    }
}

🌐 cURL / Ligne de commande

Traduction simple

curl -X POST https://VOTRE_HOTE:7860/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Bonjour le monde", "source": "fr", "target": "en"}'

Avec détection automatique

curl -X POST https://VOTRE_HOTE:7860/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "target": "fr"}'

Script bash réutilisable

#!/bin/bash
# translate.sh - Script de traduction en ligne de commande

BASE_URL="https://VOTRE_HOTE:7860"
SOURCE="auto"
TARGET="fr"

usage() {
    echo "Usage: $0 [-s source] [-t target] \"texte à traduire\""
    echo "  -s  Langue source (défaut: auto)"
    echo "  -t  Langue cible (défaut: fr)"
    exit 1
}

while getopts "s:t:h" opt; do
    case $opt in
        s) SOURCE="$OPTARG" ;;
        t) TARGET="$OPTARG" ;;
        h) usage ;;
        *) usage ;;
    esac
done
shift $((OPTIND-1))

TEXT="$*"
if [ -z "$TEXT" ]; then
    usage
fi

response=$(curl -s -X POST "$BASE_URL/translate" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg text "$TEXT" --arg src "$SOURCE" --arg tgt "$TARGET" \
    '{text: $text, source: $src, target: $tgt}')")

# Extraire le texte traduit (nécessite jq)
translated=$(echo "$response" | jq -r '.translatedText // .error // "Erreur"')
echo "$translated"

Test de charge simple

# Tester le rate limit (30 req/min)
for i in {1..35}; do
  curl -s -X POST https://VOTRE_HOTE:7860/translate \
    -H "Content-Type: application/json" \
    -d "{\"text\": \"Test $i\", \"target\": \"en\"}" \
    -w " HTTP %{http_code}\\n" \
    -o /dev/null
  sleep 1
done

⚙️ Limites et bonnes pratiques

📋 Limites actuelles

LimiteValeurDescription
Rate limit30 req/min/IPBloque avec HTTP 429 si dépassé
Taille max texte5000 caractèresErreur 400 si dépassé
Timeout30 secondesCôté serveur et client recommandé
Langues100+Codes ISO 639-1

Gestion du rate limit (HTTP 429)

async function translateWithRetry(text, source, target, retries = 3) {
  for (let attempt = 0; attempt <= retries; attempt++) {
    const response = await fetch('/translate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text, source, target })
    });
    
    if (response.status === 429) {
      const waitTime = Math.min(1000 * Math.pow(2, attempt), 30000);
      console.log(`Rate limit, attente ${waitTime}ms...`);
      await new Promise(r => setTimeout(r, waitTime));
      continue;
    }
    
    if (!response.ok) {
      const err = await response.json();
      throw new Error(err.error);
    }
    
    return response.json();
  }
  throw new Error('Max retries exceeded');
}

Bonnes pratiques

Codes d'erreur HTTP

CodeSignificationAction
200Succès-
400Requête invalideVérifiez le JSON et la taille du texte
429Trop de requêtesAttendez et réessayez (backoff)
500Erreur serveurRéessayez plus tard, contactez admin si persiste