How to Add AI Voice to Your Django App
Why Add AI Voice to a Django App? If you’ve ever wanted to turn your Django‑powered web app into something that can talk back to users, you’re not alone. Voice interfaces are moving from novelty to necessity—think acce
Why Add AI Voice to a Django App?
If you’ve ever wanted to turn your Django‑powered web app into something that can talk back to users, you’re not alone. Voice interfaces are moving from novelty to necessity—think accessibility, hands‑free experiences, and richer engagement. With modern text‑to‑speech (TTS) services you can generate natural‑sounding speech in seconds, and even clone a brand’s voice for consistency.
In this post we’ll walk through:
- Setting up an ElevenLabs account (the TTS service we’ll use)
- Creating a tiny Django endpoint that talks to the ElevenLabs API
- Hooking the endpoint up to the front‑end with a little JavaScript
- (Optional) Storing generated audio files for later reuse
By the end you’ll have a working “Speak” button that reads any string you supply, all without leaving your Django project.
1. Get an ElevenLabs API Key
ElevenLabs provides some of the most realistic neural voices on the market, and they make it easy to get started with a free tier. Sign up through this affiliate link so you get a ready‑to‑use API key:
After confirming your email, navigate to Dashboard → API Keys and copy the key – you’ll need it in the next steps.
2. Install Dependencies
We’ll use the popular requests library to call the ElevenLabs REST endpoint. If you haven’t already, add it to your project:
pip install requests
If you prefer async, you can swap requests for httpx, but the sync version keeps the example straightforward.
3. Create a Django View for TTS
Add a new view in myapp/views.py. This view accepts a POST request containing the text you want spoken, forwards it to ElevenLabs, and streams the resulting MP3 back to the browser.
# myapp/views.py
import os
import json
import requests
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
ELEVENLABS_API_URL = "https://api.elevenlabs.io/v1/text-to-speech"
VOICE_ID = "EXAVITQu4vr4xnSDxMaL" # Default voice; you can list your own in the dashboard
@csrf_exempt # For demo purposes; in production use proper CSRF handling
def generate_voice(request):
if request.method != "POST":
return JsonResponse({"error": "POST only"}, status=405)
try:
payload = json.loads(request.body)
text = payload["text"]
except (KeyError, json.JSONDecodeError):
return JsonResponse({"error": "Invalid JSON payload"}, status=400)
headers = {
"xi-api-key": settings.ELEVENLABS_API_KEY,
"Content-Type": "application/json",
}
data = {
"text": text,
"voice_settings": {
"stability": 0.75,
"similarity_boost": 0.85,
},
}
# Build the request URL with the chosen voice
url = f"{ELEVENLABS_API_URL}/{VOICE_ID}"
response = requests.post(url, json=data, headers=headers, stream=True)
if response.status_code != 200:
return JsonResponse(
{"error": "ElevenLabs API error", "details": response.text},
status=response.status_code,
)
# Stream the MP3 directly back to the client
return HttpResponse(
response.iter_content(chunk_size=8192),
content_type="audio/mpeg",
)
Key points:
- The view reads raw JSON (
{"text": "Hello world!"}) and forwards it. -
voice_settingslet you tweak stability and similarity – play with those numbers for smoother or more expressive speech. - The response is streamed, so the browser can start playing before the whole file is downloaded.
Add the endpoint to myapp/urls.py:
# myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("api/tts/", views.generate_voice, name="generate_voice"),
]
Don’t forget to expose the API key in your Django settings (never commit it to version control!):
# settings.py
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
Set the environment variable locally:
export ELEVENLABS_API_KEY=your_key_here
4. Front‑End: A Simple “Speak” Button
Create a tiny template (templates/speak.html) that lets a user type text and hear it back:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AI Voice Demo</title>
</head>
<body>
<h1>AI Voice Demo</h1>
<textarea id="text" rows="4" cols="50" placeholder="Enter text to speak..."></textarea><br>
<button id="speakBtn">Speak</button>
<audio id="player" controls></audio>
<script>
const btn = document.getElementById('speakBtn');
const player = document.getElementById('player');
const textarea = document.getElementById('text');
btn.addEventListener('click', async () => {
const text = textarea.value.trim();
if (!text) return alert('Please enter some text');
// Send request to Django endpoint
const response = await fetch('/api/tts/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text })
});
if (!response.ok) {
const err = await response.json();
return alert('Error: ' + err.error);
}
// Convert the streamed MP3 into a blob URL and play it
const blob = await response.blob();
const url = URL.createObjectURL(blob);
player.src = url;
player.play();
});
</script>
</body>
</html>
Add a route for the template:
# myapp/views.py (add below the previous view)
from django.shortcuts import render
def speak_page(request):
return render(request, "speak.html")
# myapp/urls.py (add)
path("", views.speak_page, name="speak_page"),
Now run the server:
python manage.py runserver
Visit http://localhost:8000/, type a sentence, and press Speak – you should hear the AI‑generated voice instantly.
5. (Optional) Caching Audio Files
If you expect the same phrases to be spoken repeatedly, consider persisting the MP3 to disk or a cloud bucket. Here’s a quick tweak to the view that saves the file under media/tts/ and reuses it when it exists:
import hashlib
from pathlib import Path
MEDIA_ROOT = Path(settings.BASE_DIR) / "media" / "tts"
MEDIA_ROOT.mkdir(parents=True, exist_ok=True)
def generate_voice(request):
# ... same validation as before ...
# Create a deterministic filename based on the text
filename = hashlib.sha256(text.encode()).hexdigest() + ".mp3"
file_path = MEDIA_ROOT / filename
if file_path.exists():
# Serve the cached file
with open(file_path, "rb") as f:
return HttpResponse(f.read(), content_type="audio/mpeg")
# ... call ElevenLabs as before ...
# Save the streamed content for next time
with open(file_path, "wb") as out_file:
for chunk in response.iter_content(chunk_size=8192):
out_file.write(chunk)
# Serve the newly saved file
with open(file_path, "rb") as f:
return HttpResponse(f.read(), content_type="audio/mpeg")
Don’t forget to add MEDIA_URL and MEDIA_ROOT to your urls.py if you want Django to serve those files in development.
6. Going Further
-
Voice cloning – ElevenLabs lets you upload a few minutes of your own voice and generate a custom voice model. The API call is the same; just replace
VOICE_IDwith the ID of your cloned voice. -
Streaming directly to the browser – Instead of returning a full MP3, you could pipe the stream straight into a
<audio>element using theReadableStreamAPI. -
Authentication – Protect the
/api/tts/endpoint with Django’s@login_requiredor token‑based auth if you expose it publicly.
7. Wrap‑up
Adding AI voice to a Django app is surprisingly straightforward when you lean on a high‑quality TTS provider. With just a few lines of Python and a sprinkle of JavaScript you can turn any string into a natural‑sounding spoken response, opening doors to accessibility, interactive tutorials, and even custom brand avatars.
Ready to give your users a voice? Grab your ElevenLabs API key via the affiliate link below, plug the snippets into your project, and start experimenting. The only limit is your imagination (and maybe your API quota).
Try ElevenLabs today and make your Django app speak!
https://try.elevenlabs.io/kr07zfuqn1bp
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.