whisperX-FastAPI
CLAUDE.md188 starsChanged 7 months agoMITArchived repositoryView on GitHub
whisperX-FastAPI is a REST API built with FastAPI that provides async audio/video transcription, alignment, speaker diarization, and transcript combination using WhisperX. Tasks are processed as background jobs with results tracked in a database. All developer commands are defined in Taskfile.yml (with includes in taskfiles/). Run task --list to see all available tasks. go-task is installed automatically via the devcontainer feature. Layered Architecture with Repository Pattern and Dependency Injection Container (dependency-injector library). Each folder below has its own CLAUDE.md with layer-specific…
- Reads credentials
We split this CLAUDE.md into the rules it gives an agent
29 rules. About 0 are common, 18 are distinctive, and 11 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈18
Distinctive · estimate
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 16
All developer commands are defined in Taskfile.yml (with includes in taskfiles/).
- Very specific: line 17
Run task --list to see all available tasks.
- Very specific: line 98
Create a .env file in the repo root:
- Very specific: line 123
Critical: When DEVICE=cpu, COMPUTE_TYPE is auto-corrected to int8.
- Distinctive: line 156
When a request is ambiguous, present the possible interpretations and ask which is intended.
- Distinctive: line 158
Stop when confused. Name what's unclear and ask for clarification.
- Distinctive: line 165
No features beyond what was asked.
- Distinctive: line 166
No abstractions for single-use code.
- Distinctive: line 167
No speculative "flexibility" or "configurability" that wasn't requested.
- Distinctive: line 168
No error handling for impossible scenarios.
- Distinctive: line 169
If the code you're writing could be 50 lines instead of 200, write the 50.
- Distinctive: line 174
Don't "improve" adjacent code, comments, or formatting.
- Distinctive: line 175
Don't refactor things that aren't broken.
- Distinctive: line 177
If you notice unrelated dead code, mention it — don't delete it.
- Very specific: line 178
Remove imports/variables/functions that your changes made unused.
- Distinctive: line 179
Don't remove pre-existing unused code unless asked.
- Distinctive: line 183
Follow Test-Driven Development for all new features and bug fixes:
- Distinctive: line 195
All new code must have tests written before implementation
- Very specific: line 196
Run task test after every change — ensure coverage ≥80% overall
- Very specific: line 198
Check coverage gaps proactively: uv run pytest --cov=app --cov-report=term-missing
- Distinctive: line 199
Never commit untested code paths — if you wrote it, test it first
- Very specific: line 206
Use factories (tests/factories/) over inline object construction
- Very specific: line 207
Use mocks (tests/mocks/) — extend existing mocks rather than adding conditional logic
- Distinctive: line 211
Write a test that reproduces the bug (must fail)
- Very specific: line 214
Check no regressions: task test
- Distinctive: line 218
When modifying file contents (especially Markdown/YAML frontmatter), validate that existing fields are preserved
- Distinctive: line 220
Never replace entire file contents when only a section needs updating
- Very specific: line 226
Before creating a PR, run: task check (lint + format + typecheck) and task test
- Distinctive: line 229
Verify coverage meets threshold before pushing, not after CI fails
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Project Guide
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
whisperX-FastAPI is a REST API built with FastAPI that provides async audio/video transcription, alignment, speaker diarization, and transcript combination using WhisperX. Tasks are processed as background jobs with results tracked in a database.
- Package manager:
uv— always useuv runfor all Python commands - Database: SQLAlchemy ORM (default: SQLite, configurable via
DB_URL) - Container runtime: Docker with NVIDIA CUDA (CPU fallback supported)
- See
pyproject.tomlfor exact Python and dependency versions.
Commands
All developer commands are defined in Taskfile.yml (with includes in taskfiles/).
Run task --list to see all available tasks. go-task is
installed automatically via the devcontainer feature.
Install dependencies
task deps # includes dev tools (linters, tests)
task deps:prod # production onlyRun locally
task runRun with Docker
task docker:restart # stop, start, follow logs
task docker:up # start in background
task docker:down # stop
task docker:logs # follow logsTest
task test # all tests with coverage (CI requires ≥80%)
task test:unit # unit tests only
task test:fast # exclude slow and load markers
task test:ci # full CI command with XML reports
# Single test file (use uv directly)
uv run pytest tests/unit/domain/entities/test_task.pyLint and format
task lint # ruff check --fix
task format # ruff format
task typecheck # mypy app/
task check # all three sequentially
task pre-commit # run all pre-commit hooksDependency changes
task deps:lock # regenerate uv.lock + syncArchitecture
Layered Architecture with Repository Pattern and Dependency Injection Container
(dependency-injector library). Each folder below has its own CLAUDE.md with
layer-specific guidance.
app/
├── main.py # FastAPI app, lifespan, health endpoints, router registration
├── api/ # HTTP layer: routers, schemas, mappers, DI wiring
│ ├── audio_api.py # Speech-to-text (full pipeline) endpoints
│ ├── audio_services_api.py # Individual service endpoints (transcribe/align/diarize)
│ ├── task_api.py # Task management endpoints
│ ├── dependencies.py # Injects services from Container via Depends()
│ ├── schemas/ # Pydantic request/response models
│ ├── mappers/ # API schema ↔ domain entity conversion
│ └── exception_handlers.py # Maps domain exceptions → HTTP responses
├── core/ # Config, DI Container, exception hierarchy → see app/core/CLAUDE.md
├── domain/ # Pure Python entities, repository + ML service interfaces → see app/domain/CLAUDE.md
├── infrastructure/ # SQLAlchemy + WhisperX implementations → see app/infrastructure/CLAUDE.md
└── services/ # Business logic orchestration → see app/services/CLAUDE.md
tests/ # Markers, mocks, factories, coverage → see tests/CLAUDE.md
docs/ # ADRs, stories, config migration guide → see docs/CLAUDE.mdEnvironment Variables
Create a .env file in the repo root:
HF_TOKEN=<huggingface-token> # required for diarization model downloads
WHISPER_MODEL=tiny # tiny/base/small/medium/large/distil-*
DEFAULT_LANG=en
DEVICE=cuda # cuda or cpu
COMPUTE_TYPE=float16 # float16/float32/int8 — MUST be int8 when DEVICE=cpu
LOG_LEVEL=INFO
ENVIRONMENT=production
DB_URL=sqlite:///records.db
MAX_CONCURRENT_GPU_TASKS=1 # max simultaneous GPU tasks (prevents OOM)
# API protection (all no-op by default — see app/core/config.py)
MAX_UPLOAD_SIZE_MB=0 # 413 over this many MB; 0 = unlimited
MAX_QUEUED_GPU_REQUESTS=0 # 503 when in-flight GPU requests exceed cap; 0 = unlimited
SYNC_GPU_QUOTA_FRACTION=0.5 # share of MAX_QUEUED_GPU_REQUESTS for the sync (/v1/audio/*) path
RATE_LIMIT__ENABLED=false # slowapi per-caller limiting → 429 + Retry-After
RATE_LIMIT__REQUESTS_PER_MINUTE=60
RATE_LIMIT__BURST=10
RATE_LIMIT__KEY_STRATEGY=ip # ip | bearer_token
AUTH__ENABLED=false # shared bearer-token auth → 401
AUTH__BEARER_TOKEN= # required when AUTH__ENABLED=trueCritical: When DEVICE=cpu, COMPUTE_TYPE is auto-corrected to int8. Tests set
DEVICE=cpu and COMPUTE_TYPE=int8 automatically.
API protection (rate limiting, upload cap, route concurrency caps, bearer auth) lives
in app/core/{rate_limit,concurrency}.py, app/api/{middleware,security}.py, and is wired
in main.py. Knobs come from get_settings() (loaded from env/.env at startup and
lru_cache-backed), so they are fixed for the life of the process and stay no-op until
enabled — changing them needs a restart (tests clear the caches to re-read). The upload cap
is enforced from Content-Length; the async concurrency gate is admission control (the
background GPU pipeline is bounded by MAX_CONCURRENT_GPU_TASKS). Multi-worker deployments
give each worker its own in-process budget.
CI Pipeline
.github/workflows/CI.yaml triggers on PRs and pushes to main/dev when app/,
tests/, dockerfile, docker-compose.yml, or pyproject.toml change.
Jobs: lint → test (≥80% coverage) → dependency-review + build (Docker + Trivy scan) → release-please (main only).
Dependency updates (uv packages, GitHub Actions, Docker images, pre-commit hooks) are
managed by Renovate (renovate.json), batched monthly. ML-critical packages (PyTorch,
huggingface-hub, whisperx) require manual review; minor/patch updates for all other
groups auto-merge after CI passes.
PyTorch wheels: uv.lock is platform-specific (CUDA on Linux x86_64, CPU on
macOS/Windows). Never manually edit uv.lock.
Coding Discipline
Think Before Coding
- State assumptions explicitly before writing code. If uncertain, ask rather than guess.
- When a request is ambiguous, present the possible interpretations and ask which is intended.
- Push back when a simpler approach exists — suggest it before building the complex one.
- Stop when confused. Name what's unclear and ask for clarification.
- Frame tasks as goals with verification checkpoints — "add validation" becomes "write tests for invalid inputs, then make them pass"; "refactor X" becomes "ensure tests pass before and after". For multi-step tasks, state a plan before starting.
Simplicity First
- No features beyond what was asked.
- No abstractions for single-use code.
- No speculative "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If the code you're writing could be 50 lines instead of 200, write the 50. (Applies to new code — see Surgical Changes for existing code.)
Surgical Changes
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it — don't delete it.
- Remove imports/variables/functions that your changes made unused.
- Don't remove pre-existing unused code unless asked.
Testing — TDD Process
Follow Test-Driven Development for all new features and bug fixes:
TDD Workflow
- Write failing tests first — before writing any implementation code, write tests that define the expected behavior. Run them to confirm they fail.
- Implement the minimum code to make the tests pass — no more, no less.
- Refactor — clean up the implementation while keeping tests green.
- Repeat for each new behavior or code path.
Coverage Rules
- All new code must have tests written before implementation
- Run
task testafter every change — ensure coverage ≥80% overall - Target >80% coverage on new code specifically (SonarCloud new code gate)
- Check coverage gaps proactively:
uv run pytest --cov=app --cov-report=term-missing - Never commit untested code paths — if you wrote it, test it first
Test Organization
- Unit tests (
tests/unit/) for isolated logic — mock all external deps - E2e tests (
tests/e2e/) for API endpoints — test full request/response cycle - Integration tests (
tests/integration/) for real DB or service interaction - Use factories (
tests/factories/) over inline object construction - Use mocks (
tests/mocks/) — extend existing mocks rather than adding conditional logic
When Fixing Bugs
- Write a test that reproduces the bug (must fail)
- Fix the bug
- Confirm the test passes
- Check no regressions:
task test
Data Integrity
- When modifying file contents (especially Markdown/YAML frontmatter), validate that existing fields are preserved
- Never replace entire file contents when only a section needs updating
- For batch operations, process in small batches with validation between each
- See also Surgical Changes above for scope discipline when modifying code.
PR Workflow
- Before creating a PR, run:
task check(lint + format + typecheck) andtask test - Address style violations proactively — check for unused imports, consistent naming
(
str | NonenotOptional[str]), and docstrings on public methods - Verify coverage meets threshold before pushing, not after CI fails
PR titles must be Conventional Commits
The .github/workflows/pr-title-lint.yml workflow (added in #539) enforces
Conventional Commits for every PR title via
amannn/action-semantic-pull-request. The PR will fail CI if the title doesn't match.
Why it matters: PRs are squash-merged, so the PR title becomes the merge commit subject on
the target branch. release-please parses those subjects on main to decide the version
bump and to build the changelog — a non-conventional title (e.g. Dev) flattens everything
behind a single unrecognized commit and the release detection breaks.
Allowed types: feat:, fix:, chore:, docs:, refactor:, test:, ci:, build:,
perf:, style:, revert: (the action-semantic-pull-request defaults). Use a scope when
useful — e.g. feat(security): ..., fix(api): ..., chore(deps): .... Mark breaking
changes with ! (e.g. feat(api)!: ...).
The dev → main release PR is also subject to this rule: title it with a conventional
prefix (e.g. feat: … or chore(main): release X.Y.Z) so release-please can detect it
after the squash. Do not title it Dev.
In this repository6 other files it gives its agents.
- app/CLAUDE.mdCLAUDE.md
- docs/CLAUDE.mdCLAUDE.md
- tests/CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- coverage-checkSkill
- pr-readySkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

