File size: 10,174 Bytes
4de4dfd
b8ae72a
 
4de4dfd
 
 
b8ae72a
4de4dfd
 
b8ae72a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
---
title: Translator-API
emoji: 💻
colorFrom: purple
colorTo: gray
sdk: docker
pinned: true
---

# 🌐 Translator API

> **Alternative gratuite à Google Translate** — API REST sans clé, auto-hébergée, avec dashboard admin temps réel.

[![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
[![Docker](https://img.shields.io/badge/Docker-ready-blue.svg)](https://docker.com/)
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

---

## ✨ Fonctionnalités

| Fonctionnalité | Description |
|---|---|
| 🆓 **Gratuit & Sans clé API** | Pas d'inscription, pas de quota mensuel |
| ⚡ **Rate limiting** | 30 requêtes/minute par IP |
| 🌍 **100+ langues** | Support complet ISO 639-1 + détection auto |
| 📊 **Dashboard Admin** | Métriques CPU/RAM temps réel, logs, graphiques 120s |
| ⚖️ **Architecture distribuée** | Central (API + 1 core) + Workers (1 core) |
| 🔐 **Auth admin sécurisée** | Code d'accès via variables d'environnement |
| 🐳 **Docker ready** | Déploiement 1-click sur HuggingFace Spaces |
| 📚 **Wiki intégré** | Exemples JS, Python, Java, cURL |

---

## 🚀 Démarrage rapide

### Option 1 : Docker Compose (Recommandé)

```bash
# 1. Cloner le repo
git clone https://github.com/NathMen12/Translator-API.git
cd Translator-API

# 2. Configurer les secrets
cp .env.example .env
# Éditer .env avec votre ADMIN_ACCESS_CODE

# 3. Lancer
docker-compose up -d

# 4. Accéder à l'API
curl -X POST http://localhost:7820/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Bonjour le monde", "source": "fr", "target": "en"}'
```

### Option 2 : Développement local

```bash
# Installer les dépendances
npm install

# Lancer le central (terminal 1)
npm run dev:central

# Lancer le worker (terminal 2)
npm run dev:worker

# Test
curl -X POST http://localhost:7820/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello", "target": "fr"}'
```

---

## 🌐 Déploiement sur HuggingFace Spaces

1. **Fork ce repo** sur votre GitHub
2. **Créez un Space** sur [huggingface.co/new-space](https://huggingface.co/new-space)
   - SDK: **Docker**
   - Hardware: **CPU Basic (2 vCPU, 16 GB RAM)**   - Visibility: Public ou Private
3. **Ajoutez les Secrets** dans Settings → Repository secrets :
   - `ADMIN_ACCESS_CODE` = votre mot de passe admin fort
   - `TAILSCALE_API_KEY` = (optionnel) pour découverte workers
4. **Push** → Le Space build et déploie automatiquement !

> ⚠️ Le port **7820** est exposé. HuggingFace Spaces mappe automatiquement sur le port 7860 en externe.

---

## 📖 Utilisation de l'API

### Endpoint principal

```
POST /translate
Content-Type: application/json

{
  "text": "Bonjour le monde",
  "source": "fr",     // optionnel, défaut: "auto"
  "target": "en"      // optionnel, défaut: "fr"
}
```

### Réponse

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

### Codes d'erreur

| Code | Signification |
|------|--------------|
| 200 | Succès |
| 400 | Requête invalide (texte manquant, trop long >5000 chars) |
| 429 | Rate limit dépassé (30 req/min/IP) |
| 500 | Erreur serveur |

---

## 💻 Exemples d'intégration

### JavaScript / TypeScript

```javascript
// Fetch API (navigateur / Node 18+)
async function translate(text, source = 'auto', target = 'fr') {
  const res = await fetch('https://VOTRE_SPACE.hf.space/translate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text, source, target })
  });
  
  if (!res.ok) throw new Error((await res.json()).error);
  return res.json();
}

// Utilisation
translate('Bonjour', 'fr', 'es').then(r => console.log(r.translatedText)); // "Hola"
```

### Python

```python
import requests

def translate(text, source='auto', target='fr', base_url='https://VOTRE_SPACE.hf.space'):
    resp = requests.post(f'{base_url}/translate', 
        json={'text': text, 'source': source, 'target': target}, timeout=30)
    resp.raise_for_status()
    return resp.json()

# Usage
print(translate('Hello world', 'en', 'fr')['translatedText'])  # "Bonjour le monde"
```

### Java (HttpClient 11+)

```java
var client = HttpClient.newHttpClient();
var body = "{\"text\":\"Bonjour\",\"source\":\"fr\",\"target\":\"en\"}";
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://VOTRE_SPACE.hf.space/translate"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());
// Parse JSON pour obtenir translatedText
```

### cURL

```bash
curl -X POST https://VOTRE_SPACE.hf.space/translate \
  -H "Content-Type: application/json" \
  -d '{"text": "Bonjour", "source": "fr", "target": "en"}'
```

> 📖 **Plus d'exemples** : Visitez `/wiki` sur votre instance déployée !

---

## 🔐 Panel Admin

Accédez à `https://VOTRE_SPACE.hf.space/admin` et entrez votre `ADMIN_ACCESS_CODE`.

### Onglets disponibles :

| Onglet | Contenu |
|--------|---------|
| 🖥️ **Machines** | CPU/RAM temps réel (central + workers), jobs actifs |
| 📈 **Requêtes (120s)** | Graphique requêtes/minute, stats, taux actuel |
| 📋 **Logs** | Dernières traductions : IP, durée, langues, entrée/sortie |

---

## ⚙️ Configuration

### Central (`central/settings.json`)

```json
{
  "port": 7820,
  "rateLimit": { "maxRequestsPerMinutePerIP": 30, "windowMs": 60000 },
  "scanLocalWorkers": true,
  "metricsWindowSeconds": 120,
  "maxLocalJobs": 4
}
```

### Worker (`worker/settings.json`)

```json
{
  "maxConcurrentJobs": 2,
  "centralHost": "localhost",
  "centralPort": 7820
}
```

### Variables d'environnement (Secrets)

| Variable | Requis | Description |
|----------|--------|-------------|
| `ADMIN_ACCESS_CODE` | ✅ | Mot de passe admin (fort !) |
| `TAILSCALE_API_KEY` | ❌ | Clé API Tailscale pour auto-découverte workers |
| `PORT` | ❌ | Port d'écoute (défaut: 7820) |

---

## 🏗️ Architecture

```
┌─────────────────────────────────────────────────────┐
│                   HUGGINGFACE SPACE                  │
│  ┌─────────────────────┐    ┌────────────────────┐  │
│  │     CENTRAL         │    │      WORKER        │  │
│  │  (1.5 CPU / 12GB)   │◄───│  (0.5 CPU / 4GB)   │  │
│  │  • Express API      │ WS │  • Translation     │  │
│  │  • Rate Limiting    │    │  • Job Queue       │  │
│  │  • Job Dispatch     │    │  • Metrics Push    │  │
│  │  • Admin Dashboard  │    │                    │  │
│  │  • Metrics Storage  │    │                    │  │
│  └─────────────────────┘    └────────────────────┘  │
└─────────────────────────────────────────────────────┘
```

- **Central** : Gère l'API HTTP, rate limiting, dispatch vers workers, dashboard
- **Worker** : Se connecte en WebSocket, exécute les traductions, pousse métriques
- **Communication** : WebSocket natif (ws) pour faible latence

---

## 📦 Structure du projet

```
Translator-API/
├── central/                 # Machine centrale
│   ├── src/index.js        # Serveur Express + WS + Admin
│   ├── settings.json       # Config centrale
│   ├── public/             # Frontend statique
│   │   ├── index.html      # Page d'accueil + test
│   │   ├── admin.html      # Dashboard admin (Chart.js)
│   │   └── wiki.html       # Documentation intégrée
│   └── secrets/            # .env (ignoré par git)
├── worker/                  # Worker de traduction
│   ├── src/index.js        # Client WS + file d'attente
│   └── settings.json       # Config worker
├── shared/                  # Code partagé (futur)
├── wiki/                    # Docs markdown (source)
├── Dockerfile              # Multi-stage build
├── docker-compose.yml      # Orchestration locale
├── .env.example            # Template secrets
└── package.json            # Dépendances root
```

---

## 🛠️ Développement

```bash
# Installer tout
npm run install:all

# Central en mode watch
npm run dev:central

# Worker en mode watch  
npm run dev:worker

# Tests
npm test
```

### Logs

- Central : `central/logs/central.log`
- Worker : `worker/logs/worker.log`

---

## 🔒 Sécurité

- **Pas de clé API publique** — Protection par rate limiting IP
- **Admin protégé** — Code fort dans variable d'environnement (pas dans le code)
- **Secrets HF Spaces** — Stockés chiffrés, injectés au runtime
- **Non-root Docker** — User `nodejs` (UID 1001)
- **Helmet/CORS** — Configurables selon besoins

---

## 📝 Licence

MIT License — Voir [LICENSE](LICENSE)

---

## 🤝 Contribution

1. Fork le projet
2. Créez une branche (`git checkout -b feature/amazing`)
3. Committez (`git commit -m 'Add amazing feature'`)
4. Push (`git push origin feature/amazing`)
5. Ouvrez une Pull Request

---

## 🙏 Remerciements

- [@vitalets/google-translate-api](https://github.com/vitalets/google-translate-api) — Moteur de traduction
- [Chart.js](https://www.chartjs.org/) — Graphiques admin
- [HuggingFace Spaces](https://huggingface.co/spaces) — Hébergement gratuit

---

<div align="center">
  <strong>Fait avec ❤️ par <a href="https://github.com/NathMen12">NathMen12</a></strong>
  <br>
  <a href="https://github.com/NathMen12/Translator-API">⭐ Star sur GitHub</a><a href="https://github.com/NathMen12/Translator-API/issues">🐛 Signaler un bug</a><a href="https://github.com/NathMen12/Translator-API/discussions">💬 Discussions</a>
</div>