Skip to main content

Djelia Python SDK - Advanced AI for African Languages

Project description

Djelia Python SDK Workshop

Hey there! Welcome to this fun and practical workshop on using the Djelia Python SDK. Whether you're translating between African languages, transcribing audio with realtime streaming, or generating natural sounding speech, this guide has got you covered. We'll walk through installing the SDK, setting up clients, and performing some cool operations like multi language translation, audio transcription, and text-to-speech generation. I've added a sprinkle of humor to keep things light because who said coding can't be fun, right? Let's dive in!

Table of Contents

  1. Installation
  2. Client Initialization
  3. Operations
  4. Error Handling
  5. Explore the Djelia SDK Cookbook

Installation

Let's kick things off by installing the Djelia Python SDK with one of those magical commands. Run it in your terminal, and you're good to go!

    pip install djelia

Install the Djelia Python SDK directly from GitHub:

    pip install git+https://github.com/djelia-org/djelia-python-sdk.git

Alternatively, use uv for faster dependency resolution:

    uv pip install djelia
    uv pip install git+https://github.com/djelia-org/djelia-python-sdk.git

Client Initialization

Before we can do anything fancy, we need to set up our clients. This involves loading our API key and initializing both synchronous and asynchronous clients. Here's how:

API Key Loading

First, grab your API key from a .env file it's the safest way to keep your secrets, well, secret! If you don't have one yet, head to the Djelia dashboard and conjure one up.

from dotenv import load_dotenv
import os

load_dotenv()
api_key = os.environ.get("DJELIA_API_KEY")

# Alternatively: api_key = "your_api_key_here" (but shh, that's not safe!)

# Specify your audio file for transcription tests
audio_file_path = os.environ.get("TEST_AUDIO_FILE", "audio.wav")

Note: Ensure your audio file (e.g., audio.wav) exists at the specified path. Set TEST_AUDIO_FILE in your .env file if using a custom path:

echo "TEST_AUDIO_FILE=/path/to/your/audio.wav" >> .env

Without a valid audio file, transcription operations will fail. That not what you want right 😂

Synchronous Client

For those who like to take things one step at a time, here's how to set up the synchronous client:

from djelia import Djelia

djelia_client = Djelia(api_key=api_key)

# if DJELIA_API_KEY is already set you can just do : (yes I know I'm making your life easy 😂)
djelia_client = Djelia()

Asynchronous Client

If you're ready to live on the async edge, initialize the asynchronous client like this:

from djelia import DjeliaAsync

djelia_async_client = DjeliaAsync(api_key=api_key)

# if DJELIA_API_KEY is already set you can just do : (again easy life 😂)

djelia_async_client = DjeliaAsync()

Operations 🇲🇱

Now for the fun part let's do stuff with the Djelia API! We'll cover translating between African languages, transcribing audio (with streaming!), and generating natural speech, with examples for both synchronous and asynchronous approaches. Yes, yes, let's do it ❤️‍🔥!

Translation

Let's unlock the power of multilingual communication!

Get Supported Languages

First, let's see what languages we can work with.

Synchronous

Simple and straightforward get your supported languages and print them:

supported_languages = djelia_client.translations.list_languages()
for lang in supported_languages:
    print(f"{lang.name}: {lang.code}")

Asynchronous

For the async fans, here's how to fetch supported languages. Don't forget to run it with asyncio:

import asyncio

async def get_languages_test():
    async with djelia_async_client as client:
        supported_languages = await client.translations.list_languages()
        for lang in supported_languages:
            print(f"{lang.name}: {lang.code}")

asyncio.run(get_languages_test())

Translate Text

Let's translate some text between beautiful 🇲🇱 languages and others. Feel free to try different language combinations!

With the OpenAI-style API you pass the fields straight to .create() — no need to build a request object:

from djelia.models import Language, Versions

text = "Hello, how are you today?"

Synchronous

Create that translation and see what you get:

from djelia.models import TranslationResponse

try:
    response_sync: TranslationResponse = djelia_client.translations.create(
        text=text,
        source=Language.ENGLISH,
        target=Language.BAMBARA,
        model=Versions.v1,
    )
    print(f"Original: {text}")
    print(f"Translation: {response_sync.text}")
except Exception as e:
    print(f"Translation error: {e}")

Asynchronous

Async translation because why wait around? Let's do it bro !

async def translate_async():
    async with djelia_async_client as client:
        try:
            response_async: TranslationResponse = await client.translations.create(
                text=text,
                source=Language.ENGLISH,
                target=Language.BAMBARA,
                model=Versions.v1,
            )
            print(f"Original: {text}")
            print(f"Translation: {response_async.text}")
            return response_async
        except Exception as e:
            print(f"Translation error: {e}")

asyncio.run(translate_async())

Transcription

Time to turn audio into text with timestamps and everything!

Basic Transcription

Let's transcribe some audio files. Make sure you have an audio file ready check audio_file_path.

Synchronous

from djelia.models import Versions

try:
    transcription = djelia_client.audio.transcriptions.create(
        file=audio_file_path,
        model=Versions.v2
    )
    print(f"Transcribed {len(transcription)} segments:")
    for segment in transcription:
        print(f"[{segment.start:.2f}s - {segment.end:.2f}s]: {segment.text}")
except Exception as e:
    print(f"Transcription error: {e}")

Asynchronous

For the async enthusiasts: (like me, I ❤️ it)

async def transcribe_async():
    async with djelia_async_client as client:
        try:
            transcription = await client.audio.transcriptions.create(
                file=audio_file_path,
                model=Versions.v2
            )
            print(f"Transcribed {len(transcription)} segments:")
            for segment in transcription:
                print(f"[{segment.start:.2f}s - {segment.end:.2f}s]: {segment.text}")
        except Exception as e:
            print(f"Transcription error: {e}")

asyncio.run(transcribe_async())

Streaming Transcription

Want realtime results? Let's stream that transcription! This is really important of live applications

Synchronous

print("Streaming transcription (showing first 3 segments)...")
segment_count = 0

try:
    for segment in djelia_client.audio.transcriptions.create(
        file=audio_file_path,
        stream=True,
        model=Versions.v2
    ):
        segment_count += 1
        print(f"Segment {segment_count}: [{segment.start:.2f}s]: {segment.text}")
        
        if segment_count >= 3:  # Just showing first 3 for demo
            print("...and more segments!")
            break
except Exception as e:
    print(f"Streaming transcription error: {e}")

Asynchronous

Async streaming because realtime is awesome: (bro, I'm telling you, one second is a lot)

async def stream_transcribe_async():
    async with djelia_async_client as client:
        try:
            stream = await client.audio.transcriptions.create(
                file=audio_file_path,
                stream=True,
                model=Versions.v2
            )
            segment_count = 0
            async for segment in stream:
                segment_count += 1
                print(f"Segment {segment_count}: [{segment.start:.2f}s]: {segment.text}")
                
                if segment_count >= 3:  # Just showing first 3 for demo
                    print("...and more segments!")
                    break
        except Exception as e:
            print(f"Streaming transcription error: {e}")

asyncio.run(stream_transcribe_async())

French Translation

Want to transcribe and translate to French in one go? We've got you covered!

Synchronous

try:
    french_transcription = djelia_client.audio.transcriptions.create(
        file=audio_file_path,
        translate_to_french=True,
        model=Versions.v2
    )
    print(f"French translation: {french_transcription.text}")
except Exception as e:
    print(f"French transcription error: {e}")

Asynchronous

async def transcribe_french_async():
    async with djelia_async_client as client:
        try:
            french_transcription = await client.audio.transcriptions.create(
                file=audio_file_path,
                translate_to_french=True,
                model=Versions.v2
            )
            print(f"French translation: {french_transcription.text}")
        except Exception as e:
            print(f"French transcription error: {e}")

asyncio.run(transcribe_french_async())

Text-to-Speech (TTS)

Let's make some beautiful voices! Choose between numbered speakers or describe exactly how you want it to sound.

TTS v1 with Speaker ID

Classic approach with speaker IDs (0-4). Simple and effective!

bambara_text = "Aw ni ce, i ka kɛnɛ wa?"  # "Hello, how are you?" in Bambara

Synchronous

Generate that audio and save it:

try:
    audio_file_v1 = djelia_client.audio.speech.create(
        input=bambara_text,
        voice=1,  # Choose from 0, 1, 2, 3, or 4
        output_file="hello_v1.wav",
        model=Versions.v1
    )
    print(f"Audio saved to: {audio_file_v1}")
except Exception as e:
    print(f"TTS v1 error: {e}")

Asynchronous

Async audio generation:

async def generate_audio_v1_async():
    async with djelia_async_client as client:
        try:
            audio_file_v1 = await client.audio.speech.create(
                input=bambara_text,
                voice=1,
                output_file="hello_v1_async.wav",
                model=Versions.v1
            )
            print(f"Audio saved to: {audio_file_v1}")
        except Exception as e:
            print(f"TTS v1 error: {e}")

asyncio.run(generate_audio_v1_async())

TTS v2 with Natural Descriptions

This is where it gets fun! Describe exactly how you want the voice to sound, but make sure to include one of the supported speakers: Moussa, Sekou, or Seydou.

For v2 you pass a natural-language description (which must name a supported speaker) instead of a numeric voice:

v2_description = "Seydou speaks with a warm, welcoming tone"  # Must include Moussa, Sekou, or Seydou

Note: The description field must include one of the supported speakers. For example, "Moussa speaks with a warm tone" is valid, but "Natural tone" will raise an error.

Synchronous

Create natural sounding speech:

try:
    audio_file_v2 = djelia_client.audio.speech.create(
        input=bambara_text,
        description=v2_description,
        chunk_size=1.0,  # Control speech pacing (0.1 - 2.0)
        output_file="hello_v2.wav",
        model=Versions.v2
    )
    print(f"Natural audio saved to: {audio_file_v2}")
except Exception as e:
    print(f"TTS v2 error: {e}")

Asynchronous

Async natural speech generation:

async def generate_natural_audio_async():
    async with djelia_async_client as client:
        try:
            audio_file_v2 = await client.audio.speech.create(
                input=bambara_text,
                description=v2_description,
                chunk_size=1.0,
                output_file="hello_v2_async.wav",
                model=Versions.v2
            )
            print(f"Natural audio saved to: {audio_file_v2}")
        except Exception as e:
            print(f"TTS v2 error: {e}")

asyncio.run(generate_natural_audio_async())

Streaming TTS

Realtime audio generation! Get chunks as they're created (v2 only).

long_text = "An filɛ ni ye yɔrɔ minna ni an ye an sigi ka a layɛ yala an bɛ ka baara min kɛ ɛsike a kɛlen don ka Ɲɛ wa, ..............."  # a very long text
streaming_description = "Seydou speaks clearly and naturally"

Note: By default, the SDK may process multiple chunks (e.g., up to 5 in some configurations). This example limits to 5 chunks for consistency, but you can adjust the limit based on your application needs.

Synchronous

Stream that audio generation: (this is handsome)

print("Streaming TTS generation...")
chunk_count = 0
total_bytes = 0
max_chunks = 5

try:
    for chunk in djelia_client.audio.speech.create(
        input=long_text,
        description=streaming_description,
        chunk_size=1.0,
        output_file="streamed_audio.wav",
        stream=True,
        model=Versions.v2
    ):
        chunk_count += 1
        total_bytes += len(chunk)
        print(f"Chunk {chunk_count}: {len(chunk)} bytes")
        
        if chunk_count >= max_chunks:
            print(f"...and more chunks! (Total so far: {total_bytes} bytes)")
            break
except Exception as e:
    print(f"Streaming TTS error: {e}")

Asynchronous

Async streaming TTS because realtime is the future (oops, actually it's today 😂):

async def stream_tts_async():
    async with djelia_async_client as client:
        try:
            stream = await client.audio.speech.create(
                input=long_text,
                description=streaming_description,
                chunk_size=1.0,
                output_file="streamed_audio_async.wav",
                stream=True,
                model=Versions.v2
            )
            chunk_count = 0
            total_bytes = 0
            max_chunks = 5
            
            async for chunk in stream:
                chunk_count += 1
                total_bytes += len(chunk)
                print(f"Chunk {chunk_count}: {len(chunk)} bytes")
                
                if chunk_count >= max_chunks:
                    print(f"...and more chunks! (Total so far: {total_bytes} bytes)")
                    break
        except Exception as e:
            print(f"Streaming TTS error: {e}")

asyncio.run(stream_tts_async())

Version Management

The SDK supports multiple API versions (v1, v2) via the Versions enum. Use Versions.latest() to get the latest version or Versions.all_versions() to list available versions.

from djelia.models import Versions

print(f"Latest version: {Versions.latest()}")
print(f"Available versions: {[str(v) for v in Versions.all_versions()]}")

# Use specific version
try:
    transcription = djelia_client.audio.transcriptions.create(
        file=audio_file_path,
        model=Versions.v2
    )
    print(f"Transcribed {len(transcription)} segments")
except Exception as e:
    print(f"Transcription error: {e}")

Parallel Operations

Run multiple API operations concurrently using asyncio.gather with the async client. This is great for performance in applications needing simultaneous translations, transcriptions, or TTS generation.

import asyncio
from djelia.models import Language, Versions

async def parallel_operations():
    async with DjeliaAsync(api_key=api_key) as client:
        try:
            results = await asyncio.gather(
                client.translations.create(
                    text="Hello", source=Language.ENGLISH, target=Language.BAMBARA, model=Versions.v1
                ),
                client.audio.transcriptions.create(file=audio_file_path, model=Versions.v2),
                client.audio.speech.create(
                    input="Aw ni ce, i ka kɛnɛ wa?",
                    description="Moussa speaks with a clear tone",
                    chunk_size=1.0,
                    output_file="parallel_tts.wav",
                    model=Versions.v2,
                ),
                return_exceptions=True
            )
            
            for i, result in enumerate(results):
                if isinstance(result, Exception):
                    print(f"Operation {i+1} failed: {result}")
                else:
                    print(f"Operation {i+1} succeeded: {type(result).__name__}")
        except Exception as e:
            print(f"Parallel operations error: {e}")

asyncio.run(parallel_operations())

Error Handling

The Djelia SDK provides specific exception classes to handle errors gracefully. Use these to catch and respond to issues like invalid API keys, unsupported languages, or incorrect speaker descriptions.

from djelia.utils.exceptions import AuthenticationError, APIError, ValidationError, LanguageError, SpeakerError

try:
    response = djelia_client.translations.create(
        text="Hello, how are you today?",
        source=Language.ENGLISH,
        target=Language.BAMBARA,
        model=Versions.v1,
    )
    print(f"Translation: {response.text}")
except AuthenticationError as e:
    print(f"Authentication error (check API key): {e}")
except LanguageError as e:
    print(f"Invalid or unsupported language: {e}")
except ValidationError as e:
    print(f"Validation error (e.g., invalid input): {e}")
except APIError as e:
    print(f"API error (status {e.status_code}): {e.message}")
except Exception as e:
    print(f"Unexpected error: {e}")

Common Exceptions:

  • AuthenticationError: Invalid or expired API key (HTTP 401).
  • APIError: General API issues, including forbidden access (403) or resource not found (404).
  • ValidationError: Invalid inputs, such as missing audio files or incorrect parameters (422).
  • LanguageError: Unsupported source or target language.
  • SpeakerError: Invalid speaker ID (TTS v1) or description missing a supported speaker (TTS v2).

Check logs for detailed errors, and ensure your .env file includes a valid DJELIA_API_KEY and TEST_AUDIO_FILE.

Explore the Djelia SDK Cookbook

Want to take your Djelia SDK skills to the next level? The Djelia SDK Cookbook is an interactive, rich + typer powered test suite that exercises the whole OpenAI-style API. It demonstrates:

  • Interactive Test Suite: Pick which groups to run (translation, transcription, TTS, streaming, parallel) and whether to run the sync tests, the async tests, or both.
  • Live Metrics: Each API call is timed and printed the moment it completes, followed by a per-test operations table (input → response, kind, latency) and a final pass/fail summary.
  • Configuration Management: Load API keys and audio paths from a .env file with validation.
  • Advanced Features: Parallel API operations, version management, and streaming capabilities.
  • Tidy Output: Generated audio is written under cookbook_output/ and cleaned up automatically (pass --keep-audio to keep it).

To run the cookbook, clone the repository, install dependencies, and execute:

git clone https://github.com/djelia-org/djelia-python-sdk.git
cd djelia-python-sdk
pip install -e ".[cookbook]"   # installs the SDK plus typer, rich, python-dotenv

# Run everything (sync + async):
python -m cookbook

# List the available test groups:
python -m cookbook --list

# Run only a couple of groups, sync-only:
python -m cookbook -g translation -g tts --mode sync

# Pick groups and mode from an interactive menu:
python -m cookbook --interactive

Make sure your .env file includes DJELIA_API_KEY (and optionally TEST_AUDIO_FILE). The cookbook is perfect for developers who want a ready-to-use template for building real-world applications with the Djelia SDK.

Wrapping Up

And there you have it a full workshop on using the Djelia Python SDK! You've installed it, set up clients, and mastered translation, transcription, and text-to-speech both synchronously and asynchronously. Pretty cool, right? Feel free to tweak the code, explore different languages and voices, and check out the Djelia SDK Cookbook for a deeper dive.

Pro tip: The async methods are perfect for applications that need to handle multiple operations simultaneously. The streaming features are fantastic for realtime applications. And remember, Bambara is just one of the beautiful African languages you can work with!

IMPORTANT: If you encounter any issues, please create an issue in the repository, explain the problem you encountered (include logs if possible), and tag @sudoping01.

Great job, bro 🫂! This is a fantastic integration guide built with ❤️ for 🇲🇱 and beyond!

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

djelia-3.1.1.tar.gz (32.2 kB view details)

Uploaded Source

Built Distribution

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

djelia-3.1.1-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

File details

Details for the file djelia-3.1.1.tar.gz.

File metadata

  • Download URL: djelia-3.1.1.tar.gz
  • Upload date:
  • Size: 32.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for djelia-3.1.1.tar.gz
Algorithm Hash digest
SHA256 3a2f37ff8cc7955ff1e26073278fc09b288980cbec280627c5007fe9e4b3786a
MD5 cf81b3d5765bd7480255f17ee9bd0006
BLAKE2b-256 da953dce2d2a37a9a8eeeffce7977ec6ffd098cf61af1f1d86a5ebbe6600f74a

See more details on using hashes here.

File details

Details for the file djelia-3.1.1-py3-none-any.whl.

File metadata

  • Download URL: djelia-3.1.1-py3-none-any.whl
  • Upload date:
  • Size: 30.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for djelia-3.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2d474704ba4e238128ac30c8cc9cebaa06081e4b446baa62902637d2c2fe80e0
MD5 8a9d81d9427deffd9c381424a31d61e3
BLAKE2b-256 b9148b7c842cb1eaa2c04bfb6f535db5a53c16d29c215be633662baacb939726

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