deepctl-shared-utils 0.1.10__tar.gz → 0.1.11__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.
Files changed (19) hide show
  1. deepctl_shared_utils-0.1.11/PKG-INFO +60 -0
  2. deepctl_shared_utils-0.1.11/README.md +39 -0
  3. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/pyproject.toml +2 -2
  4. deepctl_shared_utils-0.1.11/src/deepctl_shared_utils/__init__.py +31 -0
  5. deepctl_shared_utils-0.1.11/src/deepctl_shared_utils/ffprobe.py +225 -0
  6. deepctl_shared_utils-0.1.11/src/deepctl_shared_utils/ffprobe_models.py +38 -0
  7. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils/validation.py +20 -25
  8. deepctl_shared_utils-0.1.11/src/deepctl_shared_utils.egg-info/PKG-INFO +60 -0
  9. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils.egg-info/SOURCES.txt +2 -0
  10. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils.egg-info/requires.txt +1 -0
  11. deepctl_shared_utils-0.1.10/PKG-INFO +0 -23
  12. deepctl_shared_utils-0.1.10/README.md +0 -3
  13. deepctl_shared_utils-0.1.10/src/deepctl_shared_utils/__init__.py +0 -13
  14. deepctl_shared_utils-0.1.10/src/deepctl_shared_utils.egg-info/PKG-INFO +0 -23
  15. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/setup.cfg +0 -0
  16. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils/models.py +0 -0
  17. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils/py.typed +0 -0
  18. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils.egg-info/dependency_links.txt +0 -0
  19. {deepctl_shared_utils-0.1.10 → deepctl_shared_utils-0.1.11}/src/deepctl_shared_utils.egg-info/top_level.txt +0 -0
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepctl-shared-utils
3
+ Version: 0.1.11
4
+ Summary: Shared utilities for deepctl
5
+ Author-email: Deepgram <devrel@deepgram.com>
6
+ Maintainer-email: Deepgram <devrel@deepgram.com>
7
+ License-Expression: MIT
8
+ Keywords: deepgram,utilities,validation,helpers
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: pydantic>=2.0.0
18
+ Requires-Dist: click>=8.0.0
19
+ Requires-Dist: httpx>=0.24.0
20
+ Requires-Dist: rich>=13.0.0
21
+
22
+ # deepctl-shared-utils
23
+
24
+ > Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
25
+
26
+ Shared utilities for deepctl
27
+
28
+ This package provides internal APIs for deepctl and its command packages. It is not intended for direct use.
29
+
30
+ ## Installation
31
+
32
+ This package is included with deepctl and does not need to be installed separately.
33
+
34
+ ### Install deepctl
35
+
36
+ ```bash
37
+ # Install with pip
38
+ pip install deepctl
39
+
40
+ # Or install with uv
41
+ uv tool install deepctl
42
+
43
+ # Or install with pipx
44
+ pipx install deepctl
45
+
46
+ # Or run without installing
47
+ uvx deepctl --help
48
+ pipx run deepctl --help
49
+ ```
50
+
51
+ ## Dependencies
52
+
53
+ - `pydantic>=2.0.0`
54
+ - `click>=8.0.0`
55
+ - `httpx>=0.24.0`
56
+ - `rich>=13.0.0`
57
+
58
+ ## License
59
+
60
+ MIT — see [LICENSE](../../LICENSE)
@@ -0,0 +1,39 @@
1
+ # deepctl-shared-utils
2
+
3
+ > Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
4
+
5
+ Shared utilities for deepctl
6
+
7
+ This package provides internal APIs for deepctl and its command packages. It is not intended for direct use.
8
+
9
+ ## Installation
10
+
11
+ This package is included with deepctl and does not need to be installed separately.
12
+
13
+ ### Install deepctl
14
+
15
+ ```bash
16
+ # Install with pip
17
+ pip install deepctl
18
+
19
+ # Or install with uv
20
+ uv tool install deepctl
21
+
22
+ # Or install with pipx
23
+ pipx install deepctl
24
+
25
+ # Or run without installing
26
+ uvx deepctl --help
27
+ pipx run deepctl --help
28
+ ```
29
+
30
+ ## Dependencies
31
+
32
+ - `pydantic>=2.0.0`
33
+ - `click>=8.0.0`
34
+ - `httpx>=0.24.0`
35
+ - `rich>=13.0.0`
36
+
37
+ ## License
38
+
39
+ MIT — see [LICENSE](../../LICENSE)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deepctl-shared-utils"
7
- version = "0.1.10"
7
+ version = "0.1.11" # x-release-please-version
8
8
  description = "Shared utilities for deepctl"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -20,7 +20,7 @@ classifiers = [
20
20
  ]
21
21
  keywords = ["deepgram", "utilities", "validation", "helpers"]
22
22
  requires-python = ">=3.10"
23
- dependencies = ["pydantic>=2.0.0", "click>=8.0.0", "httpx>=0.24.0"]
23
+ dependencies = ["pydantic>=2.0.0", "click>=8.0.0", "httpx>=0.24.0", "rich>=13.0.0"]
24
24
 
25
25
  [tool.setuptools]
26
26
  package-dir = { "" = "src" }
@@ -0,0 +1,31 @@
1
+ """Shared utilities for deepctl."""
2
+
3
+ from .ffprobe import (
4
+ check_ffprobe,
5
+ get_ffprobe_path,
6
+ print_ffprobe_install_instructions,
7
+ probe_buffer,
8
+ probe_file,
9
+ require_ffprobe,
10
+ )
11
+ from .ffprobe_models import AudioFormatInfo, AudioProbeResult, AudioStreamInfo
12
+ from .models import FileInfo
13
+ from .validation import validate_audio_file, validate_date_format, validate_url
14
+
15
+ __all__ = [
16
+ "AudioFormatInfo",
17
+ "AudioProbeResult",
18
+ "AudioStreamInfo",
19
+ "FileInfo",
20
+ "check_ffprobe",
21
+ "get_ffprobe_path",
22
+ "print_ffprobe_install_instructions",
23
+ "probe_buffer",
24
+ "probe_file",
25
+ "require_ffprobe",
26
+ "validate_audio_file",
27
+ "validate_date_format",
28
+ "validate_url",
29
+ ]
30
+
31
+ __version__ = "0.1.11" # x-release-please-version
@@ -0,0 +1,225 @@
1
+ """Shared ffprobe wrapper for audio file analysis."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import platform
8
+ import shutil
9
+ import subprocess
10
+ import tempfile
11
+ from typing import TYPE_CHECKING
12
+
13
+ from rich.console import Console
14
+ from rich.panel import Panel
15
+
16
+ from .ffprobe_models import AudioFormatInfo, AudioProbeResult, AudioStreamInfo
17
+
18
+ if TYPE_CHECKING:
19
+ from deepctl_core import Config
20
+
21
+ console = Console()
22
+
23
+
24
+ def get_ffprobe_path(config: Config | None = None) -> str | None:
25
+ """Get the ffprobe binary path.
26
+
27
+ Checks stored config path first, then falls back to auto-detection
28
+ via shutil.which().
29
+ """
30
+ if config is not None:
31
+ stored_path = config.get("tools.ffprobe_path")
32
+ if (
33
+ stored_path
34
+ and os.path.isfile(stored_path)
35
+ and os.access(stored_path, os.X_OK)
36
+ ):
37
+ return str(stored_path)
38
+
39
+ return shutil.which("ffprobe")
40
+
41
+
42
+ def check_ffprobe(config: Config | None = None) -> bool:
43
+ """Check if ffprobe is available."""
44
+ return get_ffprobe_path(config) is not None
45
+
46
+
47
+ def print_ffprobe_install_instructions() -> None:
48
+ """Print platform-specific ffprobe installation instructions."""
49
+ system = platform.system()
50
+
51
+ if system == "Darwin":
52
+ instructions = (
53
+ "[bold]Install FFmpeg (includes ffprobe):[/bold]\n\n"
54
+ " [cyan]brew install ffmpeg[/cyan]\n"
55
+ )
56
+ elif system == "Linux":
57
+ instructions = (
58
+ "[bold]Install FFmpeg (includes ffprobe):[/bold]\n\n"
59
+ " [cyan]sudo apt install ffmpeg[/cyan] # Debian/Ubuntu\n"
60
+ " [cyan]sudo dnf install ffmpeg[/cyan] # Fedora\n"
61
+ " [cyan]sudo pacman -S ffmpeg[/cyan] # Arch\n"
62
+ )
63
+ elif system == "Windows":
64
+ instructions = (
65
+ "[bold]Install FFmpeg (includes ffprobe):[/bold]\n\n"
66
+ " [cyan]winget install FFmpeg[/cyan]\n"
67
+ " [cyan]choco install ffmpeg[/cyan] # Chocolatey\n"
68
+ " [cyan]scoop install ffmpeg[/cyan] # Scoop\n"
69
+ )
70
+ else:
71
+ instructions = (
72
+ "[bold]Install FFmpeg (includes ffprobe):[/bold]\n\n"
73
+ " Download from [cyan]https://ffmpeg.org/download.html[/cyan]\n"
74
+ )
75
+
76
+ instructions += (
77
+ "\nAfter installing, you can set a custom path with:\n"
78
+ " [dim]dg ffprobe --path /path/to/ffprobe[/dim]"
79
+ )
80
+
81
+ console.print(
82
+ Panel(
83
+ instructions,
84
+ title="[red]ffprobe not found[/red]",
85
+ border_style="red",
86
+ )
87
+ )
88
+
89
+
90
+ def require_ffprobe(config: Config | None = None) -> bool:
91
+ """Check for ffprobe and print install instructions if missing.
92
+
93
+ Returns True if ffprobe is available, False otherwise.
94
+ """
95
+ if check_ffprobe(config):
96
+ return True
97
+
98
+ print_ffprobe_install_instructions()
99
+ return False
100
+
101
+
102
+ def _parse_probe_data(data: dict[str, object]) -> AudioProbeResult:
103
+ """Parse raw ffprobe JSON output into an AudioProbeResult."""
104
+ result = AudioProbeResult(raw_data=data)
105
+
106
+ fmt = data.get("format")
107
+ if isinstance(fmt, dict):
108
+ duration_str = fmt.get("duration")
109
+ size_str = fmt.get("size")
110
+ result.format = AudioFormatInfo(
111
+ format_name=fmt.get("format_name"),
112
+ format_long_name=fmt.get("format_long_name"),
113
+ duration=float(duration_str) if duration_str else None,
114
+ size=int(size_str) if size_str else None,
115
+ bit_rate=fmt.get("bit_rate"),
116
+ )
117
+
118
+ streams_data = data.get("streams")
119
+ if isinstance(streams_data, list):
120
+ for stream in streams_data:
121
+ if not isinstance(stream, dict):
122
+ continue
123
+ if stream.get("codec_type") != "audio":
124
+ continue
125
+ duration_str = stream.get("duration")
126
+ result.streams.append(
127
+ AudioStreamInfo(
128
+ codec_name=stream.get("codec_name"),
129
+ codec_long_name=stream.get("codec_long_name"),
130
+ sample_rate=stream.get("sample_rate"),
131
+ channels=stream.get("channels"),
132
+ channel_layout=stream.get("channel_layout"),
133
+ bit_rate=stream.get("bit_rate"),
134
+ bits_per_sample=stream.get("bits_per_sample"),
135
+ duration=float(duration_str) if duration_str else None,
136
+ )
137
+ )
138
+
139
+ return result
140
+
141
+
142
+ def probe_file(file_path: str, config: Config | None = None) -> AudioProbeResult | None:
143
+ """Probe an audio file using ffprobe.
144
+
145
+ Returns AudioProbeResult on success, None on failure.
146
+ """
147
+ ffprobe_bin = get_ffprobe_path(config)
148
+ if not ffprobe_bin:
149
+ return None
150
+
151
+ try:
152
+ cmd = [
153
+ ffprobe_bin,
154
+ "-v",
155
+ "quiet",
156
+ "-print_format",
157
+ "json",
158
+ "-show_format",
159
+ "-show_streams",
160
+ file_path,
161
+ ]
162
+
163
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
164
+
165
+ if result.returncode != 0:
166
+ return None
167
+
168
+ data = json.loads(result.stdout)
169
+ return _parse_probe_data(data)
170
+
171
+ except (subprocess.TimeoutExpired, json.JSONDecodeError, OSError):
172
+ return None
173
+
174
+
175
+ def probe_buffer(
176
+ audio_bytes: bytes,
177
+ label: str = "audio",
178
+ config: Config | None = None,
179
+ ) -> AudioProbeResult | None:
180
+ """Probe audio bytes by writing to a temp file and running ffprobe.
181
+
182
+ Returns AudioProbeResult on success, None on failure.
183
+ """
184
+ if not audio_bytes:
185
+ return None
186
+
187
+ ffprobe_bin = get_ffprobe_path(config)
188
+ if not ffprobe_bin:
189
+ return None
190
+
191
+ tmp_name = None
192
+ try:
193
+ with tempfile.NamedTemporaryFile(
194
+ suffix=".raw", delete=False, prefix=f"deepctl_{label}_"
195
+ ) as tmp_file:
196
+ tmp_name = tmp_file.name
197
+ tmp_file.write(audio_bytes)
198
+
199
+ cmd = [
200
+ ffprobe_bin,
201
+ "-v",
202
+ "quiet",
203
+ "-print_format",
204
+ "json",
205
+ "-show_format",
206
+ "-show_streams",
207
+ tmp_name,
208
+ ]
209
+
210
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
211
+
212
+ if result.returncode != 0:
213
+ return None
214
+
215
+ data = json.loads(result.stdout)
216
+ return _parse_probe_data(data)
217
+
218
+ except (subprocess.TimeoutExpired, json.JSONDecodeError, OSError):
219
+ return None
220
+ finally:
221
+ if tmp_name:
222
+ try:
223
+ os.unlink(tmp_name)
224
+ except OSError:
225
+ pass
@@ -0,0 +1,38 @@
1
+ """Pydantic models for ffprobe audio analysis results."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+
10
+ class AudioStreamInfo(BaseModel):
11
+ """Information about a single audio stream from ffprobe."""
12
+
13
+ codec_name: str | None = None
14
+ codec_long_name: str | None = None
15
+ sample_rate: str | None = None
16
+ channels: int | None = None
17
+ channel_layout: str | None = None
18
+ bit_rate: str | None = None
19
+ bits_per_sample: int | None = None
20
+ duration: float | None = None
21
+
22
+
23
+ class AudioFormatInfo(BaseModel):
24
+ """Format-level information from ffprobe."""
25
+
26
+ format_name: str | None = None
27
+ format_long_name: str | None = None
28
+ duration: float | None = None
29
+ size: int | None = None
30
+ bit_rate: str | None = None
31
+
32
+
33
+ class AudioProbeResult(BaseModel):
34
+ """Complete ffprobe analysis result."""
35
+
36
+ format: AudioFormatInfo | None = None
37
+ streams: list[AudioStreamInfo] = Field(default_factory=list)
38
+ raw_data: dict[str, Any] | None = None
@@ -88,17 +88,14 @@ def validate_audio_file(file_path: str | Path) -> bool:
88
88
 
89
89
  # Check if file is readable
90
90
  if not os.access(path, os.R_OK):
91
- console.print(
92
- f"[red]Error:[/red] File is not readable: {file_path}"
93
- )
91
+ console.print(f"[red]Error:[/red] File is not readable: {file_path}")
94
92
  return False
95
93
 
96
94
  # Check file size (warn if very large)
97
95
  size_mb = path.stat().st_size / (1024 * 1024)
98
96
  if size_mb > 500: # 500 MB
99
97
  console.print(
100
- f"[yellow]Warning:[/yellow] Large file detected "
101
- f"({size_mb:.1f} MB)"
98
+ f"[yellow]Warning:[/yellow] Large file detected ({size_mb:.1f} MB)"
102
99
  )
103
100
  console.print("[dim]Large files may take longer to process[/dim]")
104
101
 
@@ -173,10 +170,19 @@ def _check_url_accessibility(url: str) -> bool:
173
170
  console.print("[dim]Checking URL accessibility...[/dim]")
174
171
 
175
172
  with httpx.Client(timeout=10.0) as client:
176
- # Use HEAD request to check without downloading
173
+ # Try HEAD first; fall back to a ranged GET if the server
174
+ # doesn't support HEAD (some CDNs/redirect services return
175
+ # 404 or 405 for HEAD but serve GET fine).
177
176
  response = client.head(url, follow_redirects=True)
178
177
 
179
- if response.status_code == 200:
178
+ if response.status_code not in range(200, 400):
179
+ response = client.get(
180
+ url,
181
+ follow_redirects=True,
182
+ headers={"Range": "bytes=0-0"},
183
+ )
184
+
185
+ if response.status_code in (200, 206):
180
186
  # Check content type if available
181
187
  content_type = response.headers.get("content-type", "").lower()
182
188
  if content_type and not any(
@@ -264,13 +270,10 @@ def validate_project_id(project_id: str) -> bool:
264
270
  return False
265
271
 
266
272
  # Check if it's a valid UUID format
267
- uuid_pattern = (
268
- r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
269
- )
273
+ uuid_pattern = r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
270
274
  if not re.match(uuid_pattern, project_id, re.IGNORECASE):
271
275
  console.print(
272
- "[yellow]Warning:[/yellow] Project ID doesn't match expected "
273
- "UUID format"
276
+ "[yellow]Warning:[/yellow] Project ID doesn't match expected UUID format"
274
277
  )
275
278
  return False
276
279
 
@@ -336,8 +339,7 @@ def validate_language_code(language: str) -> bool:
336
339
 
337
340
  if language not in supported_languages:
338
341
  console.print(
339
- f"[yellow]Warning:[/yellow] Language '{language}' may not be "
340
- f"supported"
342
+ f"[yellow]Warning:[/yellow] Language '{language}' may not be supported"
341
343
  )
342
344
  console.print(
343
345
  "[dim]Common supported languages: en-US, es-ES, fr-FR, de-DE, "
@@ -387,9 +389,7 @@ def validate_model_name(model: str) -> bool:
387
389
  }
388
390
 
389
391
  if model not in supported_models:
390
- console.print(
391
- f"[yellow]Warning:[/yellow] Model '{model}' may not be supported"
392
- )
392
+ console.print(f"[yellow]Warning:[/yellow] Model '{model}' may not be supported")
393
393
  console.print(
394
394
  "[dim]Common supported models: nova-2, nova, enhanced, base, "
395
395
  "meeting, phonecall[/dim]"
@@ -446,9 +446,7 @@ def validate_file_permissions(file_path: str | Path) -> bool:
446
446
 
447
447
  # Check read permission
448
448
  if not os.access(path, os.R_OK):
449
- console.print(
450
- f"[red]Error:[/red] No read permission for file: {file_path}"
451
- )
449
+ console.print(f"[red]Error:[/red] No read permission for file: {file_path}")
452
450
  return False
453
451
 
454
452
  # Check if file is not empty
@@ -501,12 +499,9 @@ def validate_output_format(format_type: str) -> bool:
501
499
  supported_formats = {"json", "yaml", "table", "csv"}
502
500
 
503
501
  if format_type not in supported_formats:
502
+ console.print(f"[red]Error:[/red] Unsupported output format: {format_type}")
504
503
  console.print(
505
- f"[red]Error:[/red] Unsupported output format: {format_type}"
506
- )
507
- console.print(
508
- f"[dim]Supported formats: "
509
- f"{', '.join(sorted(supported_formats))}[/dim]"
504
+ f"[dim]Supported formats: {', '.join(sorted(supported_formats))}[/dim]"
510
505
  )
511
506
  return False
512
507
 
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepctl-shared-utils
3
+ Version: 0.1.11
4
+ Summary: Shared utilities for deepctl
5
+ Author-email: Deepgram <devrel@deepgram.com>
6
+ Maintainer-email: Deepgram <devrel@deepgram.com>
7
+ License-Expression: MIT
8
+ Keywords: deepgram,utilities,validation,helpers
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: pydantic>=2.0.0
18
+ Requires-Dist: click>=8.0.0
19
+ Requires-Dist: httpx>=0.24.0
20
+ Requires-Dist: rich>=13.0.0
21
+
22
+ # deepctl-shared-utils
23
+
24
+ > Part of [deepctl](https://github.com/deepgram/cli) — Official Deepgram CLI
25
+
26
+ Shared utilities for deepctl
27
+
28
+ This package provides internal APIs for deepctl and its command packages. It is not intended for direct use.
29
+
30
+ ## Installation
31
+
32
+ This package is included with deepctl and does not need to be installed separately.
33
+
34
+ ### Install deepctl
35
+
36
+ ```bash
37
+ # Install with pip
38
+ pip install deepctl
39
+
40
+ # Or install with uv
41
+ uv tool install deepctl
42
+
43
+ # Or install with pipx
44
+ pipx install deepctl
45
+
46
+ # Or run without installing
47
+ uvx deepctl --help
48
+ pipx run deepctl --help
49
+ ```
50
+
51
+ ## Dependencies
52
+
53
+ - `pydantic>=2.0.0`
54
+ - `click>=8.0.0`
55
+ - `httpx>=0.24.0`
56
+ - `rich>=13.0.0`
57
+
58
+ ## License
59
+
60
+ MIT — see [LICENSE](../../LICENSE)
@@ -1,6 +1,8 @@
1
1
  README.md
2
2
  pyproject.toml
3
3
  src/deepctl_shared_utils/__init__.py
4
+ src/deepctl_shared_utils/ffprobe.py
5
+ src/deepctl_shared_utils/ffprobe_models.py
4
6
  src/deepctl_shared_utils/models.py
5
7
  src/deepctl_shared_utils/py.typed
6
8
  src/deepctl_shared_utils/validation.py
@@ -1,3 +1,4 @@
1
1
  pydantic>=2.0.0
2
2
  click>=8.0.0
3
3
  httpx>=0.24.0
4
+ rich>=13.0.0
@@ -1,23 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: deepctl-shared-utils
3
- Version: 0.1.10
4
- Summary: Shared utilities for deepctl
5
- Author-email: Deepgram <devrel@deepgram.com>
6
- Maintainer-email: Deepgram <devrel@deepgram.com>
7
- License-Expression: MIT
8
- Keywords: deepgram,utilities,validation,helpers
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: pydantic>=2.0.0
18
- Requires-Dist: click>=8.0.0
19
- Requires-Dist: httpx>=0.24.0
20
-
21
- # deepctl-shared-utils
22
-
23
- Shared utilities for deepctl. This package is an internal component of deepctl and is not intended for standalone use.
@@ -1,3 +0,0 @@
1
- # deepctl-shared-utils
2
-
3
- Shared utilities for deepctl. This package is an internal component of deepctl and is not intended for standalone use.
@@ -1,13 +0,0 @@
1
- """Shared utilities for deepctl."""
2
-
3
- from .models import FileInfo
4
- from .validation import validate_audio_file, validate_date_format, validate_url
5
-
6
- __all__ = [
7
- "FileInfo",
8
- "validate_audio_file",
9
- "validate_date_format",
10
- "validate_url",
11
- ]
12
-
13
- __version__ = "0.1.0"
@@ -1,23 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: deepctl-shared-utils
3
- Version: 0.1.10
4
- Summary: Shared utilities for deepctl
5
- Author-email: Deepgram <devrel@deepgram.com>
6
- Maintainer-email: Deepgram <devrel@deepgram.com>
7
- License-Expression: MIT
8
- Keywords: deepgram,utilities,validation,helpers
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: pydantic>=2.0.0
18
- Requires-Dist: click>=8.0.0
19
- Requires-Dist: httpx>=0.24.0
20
-
21
- # deepctl-shared-utils
22
-
23
- Shared utilities for deepctl. This package is an internal component of deepctl and is not intended for standalone use.