Files
audio-scribe/pyproject.toml
T
JMR-devandClaude Opus 5 605275e37e feat(jobs): add run configuration and the per-job runner
Retention deletions are sequenced so the guarantee actually holds: the video
goes only after the FLAC is extracted, verified and committed, and the FLAC only
after every output is written and committed. Each deletion records itself both
in state.json and in events.jsonl, so a later run can tell "removed as
requested" from "gone and should not be".

Two bugs the tests caught while writing this:

- params_changed compared the requested model id against the resolved one, so
  every re-run looked like a parameter change and re-transcribed. An unpinned
  model now matches whatever ran; only an explicit --model can disagree.
- chain=DEFAULT_CHAIN as a default argument binds at import time, which made
  the backend chain impossible to override. It is resolved at call time now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-13 15:04:43 -05:00

107 lines
2.8 KiB
TOML

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "ccn-transcribe"
version = "0.1.0"
description = "Download videos, extract FLAC, and transcribe with Whisper on whatever GPU is present."
requires-python = ">=3.12"
dependencies = [
"click>=8.1,<9",
"numpy>=2.5,<3",
"huggingface-hub>=1.31,<2",
"yt-dlp[default,deno]>=2026.8.19",
"yt-dlp-ejs>=0.8",
"openvino==2026.3.1",
"openvino-genai==2026.3.1.0",
]
[project.scripts]
ccn-transcribe = "ccn_transcribe.cli:main"
[dependency-groups]
dev = [
"pytest>=8",
"pytest-cov>=5",
"ruff>=0.6",
"pyright>=1.1.380",
"mypy>=1.11",
"pylint>=3.2",
"pre-commit>=3.8",
]
[tool.hatch.build.targets.wheel]
packages = ["src/ccn_transcribe"]
[tool.ruff]
line-length = 100
src = ["src", "tests"]
# ruff format also restyles Python blocks inside Markdown; docs are not ours to restyle.
extend-exclude = ["*.md"]
[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "SIM", "PTH", "RET", "ARG", "TID", "TC", "RUF", "S"]
# S607: binaries are looked up on PATH on purpose and preflight-checked with
# shutil.which; hardcoding absolute paths would be less portable, not safer.
ignore = ["S607"]
[tool.ruff.lint.per-file-ignores]
# S101: asserts are the point of a test file.
"tests/*" = ["ARG001", "ARG002", "S101"]
# Throwaway benchmarks, not pipeline code.
"scripts/*" = ["S603"]
[tool.pyright]
include = ["src", "tests"]
typeCheckingMode = "strict"
venvPath = "."
venv = ".venv"
[tool.mypy]
strict = true
files = ["src", "tests"]
[[tool.mypy.overrides]]
# These ship no py.typed marker.
module = ["openvino.*", "openvino_genai.*", "huggingface_hub.*", "yt_dlp.*"]
ignore_missing_imports = true
[tool.pylint.design]
max-attributes = 20
# Keyword-only arguments do not carry the readability cost this check guards against.
max-args = 9
# Pipeline entry points carry injectable seams for testing.
max-locals = 18
[tool.pylint.main]
# W0621: pytest fixtures shadow their names by design.
# C1803: asserting == () is more precise than truthiness about what a call returns.
# R0903: dataclasses and pytest grouping classes legitimately have few methods.
disable = [
"C0114", "C0115", "C0116", "C0301",
"W0611", "W0612", "W0621",
"R0801", "R0903", "C1803",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
# NOTE: --cov-fail-under deliberately lives in the pre-commit hook, not here, so a
# single-file TDD run (`uv run pytest tests/test_x.py`) is not blocked by coverage.
addopts = "-q"
[tool.coverage.run]
branch = true
source = ["src/ccn_transcribe"]
[tool.coverage.report]
fail_under = 100
show_missing = true
exclude_also = [
"if TYPE_CHECKING:",
'if __name__ == "__main__":',
"@overload",
"raise NotImplementedError",
"class .*\\(Protocol\\):",
]