edgespeak 0.6.4__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 (34) hide show
  1. edgespeak-0.6.4/MANIFEST.in +3 -0
  2. edgespeak-0.6.4/PKG-INFO +120 -0
  3. edgespeak-0.6.4/README.md +106 -0
  4. edgespeak-0.6.4/README.zh-CN.md +95 -0
  5. edgespeak-0.6.4/examples/_common.py +18 -0
  6. edgespeak-0.6.4/examples/align.py +48 -0
  7. edgespeak-0.6.4/examples/segment.py +31 -0
  8. edgespeak-0.6.4/examples/speakers.py +23 -0
  9. edgespeak-0.6.4/examples/transcribe.py +41 -0
  10. edgespeak-0.6.4/pyproject.toml +28 -0
  11. edgespeak-0.6.4/setup.cfg +4 -0
  12. edgespeak-0.6.4/src/edgespeak/__init__.py +10 -0
  13. edgespeak-0.6.4/src/edgespeak/_bootstrap.py +246 -0
  14. edgespeak-0.6.4/src/edgespeak/_client.py +568 -0
  15. edgespeak-0.6.4/src/edgespeak/_errors.py +65 -0
  16. edgespeak-0.6.4/src/edgespeak/_process.py +137 -0
  17. edgespeak-0.6.4/src/edgespeak/_reference.py +45 -0
  18. edgespeak-0.6.4/src/edgespeak/_streaming.py +115 -0
  19. edgespeak-0.6.4/src/edgespeak/_types.py +10 -0
  20. edgespeak-0.6.4/src/edgespeak/_version.py +3 -0
  21. edgespeak-0.6.4/src/edgespeak/py.typed +0 -0
  22. edgespeak-0.6.4/src/edgespeak.egg-info/PKG-INFO +120 -0
  23. edgespeak-0.6.4/src/edgespeak.egg-info/SOURCES.txt +32 -0
  24. edgespeak-0.6.4/src/edgespeak.egg-info/dependency_links.txt +1 -0
  25. edgespeak-0.6.4/src/edgespeak.egg-info/requires.txt +5 -0
  26. edgespeak-0.6.4/src/edgespeak.egg-info/top_level.txt +1 -0
  27. edgespeak-0.6.4/tests/test_bootstrap.py +216 -0
  28. edgespeak-0.6.4/tests/test_cli_integration.py +142 -0
  29. edgespeak-0.6.4/tests/test_client.py +272 -0
  30. edgespeak-0.6.4/tests/test_errors.py +42 -0
  31. edgespeak-0.6.4/tests/test_examples.py +61 -0
  32. edgespeak-0.6.4/tests/test_speech_features.py +432 -0
  33. edgespeak-0.6.4/tests/test_version.py +17 -0
  34. edgespeak-0.6.4/tests/typing/public_api.py +41 -0
@@ -0,0 +1,3 @@
1
+ include README.zh-CN.md
2
+ recursive-include examples *.py
3
+ recursive-include tests *.py
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.4
2
+ Name: edgespeak
3
+ Version: 0.6.4
4
+ Summary: Python client for the local EdgeSpeak CLI runtime
5
+ Project-URL: Documentation, https://edgespeak.com/docs/python-sdk
6
+ Project-URL: Source, https://github.com/lattifai/EdgeSpeak/tree/main/sdk/python
7
+ Project-URL: Issues, https://github.com/lattifai/EdgeSpeak/issues
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ Requires-Dist: httpx<1,>=0.27
11
+ Provides-Extra: dev
12
+ Requires-Dist: mypy==1.20.2; extra == "dev"
13
+ Requires-Dist: typing_extensions>=4.6; extra == "dev"
14
+
15
+ # EdgeSpeak Python SDK
16
+
17
+ Transcribe, align, segment text, identify speaker turns, and compare voice embeddings
18
+ through the local EdgeSpeak CLI. Audio is processed by the connected runtime;
19
+ the SDK does not bundle engines or models.
20
+
21
+ [简体中文](https://github.com/lattifai/EdgeSpeak/blob/main/sdk/python/README.zh-CN.md) · [Documentation](https://edgespeak.com/docs/python-sdk) · [Examples](https://github.com/lattifai/EdgeSpeak/tree/main/sdk/python/examples)
22
+
23
+ ## Installation
24
+
25
+ Requires Python 3.10+. One pure-Python wheel serves all supported Python versions
26
+ and platforms. Once published to PyPI, install with:
27
+
28
+ ```bash
29
+ python -m pip install edgespeak
30
+ ```
31
+
32
+ The first PyPI release is pending. Until then, run `python -m pip install ./sdk/python`
33
+ from the repository root. The SDK discovers an installed CLI and automatically
34
+ installs the latest official stable CLI if none meets its requirements.
35
+ Automatic installation supports macOS Apple Silicon, Linux x86_64, and Windows x64
36
+ and requires network access. Models load on demand; first use may download a model.
37
+
38
+ ## Create and configure an API KEY
39
+
40
+ 1. Sign in to [EdgeSpeak → API KEY](https://edgespeak.com/account/api-keys).
41
+ 2. Create an API KEY, choose an expiry (including never expires) and usage limit,
42
+ and copy the full key shown at creation.
43
+ 3. Set `EDGESPEAK_API_KEY` in the environment running Python:
44
+
45
+ ```bash
46
+ export EDGESPEAK_API_KEY="your API KEY"
47
+ ```
48
+
49
+ In Windows PowerShell, use `$env:EDGESPEAK_API_KEY="your API KEY"`.
50
+ `EdgeSpeak()` reads this variable automatically; you can also pass `EdgeSpeak(api_key=...)`.
51
+ An API KEY authorizes programmatic access and is different from a product activation
52
+ key. Keep it out of source control. An already activated local device can also
53
+ reuse its existing authorization.
54
+
55
+ API KEY access requires online authorization and shares the account subscription
56
+ allowance and billing period with desktop usage. Creating a key does not reset usage.
57
+ Never expires only removes the expiry date; entitlement, usage limits, and revocation
58
+ still apply.
59
+
60
+ ## Quick start
61
+
62
+ ```python
63
+ from edgespeak import EdgeSpeak
64
+
65
+ with EdgeSpeak() as client:
66
+ transcript = client.transcribe("meeting.wav", language="en", diarize=True)
67
+ print(transcript["text"])
68
+ aligned = client.align("speech.wav", text="The exact words spoken.")
69
+ speakers = client.diarize("meeting.wav", num_speakers=2)
70
+ ```
71
+
72
+ Reuse a client and use `with` or `close()` to release its owned service.
73
+ Results are usually dictionaries with timestamps in seconds;
74
+ `response_format="text"` returns a string. Alignment needs the spoken words in
75
+ the original language. It also accepts `text_file="captions.srt"`, supporting
76
+ TXT, JSON, SRT, ASS, and SSA; existing subtitle timing is recomputed from the audio.
77
+
78
+ | Method | Purpose |
79
+ | --- | --- |
80
+ | `transcribe(audio, ...)` | Transcription, optional speaker labels and word timestamps |
81
+ | `align(audio, text=... / text_file=..., ...)` | Align a transcript or subtitles to audio |
82
+ | `segment(text, ...)` / `segment(segments=..., ...)` | Segment text or resegment timed captions |
83
+ | `diarize(audio, ...)` | Independent speaker diarization |
84
+ | `speaker_embedding(audio, ...)` | Single or batch voice embeddings |
85
+ | `speaker_similarity(a, b, ...)` | Compare two embeddings from the same model |
86
+
87
+ Typed options include `timestamp_granularities=["word", "segment"]` and
88
+ `search_effort="auto"`. Use `help(EdgeSpeak.transcribe)` or `help(EdgeSpeak.align)`
89
+ for parameter details. Alignment does not perform diarization; choose a speaker
90
+ count with the independent `diarize()` method.
91
+
92
+ ## Progress and existing gateways
93
+
94
+ ```python
95
+ with EdgeSpeak() as client:
96
+ with client.align("speech.wav", text="The exact words spoken.", progress=True) as events:
97
+ for event in events:
98
+ print(event)
99
+ ```
100
+
101
+ Progress events precede the final result. Close the stream when stopping early;
102
+ closing does not guarantee cancellation of inference already running.
103
+ `transcribe(stream=True)` currently requires an attached desktop gateway and
104
+ does not support diarization or timestamp granularities.
105
+
106
+ Attach with `EdgeSpeak(base_url="http://127.0.0.1:1118/v1", gateway_key=...)`.
107
+ `gateway_key` is a gateway token, not an account API KEY. Closing an attached client
108
+ does not stop the gateway. Remote URLs require HTTPS and audio is uploaded to that
109
+ server. Environment proxies are ignored. Create a separate client in each process;
110
+ do not reuse a client inherited across fork.
111
+
112
+ ## Errors
113
+
114
+ `EdgeSpeakError` exposes `code`, `status_code`, `reason`, and `resets_at`.
115
+ Its `reason` distinguishes `api_key_expired`, `api_key_revoked`, and `usage_exhausted`.
116
+ Changing keys does not restore account allowance. Invalid arguments raise `ValueError`,
117
+ file errors raise `OSError`, and CLI startup failures raise `RuntimeStartError`.
118
+
119
+ `timeout` defaults to 600 seconds per HTTP I/O phase, not a total task deadline.
120
+ `startup_timeout` defaults to 30 seconds and excludes CLI installation time.
@@ -0,0 +1,106 @@
1
+ # EdgeSpeak Python SDK
2
+
3
+ Transcribe, align, segment text, identify speaker turns, and compare voice embeddings
4
+ through the local EdgeSpeak CLI. Audio is processed by the connected runtime;
5
+ the SDK does not bundle engines or models.
6
+
7
+ [简体中文](https://github.com/lattifai/EdgeSpeak/blob/main/sdk/python/README.zh-CN.md) · [Documentation](https://edgespeak.com/docs/python-sdk) · [Examples](https://github.com/lattifai/EdgeSpeak/tree/main/sdk/python/examples)
8
+
9
+ ## Installation
10
+
11
+ Requires Python 3.10+. One pure-Python wheel serves all supported Python versions
12
+ and platforms. Once published to PyPI, install with:
13
+
14
+ ```bash
15
+ python -m pip install edgespeak
16
+ ```
17
+
18
+ The first PyPI release is pending. Until then, run `python -m pip install ./sdk/python`
19
+ from the repository root. The SDK discovers an installed CLI and automatically
20
+ installs the latest official stable CLI if none meets its requirements.
21
+ Automatic installation supports macOS Apple Silicon, Linux x86_64, and Windows x64
22
+ and requires network access. Models load on demand; first use may download a model.
23
+
24
+ ## Create and configure an API KEY
25
+
26
+ 1. Sign in to [EdgeSpeak → API KEY](https://edgespeak.com/account/api-keys).
27
+ 2. Create an API KEY, choose an expiry (including never expires) and usage limit,
28
+ and copy the full key shown at creation.
29
+ 3. Set `EDGESPEAK_API_KEY` in the environment running Python:
30
+
31
+ ```bash
32
+ export EDGESPEAK_API_KEY="your API KEY"
33
+ ```
34
+
35
+ In Windows PowerShell, use `$env:EDGESPEAK_API_KEY="your API KEY"`.
36
+ `EdgeSpeak()` reads this variable automatically; you can also pass `EdgeSpeak(api_key=...)`.
37
+ An API KEY authorizes programmatic access and is different from a product activation
38
+ key. Keep it out of source control. An already activated local device can also
39
+ reuse its existing authorization.
40
+
41
+ API KEY access requires online authorization and shares the account subscription
42
+ allowance and billing period with desktop usage. Creating a key does not reset usage.
43
+ Never expires only removes the expiry date; entitlement, usage limits, and revocation
44
+ still apply.
45
+
46
+ ## Quick start
47
+
48
+ ```python
49
+ from edgespeak import EdgeSpeak
50
+
51
+ with EdgeSpeak() as client:
52
+ transcript = client.transcribe("meeting.wav", language="en", diarize=True)
53
+ print(transcript["text"])
54
+ aligned = client.align("speech.wav", text="The exact words spoken.")
55
+ speakers = client.diarize("meeting.wav", num_speakers=2)
56
+ ```
57
+
58
+ Reuse a client and use `with` or `close()` to release its owned service.
59
+ Results are usually dictionaries with timestamps in seconds;
60
+ `response_format="text"` returns a string. Alignment needs the spoken words in
61
+ the original language. It also accepts `text_file="captions.srt"`, supporting
62
+ TXT, JSON, SRT, ASS, and SSA; existing subtitle timing is recomputed from the audio.
63
+
64
+ | Method | Purpose |
65
+ | --- | --- |
66
+ | `transcribe(audio, ...)` | Transcription, optional speaker labels and word timestamps |
67
+ | `align(audio, text=... / text_file=..., ...)` | Align a transcript or subtitles to audio |
68
+ | `segment(text, ...)` / `segment(segments=..., ...)` | Segment text or resegment timed captions |
69
+ | `diarize(audio, ...)` | Independent speaker diarization |
70
+ | `speaker_embedding(audio, ...)` | Single or batch voice embeddings |
71
+ | `speaker_similarity(a, b, ...)` | Compare two embeddings from the same model |
72
+
73
+ Typed options include `timestamp_granularities=["word", "segment"]` and
74
+ `search_effort="auto"`. Use `help(EdgeSpeak.transcribe)` or `help(EdgeSpeak.align)`
75
+ for parameter details. Alignment does not perform diarization; choose a speaker
76
+ count with the independent `diarize()` method.
77
+
78
+ ## Progress and existing gateways
79
+
80
+ ```python
81
+ with EdgeSpeak() as client:
82
+ with client.align("speech.wav", text="The exact words spoken.", progress=True) as events:
83
+ for event in events:
84
+ print(event)
85
+ ```
86
+
87
+ Progress events precede the final result. Close the stream when stopping early;
88
+ closing does not guarantee cancellation of inference already running.
89
+ `transcribe(stream=True)` currently requires an attached desktop gateway and
90
+ does not support diarization or timestamp granularities.
91
+
92
+ Attach with `EdgeSpeak(base_url="http://127.0.0.1:1118/v1", gateway_key=...)`.
93
+ `gateway_key` is a gateway token, not an account API KEY. Closing an attached client
94
+ does not stop the gateway. Remote URLs require HTTPS and audio is uploaded to that
95
+ server. Environment proxies are ignored. Create a separate client in each process;
96
+ do not reuse a client inherited across fork.
97
+
98
+ ## Errors
99
+
100
+ `EdgeSpeakError` exposes `code`, `status_code`, `reason`, and `resets_at`.
101
+ Its `reason` distinguishes `api_key_expired`, `api_key_revoked`, and `usage_exhausted`.
102
+ Changing keys does not restore account allowance. Invalid arguments raise `ValueError`,
103
+ file errors raise `OSError`, and CLI startup failures raise `RuntimeStartError`.
104
+
105
+ `timeout` defaults to 600 seconds per HTTP I/O phase, not a total task deadline.
106
+ `startup_timeout` defaults to 30 seconds and excludes CLI installation time.
@@ -0,0 +1,95 @@
1
+ # EdgeSpeak Python SDK
2
+
3
+ 通过本机 EdgeSpeak CLI 完成转录、强制对齐、语义分句、说话人分离和声纹处理。
4
+ 音频由所连接的运行时处理,SDK 不内置引擎或模型。
5
+
6
+ [English](https://github.com/lattifai/EdgeSpeak/blob/main/sdk/python/README.md) · [完整文档](https://edgespeak.com/zh/docs/python-sdk) · [示例](https://github.com/lattifai/EdgeSpeak/tree/main/sdk/python/examples)
7
+
8
+ ## 安装
9
+
10
+ 需要 Python 3.10+。所有支持的 Python 版本和平台共用一个纯 Python wheel。
11
+ 正式发布到 PyPI 后,使用:
12
+
13
+ ```bash
14
+ python -m pip install edgespeak
15
+ ```
16
+
17
+ 首次 PyPI 发布尚未完成;当前可在仓库根目录运行 `python -m pip install ./sdk/python`。
18
+ SDK 自动查找本机 CLI;未安装或版本不满足要求时,自动安装官方最新稳定版。
19
+ 自动安装支持 macOS Apple Silicon、Linux x86_64 和 Windows x64,需要联网。
20
+ 模型按需加载,首次调用可能下载模型。
21
+
22
+ ## 创建和配置 API KEY
23
+
24
+ 1. 登录 [EdgeSpeak → API KEY](https://edgespeak.com/zh/account/api-keys)。
25
+ 2. 创建 API KEY,设置有效期(可选永久有效)及用量限制,并复制创建时显示的完整密钥。
26
+ 3. 在运行 Python 的环境中设置 `EDGESPEAK_API_KEY`:
27
+
28
+ ```bash
29
+ export EDGESPEAK_API_KEY="你的 API KEY"
30
+ ```
31
+
32
+ Windows PowerShell 使用 `$env:EDGESPEAK_API_KEY="你的 API KEY"`。
33
+ `EdgeSpeak()` 会自动读取该变量,也可显式传入 `EdgeSpeak(api_key=...)`。
34
+ API KEY 用于程序访问,与产品激活密钥不同;不要将它写入代码仓库。
35
+ 已激活的本机设备也可沿用现有授权。
36
+
37
+ API KEY 需要在线授权,与桌面端共享账号订阅额度及计费周期;新建密钥不会重置额度。
38
+ 永久有效仅表示没有到期日,账号授权、用量限制和撤销仍然生效。
39
+
40
+ ## 快速开始
41
+
42
+ ```python
43
+ from edgespeak import EdgeSpeak
44
+
45
+ with EdgeSpeak() as client:
46
+ transcript = client.transcribe("meeting.wav", language="zh", diarize=True)
47
+ print(transcript["text"])
48
+ aligned = client.align("speech.wav", text="音频中实际说出的原文。")
49
+ speakers = client.diarize("meeting.wav", num_speakers=2)
50
+ ```
51
+
52
+ 建议复用客户端,使用 `with` 或 `close()` 释放 SDK 启动的服务。
53
+ 结果通常为字典,时间戳单位为秒;`response_format="text"` 返回字符串。
54
+ 对齐需要与音频对应的原语言文本,也支持 `text_file="captions.srt"`,可读取 TXT、JSON、SRT、ASS、SSA。
55
+ 字幕原有时间会根据音频重新对齐。
56
+
57
+ | 方法 | 用途 |
58
+ | --- | --- |
59
+ | `transcribe(audio, ...)` | 音频转录,可附带说话人标注、词级时间戳 |
60
+ | `align(audio, text=... / text_file=..., ...)` | 将原文或字幕与音频对齐 |
61
+ | `segment(text, ...)` / `segment(segments=..., ...)` | 纯文本分句或带时间片段重新分句 |
62
+ | `diarize(audio, ...)` | 独立说话人分离 |
63
+ | `speaker_embedding(audio, ...)` | 提取单个或批量声纹 |
64
+ | `speaker_similarity(a, b, ...)` | 比较同一模型产生的两个声纹向量 |
65
+
66
+ 参数有类型提示,例如 `timestamp_granularities=["word", "segment"]`、
67
+ `search_effort="auto"`。可用 `help(EdgeSpeak.transcribe)`、`help(EdgeSpeak.align)` 查看参数说明。
68
+ 对齐不执行说话人分离;指定人数使用独立的 `diarize()`。
69
+
70
+ ## 进度与现有网关
71
+
72
+ ```python
73
+ with EdgeSpeak() as client:
74
+ with client.align("speech.wav", text="音频原文。", progress=True) as events:
75
+ for event in events:
76
+ print(event)
77
+ ```
78
+
79
+ 进度事件后还会返回最终结果;提前退出时应关闭流。关闭流不保证取消已开始的推理。
80
+ `transcribe(stream=True)` 目前需要连接桌面端网关,不支持说话人标注或时间粒度参数。
81
+
82
+ 已有网关使用 `EdgeSpeak(base_url="http://127.0.0.1:1118/v1", gateway_key=...)`。
83
+ `gateway_key` 是网关令牌,不是账号 API KEY;关闭客户端不会关闭已有网关。
84
+ 远程地址要求 HTTPS,音频会上传至该服务器;SDK 不读取环境代理配置。
85
+ 多进程应各自创建客户端,不复用 fork 继承的客户端。
86
+
87
+ ## 错误处理
88
+
89
+ `EdgeSpeakError` 提供 `code`、`status_code`、`reason` 和 `resets_at`。
90
+ 通过 `reason` 区分 `api_key_expired`(已过期)、`api_key_revoked`(已撤销)、
91
+ `usage_exhausted`(本期额度耗尽);更换密钥不会恢复账号额度。
92
+ 参数错误为 `ValueError`,文件错误为 `OSError`,CLI 启动错误为 `RuntimeStartError`。
93
+
94
+ `timeout` 默认为 600 秒,针对 HTTP I/O 阶段,不是任务总时限;
95
+ `startup_timeout` 默认为 30 秒,不包含 CLI 安装时间。
@@ -0,0 +1,18 @@
1
+ """Shared connection options; credentials stay in environment variables."""
2
+ import json
3
+ import os
4
+ from edgespeak import EdgeSpeak
5
+
6
+
7
+ def connect(parser):
8
+ parser.add_argument('--base-url', help='Attach to an existing gateway; never stop it')
9
+
10
+
11
+ def client(args):
12
+ if args.base_url:
13
+ return EdgeSpeak(base_url=args.base_url, gateway_key=os.environ.get('EDGESPEAK_GATEWAY_KEY'))
14
+ return EdgeSpeak()
15
+
16
+
17
+ def output(result):
18
+ print(result if isinstance(result, str) else json.dumps(result, ensure_ascii=False, indent=2))
@@ -0,0 +1,48 @@
1
+ """Align text or TXT/JSON/SRT/ASS/SSA references; original cue timing is ignored."""
2
+ import argparse
3
+ import json
4
+ from _common import client, connect, output
5
+
6
+
7
+ def main():
8
+ parser = argparse.ArgumentParser(description=__doc__)
9
+ parser.add_argument('audio')
10
+ source = parser.add_mutually_exclusive_group(required=True)
11
+ source.add_argument('--text')
12
+ source.add_argument('--text-file')
13
+ parser.add_argument('--text-format', choices=['txt', 'json', 'srt', 'ass', 'ssa'])
14
+ parser.add_argument('--language')
15
+ parser.add_argument('--model')
16
+ parser.add_argument('--start', type=float)
17
+ parser.add_argument('--end', type=float)
18
+ parser.add_argument('--search-effort', choices=['standard', 'extended', 'auto'], default='standard')
19
+ parser.add_argument('--protected-term', action='append')
20
+ parser.add_argument('--text-normalization', type=json.loads, help='API normalization JSON object')
21
+ parser.add_argument('--audio-track', type=int)
22
+ parser.add_argument('--audio-channel')
23
+ parser.add_argument('--semantic', action=argparse.BooleanOptionalAction, default=None)
24
+ parser.add_argument('--threshold', type=float)
25
+ parser.add_argument('--min-chars', type=int)
26
+ parser.add_argument('--max-chars', type=int)
27
+ parser.add_argument('--start-margin', type=float)
28
+ parser.add_argument('--end-margin', type=float)
29
+ parser.add_argument('--progress', action='store_true')
30
+ connect(parser)
31
+ args = parser.parse_args()
32
+ with client(args) as sdk:
33
+ result = sdk.align(args.audio, text=args.text, text_file=args.text_file, text_format=args.text_format,
34
+ language=args.language, model=args.model, start=args.start, end=args.end,
35
+ search_effort=args.search_effort, protected_terms=args.protected_term,
36
+ text_normalization=args.text_normalization, audio_track=args.audio_track,
37
+ audio_channel=args.audio_channel, semantic_sentence_enabled=args.semantic,
38
+ threshold=args.threshold, min_chars=args.min_chars, max_chars=args.max_chars, start_margin=args.start_margin, end_margin=args.end_margin, progress=args.progress)
39
+ if args.progress:
40
+ with result as events:
41
+ for event in events:
42
+ output(event)
43
+ else:
44
+ output(result)
45
+
46
+
47
+ if __name__ == '__main__':
48
+ main()
@@ -0,0 +1,31 @@
1
+ """Semantic sentences/paragraphs, or resegment a timed transcript with speakers."""
2
+ import argparse
3
+ import json
4
+ from pathlib import Path
5
+ from _common import client, connect, output
6
+
7
+
8
+ def main():
9
+ parser = argparse.ArgumentParser(description=__doc__)
10
+ source = parser.add_mutually_exclusive_group(required=True)
11
+ source.add_argument('--text')
12
+ source.add_argument('--text-file', help='UTF-8 plain text')
13
+ source.add_argument('--segments-file', help='Exported transcript JSON with segments')
14
+ parser.add_argument('--threshold', type=float)
15
+ parser.add_argument('--paragraph-threshold', type=float)
16
+ parser.add_argument('--min-chars', type=int)
17
+ parser.add_argument('--max-chars', type=int)
18
+ parser.add_argument('--start-margin', type=float)
19
+ parser.add_argument('--end-margin', type=float)
20
+ connect(parser)
21
+ args = parser.parse_args()
22
+ text = Path(args.text_file).read_text(encoding='utf-8-sig') if args.text_file else args.text
23
+ segments = json.loads(Path(args.segments_file).read_text(encoding='utf-8-sig'))['segments'] if args.segments_file else None
24
+ with client(args) as sdk:
25
+ output(sdk.segment(text, segments=segments, threshold=args.threshold,
26
+ paragraph_threshold=args.paragraph_threshold, min_chars=args.min_chars, max_chars=args.max_chars,
27
+ start_margin=args.start_margin, end_margin=args.end_margin))
28
+
29
+
30
+ if __name__ == '__main__':
31
+ main()
@@ -0,0 +1,23 @@
1
+ """Speaker timeline, batch embeddings and same-model voice similarity."""
2
+ import argparse
3
+ from _common import client, connect, output
4
+
5
+
6
+ def main():
7
+ parser = argparse.ArgumentParser(description=__doc__)
8
+ parser.add_argument('audio', help='Audio/video for the speaker timeline')
9
+ parser.add_argument('reference_a', help='First short voice sample')
10
+ parser.add_argument('reference_b', help='Second short voice sample')
11
+ parser.add_argument('--num-speakers', type=int)
12
+ parser.add_argument('--model', default='EdgeSpeak/Lattice-1')
13
+ connect(parser)
14
+ args = parser.parse_args()
15
+ with client(args) as sdk:
16
+ output(sdk.diarize(args.audio, num_speakers=args.num_speakers))
17
+ voices = sdk.speaker_embedding([args.reference_a, args.reference_b], model=args.model)
18
+ output(voices)
19
+ output(sdk.speaker_similarity(voices['data'][0]['embedding'], voices['data'][1]['embedding'], model=args.model))
20
+
21
+
22
+ if __name__ == '__main__':
23
+ main()
@@ -0,0 +1,41 @@
1
+ """Transcribe media with optional speaker labels, word timestamps and sentences."""
2
+ import argparse
3
+ from _common import client, connect, output
4
+
5
+
6
+ def main():
7
+ parser = argparse.ArgumentParser(description=__doc__)
8
+ parser.add_argument('audio')
9
+ parser.add_argument('--model')
10
+ parser.add_argument('--language')
11
+ parser.add_argument('--prompt')
12
+ parser.add_argument('--timestamp-granularity', action='append', choices=['word', 'segment'])
13
+ parser.add_argument('--diarize', action='store_true')
14
+ parser.add_argument('--response-format', choices=['json', 'verbose_json', 'diarized_json', 'text'])
15
+ parser.add_argument('--word-timestamps', action=argparse.BooleanOptionalAction, default=None)
16
+ parser.add_argument('--semantic', action=argparse.BooleanOptionalAction, default=None)
17
+ parser.add_argument('--min-chars', type=int)
18
+ parser.add_argument('--max-chars', type=int)
19
+ parser.add_argument('--start-margin', type=float)
20
+ parser.add_argument('--end-margin', type=float)
21
+ parser.add_argument('--candidates', type=int)
22
+ parser.add_argument('--stream', action='store_true', help='SSE; desktop gateway only')
23
+ connect(parser)
24
+ args = parser.parse_args()
25
+ with client(args) as sdk:
26
+ result = sdk.transcribe(args.audio, model=args.model, language=args.language,
27
+ diarize=args.diarize, response_format=args.response_format, stream=args.stream, prompt=args.prompt,
28
+ timestamp_granularities=args.timestamp_granularity,
29
+ word_timestamp_enabled=args.word_timestamps, candidates=args.candidates,
30
+ semantic_sentence_enabled=args.semantic, min_chars=args.min_chars, max_chars=args.max_chars,
31
+ start_margin=args.start_margin, end_margin=args.end_margin)
32
+ if args.stream:
33
+ with result as events:
34
+ for event in events:
35
+ output(event)
36
+ else:
37
+ output(result)
38
+
39
+
40
+ if __name__ == '__main__':
41
+ main()
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "edgespeak"
7
+ dynamic = ["version"]
8
+ description = "Python client for the local EdgeSpeak CLI runtime"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = ["httpx>=0.27,<1"]
12
+
13
+ [project.optional-dependencies]
14
+ dev = ["mypy==1.20.2", "typing_extensions>=4.6"]
15
+
16
+ [tool.setuptools.dynamic]
17
+ version = {attr = "edgespeak._version.__version__"}
18
+
19
+ [tool.setuptools.packages.find]
20
+ where = ["src"]
21
+
22
+ [tool.setuptools.package-data]
23
+ edgespeak = ["py.typed"]
24
+
25
+ [project.urls]
26
+ Documentation = "https://edgespeak.com/docs/python-sdk"
27
+ Source = "https://github.com/lattifai/EdgeSpeak/tree/main/sdk/python"
28
+ Issues = "https://github.com/lattifai/EdgeSpeak/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ """EdgeSpeak's Python SDK for the local CLI runtime."""
2
+ from ._client import EdgeSpeak, EdgeSpeakError
3
+ from ._process import RuntimeStartError
4
+ from ._bootstrap import MIN_CLI_VERSION
5
+ from ._streaming import EventStream
6
+ from ._types import AudioChannel, ReferenceFormat, SearchEffort, TimestampGranularity, TranscriptionFormat
7
+
8
+ from ._version import __version__ as __version__
9
+ __all__ = ["EdgeSpeak", "EdgeSpeakError", "RuntimeStartError", "MIN_CLI_VERSION", "EventStream",
10
+ "AudioChannel", "ReferenceFormat", "SearchEffort", "TimestampGranularity", "TranscriptionFormat"]