Created
July 9, 2024 02:31
-
-
Save asimjalis/8fca1821b2422b54ba1015211dc1f263 to your computer and use it in GitHub Desktop.
Code for "Learn Amazon Transcribe"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "71e1dd2c-b819-4535-a811-01ce5b0ef83a", | |
"metadata": {}, | |
"source": [ | |
"## Amazon Transcribe Demo" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"id": "3c233341-9a88-41a6-bbf9-14c032f8c26b", | |
"metadata": { | |
"execution": { | |
"iopub.execute_input": "2024-07-09T02:30:57.424543Z", | |
"iopub.status.busy": "2024-07-09T02:30:57.423709Z", | |
"iopub.status.idle": "2024-07-09T02:30:58.461834Z", | |
"shell.execute_reply": "2024-07-09T02:30:58.461290Z", | |
"shell.execute_reply.started": "2024-07-09T02:30:57.424518Z" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Requirement already satisfied: boto3 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (1.34.129)\n", | |
"Requirement already satisfied: botocore<1.35.0,>=1.34.129 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from boto3) (1.34.129)\n", | |
"Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from boto3) (1.0.1)\n", | |
"Requirement already satisfied: s3transfer<0.11.0,>=0.10.0 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from boto3) (0.10.1)\n", | |
"Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from botocore<1.35.0,>=1.34.129->boto3) (2.9.0.post0)\n", | |
"Requirement already satisfied: urllib3!=2.2.0,<3,>=1.25.4 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from botocore<1.35.0,>=1.34.129->boto3) (1.26.18)\n", | |
"Requirement already satisfied: six>=1.5 in /Users/asimjaws/.pyenv/versions/3.11.6/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages (from python-dateutil<3.0.0,>=2.1->botocore<1.35.0,>=1.34.129->boto3) (1.16.0)\n" | |
] | |
} | |
], | |
"source": [ | |
"!pip install boto3" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"id": "3906e38a-2cdd-49fa-a1e5-af51d7510c63", | |
"metadata": { | |
"execution": { | |
"iopub.execute_input": "2024-07-09T02:30:59.933588Z", | |
"iopub.status.busy": "2024-07-09T02:30:59.933195Z", | |
"iopub.status.idle": "2024-07-09T02:31:00.995033Z", | |
"shell.execute_reply": "2024-07-09T02:31:00.994434Z", | |
"shell.execute_reply.started": "2024-07-09T02:30:59.933559Z" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"upload: ./demo1.mp3 to s3://asimj-test/x-transcribe-demo/demo1.mp3 \n" | |
] | |
} | |
], | |
"source": [ | |
"!aws s3 cp demo1.mp3 s3://asimj-test/x-transcribe-demo/demo1.mp3" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"id": "030399e0-4f3c-4629-9d35-9704ca8d37a3", | |
"metadata": { | |
"execution": { | |
"iopub.execute_input": "2024-07-09T02:31:02.780958Z", | |
"iopub.status.busy": "2024-07-09T02:31:02.780366Z", | |
"iopub.status.idle": "2024-07-09T02:31:02.871916Z", | |
"shell.execute_reply": "2024-07-09T02:31:02.871647Z", | |
"shell.execute_reply.started": "2024-07-09T02:31:02.780916Z" | |
} | |
}, | |
"outputs": [], | |
"source": [ | |
"import sys, os, time, boto3, json\n", | |
"from datetime import datetime\n", | |
"\n", | |
"# Exponentially backoff with sleep\n", | |
"def exp_backoff_sleep(start_seconds, initial_backoff=4.0):\n", | |
" elapsed_seconds = time.time() - start_seconds\n", | |
" if elapsed_seconds < initial_backoff:\n", | |
" backoff = initial_backoff\n", | |
" else:\n", | |
" backoff = elapsed_seconds * 0.25\n", | |
" time.sleep(backoff)\n", | |
" app_log(f\"Waiting ... Elapsed time: {elapsed_seconds :.2f} seconds\")\n", | |
"\n", | |
"# Log status and debugging messages \n", | |
"def app_log(msg,val_dict={}):\n", | |
" timestamp_string = datetime.now().strftime(\"[%Y-%m-%d %H:%M:%S.\") + \\\n", | |
" f\"{datetime.now().microsecond // 10000:02d}\" + \"]\"\n", | |
" val_string = ' '.join(f\"{key}={value}\" for key, value in val_dict.items())\n", | |
" output_string = \" \".join([timestamp_string, msg, val_string])\n", | |
" print(output_string, file=sys.stderr)\n", | |
" sys.stderr.flush()\n", | |
"\n", | |
"def convert_s3_audio_to_transcript(s3_audio_path):\n", | |
" # Initialize the boto3 clients for S3 and Transcribe\n", | |
" s3 = boto3.client('s3')\n", | |
" transcribe = boto3.client('transcribe')\n", | |
"\n", | |
" # Extract the bucket and object key from the S3 audio file path\n", | |
" bucket, s3_key = s3_audio_path.replace(\"s3://\", \"\").split('/', 1)\n", | |
"\n", | |
" # Formatting the current timestamp for job name and output key\n", | |
" timestamp = datetime.strftime(datetime.now(), '%Y-%m-%d-%H-%M-%S-%f')\n", | |
" output_key = f\"{s3_key.rsplit('.', 1)[0]}-{timestamp}.json\"\n", | |
" s3_output_path = f\"s3://{bucket}/{output_key}\"\n", | |
" \n", | |
" # Setting up the transcription job\n", | |
" job_name = f\"TranscriptionJob-{timestamp}\"\n", | |
" job_uri = f\"s3://{bucket}/{s3_key}\"\n", | |
"\n", | |
" # Start the transcription job\n", | |
" target_language = 'en-US'\n", | |
" transcribe.start_transcription_job(\n", | |
" TranscriptionJobName=job_name,\n", | |
" Media={'MediaFileUri': job_uri},\n", | |
" MediaFormat=s3_key.split('.')[-1],\n", | |
" LanguageCode=target_language, \n", | |
" OutputBucketName=bucket,\n", | |
" OutputKey=output_key)\n", | |
"\n", | |
" # Wait for the transcription job to complete\n", | |
" app_log(\"Transcription started\")\n", | |
" start_seconds = time.time()\n", | |
" while True:\n", | |
" status = transcribe.get_transcription_job(TranscriptionJobName=job_name)\n", | |
" if status['TranscriptionJob']['TranscriptionJobStatus'] \\\n", | |
" in ['COMPLETED', 'FAILED']:\n", | |
" break\n", | |
" exp_backoff_sleep(start_seconds)\n", | |
" app_log(\"Transcription completed\")\n", | |
"\n", | |
" # Get the output file from S3\n", | |
" response = s3.get_object(Bucket=bucket, Key=output_key)\n", | |
"\n", | |
" # Read and extract the transcript text\n", | |
" transcript_text = json.load(\n", | |
" response['Body'])['results']['transcripts'][0]['transcript']\n", | |
"\n", | |
" # Infer transcript local path and write transcript to file\n", | |
" transcript_id = output_key.split('/')[-1].rsplit('.', 1)[0]\n", | |
" if not os.path.exists('output'): os.makedirs('output')\n", | |
" transcript_path = f\"output/{transcript_id}-Transcript-Raw.txt\"\n", | |
" with open(transcript_path, 'w') as file:\n", | |
" file.write(transcript_text)\n", | |
"\n", | |
" app_log(f\"Transcript saved locally at {transcript_path}\")\n", | |
"\n", | |
" # Calculate elapsed time\n", | |
" elapsed_seconds = round(time.time() - start_seconds, 2)\n", | |
"\n", | |
" # Return locals\n", | |
" return {\n", | |
" 'elapsed_seconds': elapsed_seconds,\n", | |
" 's3_audio_path': s3_audio_path,\n", | |
" 's3_output_path': s3_output_path,\n", | |
" 'transcript_id': transcript_id,\n", | |
" 'transcript_path': transcript_path,\n", | |
" 'transcript_chars': len(transcript_text)\n", | |
" }" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"id": "887dd86b-1fa6-4050-8445-a768882991fb", | |
"metadata": { | |
"execution": { | |
"iopub.execute_input": "2024-07-09T02:31:05.055479Z", | |
"iopub.status.busy": "2024-07-09T02:31:05.054819Z", | |
"iopub.status.idle": "2024-07-09T02:31:14.193048Z", | |
"shell.execute_reply": "2024-07-09T02:31:14.192247Z", | |
"shell.execute_reply.started": "2024-07-09T02:31:05.055452Z" | |
} | |
}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"[2024-07-08 21:31:05.48] Transcription started \n", | |
"[2024-07-08 21:31:09.57] Waiting ... Elapsed time: 0.09 seconds \n", | |
"[2024-07-08 21:31:10.70] Waiting ... Elapsed time: 4.17 seconds \n", | |
"[2024-07-08 21:31:12.12] Waiting ... Elapsed time: 5.31 seconds \n", | |
"[2024-07-08 21:31:13.90] Waiting ... Elapsed time: 6.74 seconds \n", | |
"[2024-07-08 21:31:13.99] Transcription completed \n", | |
"[2024-07-08 21:31:14.17] Transcript saved locally at output/demo1-2024-07-08-21-31-05-188132-Transcript-Raw.txt \n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"{'elapsed_seconds': 8.7,\n", | |
" 's3_audio_path': 's3://asimj-test/x-transcribe-demo/demo1.mp3',\n", | |
" 's3_output_path': 's3://asimj-test/x-transcribe-demo/demo1-2024-07-08-21-31-05-188132.json',\n", | |
" 'transcript_id': 'demo1-2024-07-08-21-31-05-188132',\n", | |
" 'transcript_path': 'output/demo1-2024-07-08-21-31-05-188132-Transcript-Raw.txt',\n", | |
" 'transcript_chars': 105}" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"demo1_mp3 = \"s3://asimj-test/x-transcribe-demo/demo1.mp3\"\n", | |
"convert_s3_audio_to_transcript(demo1_mp3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "064b24c1-165f-412f-806b-60eac6df85a8", | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.11.6" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment