Compare every Python translation library and API: googletrans, deep-translator, and SocketsIO. With real code, batch translation, async support, and honest cost analysis.
Python developers have several options for adding translation to their apps. The choice isn't obvious — some libraries are free but unreliable, others are reliable but expensive, and a few hit the sweet spot. This guide covers every major option with working code examples.
googletrans is a Python wrapper that scrapes Google Translate's internal API. It's popular because it's free — but it comes with serious caveats.
pip install googletrans==4.0.0rc1
from googletrans import Translator
translator = Translator()
result = translator.translate("Hello world", dest="ja")
print(result.text) # → ハローワールド
🚫 Do not use googletrans in production. It reverse-engineers Google's internal API (not the official v2 API), gets rate-limited aggressively, breaks with every Google update, and has no SLA. It's fine for personal scripts but will fail in production apps.
Common issues with googletrans:
AttributeError: 'NoneType' object has no attribute 'group' — breaks randomlydeep-translator is a more robust library that supports multiple translation backends including Google, DeepL, Microsoft, and others.
pip install deep-translator
from deep_translator import GoogleTranslator, DeepL, MicrosoftTranslator
# Google backend (unofficial, same caveats as googletrans)
result = GoogleTranslator(source="en", target="ja").translate("Hello world")
# DeepL backend (requires API key)
result = DeepL(api_key="YOUR_DEEPL_KEY", source="en", target="ja").translate("Hello world")
# Batch translation
texts = ["Hello", "Goodbye", "Thank you"]
results = GoogleTranslator(source="en", target="ja").translate_batch(texts)
deep-translator is better than googletrans for multi-backend support, but the free Google backend has the same reliability issues. For production, you'll need a paid backend (DeepL or Microsoft), which brings us back to cost.
The official Google Cloud Translation API is reliable and high-quality — but expensive.
pip install google-cloud-translate
from google.cloud import translate_v2 as translate
client = translate.Client()
# Translate text
result = client.translate("Hello world", target_language="ja")
print(result["translatedText"]) # → ハローワールド
# Detect language
detection = client.detect_language("こんにちは")
print(detection["language"]) # → ja
Requires a Google Cloud project, service account JSON, and billing enabled. At $20/million characters, costs add up fast.
SocketsIO provides a Python SDK with the same quality as Google Translate v2 at $0.50/million characters — 40× cheaper. 500K chars/month free, no credit card required.
pip install socketsio
import socketsio
client = socketsio.Client(api_key="YOUR_API_KEY")
# Simple translation
result = client.translate("Hello world", target="ja")
print(result.text) # → ハローワールド
# With source language specified
result = client.translate("Bonjour monde", source="fr", target="en")
print(result.text) # → Hello world
# Detect language
detection = client.detect("こんにちは")
print(detection.language) # → ja
print(detection.confidence) # → 0.99
import socketsio
client = socketsio.Client(api_key="YOUR_API_KEY")
# Translate a list of strings in one request
texts = [
"Add to cart",
"Checkout",
"Order confirmed",
"Track shipment",
"Contact support"
]
results = client.translate_batch(texts, target="ja")
for original, result in zip(texts, results):
print(f"{original:20} → {result.text}")
Output:
Add to cart → カートに追加
Checkout → チェックアウト
Order confirmed → 注文確認済み
Track shipment → 配送追跡
Contact support → サポートに連絡
import requests
API_KEY = "demo-key-socketsio-2026" # Replace with your key
def translate(text, target, source="auto"):
resp = requests.post(
"https://api.socketsio.com/translate",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"q": text, "source": source, "target": target}
)
resp.raise_for_status()
return resp.json()["data"]["translations"][0]["translatedText"]
print(translate("Hello world", "ja")) # → ハローワールド
print(translate("Hello world", "es")) # → Hola mundo
print(translate("Hello world", "zh")) # → 你好世界
| Library / API | Free Tier | Cost (1M chars) | Production Ready | Async | Credit Card |
|---|---|---|---|---|---|
| googletrans | Unlimited* | $0 | ❌ No | Partial | No |
| deep-translator (Google) | Limited* | $0 | ❌ No | No | No |
| Google Cloud Translate | 500K chars | $20 | ✅ Yes | Yes | Yes |
| DeepL API | 500K chars | $25 | ✅ Yes | Yes | Yes |
| Microsoft Azure Translator | 2M chars | $10 | ✅ Yes | Yes | Yes |
| SocketsIO | 500K chars | $0.50 | ✅ Yes | Yes | No |
* Unofficial APIs scrape Google's internal endpoints and are rate-limited without warning.
For high-throughput applications, use async HTTP to translate multiple texts concurrently:
import asyncio
import aiohttp
API_KEY = "YOUR_API_KEY"
async def translate_async(session, text, target):
async with session.post(
"https://api.socketsio.com/translate",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"q": text, "source": "auto", "target": target}
) as resp:
data = await resp.json()
return data["data"]["translations"][0]["translatedText"]
async def translate_many(texts, target):
async with aiohttp.ClientSession() as session:
tasks = [translate_async(session, t, target) for t in texts]
return await asyncio.gather(*tasks)
# Translate 100 strings concurrently
texts = [f"Product description {i}" for i in range(100)]
results = asyncio.run(translate_many(texts, "ja"))
print(f"Translated {len(results)} strings")
For translating large files (product catalogs, documentation), process in chunks:
import requests
import json
import time
API_KEY = "YOUR_API_KEY"
CHUNK_SIZE = 50 # Strings per request
def translate_dataset(texts, target_lang):
"""Translate a large list of strings with chunking and rate limit handling."""
results = []
for i in range(0, len(texts), CHUNK_SIZE):
chunk = texts[i:i + CHUNK_SIZE]
try:
resp = requests.post(
"https://api.socketsio.com/translate",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"q": chunk, "source": "en", "target": target_lang},
timeout=30
)
if resp.status_code == 429:
# Rate limited — wait and retry
retry_after = int(resp.headers.get("Retry-After", 5))
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
resp = requests.post(...) # Retry
resp.raise_for_status()
translations = resp.json()["data"]["translations"]
results.extend([t["translatedText"] for t in translations])
print(f"Progress: {min(i + CHUNK_SIZE, len(texts))}/{len(texts)}")
except requests.RequestException as e:
print(f"Error on chunk {i}: {e}")
results.extend(["[ERROR]"] * len(chunk))
return results
# Example: translate a product catalog
with open("products_en.json") as f:
products = json.load(f)
descriptions = [p["description"] for p in products]
translated = translate_dataset(descriptions, "ja")
for product, translation in zip(products, translated):
product["description_ja"] = translation
with open("products_ja.json", "w", encoding="utf-8") as f:
json.dump(products, f, ensure_ascii=False, indent=2)
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import logging
logger = logging.getLogger(__name__)
class TranslationClient:
def __init__(self, api_key):
self.api_key = api_key
self.session = requests.Session()
# Auto-retry on transient errors
retry = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["POST"]
)
self.session.mount("https://", HTTPAdapter(max_retries=retry))
def translate(self, text, target, source="auto"):
try:
resp = self.session.post(
"https://api.socketsio.com/translate",
headers={"Authorization": f"Bearer {self.api_key}"},
json={"q": text, "source": source, "target": target},
timeout=15
)
resp.raise_for_status()
return resp.json()["data"]["translations"][0]["translatedText"]
except requests.exceptions.Timeout:
logger.error(f"Translation timeout for text: {text[:50]}...")
raise
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
raise ValueError("Invalid API key") from e
elif e.response.status_code == 400:
raise ValueError(f"Bad request: {e.response.json()}") from e
raise
except requests.exceptions.ConnectionError:
logger.error("Failed to connect to translation API")
raise
# Usage
client = TranslationClient("YOUR_API_KEY")
try:
result = client.translate("Hello world", "ja")
print(result)
except ValueError as e:
print(f"Configuration error: {e}")
except Exception as e:
print(f"Translation failed: {e}")
If you're currently using googletrans, here's a drop-in replacement:
# Before (googletrans — unreliable)
from googletrans import Translator
translator = Translator()
result = translator.translate(text, dest=target_lang)
translated = result.text
# After (SocketsIO — production-ready, 500K free/month)
import requests
def translate(text, dest, src="auto"):
resp = requests.post(
"https://api.socketsio.com/translate",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"q": text, "source": src, "target": dest}
)
return resp.json()["data"]["translations"][0]["translatedText"]
translated = translate(text, target_lang)
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
SOCKETSIO_KEY = "YOUR_API_KEY"
@app.route("/api/translate", methods=["POST"])
def translate_endpoint():
data = request.json
text = data.get("text", "")
target = data.get("target", "en")
if not text:
return jsonify({"error": "text required"}), 400
resp = requests.post(
"https://api.socketsio.com/translate",
headers={"Authorization": f"Bearer {SOCKETSIO_KEY}"},
json={"q": text, "source": "auto", "target": target}
)
if resp.ok:
translated = resp.json()["data"]["translations"][0]["translatedText"]
return jsonify({"translated": translated, "target": target})
return jsonify({"error": "Translation failed"}), 500
500,000 characters/month free. No credit card. Production-ready with 99.9% uptime SLA.
Get Your Free API Key →Or test instantly in the API Playground — no signup needed
| Monthly Volume | googletrans | Google Cloud | DeepL | SocketsIO |
|---|---|---|---|---|
| 500K chars | $0 (unreliable) | $0 (CC required) | $0 (CC required) | $0 (no CC) |
| 5M chars | Blocked | $100 | $125 | $2.50 |
| 50M chars | Blocked | $1,000 | $1,250 | $25 |
| 500M chars | Blocked | $10,000 | $12,500 | $250 |