AkomptaBackend / api /assemblyai_service.py
rinogeek's picture
Initial commit of backend code to Hugging Face Space
385a349
Raw
History Blame Contribute Delete
3.97 kB
import os
import time
import requests
from pathlib import Path
from django.conf import settings
class AssemblyAIService:
def __init__(self):
# Try to load from environment first
self.api_key = os.environ.get("ASSEMBLYAI_API_KEY")
# If not in environment, try loading from .env file directly
if not self.api_key:
env_path = Path(__file__).resolve().parent.parent / '.env'
if env_path.exists():
with open(env_path, 'r') as f:
for line in f:
line = line.strip()
if line.startswith('ASSEMBLYAI_API_KEY='):
self.api_key = line.split('=', 1)[1].strip()
break
if not self.api_key:
print("Warning: ASSEMBLYAI_API_KEY not found.")
self.headers = {
"Authorization": self.api_key,
"Content-Type": "application/json"
}
self.upload_url = "https://api.assemblyai.com/v2/upload"
self.transcript_url = "https://api.assemblyai.com/v2/transcript"
def upload_file(self, audio_file):
"""Upload audio file to AssemblyAI"""
if not self.api_key:
return None
try:
# AssemblyAI expects the raw file content in the body
audio_file.seek(0)
response = requests.post(
self.upload_url,
headers={"Authorization": self.api_key},
data=audio_file.read()
)
if response.status_code != 200:
print(f"AssemblyAI Upload Error: {response.status_code} - {response.text}")
response.raise_for_status()
return response.json()["upload_url"]
except Exception as e:
print(f"Error uploading to AssemblyAI: {e}")
return None
def transcribe(self, audio_file, language=None):
"""
Transcribe audio file using AssemblyAI REST API.
"""
if not self.api_key:
return None
try:
# 1. Upload
upload_url = self.upload_file(audio_file)
if not upload_url:
return None
# Start transcription with required speech model
lang_to_use = language.lower()[:2] if language else "fr"
payload = {
"audio_url": upload_url,
"language_code": lang_to_use,
"speech_models": ["universal-3-pro"] # Matches the error suggestion
}
response = requests.post(self.transcript_url, json=payload, headers=self.headers)
if response.status_code != 200 and response.status_code != 201:
print(f"AssemblyAI error response: {response.text}")
response.raise_for_status()
transcript_id = response.json()["id"]
# 3. Polling for results
polling_url = f"{self.transcript_url}/{transcript_id}"
max_attempts = 30
attempts = 0
while attempts < max_attempts:
polling_response = requests.get(polling_url, headers=self.headers)
polling_response.raise_for_status()
data = polling_response.json()
if data["status"] == "completed":
return data["text"]
elif data["status"] == "error":
print(f"AssemblyAI transcription error: {data.get('error')}")
return None
attempts += 1
time.sleep(1) # Poll every second
print("AssemblyAI transcription timed out.")
return None
except Exception as e:
print(f"Error calling AssemblyAI STT: {e}")
return None