deepctl-cmd-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.
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepctl-cmd-transcribe
3
+ Version: 0.1.0
4
+ Summary: Transcribe command for deepctl
5
+ Author-email: Deepgram <devrel@deepgram.com>
6
+ Maintainer-email: Deepgram <devrel@deepgram.com>
7
+ License-Expression: MIT
8
+ Keywords: deepgram,cli,transcribe,speech,audio
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: deepctl-core>=0.1.0
18
+ Requires-Dist: deepctl-shared-utils>=0.1.0
19
+ Requires-Dist: click>=8.0.0
20
+ Requires-Dist: rich>=13.0.0
21
+ Requires-Dist: deepgram-sdk>=3.0.0
22
+ Requires-Dist: pydantic>=2.0.0
23
+
24
+ # deepctl-cmd-transcribe
25
+
26
+ Transcribe command for deepctl. This package is an internal component of deepctl and is not intended for standalone use.
@@ -0,0 +1,3 @@
1
+ # deepctl-cmd-transcribe
2
+
3
+ Transcribe command for deepctl. This package is an internal component of deepctl and is not intended for standalone use.
@@ -0,0 +1,43 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "deepctl-cmd-transcribe"
7
+ version = "0.1.0"
8
+ description = "Transcribe command for deepctl"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ authors = [{ name = "Deepgram", email = "devrel@deepgram.com" }]
12
+ maintainers = [{ name = "Deepgram", email = "devrel@deepgram.com" }]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ ]
21
+ keywords = ["deepgram", "cli", "transcribe", "speech", "audio"]
22
+ requires-python = ">=3.10"
23
+ dependencies = [
24
+ "deepctl-core>=0.1.0",
25
+ "deepctl-shared-utils>=0.1.0",
26
+ "click>=8.0.0",
27
+ "rich>=13.0.0",
28
+ "deepgram-sdk>=3.0.0",
29
+ "pydantic>=2.0.0",
30
+ ]
31
+
32
+ [project.scripts]
33
+ # Internal commands not meant to be called directly
34
+
35
+ [project.entry-points."deepctl.commands"]
36
+ transcribe = "deepctl_cmd_transcribe.command:TranscribeCommand"
37
+
38
+ [tool.setuptools]
39
+ package-dir = { "" = "src" }
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["src"]
43
+ include = ["deepctl_cmd_transcribe*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ """Transcribe command package for deepctl."""
2
+
3
+ from .command import TranscribeCommand
4
+ from .models import TranscribeResult
5
+
6
+ __all__ = ["TranscribeCommand", "TranscribeResult"]
@@ -0,0 +1,242 @@
1
+ """Transcribe command for deepctl."""
2
+
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ from deepctl_core import (
7
+ AuthManager,
8
+ BaseCommand,
9
+ BaseResult,
10
+ Config,
11
+ DeepgramClient,
12
+ )
13
+ from deepctl_shared_utils import validate_audio_file, validate_url
14
+ from rich.console import Console
15
+
16
+ from .models import TranscribeResult
17
+
18
+ console = Console()
19
+
20
+
21
+ class TranscribeCommand(BaseCommand):
22
+ """Command for transcribing audio files and URLs."""
23
+
24
+ name = "transcribe"
25
+ help = "Transcribe audio files or URLs using Deepgram"
26
+ short_help = "Transcribe audio"
27
+
28
+ # Transcription requires authentication
29
+ requires_auth = True
30
+ requires_project = False # Project ID is optional for transcription
31
+ ci_friendly = True
32
+
33
+ def get_arguments(self) -> list[dict[str, Any]]:
34
+ """Get command arguments and options."""
35
+ return [
36
+ {
37
+ "name": "source",
38
+ "help": "Audio file path or URL to transcribe",
39
+ "type": str,
40
+ "required": True,
41
+ "nargs": 1,
42
+ },
43
+ {
44
+ "names": ["--model", "-m"],
45
+ "help": "Deepgram model to use",
46
+ "type": str,
47
+ "default": "nova-2",
48
+ "is_option": True,
49
+ },
50
+ {
51
+ "names": ["--language", "-l"],
52
+ "help": "Language code (e.g., en-US, es-ES)",
53
+ "type": str,
54
+ "default": "en-US",
55
+ "is_option": True,
56
+ },
57
+ {
58
+ "names": ["--smart-format"],
59
+ "help": "Enable smart formatting",
60
+ "is_flag": True,
61
+ "default": True,
62
+ "is_option": True,
63
+ },
64
+ {
65
+ "names": ["--punctuate"],
66
+ "help": "Enable punctuation",
67
+ "is_flag": True,
68
+ "default": True,
69
+ "is_option": True,
70
+ },
71
+ {
72
+ "names": ["--diarize"],
73
+ "help": "Enable speaker diarization",
74
+ "is_flag": True,
75
+ "is_option": True,
76
+ },
77
+ {
78
+ "names": ["--summarize"],
79
+ "help": "Enable summarization",
80
+ "is_flag": True,
81
+ "is_option": True,
82
+ },
83
+ {
84
+ "names": ["--detect-topics"],
85
+ "help": "Enable topic detection",
86
+ "is_flag": True,
87
+ "is_option": True,
88
+ },
89
+ {
90
+ "names": ["--save-to", "-s"],
91
+ "help": "Save transcription to file",
92
+ "type": str,
93
+ "is_option": True,
94
+ },
95
+ {
96
+ "names": ["--no-validate"],
97
+ "help": "Skip input validation",
98
+ "is_flag": True,
99
+ "is_option": True,
100
+ },
101
+ ]
102
+
103
+ def handle(
104
+ self,
105
+ config: Config,
106
+ auth_manager: AuthManager,
107
+ client: DeepgramClient,
108
+ **kwargs: Any,
109
+ ) -> BaseResult:
110
+ """Handle transcribe command."""
111
+ source = kwargs.get("source")
112
+ model = kwargs.get("model", "nova-2")
113
+ language = kwargs.get("language", "en-US")
114
+ smart_format = kwargs.get("smart_format", True)
115
+ punctuate = kwargs.get("punctuate", True)
116
+ diarize = kwargs.get("diarize", False)
117
+ summarize = kwargs.get("summarize", False)
118
+ detect_topics = kwargs.get("detect_topics", False)
119
+ save_to = kwargs.get("save_to")
120
+ no_validate = kwargs.get("no_validate", False)
121
+
122
+ # Check if source is provided
123
+ if not source:
124
+ return BaseResult(
125
+ status="error", message="No audio source provided"
126
+ )
127
+
128
+ # Validate input if not skipped
129
+ if not no_validate and not self._validate_source(source):
130
+ return BaseResult(status="error", message="Invalid audio source")
131
+
132
+ # Build transcription options
133
+ options = {
134
+ "model": model,
135
+ "language": language,
136
+ "smart_format": str(smart_format).lower(),
137
+ "punctuate": str(punctuate).lower(),
138
+ }
139
+
140
+ # Only add optional features if explicitly enabled
141
+ if diarize:
142
+ options["diarize"] = "true"
143
+ if summarize:
144
+ options["summarize"] = "true"
145
+ if detect_topics:
146
+ options["detect_topics"] = "true"
147
+
148
+ try:
149
+ console.print(f"[blue]Transcribing:[/blue] {source}")
150
+ console.print(f"[dim]Model:[/dim] {model}")
151
+ console.print(f"[dim]Language:[/dim] {language}")
152
+
153
+ # Determine if source is file or URL
154
+ if self._is_url(source):
155
+ console.print("[dim]Processing URL...[/dim]")
156
+ result = client.transcribe_url(source, options)
157
+ else:
158
+ console.print("[dim]Processing file...[/dim]")
159
+ result = client.transcribe_file(source, options)
160
+
161
+ # Convert SDK response object to dict
162
+ result_dict = result
163
+ if hasattr(result, "to_dict"):
164
+ result_dict = result.to_dict()
165
+ elif hasattr(result, "dict"):
166
+ result_dict = result.dict()
167
+ elif hasattr(result, "__dict__"):
168
+ result_dict = result.__dict__
169
+
170
+ # Extract transcript text
171
+ transcript = self._extract_transcript(result_dict)
172
+
173
+ # Save to file if requested
174
+ if save_to:
175
+ self._save_transcript(transcript, save_to)
176
+ console.print(
177
+ f"[green]✓[/green] Transcript saved to: {save_to}"
178
+ )
179
+
180
+ # Return structured result
181
+ return TranscribeResult(
182
+ status="success",
183
+ source=source,
184
+ model=model,
185
+ language=language,
186
+ transcript=transcript,
187
+ full_result=result_dict,
188
+ saved_to=save_to,
189
+ )
190
+
191
+ except Exception as e:
192
+ console.print(f"[red]Transcription failed:[/red] {e}")
193
+ return BaseResult(status="error", message=str(e))
194
+
195
+ def _validate_source(self, source: str) -> bool:
196
+ """Validate audio source (file or URL)."""
197
+ if self._is_url(source):
198
+ return validate_url(source, check_accessibility=True)
199
+ else:
200
+ return validate_audio_file(source)
201
+
202
+ def _is_url(self, source: str) -> bool:
203
+ """Check if source is a URL."""
204
+ return source.startswith(("http://", "https://"))
205
+
206
+ def _extract_transcript(self, result: dict[str, Any]) -> str:
207
+ """Extract transcript text from API result."""
208
+ try:
209
+ # Handle different response formats
210
+ if "results" in result and "channels" in result["results"]:
211
+ # Standard format
212
+ channels = result["results"]["channels"]
213
+ if channels and "alternatives" in channels[0]:
214
+ return str(channels[0]["alternatives"][0]["transcript"])
215
+
216
+ # Fallback to looking for transcript in other locations
217
+ if "transcript" in result:
218
+ return str(result["transcript"])
219
+
220
+ return "No transcript found in response"
221
+
222
+ except Exception as e:
223
+ console.print(
224
+ f"[yellow]Warning:[/yellow] Could not extract transcript: {e}"
225
+ )
226
+ return str(result)
227
+
228
+ def _save_transcript(self, transcript: str, file_path: str) -> None:
229
+ """Save transcript to file."""
230
+ try:
231
+ path = Path(file_path)
232
+
233
+ # Create directory if it doesn't exist
234
+ path.parent.mkdir(parents=True, exist_ok=True)
235
+
236
+ # Write transcript
237
+ with open(path, "w", encoding="utf-8") as f:
238
+ f.write(transcript)
239
+
240
+ except Exception as e:
241
+ console.print(f"[red]Error saving transcript:[/red] {e}")
242
+ raise
@@ -0,0 +1,14 @@
1
+ """Models for transcribe command."""
2
+
3
+ from typing import Any
4
+
5
+ from deepctl_core import BaseResult
6
+
7
+
8
+ class TranscribeResult(BaseResult):
9
+ source: str
10
+ model: str
11
+ language: str
12
+ transcript: str
13
+ saved_to: str | None = None
14
+ full_result: dict[str, Any]
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepctl-cmd-transcribe
3
+ Version: 0.1.0
4
+ Summary: Transcribe command for deepctl
5
+ Author-email: Deepgram <devrel@deepgram.com>
6
+ Maintainer-email: Deepgram <devrel@deepgram.com>
7
+ License-Expression: MIT
8
+ Keywords: deepgram,cli,transcribe,speech,audio
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: deepctl-core>=0.1.0
18
+ Requires-Dist: deepctl-shared-utils>=0.1.0
19
+ Requires-Dist: click>=8.0.0
20
+ Requires-Dist: rich>=13.0.0
21
+ Requires-Dist: deepgram-sdk>=3.0.0
22
+ Requires-Dist: pydantic>=2.0.0
23
+
24
+ # deepctl-cmd-transcribe
25
+
26
+ Transcribe command for deepctl. This package is an internal component of deepctl and is not intended for standalone use.
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/deepctl_cmd_transcribe/__init__.py
4
+ src/deepctl_cmd_transcribe/command.py
5
+ src/deepctl_cmd_transcribe/models.py
6
+ src/deepctl_cmd_transcribe.egg-info/PKG-INFO
7
+ src/deepctl_cmd_transcribe.egg-info/SOURCES.txt
8
+ src/deepctl_cmd_transcribe.egg-info/dependency_links.txt
9
+ src/deepctl_cmd_transcribe.egg-info/entry_points.txt
10
+ src/deepctl_cmd_transcribe.egg-info/requires.txt
11
+ src/deepctl_cmd_transcribe.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [deepctl.commands]
2
+ transcribe = deepctl_cmd_transcribe.command:TranscribeCommand
@@ -0,0 +1,6 @@
1
+ deepctl-core>=0.1.0
2
+ deepctl-shared-utils>=0.1.0
3
+ click>=8.0.0
4
+ rich>=13.0.0
5
+ deepgram-sdk>=3.0.0
6
+ pydantic>=2.0.0