fasiri
Fasiri (Swahili: to interpret) - Unified translation and speech API for 30+ African languages.
The official Python SDK for the Fasiri African Language API.
Installation
pip install fasiri
Requires Python 3.9+.
Two modes of operation
Mode 1 - Fasiri Cloud
Use the hosted Fasiri API. Get a free key in seconds - no account required.
from fasiri import Fasiri
client = Fasiri(api_key="fsri_...")
result = client.translate("Good morning", target="lug")
print(result) # Wasuze otya
print(result.provider) # sunbird
Get your free key at fasiri-bu9u.onrender.com.
Mode 2 - Direct mode (bring your own keys)
Call providers directly with your own API keys. No Fasiri account needed. You handle your own provider billing. Fasiri is just the routing layer - like LangChain for OpenAI.
from fasiri import Fasiri
from fasiri.providers import SunbirdProvider, KhayaProvider, HuggingFaceProvider
client = Fasiri(
providers=[
SunbirdProvider(api_key="eyJ..."), # Sunbird JWT
KhayaProvider(api_key="your-khaya-key"), # Khaya subscription key
HuggingFaceProvider(api_key="hf_..."), # HuggingFace token
]
)
# Same interface as cloud mode
result = client.translate("Good morning", target="lug")
print(result) # Wasuze otya
print(result.provider) # sunbird
In direct mode, Fasiri automatically picks the best provider for each language pair and falls back if one fails. Requests go from your machine straight to the provider.
Getting provider keys
Sunbird AI (Ugandan languages)
Supports: Luganda, Acholi, Ateso, Runyankore, Lugbara
# 1. Register
curl -X POST https://api.sunbird.ai/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"you","email":"you@example.com","password":"yourpassword"}'
# 2. Get token (JWT starting with "ey...")
curl -X POST https://api.sunbird.ai/auth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=you@example.com&password=yourpassword"
from fasiri.providers import SunbirdProvider
provider = SunbirdProvider(api_key="eyJ...")
Khaya AI (West and East African languages)
Supports: Yoruba, Twi, Ewe, Ga, Dagbani, Kikuyu, Luo, Kimeru, Kusaal
Register at translation.ghananlp.org/signup.
from fasiri.providers import KhayaProvider
provider = KhayaProvider(api_key="your-subscription-key")
HuggingFace (Swahili, French, Arabic, Afrikaans)
Get a free token at huggingface.co/settings/tokens.
from fasiri.providers import HuggingFaceProvider
provider = HuggingFaceProvider(api_key="hf_...")
Supported Languages
| Code | Language | Region | Translate | STT | TTS | Provider |
|---|---|---|---|---|---|---|
lug |
Luganda | Uganda | Yes | Yes | Yes | Sunbird |
ach |
Acholi | Uganda | Yes | Yes | Yes | Sunbird |
teo |
Ateso | Uganda | Yes | Yes | Yes | Sunbird |
nyn |
Runyankore | Uganda | Yes | Yes | Yes | Sunbird |
lgg |
Lugbara | Uganda | Yes | Yes | Yes | Sunbird |
yo |
Yoruba | Nigeria | Yes | No | No | Khaya |
tw |
Twi | Ghana | Yes | No | No | Khaya |
ee |
Ewe | Ghana/Togo | Yes | No | No | Khaya |
gaa |
Ga | Ghana | Yes | No | No | Khaya |
dag |
Dagbani | Ghana | Yes | No | No | Khaya |
ki |
Kikuyu | Kenya | Yes | No | No | Khaya |
luo |
Luo | Kenya | Yes | No | No | Khaya |
mer |
Kimeru | Kenya | Yes | No | No | Khaya |
kus |
Kusaal | Ghana | Yes | No | No | Khaya |
sw |
Swahili | East Africa | Yes | Yes | No | HuggingFace |
fr |
French | Francophone | Yes | No | No | HuggingFace |
ar |
Arabic | North Africa | Yes | No | No | HuggingFace |
af |
Afrikaans | South Africa | Yes | No | No | HuggingFace |
Translation
Single translation
result = client.translate(
text="Good morning, how are you?",
target="lug",
source="en", # optional - auto-detected if omitted
provider="auto", # cloud mode only
)
print(result.translated_text) # "Wasuze otya, oli otya?"
print(result.provider) # "sunbird"
print(result.model_used) # "sunbird/translate"
print(result.quality_score) # 0.92
print(result.latency_ms) # 1823
print(result.characters_translated) # 26
Batch translation
results = client.translate_batch([
{"id": "1", "text": "Good morning", "target": "lug"},
{"id": "2", "text": "How are you?", "target": "yo"},
{"id": "3", "text": "Thank you", "target": "tw"},
])
print(f"{results.succeeded}/{results.total} succeeded")
for item in results.successful():
print(f"[{item.id}] {item.translated_text} (via {item.provider})")
for item in results.errors():
print(f"[{item.id}] FAILED: {item.error}")
Speech
Speech-to-Text
# From a file path
result = client.transcribe("meeting.wav", language="lug")
print(result.transcript)
# From bytes
with open("audio.mp3", "rb") as f:
result = client.transcribe(f.read(), language="ach")
print(result.transcript)
Text-to-Speech
result = client.synthesise("Oli otya?", language="lug")
print(result.audio_url)
Async usage
All methods have async equivalents:
import asyncio
from fasiri import Fasiri
from fasiri.providers import SunbirdProvider, KhayaProvider
# Works in both cloud and direct mode
async def main():
# Cloud mode
async with Fasiri(api_key="fsri_...") as client:
result = await client.async_translate("Hello", target="lug")
print(result)
# Direct mode
client = Fasiri(providers=[
SunbirdProvider(api_key="eyJ..."),
KhayaProvider(api_key="your-key"),
])
# Batch runs concurrently in direct mode
results = await client.async_translate_batch([
{"id": "1", "text": "Hello", "target": "lug"},
{"id": "2", "text": "Thank you", "target": "yo"},
])
print(f"{results.succeeded}/{results.total} succeeded")
asyncio.run(main())
Using individual providers
You can use providers directly without the Fasiri client:
from fasiri.providers import SunbirdProvider
provider = SunbirdProvider(api_key="eyJ...")
# Translate
result = provider.translate("Good morning", target_lang="lug")
print(result) # Wasuze otya
# STT
with open("audio.wav", "rb") as f:
stt = provider.speech_to_text(f.read(), language="lug")
print(stt.transcript)
# TTS
tts = provider.text_to_speech("Oli otya?", language="lug")
print(tts.audio_url)
Error handling
from fasiri import (
Fasiri,
AuthenticationError,
RateLimitError,
UnsupportedLanguageError,
ProviderError,
FasiriError,
)
try:
result = client.translate("Hello", target="lug")
except AuthenticationError as e:
print(f"Invalid API key: {e}")
except RateLimitError as e:
import time
time.sleep(e.retry_after)
except UnsupportedLanguageError as e:
print(f"Language not supported: {e}")
except ProviderError as e:
print(f"All providers failed: {e}")
except FasiriError as e:
print(f"Error [{e.code}]: {e}")
Changelog
v1.1.0
- Added direct mode - call providers with your own keys
- Added
SunbirdProvider,KhayaProvider,HuggingFaceProvider - Async batch in direct mode runs concurrently
- Same interface for both cloud and direct modes
v1.0.0
- Initial release
- Cloud mode with Fasiri hosted API
- Translation, STT, TTS
- Sync and async client
License
MIT - Beta-Tech Labs
Metadata
Release files for fasiri 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fasiri-1.1.0.tar.gz | 18.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fasiri-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.9 kB
Release files / fasiri-1.1.0.tar.gz
| Download URL | fasiri-1.1.0.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cd86d478db82dd64bdfc66ad904a70ffdb568945c40e42fe5206b2b0b5861191
|
|
BLAKE2b-256 checksum How to use checksums |
69aa13789978f354b66af90e4cf619d4132726b67da17e172a20f5226efc0ea2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / fasiri-1.1.0-py3-none-any.whl
| Download URL | fasiri-1.1.0-py3-none-any.whl |
|---|---|
| Size | 22.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a649ab70ece91afc88a4df62cdfc6e6e53fdba5b18c280ac85e0a7f133dd50f7
|
|
BLAKE2b-256 checksum How to use checksums |
3c62f75df42e93740f700556f5f8c9b4c21de9a6c73a7bd6a52f9ace9768e8a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|