webinar-transcriber 1.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- webinar_transcriber-1.3.0/.editorconfig +16 -0
- webinar_transcriber-1.3.0/.gitattributes +6 -0
- webinar_transcriber-1.3.0/.github/dependabot.yml +21 -0
- webinar_transcriber-1.3.0/.github/workflows/ci.yml +36 -0
- webinar_transcriber-1.3.0/.github/workflows/codeql.yml +40 -0
- webinar_transcriber-1.3.0/.github/workflows/release.yml +122 -0
- webinar_transcriber-1.3.0/.gitignore +214 -0
- webinar_transcriber-1.3.0/.markdownlint.json +5 -0
- webinar_transcriber-1.3.0/.mdformat.toml +1 -0
- webinar_transcriber-1.3.0/.prettierrc.json +11 -0
- webinar_transcriber-1.3.0/.python-version +1 -0
- webinar_transcriber-1.3.0/.vscode/extensions.json +6 -0
- webinar_transcriber-1.3.0/.vscode/settings.json +8 -0
- webinar_transcriber-1.3.0/AGENTS.md +188 -0
- webinar_transcriber-1.3.0/LICENSE +21 -0
- webinar_transcriber-1.3.0/LICENSE-3RDPARTY.md +27 -0
- webinar_transcriber-1.3.0/Makefile +77 -0
- webinar_transcriber-1.3.0/PKG-INFO +335 -0
- webinar_transcriber-1.3.0/README.md +273 -0
- webinar_transcriber-1.3.0/docs/assets/social-preview-dark.png +0 -0
- webinar_transcriber-1.3.0/docs/assets/social-preview.png +0 -0
- webinar_transcriber-1.3.0/docs/development.md +63 -0
- webinar_transcriber-1.3.0/docs/pipeline.md +92 -0
- webinar_transcriber-1.3.0/docs/releasing.md +42 -0
- webinar_transcriber-1.3.0/docs/troubleshooting.md +65 -0
- webinar_transcriber-1.3.0/pyproject.toml +253 -0
- webinar_transcriber-1.3.0/uv.lock +2092 -0
- webinar_transcriber-1.3.0/webinar_transcriber/__init__.py +27 -0
- webinar_transcriber-1.3.0/webinar_transcriber/__main__.py +8 -0
- webinar_transcriber-1.3.0/webinar_transcriber/_env.py +56 -0
- webinar_transcriber-1.3.0/webinar_transcriber/_version.py +24 -0
- webinar_transcriber-1.3.0/webinar_transcriber/asr/__init__.py +22 -0
- webinar_transcriber-1.3.0/webinar_transcriber/asr/carryover.py +21 -0
- webinar_transcriber-1.3.0/webinar_transcriber/asr/config.py +20 -0
- webinar_transcriber-1.3.0/webinar_transcriber/asr/transcriber.py +362 -0
- webinar_transcriber-1.3.0/webinar_transcriber/asr/windows.py +43 -0
- webinar_transcriber-1.3.0/webinar_transcriber/assets/__init__.py +1 -0
- webinar_transcriber-1.3.0/webinar_transcriber/assets/silero_vad.onnx +0 -0
- webinar_transcriber-1.3.0/webinar_transcriber/cli.py +132 -0
- webinar_transcriber-1.3.0/webinar_transcriber/diagnostics.py +41 -0
- webinar_transcriber-1.3.0/webinar_transcriber/diarization/__init__.py +76 -0
- webinar_transcriber-1.3.0/webinar_transcriber/diarization/sherpa_diarizer.py +361 -0
- webinar_transcriber-1.3.0/webinar_transcriber/export/__init__.py +9 -0
- webinar_transcriber-1.3.0/webinar_transcriber/export/docx_report.py +131 -0
- webinar_transcriber-1.3.0/webinar_transcriber/export/formatting.py +56 -0
- webinar_transcriber-1.3.0/webinar_transcriber/export/json_report.py +22 -0
- webinar_transcriber-1.3.0/webinar_transcriber/export/markdown.py +59 -0
- webinar_transcriber-1.3.0/webinar_transcriber/io.py +15 -0
- webinar_transcriber-1.3.0/webinar_transcriber/llm/__init__.py +19 -0
- webinar_transcriber-1.3.0/webinar_transcriber/llm/processor.py +270 -0
- webinar_transcriber-1.3.0/webinar_transcriber/llm/prompts.py +57 -0
- webinar_transcriber-1.3.0/webinar_transcriber/llm/providers.py +96 -0
- webinar_transcriber-1.3.0/webinar_transcriber/llm/types.py +37 -0
- webinar_transcriber-1.3.0/webinar_transcriber/llm/utils.py +238 -0
- webinar_transcriber-1.3.0/webinar_transcriber/media.py +159 -0
- webinar_transcriber-1.3.0/webinar_transcriber/models.py +278 -0
- webinar_transcriber-1.3.0/webinar_transcriber/normalized_audio.py +123 -0
- webinar_transcriber-1.3.0/webinar_transcriber/paths.py +103 -0
- webinar_transcriber-1.3.0/webinar_transcriber/processor.py +529 -0
- webinar_transcriber-1.3.0/webinar_transcriber/py.typed +0 -0
- webinar_transcriber-1.3.0/webinar_transcriber/segmentation.py +152 -0
- webinar_transcriber-1.3.0/webinar_transcriber/structure.py +197 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/__init__.py +1 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/conftest.py +371 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/fixtures/sample-audio.mp3 +0 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/fixtures/sample-video.mp4 +0 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/fixtures/speech-sample.wav +0 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_asr.py +515 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_cli.py +314 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_coalesce.py +139 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_diarization.py +677 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_export.py +401 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_llm.py +752 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_llm_utils.py +133 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_media.py +191 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_models.py +136 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_normalized_audio.py +381 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_paths.py +66 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_processor.py +866 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_reconciliation.py +146 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_structure.py +339 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_ui.py +141 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_version.py +28 -0
- webinar_transcriber-1.3.0/webinar_transcriber/tests/test_video_pipeline.py +207 -0
- webinar_transcriber-1.3.0/webinar_transcriber/text_utils.py +38 -0
- webinar_transcriber-1.3.0/webinar_transcriber/transcript/__init__.py +8 -0
- webinar_transcriber-1.3.0/webinar_transcriber/transcript/coalesce.py +85 -0
- webinar_transcriber-1.3.0/webinar_transcriber/transcript/reconcile.py +99 -0
- webinar_transcriber-1.3.0/webinar_transcriber/ui.py +181 -0
- webinar_transcriber-1.3.0/webinar_transcriber/video/__init__.py +15 -0
- webinar_transcriber-1.3.0/webinar_transcriber/video/scenes.py +214 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*.md]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
insert_final_newline = true
|
|
7
|
+
max_line_length = 100
|
|
8
|
+
trim_trailing_whitespace = false
|
|
9
|
+
|
|
10
|
+
[*.sh]
|
|
11
|
+
indent_style = space
|
|
12
|
+
indent_size = 4
|
|
13
|
+
|
|
14
|
+
[*.json]
|
|
15
|
+
indent_style = space
|
|
16
|
+
indent_size = 4
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "uv"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
open-pull-requests-limit: 5
|
|
8
|
+
groups:
|
|
9
|
+
python-dependencies:
|
|
10
|
+
patterns:
|
|
11
|
+
- "*"
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "github-actions"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
open-pull-requests-limit: 5
|
|
18
|
+
groups:
|
|
19
|
+
github-actions:
|
|
20
|
+
patterns:
|
|
21
|
+
- "*"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
lint-test:
|
|
13
|
+
name: lint-test (${{ matrix.os }})
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ubuntu-latest, macos-latest]
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v6
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
- uses: actions/setup-python@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
- uses: astral-sh/setup-uv@v7
|
|
27
|
+
- name: Sync dependencies
|
|
28
|
+
run: uv sync --extra llm --group dev
|
|
29
|
+
- name: Smoke CLI help
|
|
30
|
+
run: uv run webinar-transcriber --help
|
|
31
|
+
- name: Smoke whisper runtime
|
|
32
|
+
run: uv run python -c "from pywhispercpp.model import Model; assert Model.system_info().strip()"
|
|
33
|
+
- name: Lint
|
|
34
|
+
run: make lint
|
|
35
|
+
- name: Test
|
|
36
|
+
run: make test-all
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "24 5 * * 2"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
analyze:
|
|
16
|
+
name: Analyze (${{ matrix.language }})
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
actions: read
|
|
20
|
+
contents: read
|
|
21
|
+
security-events: write
|
|
22
|
+
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
language: [actions, python]
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout repository
|
|
30
|
+
uses: actions/checkout@v6
|
|
31
|
+
|
|
32
|
+
- name: Initialize CodeQL
|
|
33
|
+
uses: github/codeql-action/init@v4
|
|
34
|
+
with:
|
|
35
|
+
languages: ${{ matrix.language }}
|
|
36
|
+
|
|
37
|
+
- name: Perform CodeQL Analysis
|
|
38
|
+
uses: github/codeql-action/analyze@v4
|
|
39
|
+
with:
|
|
40
|
+
category: "/language:${{ matrix.language }}"
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
validate:
|
|
11
|
+
name: validate (${{ matrix.os }})
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
strategy:
|
|
16
|
+
fail-fast: false
|
|
17
|
+
matrix:
|
|
18
|
+
os: [ubuntu-latest, macos-latest]
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v6
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
|
|
24
|
+
- uses: actions/setup-python@v6
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
|
|
28
|
+
- uses: astral-sh/setup-uv@v7
|
|
29
|
+
|
|
30
|
+
- name: Sync dependencies
|
|
31
|
+
run: uv sync --extra llm --group dev
|
|
32
|
+
|
|
33
|
+
- name: Smoke CLI help
|
|
34
|
+
run: uv run webinar-transcriber --help
|
|
35
|
+
|
|
36
|
+
- name: Smoke whisper runtime
|
|
37
|
+
run: uv run python -c "from pywhispercpp.model import Model; assert Model.system_info().strip()"
|
|
38
|
+
|
|
39
|
+
- name: Lint
|
|
40
|
+
run: make lint
|
|
41
|
+
|
|
42
|
+
- name: Test
|
|
43
|
+
run: make test-all
|
|
44
|
+
|
|
45
|
+
release:
|
|
46
|
+
needs: validate
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
permissions:
|
|
49
|
+
contents: write
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v6
|
|
52
|
+
with:
|
|
53
|
+
fetch-depth: 0
|
|
54
|
+
|
|
55
|
+
- uses: actions/setup-python@v6
|
|
56
|
+
with:
|
|
57
|
+
python-version: "3.12"
|
|
58
|
+
|
|
59
|
+
- uses: astral-sh/setup-uv@v7
|
|
60
|
+
|
|
61
|
+
- name: Sync dependencies
|
|
62
|
+
run: uv sync --extra llm --group dev
|
|
63
|
+
|
|
64
|
+
- name: Build package
|
|
65
|
+
run: uv build
|
|
66
|
+
|
|
67
|
+
- name: Upload artifacts
|
|
68
|
+
uses: actions/upload-artifact@v7
|
|
69
|
+
with:
|
|
70
|
+
name: dist
|
|
71
|
+
path: |
|
|
72
|
+
dist/*.whl
|
|
73
|
+
dist/*.tar.gz
|
|
74
|
+
|
|
75
|
+
- name: Create GitHub Release
|
|
76
|
+
if: github.event_name == 'push'
|
|
77
|
+
uses: softprops/action-gh-release@v3
|
|
78
|
+
with:
|
|
79
|
+
files: |
|
|
80
|
+
dist/*.whl
|
|
81
|
+
dist/*.tar.gz
|
|
82
|
+
|
|
83
|
+
publish-testpypi:
|
|
84
|
+
needs: release
|
|
85
|
+
if: github.event_name == 'workflow_dispatch'
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
environment:
|
|
88
|
+
name: testpypi
|
|
89
|
+
url: https://test.pypi.org/p/webinar-transcriber
|
|
90
|
+
permissions:
|
|
91
|
+
id-token: write
|
|
92
|
+
steps:
|
|
93
|
+
- name: Download built distributions
|
|
94
|
+
uses: actions/download-artifact@v7
|
|
95
|
+
with:
|
|
96
|
+
name: dist
|
|
97
|
+
path: dist
|
|
98
|
+
|
|
99
|
+
- name: Publish to TestPyPI
|
|
100
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
101
|
+
with:
|
|
102
|
+
repository-url: https://test.pypi.org/legacy/
|
|
103
|
+
skip-existing: true
|
|
104
|
+
|
|
105
|
+
publish-pypi:
|
|
106
|
+
needs: release
|
|
107
|
+
if: github.event_name == 'push'
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
environment:
|
|
110
|
+
name: pypi
|
|
111
|
+
url: https://pypi.org/p/webinar-transcriber
|
|
112
|
+
permissions:
|
|
113
|
+
id-token: write
|
|
114
|
+
steps:
|
|
115
|
+
- name: Download built distributions
|
|
116
|
+
uses: actions/download-artifact@v7
|
|
117
|
+
with:
|
|
118
|
+
name: dist
|
|
119
|
+
path: dist
|
|
120
|
+
|
|
121
|
+
- name: Publish to PyPI
|
|
122
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
webinar_transcriber/_version.py
|
|
54
|
+
runs/
|
|
55
|
+
models/.DS_Store
|
|
56
|
+
models/whisper-cpp/*.bin
|
|
57
|
+
models/whisper-cpp/*.wav
|
|
58
|
+
models/whisper-cpp/*.json
|
|
59
|
+
|
|
60
|
+
# Translations
|
|
61
|
+
*.mo
|
|
62
|
+
*.pot
|
|
63
|
+
|
|
64
|
+
# Django stuff:
|
|
65
|
+
*.log
|
|
66
|
+
local_settings.py
|
|
67
|
+
db.sqlite3
|
|
68
|
+
db.sqlite3-journal
|
|
69
|
+
|
|
70
|
+
# Flask stuff:
|
|
71
|
+
instance/
|
|
72
|
+
.webassets-cache
|
|
73
|
+
|
|
74
|
+
# Scrapy stuff:
|
|
75
|
+
.scrapy
|
|
76
|
+
|
|
77
|
+
# Sphinx documentation
|
|
78
|
+
docs/_build/
|
|
79
|
+
|
|
80
|
+
# PyBuilder
|
|
81
|
+
.pybuilder/
|
|
82
|
+
target/
|
|
83
|
+
|
|
84
|
+
# Jupyter Notebook
|
|
85
|
+
.ipynb_checkpoints
|
|
86
|
+
|
|
87
|
+
# IPython
|
|
88
|
+
profile_default/
|
|
89
|
+
ipython_config.py
|
|
90
|
+
|
|
91
|
+
# pyenv
|
|
92
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
93
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
94
|
+
# .python-version
|
|
95
|
+
.DS_Store
|
|
96
|
+
|
|
97
|
+
# pipenv
|
|
98
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
99
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
100
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
101
|
+
# install all needed dependencies.
|
|
102
|
+
#Pipfile.lock
|
|
103
|
+
|
|
104
|
+
# UV
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
106
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
107
|
+
# commonly ignored for libraries.
|
|
108
|
+
#uv.lock
|
|
109
|
+
|
|
110
|
+
# poetry
|
|
111
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
112
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
113
|
+
# commonly ignored for libraries.
|
|
114
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
115
|
+
#poetry.lock
|
|
116
|
+
#poetry.toml
|
|
117
|
+
|
|
118
|
+
# pdm
|
|
119
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
120
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
121
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
122
|
+
#pdm.lock
|
|
123
|
+
#pdm.toml
|
|
124
|
+
.pdm-python
|
|
125
|
+
.pdm-build/
|
|
126
|
+
|
|
127
|
+
# pixi
|
|
128
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
129
|
+
#pixi.lock
|
|
130
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
131
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
132
|
+
.pixi
|
|
133
|
+
|
|
134
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
135
|
+
__pypackages__/
|
|
136
|
+
|
|
137
|
+
# Celery stuff
|
|
138
|
+
celerybeat-schedule
|
|
139
|
+
celerybeat.pid
|
|
140
|
+
|
|
141
|
+
# SageMath parsed files
|
|
142
|
+
*.sage.py
|
|
143
|
+
|
|
144
|
+
# Environments
|
|
145
|
+
.env
|
|
146
|
+
.envrc
|
|
147
|
+
.venv
|
|
148
|
+
env/
|
|
149
|
+
venv/
|
|
150
|
+
ENV/
|
|
151
|
+
env.bak/
|
|
152
|
+
venv.bak/
|
|
153
|
+
|
|
154
|
+
# Spyder project settings
|
|
155
|
+
.spyderproject
|
|
156
|
+
.spyproject
|
|
157
|
+
|
|
158
|
+
# Rope project settings
|
|
159
|
+
.ropeproject
|
|
160
|
+
|
|
161
|
+
# mkdocs documentation
|
|
162
|
+
/site
|
|
163
|
+
|
|
164
|
+
# mypy
|
|
165
|
+
.mypy_cache/
|
|
166
|
+
.dmypy.json
|
|
167
|
+
dmypy.json
|
|
168
|
+
|
|
169
|
+
# Pyre type checker
|
|
170
|
+
.pyre/
|
|
171
|
+
|
|
172
|
+
# pytype static type analyzer
|
|
173
|
+
.pytype/
|
|
174
|
+
|
|
175
|
+
# Cython debug symbols
|
|
176
|
+
cython_debug/
|
|
177
|
+
|
|
178
|
+
# PyCharm
|
|
179
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
180
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
181
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
182
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
183
|
+
#.idea/
|
|
184
|
+
|
|
185
|
+
# Abstra
|
|
186
|
+
# Abstra is an AI-powered process automation framework.
|
|
187
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
188
|
+
# Learn more at https://abstra.io/docs
|
|
189
|
+
.abstra/
|
|
190
|
+
|
|
191
|
+
# Visual Studio Code
|
|
192
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
193
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
194
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
195
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
196
|
+
# .vscode/
|
|
197
|
+
|
|
198
|
+
# Ruff stuff:
|
|
199
|
+
.ruff_cache/
|
|
200
|
+
|
|
201
|
+
# PyPI configuration file
|
|
202
|
+
.pypirc
|
|
203
|
+
|
|
204
|
+
# Cursor
|
|
205
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
206
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
207
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
208
|
+
.cursorignore
|
|
209
|
+
.cursorindexingignore
|
|
210
|
+
|
|
211
|
+
# Marimo
|
|
212
|
+
marimo/_static/
|
|
213
|
+
marimo/_lsp/
|
|
214
|
+
__marimo__/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
wrap = 100
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# AGENTS
|
|
2
|
+
|
|
3
|
+
This file is the contributor and coding-agent guide for this repository.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
Documentation is organized by [Diátaxis](https://diataxis.fr) mode. Decide where content goes by
|
|
8
|
+
what it serves, not by which file is nearest:
|
|
9
|
+
|
|
10
|
+
- `README.md`: the entry point. A how-to quick start, user-facing reference (CLI flags, environment
|
|
11
|
+
variables, output layout), and a brief explanation of what the tool is.
|
|
12
|
+
- `docs/pipeline.md`: explanation. How and why the stages work; no step-by-step instructions and no
|
|
13
|
+
flag tables.
|
|
14
|
+
- `docs/troubleshooting.md`: how-to. Error-indexed fixes.
|
|
15
|
+
- `docs/development.md`: how-to and reference. Checkout setup, running from source, and the
|
|
16
|
+
make-target and quality-gate reference.
|
|
17
|
+
- `docs/releasing.md`: how-to. The release process.
|
|
18
|
+
- `AGENTS.md`: contributor and coding-agent process the user docs do not need.
|
|
19
|
+
|
|
20
|
+
When unsure, place content by Diátaxis axis: action for someone working is how-to, information for
|
|
21
|
+
someone working is reference, understanding is explanation. Keep modes separate within a file: do
|
|
22
|
+
not fold explanation into a how-to, or a flag table into the pipeline explanation.
|
|
23
|
+
|
|
24
|
+
Prefer extending `README.md` first. Add a new file under `docs/` only when a section is long enough
|
|
25
|
+
to obscure the user-facing flow and self-contained enough to read on its own.
|
|
26
|
+
|
|
27
|
+
Repository-visible assets stay under `docs/assets/`. The README preview uses GitHub's theme
|
|
28
|
+
suffixes: `social-preview.png#gh-light-mode-only` and `social-preview-dark.png#gh-dark-mode-only`.
|
|
29
|
+
Keep `social-preview-dark.png` suitable for the repository social-preview setting.
|
|
30
|
+
|
|
31
|
+
## Tooling
|
|
32
|
+
|
|
33
|
+
Keep setup docs and Makefile targets in sync. If you add, rename, or remove a `make install*`
|
|
34
|
+
target, update README in the same change. If you add, rename, or remove a `make sync*` target or
|
|
35
|
+
quality-gate target, update `docs/development.md` in the same change.
|
|
36
|
+
|
|
37
|
+
Use `make test` for quick iteration (fast subset, skips slow tests, no coverage gate). Run
|
|
38
|
+
`make format` then `make check` before committing — `make check` is the full coverage-gated gate.
|
|
39
|
+
|
|
40
|
+
GitHub Actions runs `make lint` and `make test-all` so CI mirrors the local quality gate. CI runs on
|
|
41
|
+
`ubuntu-latest` and `macos-latest`; Windows is not part of the CI matrix and is treated as
|
|
42
|
+
best-effort.
|
|
43
|
+
|
|
44
|
+
In sandboxed Codex runs, prefer `UV_CACHE_DIR=/tmp/uv-cache` for `uv` and `make` commands to avoid
|
|
45
|
+
cache-permission failures.
|
|
46
|
+
|
|
47
|
+
## Definition of Done
|
|
48
|
+
|
|
49
|
+
A change is ready to merge when all of the following hold:
|
|
50
|
+
|
|
51
|
+
- **Quality gates pass.** `make format && make check` runs cleanly — the full coverage-gated test
|
|
52
|
+
suite, `ruff`, `ty`, and the markdown linters.
|
|
53
|
+
- **100% coverage stays.** Add `# pragma: no cover` to genuinely unreachable defensive branches
|
|
54
|
+
rather than lowering the threshold.
|
|
55
|
+
- **Docs stay in sync.** If the change affects CLI flags, output artifacts, install targets, package
|
|
56
|
+
layout, or runtime contracts, update `README.md` and `AGENTS.md` in the same PR.
|
|
57
|
+
- **No dead code.** Remove unused imports, helpers with no callers, fields that are written or
|
|
58
|
+
serialized but never read back, and `# TODO` comments that will not be addressed in this PR.
|
|
59
|
+
- **PR has a summary and a test plan.** Each pull request description includes a brief summary and
|
|
60
|
+
an explicit test-plan checklist.
|
|
61
|
+
- **Commits follow Conventional Commits.** Prefix commit messages with `refactor:`, `docs:`, `ci:`,
|
|
62
|
+
`style:`, `feat:`, `fix:`, `test:`, `build:`, or `chore:`. Use an optional scope when it adds
|
|
63
|
+
clarity, for example `build(deps):`.
|
|
64
|
+
|
|
65
|
+
## Package Layout
|
|
66
|
+
|
|
67
|
+
The package is deliberately flat: shallow subpackages by domain (`asr`, `diarization`, `llm`,
|
|
68
|
+
`transcript`, `video`, `export`) with leaf modules at the root. Read the tree directly rather than
|
|
69
|
+
maintaining a copy here, and avoid adding deep nesting.
|
|
70
|
+
|
|
71
|
+
## Runtime Contracts
|
|
72
|
+
|
|
73
|
+
- Successful default CLI runs write the report artifact set described in `README.md`.
|
|
74
|
+
- `--diarize` runs locally and adds `diarization.json` plus speaker fields on transcript segments.
|
|
75
|
+
- Successful runs write `diagnostics.json`; failed runs also write it once the run directory exists,
|
|
76
|
+
though early failures can still leave only partial intermediate artifacts and no final report
|
|
77
|
+
outputs.
|
|
78
|
+
- Temporary WAV audio extracted for transcription should stay outside the run directory;
|
|
79
|
+
`--keep-audio` may write the compressed `transcription-audio.mp3` artifact described in
|
|
80
|
+
`README.md`.
|
|
81
|
+
|
|
82
|
+
## Testing Notes
|
|
83
|
+
|
|
84
|
+
- Keep tests under `webinar_transcriber/tests/`, mirroring the package hierarchy in filenames and
|
|
85
|
+
grouping where it helps scanability. Split a test file into a sibling when it crosses roughly 800
|
|
86
|
+
lines or when the production-side module it covers has already split — for example, `llm/utils.py`
|
|
87
|
+
and `llm/processor.py` map to `test_llm_utils.py` and `test_llm.py`.
|
|
88
|
+
- Prefer tiny deterministic fixtures committed to the repo.
|
|
89
|
+
- Prefer `pytest` `monkeypatch` for simple state replacement and `unittest.mock.patch` when a test
|
|
90
|
+
needs mock semantics such as `side_effect`, `return_value`, or call assertions.
|
|
91
|
+
- Group related tests by behavior using `class Test...` when it improves scanability; keep helpers
|
|
92
|
+
and fakes scoped to the narrowest test class that uses them, and leave them module-level only when
|
|
93
|
+
they are intentionally shared across multiple test classes or fixtures.
|
|
94
|
+
- CLI tests should generally monkeypatch the reporter and heavy runtime seams instead of invoking
|
|
95
|
+
real media-processing work.
|
|
96
|
+
- Use `pytest.mark.parametrize` when cases share the same setup and assertions and the test
|
|
97
|
+
naturally becomes a clear input/output table; avoid it when cases need materially different
|
|
98
|
+
fixtures, monkeypatching, or fake-object wiring.
|
|
99
|
+
- Prefer asserting current observable behavior over asserting that recently removed options, fields,
|
|
100
|
+
dependencies, import paths, or artifacts are absent. Deletion-based assertions are usually shallow
|
|
101
|
+
and brittle.
|
|
102
|
+
- Avoid tests that only prove one function forwards fields into another helper unless that wiring is
|
|
103
|
+
itself a meaningful behavioral contract.
|
|
104
|
+
- For predicate-style tests, prefer `assert expr` / `assert not expr`. Reserve `is True` /
|
|
105
|
+
`is False` for cases where exact boolean identity matters.
|
|
106
|
+
|
|
107
|
+
## Implementation Notes
|
|
108
|
+
|
|
109
|
+
- When an earlier pipeline stage already guarantees an invariant, prefer enforcing that invariant
|
|
110
|
+
directly instead of carrying defensive conversion logic downstream. For example, transcription
|
|
111
|
+
audio is normalized to `16000 Hz`, so the `sherpa-onnx` Silero VAD integration should assert that
|
|
112
|
+
contract rather than silently resample.
|
|
113
|
+
- Let genuine errors propagate. Reserve warnings for recoverable, user-actionable conditions; do not
|
|
114
|
+
downgrade a real failure (a failed image write, a missing required stream) into a warning that the
|
|
115
|
+
run then has to thread around.
|
|
116
|
+
- The Silero VAD ONNX model is vendored under `webinar_transcriber/assets/` so default speech-region
|
|
117
|
+
detection does not require PyTorch or a first-run network download.
|
|
118
|
+
- Speaker diarization uses `sherpa-onnx` with downloaded ONNX models cached under
|
|
119
|
+
`~/.cache/webinar-transcriber/diarization`; keep those model artifacts out of the wheel.
|
|
120
|
+
|
|
121
|
+
## Simplification and Refactoring Notes
|
|
122
|
+
|
|
123
|
+
This repo has improved repeatedly by making complexity justify itself, not the reverse. In review
|
|
124
|
+
the maintainer keeps pushing past a first "this is load-bearing" reading and is usually right. Carry
|
|
125
|
+
that prior: an abstraction must earn its keep, the default answer to "can this be simpler" is yes
|
|
126
|
+
until the code proves otherwise, and a challenge to a conservative answer is a request for evidence.
|
|
127
|
+
Grep the real readers and callers, then produce a verified cleanup or give the precise structural
|
|
128
|
+
reason it can't be done and act rather than re-explain. A small flag-free helper is fine when a
|
|
129
|
+
linter genuinely forces extraction; a state flag or multi-helper split to dodge one is
|
|
130
|
+
over-engineering.
|
|
131
|
+
|
|
132
|
+
Recurring smells to check for:
|
|
133
|
+
|
|
134
|
+
- **Test-only knobs** — a param/field whose only non-default caller is a test; delete it and let
|
|
135
|
+
tests monkeypatch the constant or exercise the real contract.
|
|
136
|
+
- **1:1 wrappers / single-caller helpers** that only rename one shape or forward one call; inline at
|
|
137
|
+
the call site.
|
|
138
|
+
- **Write-only fields** serialized or assigned but never read back; delete unless an external
|
|
139
|
+
artifact contract consumes them.
|
|
140
|
+
- **Duplicated diagnostics or serialization** — one value under two keys or two artifacts; pick the
|
|
141
|
+
single owner.
|
|
142
|
+
- **Wrapper / result-object chains** threading one value through re-keying passes, or a plan/spec
|
|
143
|
+
wrapping a `min()`/`len()`; collapse to one shape or a function.
|
|
144
|
+
- **Re-export / lazy-import surfaces with no production consumer**; import from the defining leaf
|
|
145
|
+
module, keeping a package re-export only to isolate an optional extra or a real public boundary.
|
|
146
|
+
- **Protocols for a single in-tree implementation**; type the collaborator concretely and let tests
|
|
147
|
+
use duck-typed fakes. A Protocol earns its place only at a third-party or polymorphic seam.
|
|
148
|
+
- **Fakes re-implementing production logic**; replace with a Mock-based double that runs the real
|
|
149
|
+
policy or object, so the test proves production behavior.
|
|
150
|
+
- **Defensive branches guarding states an earlier stage forbids** (a guard on a positive constant, a
|
|
151
|
+
`getattr` default masking a missing attribute); assert the invariant or delete the branch.
|
|
152
|
+
- **Errors downgraded to warnings** the run then threads around; let them propagate, reserving
|
|
153
|
+
warnings for recoverable, user-actionable conditions.
|
|
154
|
+
- **Config bags between exactly two callers**; inline as kwargs or fields.
|
|
155
|
+
- **Stale suppressions** — ruff ignores with zero hits, `type: ignore` / `cast()` that narrow away
|
|
156
|
+
with `isinstance`; re-enable or narrow, keeping only documented stub gaps.
|
|
157
|
+
|
|
158
|
+
When acting: put ownership at the boundary that already knows the value (the CLI builds
|
|
159
|
+
collaborators, stages record their own diagnostics, ASR owns window policy, export/report models
|
|
160
|
+
carry no diagnostics-only data); prefer the narrowest cohesive cleanup with a clear before/after
|
|
161
|
+
story; verify with a byte-identical fixture-artifact diff where possible over tests that only prove
|
|
162
|
+
one helper forwarded to another; and make any user-visible contract change (CLI flags, artifact
|
|
163
|
+
paths, JSON shapes, diagnostics or stage keys) explicit in the PR with `README.md` and `AGENTS.md`
|
|
164
|
+
updated in the same change.
|
|
165
|
+
|
|
166
|
+
## Style Notes
|
|
167
|
+
|
|
168
|
+
- `cast()` is a runtime no-op and a smell when used purely to satisfy the type checker. Prefer
|
|
169
|
+
`isinstance()` checks for narrowing. Reserve `cast()` for genuine third-party stub gaps and always
|
|
170
|
+
add a comment explaining which stub is missing and why.
|
|
171
|
+
- `# type: ignore` is the same smell. Only use it for genuine stub gaps, bare (no bracket error
|
|
172
|
+
codes — `ty` does not use mypy's `[attr-defined]` syntax), with a comment on the same or preceding
|
|
173
|
+
line.
|
|
174
|
+
- When adapting third-party types that don't stub well, define a private `Protocol`. If `Any` is
|
|
175
|
+
unavoidable in a Protocol method signature due to stub-level invariance constraints, suppress ruff
|
|
176
|
+
with `# noqa: ANN401` and add a comment.
|
|
177
|
+
- Bind caught exceptions as `ex` — `except SomeError as ex:` — never `as error:` or `as exc:`. The
|
|
178
|
+
same applies to `pytest.raises(...) as ex` in tests.
|
|
179
|
+
- Replace `assert x is not None` guards in production code with explicit `if x is None: raise`.
|
|
180
|
+
`assert` is stripped by optimised builds and banned by ruff S101.
|
|
181
|
+
- Use the walrus operator selectively when it removes repeated work without making the code harder
|
|
182
|
+
to read.
|
|
183
|
+
- Prefer short loop and comprehension variable names when the surrounding context already makes the
|
|
184
|
+
meaning obvious.
|
|
185
|
+
- In ASR code and artifacts, use `speech region` for VAD/planning inputs and `window` for Whisper
|
|
186
|
+
decode units; avoid `chunk` for ASR concepts.
|
|
187
|
+
- Treat acronyms as words in PascalCase identifiers: `LlmProcessor`, `AsrPipelineDiagnostics`,
|
|
188
|
+
`WhisperCppTranscriber`. Constants stay SCREAMING_SNAKE: `ASR_BACKEND_NAME`, `LLM_PROVIDER_ENV`.
|