Skip to main content

Unified translation and speech API for 30+ African languages

Project description

fasiri

Fasiri (Swahili: to interpret) - Unified translation and speech API for 30+ African languages.

The official Python SDK for the Fasiri African Language API.

PyPI Python License


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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fasiri-1.1.0.tar.gz (18.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fasiri-1.1.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file fasiri-1.1.0.tar.gz.

File metadata

  • Download URL: fasiri-1.1.0.tar.gz
  • Upload date:
  • Size: 18.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for fasiri-1.1.0.tar.gz
Algorithm Hash digest
SHA256 cd86d478db82dd64bdfc66ad904a70ffdb568945c40e42fe5206b2b0b5861191
MD5 92e8080c413910f49458f375b45cbc4e
BLAKE2b-256 69aa13789978f354b66af90e4cf619d4132726b67da17e172a20f5226efc0ea2

See more details on using hashes here.

File details

Details for the file fasiri-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: fasiri-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for fasiri-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a649ab70ece91afc88a4df62cdfc6e6e53fdba5b18c280ac85e0a7f133dd50f7
MD5 7224b97f3c6a2452a9027df63429ae11
BLAKE2b-256 3c62f75df42e93740f700556f5f8c9b4c21de9a6c73a7bd6a52f9ace9768e8a8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page