File size: 3,968 Bytes
385a349
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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