AWS Serverless Transcriber — demo pack¶
This page assembles sections relevant to demos and stakeholder presentations: overview, role, architecture, decisions, roadmap, and demonstration.
Contents¶
- Summary
- Overview
- Role and Responsibilities
- Architecture and Integrations
- Decisions, Trade-offs, and Risks
- Roadmap and Demonstration
Summary¶
Status¶
In production
Role¶
System Designer
Stack¶
Python, AWS Lambda, API Gateway, DynamoDB, AWS S3, Terraform, LLM API integration
Project value¶
For the user:
- fast transcription of long audio recordings without uploading to heavy SaaS services;
- controlled access to results via Cognito and presigned URLs;
- minimal ongoing costs through a serverless model.
For the professional profile:
- practical design of an AWS serverless workflow;
- working with async processing, webhooks, polling UI, and job lifecycle;
- applying Infrastructure-as-Code through Terraform;
- choosing solutions based on episodic load and cost constraints (cost-driven architecture).
Overview¶
Product Overview¶
A serverless solution for transcribing audio recordings using an external transcription API.
Technology Stack¶
- Backend: Python on AWS Lambda
- Data: Amazon S3 (recording files, transcriptions), AWS DynamoDB (job statuses)
- Frontend: static HTML + JS on Amazon S3 deployed via AWS CloudFront
- AI: AssemblyAI API
- Security: AWS Cognito
- Infrastructure: AWS API Gateway, packaged as a Terraform project
Role and Responsibilities¶
My Role¶
I acted as the system designer and technical owner of the solution.
My work included:
- translating a personal need into requirements, constraints, and an architectural model;
- choosing a serverless architecture given episodic load and cost constraints;
- designing the asynchronous process: upload -> transcription request -> webhook -> result storage -> download;
- designing the transcription job state model;
- selecting AWS services and responsibility boundaries between Lambda, S3, DynamoDB, API Gateway, Cognito, and the external transcription provider;
- documenting sequence diagrams and ADRs;
- using AI-assisted development tools as an implementation accelerator while keeping manual control over architecture, security boundaries, and deployment decisions.
AI Usage¶
The project was developed with AI assistance.
LLMs were used to accelerate implementation, generate boilerplate code, and iterate quickly. Key decisions remained under manual control:
- requirements interpretation;
- domain modeling;
- architecture decisions;
- data boundaries;
- access model;
- code review;
- debugging;
- deployment decisions;
- technical documentation.
Architecture and Integrations¶
Architecture¶
Architectural concept¶
The system is built on an event-driven model.
The static frontend is served via S3/CloudFront. The user authenticates through Cognito Hosted UI and calls API Gateway using the obtained JWT. API Gateway routes requests to Lambda functions.
Large audio files do not pass through API Gateway and Lambda. The backend issues a presigned POST URL, after which the browser uploads the file directly to S3. An S3 ObjectCreated event triggers a handler that creates a temporary URL for the transcription provider and submits a new transcription request. The external provider performs long transcription asynchronously and returns the result via webhook. The final text transcript is saved to S3, and the job status is updated and stored in DynamoDB.
architecture-beta
service dynamo(aws:dynamodb)[AWS DynamoDB]
service lambda(aws:lambda)[AWS Lambda]
service api(aws:api-gateway)[AWS API Gateway]
service static(aws:simple-storage-service)[Static website at Amazon S3]
service storage(aws:simple-storage-service)[File storage at Amazon S3]
service browser(logos:chrome)[Browser]
service cognito(aws:cognito)[AWS Cognito]
service ai(logos:webhooks)[Transcriber API]
service front(aws:cloudfront)[AWS CloudFront]
front:T --> B:static
browser:T --> B:api
browser:L --> R:front
browser:B --> T:cognito
api:R --> L:lambda
api:T <-- B:ai
lambda:T --> R:ai
lambda:R --> L:dynamo
lambda:B --> T:storage
storage:L <-- R:browser Integration flows¶
Sequence diagrams¶
Audio file submission¶
sequenceDiagram
autonumber
actor U as Browser (SPA)
participant API as API Gateway
participant L as AWS Lambda
participant S3 as Amazon S3
participant DB as DynamoDB
U->>API: GET /upload-url (+JWT in Header)
activate API
API->>L: Invoke get_upload_url
deactivate API
activate L
L->>DB: Create record (Status: UPLOADING)
L->>S3: Generate Presigned POST URL
activate S3
S3-->>L: Upload link
deactivate S3
L-->>U: JSON: { uploadUrl, fileId }
deactivate L
Direct upload and asynchronous trigger (event-driven)¶
sequenceDiagram
autonumber
actor U as Browser (SPA)
participant L as AWS Lambda
participant S3 as Amazon S3
participant DB as DynamoDB
participant AI as TranscribeProvider
U->>S3: POST Upload audio file (Bypass API Gateway)
activate S3
S3-->>U: 204 No Content (Success)
deactivate S3
S3-)L: Event: ObjectCreated (Async invoke s3_trigger)
activate L
L->>DB: Update status (TRANSMITTING)
L->>S3: Generate temporary GET Presigned URL for AI
L->>AI: POST /v2/transcript (Audio URL + Webhook URL)
activate AI
alt TranscribeProvider accepts request
AI-->>L: 201 Created (transcript_id)
L->>DB: Status = PROCESSING (save ID)
else API error (e.g. HTTP 400/500)
AI-->>L: 4xx / 5xx Error
deactivate AI
L->>DB: Status = ERROR (Log reason)
end
deactivate L
AI processing and webhook (up to several minutes)¶
sequenceDiagram
autonumber
actor U as Browser (SPA)
participant API as API Gateway
participant L as AWS Lambda
participant S3 as Amazon S3
participant DB as DynamoDB
participant AI as TranscribeProvider
loop Every 15 seconds (Polling)
U->>API: GET /jobs
activate API
API->>L: Invoke get_jobs
deactivate API
activate L
L->>DB: Request user's file list
activate DB
DB-->>L: Data (Status: PROCESSING)
deactivate DB
L-->>U: Update UI
deactivate L
end
Note over AI, DB: TranscribeProvider completes processing
AI->>API: POST /webhook (pass transcript_id)
activate API
API->>L: Invoke webhook_TranscribeProvider
deactivate API
activate L
L->>AI: GET /v2/transcript/{id}
activate AI
AI-->>L: Completed transcription text
deactivate AI
L->>S3: PUT Save text (Transcript.txt)
L->>DB: Update status (READY)
deactivate L
Result retrieval (download)¶
sequenceDiagram
autonumber
actor U as Browser (SPA)
participant API as API Gateway
participant L as AWS Lambda
participant S3 as Amazon S3
participant DB as DynamoDB
U->>API: GET /jobs (Next polling interval)
activate API
API-->>U: Status: READY (Download button active)
deactivate API
U->>API: GET /download-url?fileId=...
activate API
API->>L: Invoke get_download_url
deactivate API
activate L
L->>DB: Verify user access rights to file
L->>S3: Generate Presigned GET URL (with Content-Disposition)
L-->>U: JSON: { downloadUrl }
deactivate L
U->>S3: Direct download of Transcript.txt
activate S3
S3-->>U: Transcription file
deactivate S3 Decisions, Trade-offs, and Risks¶
Key decisions¶
Full event-driven model¶
Transcription is a long-running process that may exceed Lambda function execution time. * Decision: Implement an event-driven model. Temporally decouple audio file submission from text result retrieval. Find a transcription provider that offers webhook notification functionality.
Working with 300 MB files¶
File size may exceed API Gateway limits and increase Lambda function runtime. * Decision: Use Presigned URL functionality provided by Amazon S3 out of the box. This allows the client to access S3 directly, bypassing API Gateway and Lambda.
Architectural trade-offs (ADR)¶
1. Optimal architectural style¶
Context¶
The episodic nature of tool usage, a small number of use cases, broad availability zone, and strict infrastructure and maintenance cost requirements must be accounted for.
Decision¶
Use a Serverless approach and AWS Lambda infrastructure.
Rejected alternative¶
VPS, Telegram bot
Rationale¶
-
Lambda functions are billed for execution time; with episodic usage they can fit within the Free tier (1M requests or 400 TB-s per month), i.e. business logic is free under given conditions. AWS Lambda also handles infrastructure security on Amazon's side, eliminating maintenance costs.
-
VPS require periodic payment for capacity (even when the service is unused this can be $3–7 per month), and require resources to maintain the required security level (OS security updates, fresh packages, etc.).
-
A Telegram bot as a channel is convenient enough, but unsuitable due to audio file size limits (50 MB) + it does not eliminate the need to host bot logic somewhere (VPS with all that entails).
Trade-offs¶
- Serverless requires more careful design, maximizing offloading of heavy operations outside functions (Presigned URLs in S3). Function stability requirements must be higher. Quotas on invocations and spend alerts must be configured.
- Serverless is harder to debug.
2. Optimal transcription infrastructure¶
Context¶
Budget for running an open-source model on owned hardware is not planned.
Decision¶
Use a third-party transcription API service.
Rejected alternative¶
Locally run open-source model, rented hardware for running an open-source model.
Rationale¶
-
A third-party transcription API service works fast and requires no maintenance. AssemblyAI was chosen as optimal quality-to-price ratio — $0.15 per hour. Cost per minute is $0.0025 when using Amazon cloud and serverless approach, which is 120 times less than required. The limit of 5 concurrent transcription processes is also met.
-
No hardware available for local model deployment (minimum requirements — 16 GB RAM and 8 GB video memory on an external GPU). Purchasing additional hardware is outside the digital nomad paradigm.
-
Renting compatible hardware costs $5–10 per month with hourly billing, requires separate resources for deployment, launch, and security (security updates). Running such hardware continuously costs $40–60 per month. The solution is suboptimal.
Trade-offs¶
-
Recordings are sent to a third-party service; the privacy requirement is not met. Agreed with the stakeholder.
-
The third-party service may change pricing or shut down.
-
API keys must be stored securely. Storing in code is insecure and bad practice. AWS Secrets Manager costs $0.40 per month + $0.05 per 10,000 requests — this must be factored into the final cost per transcription minute.
3. User data isolation¶
Context¶
Access restriction and data separation requirements must be met, and the service must support multiple users without open registration.
Decision¶
AWS Cognito
Rejected alternative¶
Password protection of a static HTML page
Rationale¶
-
AWS Cognito has built-in account management, registration, 2FA, brute-force protection, etc. The service integrates seamlessly into the AWS ecosystem. Project needs fit within the Free tier (<10,000 MAU).
-
HTML password protection is poorly adapted to brute-force attacks; changing the password via code changes is not best practice. No ability to separate access between multiple users.
-
A custom access management system is over-engineering on top of a single business process.
Trade-offs¶
- Free tier terms may change and user management functionality may become paid. Solution cost must be re-evaluated.
... Key ADRs are presented only partially for demonstration purposes
Roadmap and Demonstration¶
Roadmap¶
| Phase | Goal | Changes | Exit criteria |
|---|---|---|---|
| v1 | Basic transcription | upload, async transcription, status, download | stable processing of long files |
| v1.1 | Operational resilience | stuck job detection, quota and budget alerts, old log cleanup, old file cleanup | predictable operation without manual monitoring |
| v2 | Transcript post-processing | speaker-aware summarization | user receives not only a transcript but also a brief summary |
| v3 | Format expansion | additional formats, metadata extraction | less manual preparation of source audio and transcript post-processing |
Screenshots and demo¶
Main menu¶
Uploading an audio recording¶
File processing¶
What this project demonstrates¶
This project demonstrates my ability to:
- translate a personal/operational need into requirements, constraints, and an architectural solution;
- design a serverless process accounting for long asynchronous operations;
- use AWS services to minimize ongoing costs;
- bypass API Gateway/Lambda limits via direct upload to S3 object storage;
- design a state machine for the job lifecycle;
- apply Cognito, JWT, and presigned URLs for restricted file access;
- document architectural trade-offs through ADRs;
- use Terraform for reproducible infrastructure deployment.


