Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions authors/lucas_chinook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Author: Lucas Chinook Title: AI Engineer Description: Lucas Chinook builds
developer automation, AI-assisted coding workflows, and reproducible cloud
development guides. Lucas focuses on practical systems that engineers can
verify locally before they rely on them in production. Author GitHub:
[GitHub](https://github.com/chinook1001)
30 changes: 30 additions & 0 deletions definitions/20260530_definition_service_instance_transcription.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Service Instance Transcription"
description: "Service instance transcription sends prepared audio to a cloud speech-to-text endpoint that is scoped to one provider account or deployment."
date: 2026-05-30
author: "Lucas Chinook"
---

# Service Instance Transcription

## Definition

Service instance transcription is a speech-to-text workflow where audio is sent
to a cloud service URL that belongs to a specific provider instance, region, or
deployment. Instead of calling a single global endpoint, the client combines an
account-specific service URL with an API key or access token, then requests a
transcript for a prepared audio file.

## Context and Usage

This pattern is common for enterprise speech platforms because credentials,
region, data handling rules, and available models are often tied to a service
instance. IBM Watson Speech to Text is one example: a project stores an API key
and a service URL, then calls the instance's `/v1/recognize` endpoint with a
content type such as `audio/wav`.

Inside a reproducible development environment, service instance transcription
is easier to operate safely. The workspace can keep secrets in `.env`, convert
audio into a provider-supported format, run the same transcription command
across test clips, and document which model was used. This makes transcripts
more auditable than a one-off upload from a developer laptop.
332 changes: 332 additions & 0 deletions guides/20260530_run_ibm_watson_speech_to_text_with_sapat_in_daytona.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,332 @@
---
title: 'Run IBM Watson Speech to Text With Sapat in Daytona'
description:
'Create a reproducible Daytona workspace for transcribing media with Sapat
and IBM Watson Speech to Text.'
date: 2026-05-30
author: 'Lucas Chinook'
tags: ['AI', 'transcription', 'python', 'daytona']
---

# Run IBM Watson Speech to Text With Sapat in Daytona

Speech-to-text work gets messy when the service URL, API key, audio conversion,
and model choice all live on a single developer machine. A Daytona workspace
turns that setup into a repeatable project. Sapat handles media conversion and
provider routing. IBM Watson Speech to Text handles the transcript request
through a service-instance endpoint.

This guide shows how to run Sapat with IBM Watson Speech to Text inside a
Daytona workspace. The workflow uses a companion Sapat provider implementation
in [nibzard/sapat#62](https://github.com/nibzard/sapat/pull/62). It is designed
for AI engineers who need a predictable [service instance transcription](../definitions/20260530_definition_service_instance_transcription.md)
workflow without committing keys, private recordings, or generated transcripts.

![Sapat IBM Watson workflow](./assets/20260530_run_ibm_watson_speech_to_text_with_sapat_in_daytona_workflow.svg)

## What You Will Build

You will create a small transcription workspace with:

- A Daytona workspace cloned from Sapat.
- A local `.env` file for IBM Watson Speech to Text credentials.
- An input folder for short test recordings.
- A repeatable Sapat command that converts media to WAV and calls IBM's
synchronous `POST /v1/recognize` endpoint.
- A review checklist for validating transcript output before using it in a
downstream AI workflow.

The result is not a magic upload button. It is a developer-friendly runbook:
clone, configure, transcribe, inspect, and repeat.

## Prerequisites

Before starting, make sure you have:

- [Daytona](https://github.com/daytonaio/daytona) installed and authenticated.
- Python 3.9 or newer available in the workspace.
- `ffmpeg`, because Sapat converts source media before sending audio to a
provider.
- A Sapat branch or release that includes the `ibm_watson` provider.
- An IBM Watson Speech to Text service instance, API key, and service URL.

IBM documents the synchronous HTTP interface as a single `POST /v1/recognize`
method for speech recognition requests. The API reference also lists supported
audio content types and notes that synchronous recognize requests accept audio
data and return final transcription results. The Sapat provider in this guide
uses that synchronous flow with basic API key authentication.

## Step 1: Create the Workspace Project

Create a small project folder for the IBM Watson transcription workflow:

```bash
mkdir sapat-ibm-watson-daytona
cd sapat-ibm-watson-daytona
```

Add a minimal README so future runs explain what the folder is for:

```bash
cat > README.md <<'EOF'
# Sapat IBM Watson Transcription

This workspace runs Sapat with IBM Watson Speech to Text.
Secrets stay in .env. Source media stays in input/. Transcript outputs are
reviewed before being used in downstream AI workflows.
EOF
```

Create the folder layout:

```bash
mkdir -p input transcripts notes
touch .gitignore
printf ".env\ninput/*\ntranscripts/*\n" >> .gitignore
```

Keep sample files short while validating the provider. IBM's synchronous API is
best for direct request-response checks, so start with a short WAV or MP4 clip
before moving to longer recordings.

## Step 2: Open the Project in Daytona

Initialize Git and create the workspace:

```bash
git init
git add README.md .gitignore
git commit -m "Initialize IBM Watson transcription workspace"
daytona create . --code
```

Inside the Daytona workspace terminal, install system and Python dependencies:

```bash
sudo apt-get update
sudo apt-get install -y ffmpeg
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
```

Install Sapat from the companion branch while the provider PR is under review:

```bash
python -m pip install \
"git+https://github.com/chinook1001/sapat.git@codex/ibm-watson-provider"
```

After the provider lands upstream, switch the install URL back to the main Sapat
repository:

```bash
python -m pip install "git+https://github.com/nibzard/sapat.git"
```

## Step 3: Configure IBM Watson Credentials

Create `.env` locally in the workspace. Do not commit this file.

```bash
cat > .env <<'EOF'
IBM_WATSON_STT_API_KEY=replace-with-your-api-key
IBM_WATSON_STT_URL=https://api.us-south.speech-to-text.watson.cloud.ibm.com/instances/replace-with-instance-id
IBM_WATSON_STT_TIMEOUT=120
EOF
```

Load the variables for the current shell:

```bash
set -a
. ./.env
set +a
```

Confirm the variables are present without printing the secret:

```bash
test -n "$IBM_WATSON_STT_API_KEY" && echo "IBM Watson key loaded"
test -n "$IBM_WATSON_STT_URL" && echo "IBM Watson service URL loaded"
```

IBM service URLs are instance-specific. Keep the exact URL from the IBM Cloud
resource page, including its region and instance path. Sapat appends
`/v1/recognize` when it sends the transcription request.

## Step 4: Prepare a Safe Test Clip

Copy a short, non-sensitive recording into `input/`:

```bash
cp ~/Downloads/product-demo-short.mp4 input/product-demo-short.mp4
```

If you already have a WAV file, that is fine too. The IBM provider prefers WAV,
so Sapat will ask `ffmpeg` to convert video or compressed audio into a 16 kHz
mono WAV file before upload. That keeps the content type explicit and avoids
guessing at the provider boundary.

For the first validation run, use a clip under one minute with known wording.
Write the expected names, product terms, or acronyms in `notes/expected.md`:

```bash
cat > notes/expected.md <<'EOF'
# Expected Terms

- Daytona
- Sapat
- IBM Watson Speech to Text
- service instance transcription
EOF
```

## Step 5: Run Sapat With IBM Watson

Run Sapat with the provider name and a model:

```bash
sapat input/product-demo-short.mp4 \
--provider ibm_watson \
--model en-US_BroadbandModel \
--language en \
--quality H
```

The command prints the selected provider and model, converts the source file to
WAV, sends the WAV bytes to IBM Watson Speech to Text, writes the transcript as
`input/product-demo-short.txt`, and removes the temporary WAV file.

Move the transcript into the review folder:

```bash
mv input/product-demo-short.txt transcripts/product-demo-short.ibm-watson.txt
```

Then create a compact run note:

```bash
cat > notes/product-demo-short.ibm-watson.md <<'EOF'
# IBM Watson Transcription Run

- Provider: ibm_watson
- Model: en-US_BroadbandModel
- Source: input/product-demo-short.mp4
- Output: transcripts/product-demo-short.ibm-watson.txt
- Reviewer:
- Issues:
EOF
```

## Step 6: Review the Transcript

Before sending the transcript into an AI summarizer or retrieval pipeline, check
the basics:

- Does the transcript include the expected product names?
- Are acronyms readable enough to search?
- Are speaker turns or topic transitions obvious from the text?
- Did the command use the intended IBM service instance URL?
- Was the audio safe to send to the provider?

For a repeatable comparison, keep a small shell helper:

```bash
cat > run-ibm-watson.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

input="${1:?usage: ./run-ibm-watson.sh input/file.mp4}"
base="$(basename "${input%.*}")"

sapat "$input" \
--provider ibm_watson \
--model "${IBM_WATSON_STT_MODEL:-en-US_BroadbandModel}" \
--language "${IBM_WATSON_STT_LANGUAGE:-en}" \
--quality "${SAPAT_QUALITY:-H}"

mkdir -p transcripts
mv "${input%.*}.txt" "transcripts/${base}.ibm-watson.txt"
EOF
chmod +x run-ibm-watson.sh
```

Now each new recording uses the same provider settings:

```bash
./run-ibm-watson.sh input/standup-demo.mp4
```

## Step 7: Validate the Provider Path

The companion Sapat PR includes mocked tests for the provider. You can run the
same focused checks in the workspace:

```bash
git clone https://github.com/chinook1001/sapat.git
cd sapat
git checkout codex/ibm-watson-provider
python -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev]"
python -m pytest tests/providers/test_ibm_watson.py tests/test_registry.py -q
python -m black --check sapat/providers/ibm_watson.py tests/providers/test_ibm_watson.py
python -m compileall sapat/providers/ibm_watson.py tests/providers/test_ibm_watson.py
git diff --check
```

The tests verify that the provider:

- Registers only when `IBM_WATSON_STT_API_KEY` and `IBM_WATSON_STT_URL` are set.
- Calls the service instance's `/v1/recognize` endpoint.
- Sends binary audio with the correct `Content-Type`.
- Uses API key authentication.
- Extracts transcript text from IBM Watson recognition results.
- Raises useful errors when the API fails or returns no transcript text.

## Troubleshooting

**Problem:** Sapat says no providers are available.

**Solution:** Confirm the `.env` file is loaded and both IBM Watson variables
are set. The provider registry skips providers when required environment
variables are missing.

**Problem:** IBM returns an authentication error.

**Solution:** Check that the API key belongs to the Speech to Text instance
whose service URL you are using. A key from a different IBM service or region
will not authenticate the same request.

**Problem:** IBM returns an unsupported content type error.

**Solution:** Let Sapat convert to WAV instead of uploading the original file
directly. The provider maps `.wav` files to `audio/wav`, which IBM lists as a
supported recognition content type.

**Problem:** The transcript is empty.

**Solution:** Try a clearer audio sample, verify that the file is longer than a
short silence-only clip, and review whether the selected model matches the
recording language. The provider raises an error when IBM returns no transcript
text so the run is not mistaken for a successful blank transcript.

## Conclusion

You now have a reproducible Daytona workflow for running Sapat with IBM Watson
Speech to Text. Daytona keeps the development environment consistent, Sapat
handles conversion and provider routing, and IBM Watson processes the prepared
audio through a service-instance endpoint.

The important habit is to treat the transcript as a build artifact. Keep the
raw media private, load secrets from `.env`, write down the provider and model,
and review the text before sending it to another AI system.

## References

- [IBM Speech to Text getting started documentation](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-gettingStarted)
- [IBM Speech to Text API reference](https://cloud.ibm.com/apidocs/speech-to-text)
- [IBM synchronous HTTP interface documentation](https://cloud.ibm.com/docs/speech-to-text?topic=speech-to-text-http)
- [Sapat IBM Watson provider PR](https://github.com/nibzard/sapat/pull/62)
- [Sapat repository](https://github.com/nibzard/sapat)
Loading