conversa-transcribe 0.1.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.
- conversa_transcribe-0.1.0/.github/workflows/publish.yml +33 -0
- conversa_transcribe-0.1.0/.github/workflows/test.yml +23 -0
- conversa_transcribe-0.1.0/.gitignore +28 -0
- conversa_transcribe-0.1.0/LICENSE +21 -0
- conversa_transcribe-0.1.0/PKG-INFO +129 -0
- conversa_transcribe-0.1.0/README.md +102 -0
- conversa_transcribe-0.1.0/conversa.example.toml +29 -0
- conversa_transcribe-0.1.0/plans/visibility-license-topics-pypi.md +108 -0
- conversa_transcribe-0.1.0/pyproject.toml +45 -0
- conversa_transcribe-0.1.0/src/conversa/__init__.py +3 -0
- conversa_transcribe-0.1.0/src/conversa/asr.py +234 -0
- conversa_transcribe-0.1.0/src/conversa/cli.py +167 -0
- conversa_transcribe-0.1.0/src/conversa/config.py +96 -0
- conversa_transcribe-0.1.0/src/conversa/pipeline.py +122 -0
- conversa_transcribe-0.1.0/src/conversa/postprocess.py +203 -0
- conversa_transcribe-0.1.0/src/conversa/prompts/clean.txt +17 -0
- conversa_transcribe-0.1.0/src/conversa/prompts/narrate.txt +26 -0
- conversa_transcribe-0.1.0/src/conversa/prompts/narrate_brief.txt +36 -0
- conversa_transcribe-0.1.0/src/conversa/prompts/summary.txt +26 -0
- conversa_transcribe-0.1.0/src/conversa/secrets.py +41 -0
- conversa_transcribe-0.1.0/src/conversa/speakers.py +63 -0
- conversa_transcribe-0.1.0/tests/test_language.py +59 -0
- conversa_transcribe-0.1.0/tests/test_speakers.py +60 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.11"
|
|
16
|
+
- run: python -m pip install --upgrade build
|
|
17
|
+
- run: python -m build
|
|
18
|
+
- uses: actions/upload-artifact@v4
|
|
19
|
+
with:
|
|
20
|
+
name: dist
|
|
21
|
+
path: dist/
|
|
22
|
+
|
|
23
|
+
publish:
|
|
24
|
+
needs: build
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
permissions:
|
|
27
|
+
id-token: write # required for PyPI trusted publishing (OIDC), no secrets
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/download-artifact@v4
|
|
30
|
+
with:
|
|
31
|
+
name: dist
|
|
32
|
+
path: dist/
|
|
33
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: "3.11"
|
|
16
|
+
# whisperx (torch) isn't needed for these tests: conversa.asr imports it
|
|
17
|
+
# lazily inside Transcriber.__init__, not at module load time.
|
|
18
|
+
- name: Install (skip heavy ASR deps)
|
|
19
|
+
run: |
|
|
20
|
+
python -m pip install --upgrade pip
|
|
21
|
+
pip install anthropic pytest
|
|
22
|
+
pip install -e . --no-deps
|
|
23
|
+
- run: pytest
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
.venv-*/
|
|
6
|
+
venv/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
|
|
11
|
+
# Secrets
|
|
12
|
+
.env
|
|
13
|
+
|
|
14
|
+
# Generated outputs
|
|
15
|
+
transcripciones/
|
|
16
|
+
relatos*/
|
|
17
|
+
|
|
18
|
+
# Source recordings — never commit sensitive audio
|
|
19
|
+
*.m4a
|
|
20
|
+
*.mp3
|
|
21
|
+
*.wav
|
|
22
|
+
*.mp4
|
|
23
|
+
*.ogg
|
|
24
|
+
*.flac
|
|
25
|
+
*.zip
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Salvador
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: conversa-transcribe
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local, evidence-oriented conversation transcription (WhisperX + Anthropic)
|
|
5
|
+
Project-URL: Repository, https://github.com/salvagit/conversa
|
|
6
|
+
Project-URL: Issues, https://github.com/salvagit/conversa/issues
|
|
7
|
+
Author: Salvador
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: anthropic,claude,cli,evidence,speaker-diarization,speech-to-text,transcription,whisper,whisperx
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Legal Industry
|
|
14
|
+
Classifier: Intended Audience :: Other Audience
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
20
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: anthropic<1,>=0.40
|
|
23
|
+
Requires-Dist: whisperx<4,>=3.4
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# conversa
|
|
29
|
+
|
|
30
|
+
Local console tool to transcribe spoken conversations with speaker separation
|
|
31
|
+
(WhisperX + diarization) and post-process them with the Anthropic API: filler-word
|
|
32
|
+
cleanup, structured summarization, and first-person narrative. Designed for use
|
|
33
|
+
with evidentiary value (interviews, evidence): the audio never leaves your
|
|
34
|
+
machine; only the text is, optionally, sent to the language model.
|
|
35
|
+
|
|
36
|
+
> ⚠️ Transcripts are **automatic** and may contain errors. The primary evidence
|
|
37
|
+
> is always the recording.
|
|
38
|
+
|
|
39
|
+
## Requirements
|
|
40
|
+
|
|
41
|
+
- Python 3.11+
|
|
42
|
+
- `ffmpeg` on `PATH` (`brew install ffmpeg`)
|
|
43
|
+
- A Hugging Face token with access to
|
|
44
|
+
`pyannote/speaker-diarization-community-1` (accept the terms)
|
|
45
|
+
- An Anthropic API key (console.anthropic.com — pay-as-you-go, **different from
|
|
46
|
+
a Claude Pro/Max subscription**)
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
python3.11 -m venv .venv && source .venv/bin/activate
|
|
52
|
+
pip install -e .
|
|
53
|
+
conversa init # creates conversa.toml and .env.example
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Fill in `.env` with `HF_TOKEN` and `ANTHROPIC_API_KEY`.
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
conversa run audios/ # full pipeline (transcribe→clean→summarize)
|
|
62
|
+
conversa transcribe audios/my.m4a # WhisperX only
|
|
63
|
+
conversa clean audios/ # cleanup only
|
|
64
|
+
conversa summarize audios/ # summary only
|
|
65
|
+
conversa rename my-audio --map "A=Ana,B=Beto" --to names/
|
|
66
|
+
conversa narrate names/my-audio.limpia.md --narrator Ana --brief \
|
|
67
|
+
--context "September 3, 2024. Participants: Ana and Beto."
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Outputs (in `output_dir`, `transcripciones/` by default): `<base>.md`,
|
|
71
|
+
`<base>.srt`, `<base>.limpia.md`, `<base>.resumen.md`.
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
`conversa.toml` (optional) lets you override models, language, speaker range,
|
|
76
|
+
audio extensions, output folder and tokens. Prompts live in
|
|
77
|
+
`src/conversa/prompts/*.txt` and can be edited without touching code.
|
|
78
|
+
|
|
79
|
+
## Language
|
|
80
|
+
|
|
81
|
+
`conversa` works with any language WhisperX/Whisper supports (~100 languages).
|
|
82
|
+
A single `language` setting (ISO 639-1 code, `"es"` by default) drives both
|
|
83
|
+
transcription and the LLM stages: `clean`, `summarize` and `narrate` all write
|
|
84
|
+
their output in that language.
|
|
85
|
+
|
|
86
|
+
**This is not auto-detected.** You must set `language` to match your audio;
|
|
87
|
+
conversa always tells Whisper which language to expect instead of letting it
|
|
88
|
+
guess. Whisper's own auto-detection is disabled on purpose — it's unreliable
|
|
89
|
+
on noisy, accented phone-call audio, which is exactly this tool's main use
|
|
90
|
+
case, and a wrong guess silently produces a garbled transcript. If you record
|
|
91
|
+
audio in English but leave the default `language = "es"`, expect a bad
|
|
92
|
+
transcription. Set it in `conversa.toml`:
|
|
93
|
+
|
|
94
|
+
```toml
|
|
95
|
+
[general]
|
|
96
|
+
language = "en" # or "pt", "fr", "de", ...
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Languages listed in `src/conversa/config.py:LANGUAGE_NAMES` get a friendly name
|
|
100
|
+
in the prompt instructions (e.g. "in Spanish"); anything else still works, the
|
|
101
|
+
model just sees the raw ISO code instead. The Spanish (`es`) summary headings
|
|
102
|
+
are hardcoded for exact, tested wording; other languages get the model's own
|
|
103
|
+
translation of the English headings, which reads naturally but isn't pinned
|
|
104
|
+
word-for-word.
|
|
105
|
+
|
|
106
|
+
## Security and privacy
|
|
107
|
+
|
|
108
|
+
Evidentiary, sensitive material. Keep the data flow in mind:
|
|
109
|
+
|
|
110
|
+
- **The audio never leaves your machine.** Transcription (WhisperX +
|
|
111
|
+
diarization) runs 100% locally.
|
|
112
|
+
- **The text IS sent to the Anthropic API** in the `clean`, `summarize` and
|
|
113
|
+
`narrate` stages. If you need **nothing** to leave the machine, use only
|
|
114
|
+
`conversa transcribe` (raw transcription, no LLM). Review Anthropic's API
|
|
115
|
+
data-retention policy for your case.
|
|
116
|
+
- **Secrets:** `HF_TOKEN` and `ANTHROPIC_API_KEY` go in environment variables or
|
|
117
|
+
in `.env` (excluded by `.gitignore`). Prefer environment variables and run the
|
|
118
|
+
tool in trusted directories (a foreign `.env` could inject a different API
|
|
119
|
+
key).
|
|
120
|
+
- **Always review the outputs.** Transcription is automatic (ASR errors) and the
|
|
121
|
+
LLM can be influenced by the audio content itself (prompt injection). For
|
|
122
|
+
evidence, the primary proof is the recording; rely on the `.srt` with
|
|
123
|
+
timestamps to cross-check figures and key phrases.
|
|
124
|
+
|
|
125
|
+
## Next steps
|
|
126
|
+
|
|
127
|
+
- Provenance manifest (model/version/hash per output) for chain of custody.
|
|
128
|
+
- `--local-only` flag / explicit consent before sending text to the LLM.
|
|
129
|
+
- Graphical interface for non-technical users.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# conversa
|
|
2
|
+
|
|
3
|
+
Local console tool to transcribe spoken conversations with speaker separation
|
|
4
|
+
(WhisperX + diarization) and post-process them with the Anthropic API: filler-word
|
|
5
|
+
cleanup, structured summarization, and first-person narrative. Designed for use
|
|
6
|
+
with evidentiary value (interviews, evidence): the audio never leaves your
|
|
7
|
+
machine; only the text is, optionally, sent to the language model.
|
|
8
|
+
|
|
9
|
+
> ⚠️ Transcripts are **automatic** and may contain errors. The primary evidence
|
|
10
|
+
> is always the recording.
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- Python 3.11+
|
|
15
|
+
- `ffmpeg` on `PATH` (`brew install ffmpeg`)
|
|
16
|
+
- A Hugging Face token with access to
|
|
17
|
+
`pyannote/speaker-diarization-community-1` (accept the terms)
|
|
18
|
+
- An Anthropic API key (console.anthropic.com — pay-as-you-go, **different from
|
|
19
|
+
a Claude Pro/Max subscription**)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python3.11 -m venv .venv && source .venv/bin/activate
|
|
25
|
+
pip install -e .
|
|
26
|
+
conversa init # creates conversa.toml and .env.example
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Fill in `.env` with `HF_TOKEN` and `ANTHROPIC_API_KEY`.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
conversa run audios/ # full pipeline (transcribe→clean→summarize)
|
|
35
|
+
conversa transcribe audios/my.m4a # WhisperX only
|
|
36
|
+
conversa clean audios/ # cleanup only
|
|
37
|
+
conversa summarize audios/ # summary only
|
|
38
|
+
conversa rename my-audio --map "A=Ana,B=Beto" --to names/
|
|
39
|
+
conversa narrate names/my-audio.limpia.md --narrator Ana --brief \
|
|
40
|
+
--context "September 3, 2024. Participants: Ana and Beto."
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Outputs (in `output_dir`, `transcripciones/` by default): `<base>.md`,
|
|
44
|
+
`<base>.srt`, `<base>.limpia.md`, `<base>.resumen.md`.
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
`conversa.toml` (optional) lets you override models, language, speaker range,
|
|
49
|
+
audio extensions, output folder and tokens. Prompts live in
|
|
50
|
+
`src/conversa/prompts/*.txt` and can be edited without touching code.
|
|
51
|
+
|
|
52
|
+
## Language
|
|
53
|
+
|
|
54
|
+
`conversa` works with any language WhisperX/Whisper supports (~100 languages).
|
|
55
|
+
A single `language` setting (ISO 639-1 code, `"es"` by default) drives both
|
|
56
|
+
transcription and the LLM stages: `clean`, `summarize` and `narrate` all write
|
|
57
|
+
their output in that language.
|
|
58
|
+
|
|
59
|
+
**This is not auto-detected.** You must set `language` to match your audio;
|
|
60
|
+
conversa always tells Whisper which language to expect instead of letting it
|
|
61
|
+
guess. Whisper's own auto-detection is disabled on purpose — it's unreliable
|
|
62
|
+
on noisy, accented phone-call audio, which is exactly this tool's main use
|
|
63
|
+
case, and a wrong guess silently produces a garbled transcript. If you record
|
|
64
|
+
audio in English but leave the default `language = "es"`, expect a bad
|
|
65
|
+
transcription. Set it in `conversa.toml`:
|
|
66
|
+
|
|
67
|
+
```toml
|
|
68
|
+
[general]
|
|
69
|
+
language = "en" # or "pt", "fr", "de", ...
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Languages listed in `src/conversa/config.py:LANGUAGE_NAMES` get a friendly name
|
|
73
|
+
in the prompt instructions (e.g. "in Spanish"); anything else still works, the
|
|
74
|
+
model just sees the raw ISO code instead. The Spanish (`es`) summary headings
|
|
75
|
+
are hardcoded for exact, tested wording; other languages get the model's own
|
|
76
|
+
translation of the English headings, which reads naturally but isn't pinned
|
|
77
|
+
word-for-word.
|
|
78
|
+
|
|
79
|
+
## Security and privacy
|
|
80
|
+
|
|
81
|
+
Evidentiary, sensitive material. Keep the data flow in mind:
|
|
82
|
+
|
|
83
|
+
- **The audio never leaves your machine.** Transcription (WhisperX +
|
|
84
|
+
diarization) runs 100% locally.
|
|
85
|
+
- **The text IS sent to the Anthropic API** in the `clean`, `summarize` and
|
|
86
|
+
`narrate` stages. If you need **nothing** to leave the machine, use only
|
|
87
|
+
`conversa transcribe` (raw transcription, no LLM). Review Anthropic's API
|
|
88
|
+
data-retention policy for your case.
|
|
89
|
+
- **Secrets:** `HF_TOKEN` and `ANTHROPIC_API_KEY` go in environment variables or
|
|
90
|
+
in `.env` (excluded by `.gitignore`). Prefer environment variables and run the
|
|
91
|
+
tool in trusted directories (a foreign `.env` could inject a different API
|
|
92
|
+
key).
|
|
93
|
+
- **Always review the outputs.** Transcription is automatic (ASR errors) and the
|
|
94
|
+
LLM can be influenced by the audio content itself (prompt injection). For
|
|
95
|
+
evidence, the primary proof is the recording; rely on the `.srt` with
|
|
96
|
+
timestamps to cross-check figures and key phrases.
|
|
97
|
+
|
|
98
|
+
## Next steps
|
|
99
|
+
|
|
100
|
+
- Provenance manifest (model/version/hash per output) for chain of custody.
|
|
101
|
+
- `--local-only` flag / explicit consent before sending text to the LLM.
|
|
102
|
+
- Graphical interface for non-technical users.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Example conversa configuration. Copy it to `conversa.toml` in the directory
|
|
2
|
+
# from which you run the tool (or generate it with `conversa init`).
|
|
3
|
+
# All keys are optional; anything omitted falls back to the code defaults.
|
|
4
|
+
|
|
5
|
+
[general]
|
|
6
|
+
# ISO 639-1 code. Drives both the Whisper ASR model and the language the LLM
|
|
7
|
+
# stages (clean/summarize/narrate) write their output in. Must match your
|
|
8
|
+
# audio's actual language — Whisper's auto-detection is intentionally
|
|
9
|
+
# disabled (unreliable on noisy call audio), so a mismatch silently produces
|
|
10
|
+
# a garbled transcript. Any language Whisper supports works; see
|
|
11
|
+
# src/conversa/config.py:LANGUAGE_NAMES for the ones with a friendly display
|
|
12
|
+
# name (others still work, just less polished prompts).
|
|
13
|
+
language = "es"
|
|
14
|
+
|
|
15
|
+
[asr]
|
|
16
|
+
model = "large-v3-turbo" # large-v3-turbo | medium | small
|
|
17
|
+
min_speakers = 2
|
|
18
|
+
max_speakers = 3
|
|
19
|
+
threads = 8
|
|
20
|
+
|
|
21
|
+
[io]
|
|
22
|
+
output_dir = "transcripciones"
|
|
23
|
+
audio_exts = [".m4a", ".mp3", ".wav", ".mp4", ".ogg", ".flac"]
|
|
24
|
+
|
|
25
|
+
[llm]
|
|
26
|
+
clean_model = "claude-haiku-4-5"
|
|
27
|
+
summary_model = "claude-sonnet-5"
|
|
28
|
+
narrate_model = "claude-sonnet-5"
|
|
29
|
+
chunk_chars = 8000
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Plan — Visibilidad: LICENSE, topics de GitHub, publicación en PyPI
|
|
2
|
+
|
|
3
|
+
_Fecha: 2026-07-07_
|
|
4
|
+
|
|
5
|
+
## Contexto
|
|
6
|
+
|
|
7
|
+
`conversa` es público en `github.com/salvagit/conversa` pero invisible: sin
|
|
8
|
+
licencia, sin topics, y solo instalable clonando el repo. "SEO" tradicional
|
|
9
|
+
no aplica a una herramienta de consola — la visibilidad acá se juega en
|
|
10
|
+
señales que entiende GitHub (licencia, topics, CI) y en estar donde la gente
|
|
11
|
+
instala paquetes (PyPI). Se prioriza esto sobre otras acciones (badges, demo,
|
|
12
|
+
awesome-lists, redes) que se evalúan después.
|
|
13
|
+
|
|
14
|
+
## Hallazgo bloqueante: nombre en PyPI
|
|
15
|
+
|
|
16
|
+
El nombre **`conversa` ya está tomado** en PyPI (paquete no relacionado, de
|
|
17
|
+
conversión de unidades). Verificado libres: `conversa-cli`,
|
|
18
|
+
`conversa-transcribe`, `conversa-evidence`.
|
|
19
|
+
|
|
20
|
+
Esto **no afecta al usuario final**: `[project.scripts]` define el comando
|
|
21
|
+
`conversa` de forma independiente del nombre de distribución (`[project]
|
|
22
|
+
name`). Cambiar el nombre de distribución para PyPI no cambia que el comando
|
|
23
|
+
siga siendo `conversa` una vez instalado.
|
|
24
|
+
|
|
25
|
+
## Decisiones (ya tomadas por el usuario, 2026-07-07)
|
|
26
|
+
|
|
27
|
+
1. **Nombre de distribución en PyPI: `conversa-transcribe`.** El comando que
|
|
28
|
+
escribe el usuario final sigue siendo `conversa` (no cambia).
|
|
29
|
+
2. **Cuenta de PyPI: no existe todavía, hay que crearla.** Bloquea solo el
|
|
30
|
+
paso 3.4 (configurar Trusted Publisher); el resto del código se prepara
|
|
31
|
+
igual sin necesitar la cuenta.
|
|
32
|
+
3. **Método de publicación: Trusted Publisher** (OIDC de GitHub Actions →
|
|
33
|
+
PyPI), sin tokens ni secrets. Evita repetir el problema de la API key de
|
|
34
|
+
Anthropic compartida en texto plano.
|
|
35
|
+
|
|
36
|
+
## Fase 1 — LICENSE (sin dependencias, se puede hacer ya)
|
|
37
|
+
|
|
38
|
+
- Agregar `LICENSE` en la raíz del repo: texto MIT estándar, copyright
|
|
39
|
+
"Salvador", año 2026 (coincide con `pyproject.toml: license = {text="MIT"}`).
|
|
40
|
+
- Verificar que GitHub detecta la licencia (aparece en la barra lateral del repo).
|
|
41
|
+
|
|
42
|
+
## Fase 2 — Topics de GitHub (sin dependencias, se puede hacer ya)
|
|
43
|
+
|
|
44
|
+
- `gh repo edit salvagit/conversa --add-topic <topic>` para cada uno:
|
|
45
|
+
`cli`, `transcription`, `speech-to-text`, `whisper`, `whisperx`,
|
|
46
|
+
`speaker-diarization`, `anthropic`, `claude`, `legal-tech`, `evidence`,
|
|
47
|
+
`python`.
|
|
48
|
+
- Verificar con `gh repo view --json repositoryTopics`.
|
|
49
|
+
|
|
50
|
+
## Fase 3 — Publicación en PyPI (requiere decisiones del usuario arriba)
|
|
51
|
+
|
|
52
|
+
3.1. **Metadata de `pyproject.toml`** para descubribilidad en PyPI:
|
|
53
|
+
- Cambiar `[project] name` al nombre de distribución elegido (el
|
|
54
|
+
`[project.scripts] conversa = ...` NO cambia).
|
|
55
|
+
- Agregar `keywords` (transcription, whisper, diarization, evidence, cli,
|
|
56
|
+
spanish, anthropic, claude).
|
|
57
|
+
- Agregar `classifiers` (Development Status, Intended Audience, License ::
|
|
58
|
+
OSI Approved :: MIT, Programming Language :: Python :: 3.11/3.12,
|
|
59
|
+
Topic :: Multimedia :: Sound/Audio :: Speech, Environment :: Console).
|
|
60
|
+
- Agregar `[project.urls]` (Repository, Issues) apuntando a
|
|
61
|
+
`github.com/salvagit/conversa`.
|
|
62
|
+
|
|
63
|
+
3.2. **CI mínimo** (`.github/workflows/test.yml`): correr `pytest` en cada
|
|
64
|
+
push/PR. Barato (ya hay 22 tests livianos, sin whisperx) y da una señal de
|
|
65
|
+
confianza real (badge verde) para cualquiera que llegue al repo.
|
|
66
|
+
|
|
67
|
+
3.3. **Workflow de publicación** (`.github/workflows/publish.yml`): build con
|
|
68
|
+
`python -m build`, publish vía `pypa/gh-action-pypi-publish` usando Trusted
|
|
69
|
+
Publisher (sin secrets), disparado por tags `v*.*.*`.
|
|
70
|
+
|
|
71
|
+
3.4. **Configurar Trusted Publisher en pypi.org** (acción manual del usuario:
|
|
72
|
+
crear cuenta si no existe, ir a "Publishing" → agregar repo
|
|
73
|
+
`salvagit/conversa`, workflow `publish.yml`, environment opcional).
|
|
74
|
+
|
|
75
|
+
3.5. **Primer release**: tag `v0.1.0` → dispara el workflow → publica en PyPI.
|
|
76
|
+
Verificar `pip install <nombre-elegido>` funciona en un venv limpio y expone
|
|
77
|
+
el comando `conversa`.
|
|
78
|
+
|
|
79
|
+
3.6. Actualizar `README.md`: instrucciones de instalación pasan a
|
|
80
|
+
`pip install <nombre-elegido>` como opción principal, con "desde código
|
|
81
|
+
fuente" como alternativa para desarrollo.
|
|
82
|
+
|
|
83
|
+
## Estado (2026-07-07)
|
|
84
|
+
|
|
85
|
+
- ✅ Fase 1 (LICENSE), Fase 2 (topics), Fase 3.1-3.3 (metadata, CI, workflow de
|
|
86
|
+
publicación) hechas, commiteadas (`8adc173`) y pusheadas. CI corrido y
|
|
87
|
+
**verde en GitHub** (no solo local).
|
|
88
|
+
- 🐛 Encontrado y arreglado en el camino: `python -m build` fallaba
|
|
89
|
+
(`force-include` de prompts duplicaba archivos). No lo detectaba
|
|
90
|
+
`pip install -e .` porque usa un code path distinto. Verificado con un
|
|
91
|
+
build real + instalación del wheel en venv limpio: `conversa --version`
|
|
92
|
+
y los prompts cargan bien.
|
|
93
|
+
- ⏳ Pendiente, bloqueado por acción del usuario: 3.4 (cuenta de PyPI +
|
|
94
|
+
Trusted Publisher) y 3.5/3.6 (primer release + actualizar README).
|
|
95
|
+
|
|
96
|
+
## Verificación
|
|
97
|
+
|
|
98
|
+
- `LICENSE` presente y detectado por GitHub.
|
|
99
|
+
- Topics visibles en `gh repo view --json repositoryTopics`.
|
|
100
|
+
- CI verde en un push de prueba.
|
|
101
|
+
- `pip install <nombre-elegido>` en un venv limpio (o Docker) instala y
|
|
102
|
+
`conversa --version` funciona.
|
|
103
|
+
- README refleja el nuevo método de instalación.
|
|
104
|
+
|
|
105
|
+
## Fuera de alcance (para después)
|
|
106
|
+
|
|
107
|
+
Badges en el README, GIF de demo, listas "awesome-*", publicación en foros/redes
|
|
108
|
+
(Show HN, Reddit, etc.) — se retoman una vez esto esté andando.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "conversa-transcribe"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Local, evidence-oriented conversation transcription (WhisperX + Anthropic)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Salvador" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"transcription", "whisper", "whisperx", "speaker-diarization",
|
|
15
|
+
"speech-to-text", "evidence", "cli", "anthropic", "claude",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Environment :: Console",
|
|
20
|
+
"Intended Audience :: Legal Industry",
|
|
21
|
+
"Intended Audience :: Other Audience",
|
|
22
|
+
"License :: OSI Approved :: MIT License",
|
|
23
|
+
"Operating System :: OS Independent",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Multimedia :: Sound/Audio :: Speech",
|
|
27
|
+
"Topic :: Text Processing :: Linguistic",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"whisperx>=3.4,<4",
|
|
31
|
+
"anthropic>=0.40,<1",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Repository = "https://github.com/salvagit/conversa"
|
|
36
|
+
Issues = "https://github.com/salvagit/conversa/issues"
|
|
37
|
+
|
|
38
|
+
[project.optional-dependencies]
|
|
39
|
+
dev = ["pytest>=8"]
|
|
40
|
+
|
|
41
|
+
[project.scripts]
|
|
42
|
+
conversa = "conversa.cli:main"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.wheel]
|
|
45
|
+
packages = ["src/conversa"]
|