| 1 | import requests |
| 2 | import time |
| 3 | |
| 4 | API_KEY = "YOUR_API_KEY" |
| 5 | audio_file_path = "./meeting.mp3" |
| 6 | |
| 7 | # ------------------------------------------ |
| 8 | # Step 1: Upload the audio file |
| 9 | # ------------------------------------------ |
| 10 | def upload_file(filename): |
| 11 | with open(filename, "rb") as f: |
| 12 | upload_url = "https://api.assemblyai.com/v2/upload" |
| 13 | headers = {"authorization": API_KEY} |
| 14 | response = requests.post(upload_url, headers=headers, data=f) |
| 15 | response.raise_for_status() |
| 16 | return response.json()["upload_url"] |
| 17 | |
| 18 | audio_url = upload_file(audio_file_path) |
| 19 | print(f"Uploaded audio file. URL: {audio_url}") |
| 20 | |
| 21 | # ------------------------------------------ |
| 22 | # Step 2: Request transcription |
| 23 | # ------------------------------------------ |
| 24 | transcript_request = requests.post( |
| 25 | "https://api.assemblyai.com/v2/transcript", |
| 26 | headers={"authorization": API_KEY, "content-type": "application/json"}, |
| 27 | json={"audio_url": audio_url, "speech_models": ["universal-3-pro"]}, |
| 28 | ) |
| 29 | |
| 30 | transcript_id = transcript_request.json()["id"] |
| 31 | |
| 32 | # Poll until completed |
| 33 | while True: |
| 34 | polling_response = requests.get( |
| 35 | f"https://api.assemblyai.com/v2/transcript/{transcript_id}", |
| 36 | headers={"authorization": API_KEY}, |
| 37 | ) |
| 38 | status = polling_response.json()["status"] |
| 39 | |
| 40 | if status == "completed": |
| 41 | break |
| 42 | elif status == "error": |
| 43 | raise RuntimeError(f"Transcription failed: {polling_response.json()['error']}") |
| 44 | else: |
| 45 | print(f"Transcription status: {status}") |
| 46 | time.sleep(3) |
| 47 | |
| 48 | print("\nTranscription complete.\n") |
| 49 | |
| 50 | # ------------------------------------------ |
| 51 | # Step 3: Define questions |
| 52 | # ------------------------------------------ |
| 53 | agent_context = "The agent is trying to get the customer to go through with the update to their car." |
| 54 | customer_context = "The customer is calling to check how much it would cost to update the map in his car." |
| 55 | |
| 56 | answer_format = "<answer in one sentence> <reason in one sentence>" |
| 57 | |
| 58 | questions = [ |
| 59 | { |
| 60 | "question": "What was the overall sentiment of the call?", |
| 61 | "context": customer_context, |
| 62 | "answer_format": answer_format, |
| 63 | }, |
| 64 | { |
| 65 | "question": "What was the sentiment of the agent in this call?", |
| 66 | "context": agent_context, |
| 67 | "answer_format": answer_format, |
| 68 | }, |
| 69 | { |
| 70 | "question": "What was the sentiment of the customer in this call?", |
| 71 | "context": customer_context, |
| 72 | "answer_format": answer_format, |
| 73 | }, |
| 74 | { |
| 75 | "question": "What quote best demonstrates the customer's level of interest?", |
| 76 | "context": customer_context, |
| 77 | "answer_format": answer_format, |
| 78 | }, |
| 79 | { |
| 80 | "question": "Provide a quote from the agent that demonstrates their level of enthusiasm.", |
| 81 | "context": agent_context, |
| 82 | "answer_format": answer_format, |
| 83 | }, |
| 84 | ] |
| 85 | |
| 86 | # ------------------------------------------ |
| 87 | # Step 4: Build prompt for the LLM |
| 88 | # ------------------------------------------ |
| 89 | question_strs = [] |
| 90 | for q in questions: |
| 91 | q_str = f"Question: {q['question']}" |
| 92 | if q.get("context"): |
| 93 | q_str += f"\nContext: {q['context']}" |
| 94 | if q.get("answer_format"): |
| 95 | q_str += f"\nAnswer Format: {q['answer_format']}" |
| 96 | question_strs.append(q_str) |
| 97 | |
| 98 | questions_prompt = "\n\n".join(question_strs) |
| 99 | |
| 100 | prompt = f""" |
| 101 | You are an expert at analyzing call transcripts. |
| 102 | Given the series of questions below, answer them accurately and concisely. |
| 103 | When context or answer format is provided, use it to guide your answers. |
| 104 | |
| 105 | Transcript: |
| 106 | {{{{ transcript }}}} |
| 107 | |
| 108 | Questions: |
| 109 | {questions_prompt} |
| 110 | """ |
| 111 | |
| 112 | # ------------------------------------------ |
| 113 | # Step 5: Query the LLM Gateway |
| 114 | # ------------------------------------------ |
| 115 | headers = {"authorization": API_KEY} |
| 116 | |
| 117 | response = requests.post( |
| 118 | "https://llm-gateway.assemblyai.com/v1/chat/completions", |
| 119 | headers=headers, |
| 120 | json={ |
| 121 | "model": "claude-sonnet-4-5-20250929", |
| 122 | "messages": [{"role": "user", "content": prompt}], |
| 123 | "transcript_id": transcript_id, |
| 124 | "max_tokens": 2000, |
| 125 | }, |
| 126 | ) |
| 127 | |
| 128 | response_json = response.json() |
| 129 | llm_output = response_json["choices"][0]["message"]["content"] |
| 130 | |
| 131 | # ------------------------------------------ |
| 132 | # Step 6: Parse and display the results |
| 133 | # ------------------------------------------ |
| 134 | print("\n--- LLM Responses ---\n") |
| 135 | print(llm_output) |