echo-vector 0.1.1__tar.gz → 1.0.3__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.
- echo_vector-1.0.3/.claude/commands/release.md +15 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/.gitignore +9 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/PKG-INFO +5 -8
- {echo_vector-0.1.1 → echo_vector-1.0.3}/README.md +2 -2
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/clap.py +8 -20
- {echo_vector-0.1.1 → echo_vector-1.0.3}/pyproject.toml +3 -5
- echo_vector-1.0.3/tests/integration/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/uv.lock +31 -36
- echo_vector-0.1.1/.claude/settings.json +0 -16
- echo_vector-0.1.1/demo.py +0 -76
- echo_vector-0.1.1/demo_audio/alert.wav +0 -0
- echo_vector-0.1.1/demo_audio/bass_talk.wav +0 -0
- echo_vector-0.1.1/demo_index/metadata.sqlite +0 -0
- /echo_vector-0.1.1/tests/__init__.py → /echo_vector-1.0.3/.claude/settings.json +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/.github/workflows/workflow.yml +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/.pre-commit-config.yaml +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/.python-version +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/CLAUDE.md +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/Makefile +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/api/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/api/server.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/audio/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/audio/chunker.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/audio/metadata.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/audio/processor.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/audio/streaming.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/cli/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/cli/main.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/core.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/ast_model.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/base.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/cache.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/factory.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/hubert.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/local.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/wav2vec2.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/embeddings/whisper_enc.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/evaluation/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/evaluation/metrics.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/indexing/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/indexing/base.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/indexing/faiss_index.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/indexing/store.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/search/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/search/engine.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/search/filters.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/search/results.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/utils/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/utils/config.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/echovector/utils/logging.py +0 -0
- {echo_vector-0.1.1/tests/integration → echo_vector-1.0.3/tests}/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/conftest.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/e2e/test_cli.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/fixtures/__init__.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/fixtures/audio_generators.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/integration/test_integration.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/test_audio.mp3 +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_api.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_audio_processor.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_chunker.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_core.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_embeddings.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_faiss_index.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_results.py +0 -0
- {echo_vector-0.1.1 → echo_vector-1.0.3}/tests/unit/test_search_engine.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Run the full release pipeline: lint, typecheck, test, commit, tag, and push to trigger CI/CD publish to PyPI.
|
|
2
|
+
|
|
3
|
+
Usage: /release <version> (e.g. /release v0.1.3)
|
|
4
|
+
|
|
5
|
+
Steps:
|
|
6
|
+
1. Verify a version argument was provided (format: vX.Y.Z)
|
|
7
|
+
2. Run `uv run ruff format --check echovector/ tests/` and `uv run ruff check echovector/ tests/`
|
|
8
|
+
3. Run `uv run mypy echovector/`
|
|
9
|
+
4. Run `uv run pytest tests/ -m "not slow and not gpu" -q`
|
|
10
|
+
5. If there are uncommitted changes, stage and commit them with message "release: $ARGUMENTS"
|
|
11
|
+
6. Create git tag `$ARGUMENTS`
|
|
12
|
+
7. Push the branch and the tag: `git push origin master` and `git push origin $ARGUMENTS`
|
|
13
|
+
8. Report the tag that was pushed and remind the user to monitor CI at https://github.com/ahron-maslin/echo_vector/actions
|
|
14
|
+
|
|
15
|
+
If any step fails, stop and report the failure before proceeding.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: echo_vector
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.3
|
|
4
4
|
Summary: Semantic text search over audio files without full transcription
|
|
5
5
|
Project-URL: Homepage, https://github.com/ahron-maslin/echo_vector
|
|
6
6
|
Project-URL: Documentation, https://github.com/ahron-maslin/echo_vector#readme
|
|
@@ -30,7 +30,9 @@ Requires-Dist: pydantic<3,>=2.5
|
|
|
30
30
|
Requires-Dist: pydub<1,>=0.25
|
|
31
31
|
Requires-Dist: rich<14,>=13.7
|
|
32
32
|
Requires-Dist: soundfile<1,>=0.12
|
|
33
|
+
Requires-Dist: torch<3,>=2.1
|
|
33
34
|
Requires-Dist: tqdm<5,>=4.66
|
|
35
|
+
Requires-Dist: transformers<5,>=4.36
|
|
34
36
|
Requires-Dist: typer[all]<1,>=0.12
|
|
35
37
|
Provides-Extra: all
|
|
36
38
|
Requires-Dist: fastapi<1,>=0.109; extra == 'all'
|
|
@@ -48,15 +50,10 @@ Requires-Dist: pytest-cov<6,>=5.0; extra == 'all'
|
|
|
48
50
|
Requires-Dist: pytest-xdist<4,>=3.5; extra == 'all'
|
|
49
51
|
Requires-Dist: pytest<9,>=8.0; extra == 'all'
|
|
50
52
|
Requires-Dist: ruff<1,>=0.15; extra == 'all'
|
|
51
|
-
Requires-Dist: torch<3,>=2.1; extra == 'all'
|
|
52
|
-
Requires-Dist: transformers<5,>=4.36; extra == 'all'
|
|
53
53
|
Requires-Dist: uvicorn[standard]<1,>=0.27; extra == 'all'
|
|
54
54
|
Provides-Extra: api
|
|
55
55
|
Requires-Dist: fastapi<1,>=0.109; extra == 'api'
|
|
56
56
|
Requires-Dist: uvicorn[standard]<1,>=0.27; extra == 'api'
|
|
57
|
-
Provides-Extra: clap
|
|
58
|
-
Requires-Dist: torch<3,>=2.1; extra == 'clap'
|
|
59
|
-
Requires-Dist: transformers<5,>=4.36; extra == 'clap'
|
|
60
57
|
Provides-Extra: dev
|
|
61
58
|
Requires-Dist: httpx2<3,>=2.0; extra == 'dev'
|
|
62
59
|
Requires-Dist: hypothesis<7,>=6.92; extra == 'dev'
|
|
@@ -121,13 +118,13 @@ Text Query → Text Embedding ──────────────┘
|
|
|
121
118
|
### Installation
|
|
122
119
|
|
|
123
120
|
```bash
|
|
124
|
-
pip install
|
|
121
|
+
pip install echo_vector
|
|
125
122
|
```
|
|
126
123
|
|
|
127
124
|
Or with uv:
|
|
128
125
|
|
|
129
126
|
```bash
|
|
130
|
-
uv add
|
|
127
|
+
uv add echo_vector
|
|
131
128
|
```
|
|
132
129
|
|
|
133
130
|
### CLI Usage
|
|
@@ -44,13 +44,13 @@ Text Query → Text Embedding ──────────────┘
|
|
|
44
44
|
### Installation
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
pip install
|
|
47
|
+
pip install echo_vector
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
Or with uv:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
uv add
|
|
53
|
+
uv add echo_vector
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
### CLI Usage
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
"""CLAP (Contrastive Language-Audio Pretraining) embedding backend."""
|
|
2
2
|
|
|
3
|
-
from typing import cast
|
|
3
|
+
from typing import Any, cast
|
|
4
4
|
|
|
5
5
|
import librosa
|
|
6
6
|
import numpy as np
|
|
7
7
|
import numpy.typing as npt
|
|
8
|
+
import torch
|
|
9
|
+
from transformers import ClapModel, ClapProcessor
|
|
8
10
|
|
|
9
11
|
from echovector.embeddings.base import EmbeddingBackend
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
import torch
|
|
13
|
-
from transformers import ClapModel, ClapProcessor
|
|
14
|
-
|
|
15
|
-
_CLAP_AVAILABLE = True
|
|
16
|
-
except ImportError: # pragma: no cover
|
|
17
|
-
_CLAP_AVAILABLE = False
|
|
13
|
+
_CLAP_AVAILABLE = True
|
|
18
14
|
|
|
19
15
|
|
|
20
16
|
class ClapBackend(EmbeddingBackend):
|
|
@@ -33,22 +29,14 @@ class ClapBackend(EmbeddingBackend):
|
|
|
33
29
|
Args:
|
|
34
30
|
model_name: The Hugging Face model identifier.
|
|
35
31
|
device: Device to run the model on (e.g., 'cpu', 'cuda').
|
|
36
|
-
|
|
37
|
-
Raises:
|
|
38
|
-
ImportError: If torch or transformers are not installed.
|
|
39
32
|
"""
|
|
40
|
-
if not _CLAP_AVAILABLE:
|
|
41
|
-
raise ImportError(
|
|
42
|
-
"CLAP backend requires torch and transformers. "
|
|
43
|
-
"Install them with: pip install 'echo_vector[clap]'"
|
|
44
|
-
)
|
|
45
33
|
if device is None:
|
|
46
34
|
self.device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
47
35
|
else:
|
|
48
36
|
self.device = device
|
|
49
37
|
|
|
50
|
-
self.processor = ClapProcessor.from_pretrained(model_name)
|
|
51
|
-
self.model = ClapModel.from_pretrained(model_name)
|
|
38
|
+
self.processor: Any = ClapProcessor.from_pretrained(model_name) # pyright: ignore[reportArgumentType]
|
|
39
|
+
self.model: Any = ClapModel.from_pretrained(model_name) # pyright: ignore[reportArgumentType]
|
|
52
40
|
self.model.to(self.device)
|
|
53
41
|
self.model.eval()
|
|
54
42
|
|
|
@@ -81,7 +69,7 @@ class ClapBackend(EmbeddingBackend):
|
|
|
81
69
|
|
|
82
70
|
audios = [self._load_and_resample(path, target_sr) for path in audio_paths]
|
|
83
71
|
|
|
84
|
-
inputs = self.processor(
|
|
72
|
+
inputs = cast("Any", self.processor)(
|
|
85
73
|
audios=audios,
|
|
86
74
|
return_tensors="pt",
|
|
87
75
|
sampling_rate=target_sr,
|
|
@@ -107,7 +95,7 @@ class ClapBackend(EmbeddingBackend):
|
|
|
107
95
|
Returns:
|
|
108
96
|
A numpy array of shape (batch_size, embedding_dim).
|
|
109
97
|
"""
|
|
110
|
-
inputs = self.processor(
|
|
98
|
+
inputs = cast("Any", self.processor)(
|
|
111
99
|
text=texts,
|
|
112
100
|
return_tensors="pt",
|
|
113
101
|
padding=True,
|
|
@@ -37,13 +37,11 @@ dependencies = [
|
|
|
37
37
|
"rich>=13.7,<14",
|
|
38
38
|
"pydub>=0.25,<1",
|
|
39
39
|
"tqdm>=4.66,<5",
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
[project.optional-dependencies]
|
|
43
|
-
clap = [
|
|
44
40
|
"torch>=2.1,<3",
|
|
45
41
|
"transformers>=4.36,<5",
|
|
46
42
|
]
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
47
45
|
api = [
|
|
48
46
|
"fastapi>=0.109,<1",
|
|
49
47
|
"uvicorn[standard]>=0.27,<1",
|
|
@@ -66,7 +64,7 @@ docs = [
|
|
|
66
64
|
"mkdocs-gen-files>=0.5,<1",
|
|
67
65
|
"mkdocs-literate-nav>=0.6,<1",
|
|
68
66
|
]
|
|
69
|
-
all = ["echo_vector[
|
|
67
|
+
all = ["echo_vector[api,dev,docs]"]
|
|
70
68
|
|
|
71
69
|
[project.scripts]
|
|
72
70
|
echovector = "echovector.cli.main:app"
|
|
File without changes
|
|
@@ -477,14 +477,16 @@ dependencies = [
|
|
|
477
477
|
{ name = "pydub" },
|
|
478
478
|
{ name = "rich" },
|
|
479
479
|
{ name = "soundfile" },
|
|
480
|
+
{ name = "torch" },
|
|
480
481
|
{ name = "tqdm" },
|
|
482
|
+
{ name = "transformers" },
|
|
481
483
|
{ name = "typer" },
|
|
482
484
|
]
|
|
483
485
|
|
|
484
486
|
[package.optional-dependencies]
|
|
485
487
|
all = [
|
|
486
488
|
{ name = "fastapi" },
|
|
487
|
-
{ name = "
|
|
489
|
+
{ name = "httpx2" },
|
|
488
490
|
{ name = "hypothesis" },
|
|
489
491
|
{ name = "mkdocs-gen-files" },
|
|
490
492
|
{ name = "mkdocs-literate-nav" },
|
|
@@ -498,20 +500,14 @@ all = [
|
|
|
498
500
|
{ name = "pytest-cov" },
|
|
499
501
|
{ name = "pytest-xdist" },
|
|
500
502
|
{ name = "ruff" },
|
|
501
|
-
{ name = "torch" },
|
|
502
|
-
{ name = "transformers" },
|
|
503
503
|
{ name = "uvicorn", extra = ["standard"] },
|
|
504
504
|
]
|
|
505
505
|
api = [
|
|
506
506
|
{ name = "fastapi" },
|
|
507
507
|
{ name = "uvicorn", extra = ["standard"] },
|
|
508
508
|
]
|
|
509
|
-
clap = [
|
|
510
|
-
{ name = "torch" },
|
|
511
|
-
{ name = "transformers" },
|
|
512
|
-
]
|
|
513
509
|
dev = [
|
|
514
|
-
{ name = "
|
|
510
|
+
{ name = "httpx2" },
|
|
515
511
|
{ name = "hypothesis" },
|
|
516
512
|
{ name = "mutmut" },
|
|
517
513
|
{ name = "mypy" },
|
|
@@ -529,18 +525,13 @@ docs = [
|
|
|
529
525
|
{ name = "mkdocstrings", extra = ["python"] },
|
|
530
526
|
]
|
|
531
527
|
|
|
532
|
-
[package.dev-dependencies]
|
|
533
|
-
dev = [
|
|
534
|
-
{ name = "httpx" },
|
|
535
|
-
]
|
|
536
|
-
|
|
537
528
|
[package.metadata]
|
|
538
529
|
requires-dist = [
|
|
539
530
|
{ name = "faiss-cpu", specifier = ">=1.7,<2" },
|
|
540
531
|
{ name = "fastapi", marker = "extra == 'all'", specifier = ">=0.109,<1" },
|
|
541
532
|
{ name = "fastapi", marker = "extra == 'api'", specifier = ">=0.109,<1" },
|
|
542
|
-
{ name = "
|
|
543
|
-
{ name = "
|
|
533
|
+
{ name = "httpx2", marker = "extra == 'all'", specifier = ">=2.0,<3" },
|
|
534
|
+
{ name = "httpx2", marker = "extra == 'dev'", specifier = ">=2.0,<3" },
|
|
544
535
|
{ name = "hypothesis", marker = "extra == 'all'", specifier = ">=6.92,<7" },
|
|
545
536
|
{ name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.92,<7" },
|
|
546
537
|
{ name = "librosa", specifier = ">=0.10,<1" },
|
|
@@ -570,22 +561,17 @@ requires-dist = [
|
|
|
570
561
|
{ name = "pytest-xdist", marker = "extra == 'all'", specifier = ">=3.5,<4" },
|
|
571
562
|
{ name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.5,<4" },
|
|
572
563
|
{ name = "rich", specifier = ">=13.7,<14" },
|
|
573
|
-
{ name = "ruff", marker = "extra == 'all'", specifier = ">=0.
|
|
574
|
-
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.
|
|
564
|
+
{ name = "ruff", marker = "extra == 'all'", specifier = ">=0.15,<1" },
|
|
565
|
+
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15,<1" },
|
|
575
566
|
{ name = "soundfile", specifier = ">=0.12,<1" },
|
|
576
|
-
{ name = "torch",
|
|
577
|
-
{ name = "torch", marker = "extra == 'clap'", specifier = ">=2.1,<3" },
|
|
567
|
+
{ name = "torch", specifier = ">=2.1,<3" },
|
|
578
568
|
{ name = "tqdm", specifier = ">=4.66,<5" },
|
|
579
|
-
{ name = "transformers",
|
|
580
|
-
{ name = "transformers", marker = "extra == 'clap'", specifier = ">=4.36,<5" },
|
|
569
|
+
{ name = "transformers", specifier = ">=4.36,<5" },
|
|
581
570
|
{ name = "typer", extras = ["all"], specifier = ">=0.12,<1" },
|
|
582
571
|
{ name = "uvicorn", extras = ["standard"], marker = "extra == 'all'", specifier = ">=0.27,<1" },
|
|
583
572
|
{ name = "uvicorn", extras = ["standard"], marker = "extra == 'api'", specifier = ">=0.27,<1" },
|
|
584
573
|
]
|
|
585
|
-
provides-extras = ["all", "api", "
|
|
586
|
-
|
|
587
|
-
[package.metadata.requires-dev]
|
|
588
|
-
dev = [{ name = "httpx", specifier = ">=0.28.1" }]
|
|
574
|
+
provides-extras = ["all", "api", "dev", "docs"]
|
|
589
575
|
|
|
590
576
|
[[package]]
|
|
591
577
|
name = "execnet"
|
|
@@ -717,16 +703,16 @@ wheels = [
|
|
|
717
703
|
]
|
|
718
704
|
|
|
719
705
|
[[package]]
|
|
720
|
-
name = "
|
|
721
|
-
version = "
|
|
706
|
+
name = "httpcore2"
|
|
707
|
+
version = "2.3.0"
|
|
722
708
|
source = { registry = "https://pypi.org/simple" }
|
|
723
709
|
dependencies = [
|
|
724
|
-
{ name = "certifi" },
|
|
725
710
|
{ name = "h11" },
|
|
711
|
+
{ name = "truststore" },
|
|
726
712
|
]
|
|
727
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
713
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e6/34/18f1c596e677962f040284246f393b10a1f8ce440b3a7e69c637d0f1c7ad/httpcore2-2.3.0.tar.gz", hash = "sha256:07327e251560960eea8e969d92d4c6a325feb13cca39e25340731336c3baf924", size = 64300, upload-time = "2026-06-01T13:15:02.998Z" }
|
|
728
714
|
wheels = [
|
|
729
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
715
|
+
{ url = "https://files.pythonhosted.org/packages/c2/dd/3357218c69360d1cecc196c230c9a1d5c9afd5dba362056e23e60a5e64e5/httpcore2-2.3.0-py3-none-any.whl", hash = "sha256:477e9e334f74e5240dcac002e890580f36a57d40ff0fb14cc9655731d23b8415", size = 80024, upload-time = "2026-06-01T13:15:00.001Z" },
|
|
730
716
|
]
|
|
731
717
|
|
|
732
718
|
[[package]]
|
|
@@ -759,18 +745,18 @@ wheels = [
|
|
|
759
745
|
]
|
|
760
746
|
|
|
761
747
|
[[package]]
|
|
762
|
-
name = "
|
|
763
|
-
version = "
|
|
748
|
+
name = "httpx2"
|
|
749
|
+
version = "2.3.0"
|
|
764
750
|
source = { registry = "https://pypi.org/simple" }
|
|
765
751
|
dependencies = [
|
|
766
752
|
{ name = "anyio" },
|
|
767
|
-
{ name = "
|
|
768
|
-
{ name = "httpcore" },
|
|
753
|
+
{ name = "httpcore2" },
|
|
769
754
|
{ name = "idna" },
|
|
755
|
+
{ name = "truststore" },
|
|
770
756
|
]
|
|
771
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
757
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9f/9a/cca0b9145f13d8ae34b885ae28d403a1469a433abc78e0f94f4ce94e650b/httpx2-2.3.0.tar.gz", hash = "sha256:227e7c41d95a76d4077a52640564132777215fc3394e07b66a3116c33d668fa9", size = 81115, upload-time = "2026-06-01T13:15:04.324Z" }
|
|
772
758
|
wheels = [
|
|
773
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
759
|
+
{ url = "https://files.pythonhosted.org/packages/87/ce/ae2911859847f9ba1d6b23027e53481cbeb50b93234f355a968d300ca2cb/httpx2-2.3.0-py3-none-any.whl", hash = "sha256:6f393663bdf6dbe7fe90118e3eb5b2bd024a675cae0390ac08cec9198812d8b7", size = 74538, upload-time = "2026-06-01T13:15:01.566Z" },
|
|
774
760
|
]
|
|
775
761
|
|
|
776
762
|
[[package]]
|
|
@@ -2544,6 +2530,15 @@ wheels = [
|
|
|
2544
2530
|
{ url = "https://files.pythonhosted.org/packages/c1/68/fa86e5a39608000f645535b2c124920126327ab731f8c4fafd5b07ff8d4b/triton-3.7.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce061073102714b725f3660ec6939d94a1da7984b3aa99c921417cae273672f5", size = 201546766, upload-time = "2026-05-07T18:46:42.088Z" },
|
|
2545
2531
|
]
|
|
2546
2532
|
|
|
2533
|
+
[[package]]
|
|
2534
|
+
name = "truststore"
|
|
2535
|
+
version = "0.10.4"
|
|
2536
|
+
source = { registry = "https://pypi.org/simple" }
|
|
2537
|
+
sdist = { url = "https://files.pythonhosted.org/packages/53/a3/1585216310e344e8102c22482f6060c7a6ea0322b63e026372e6dcefcfd6/truststore-0.10.4.tar.gz", hash = "sha256:9d91bd436463ad5e4ee4aba766628dd6cd7010cf3e2461756b3303710eebc301", size = 26169, upload-time = "2025-08-12T18:49:02.73Z" }
|
|
2538
|
+
wheels = [
|
|
2539
|
+
{ url = "https://files.pythonhosted.org/packages/19/97/56608b2249fe206a67cd573bc93cd9896e1efb9e98bce9c163bcdc704b88/truststore-0.10.4-py3-none-any.whl", hash = "sha256:adaeaecf1cbb5f4de3b1959b42d41f6fab57b2b1666adb59e89cb0b53361d981", size = 18660, upload-time = "2025-08-12T18:49:01.46Z" },
|
|
2540
|
+
]
|
|
2541
|
+
|
|
2547
2542
|
[[package]]
|
|
2548
2543
|
name = "typer"
|
|
2549
2544
|
version = "0.25.1"
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"PostToolUse": [
|
|
4
|
-
{
|
|
5
|
-
"matcher": "Edit|Write",
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "git add -A && git diff --cached --quiet || (COUNT=$(git diff --cached --name-only | wc -l | tr -d ' '); FILES=$(git diff --cached --name-only | head -3 | tr '\n' ' ' | sed 's/ $//'); if [ \"$COUNT\" -le 3 ]; then MSG=\"auto: edit $FILES\"; else FIRST=$(git diff --cached --name-only | head -2 | paste -sd ', '); MSG=\"auto: edit $COUNT files ($FIRST, ...)\"; fi; git commit -m \"$MSG\" 2>/dev/null || true)",
|
|
10
|
-
"statusMessage": "Committing changes..."
|
|
11
|
-
}
|
|
12
|
-
]
|
|
13
|
-
}
|
|
14
|
-
]
|
|
15
|
-
}
|
|
16
|
-
}
|
echo_vector-0.1.1/demo.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
import soundfile as sf
|
|
5
|
-
|
|
6
|
-
from echovector import EchoVector
|
|
7
|
-
from echovector.utils.logging import setup_logger
|
|
8
|
-
|
|
9
|
-
logger = setup_logger("demo")
|
|
10
|
-
|
|
11
|
-
def generate_synthetic_wav(
|
|
12
|
-
filepath: str,
|
|
13
|
-
duration: float,
|
|
14
|
-
sr: int = 16000,
|
|
15
|
-
freq: float = 440.0,
|
|
16
|
-
) -> None:
|
|
17
|
-
"""Generates a synthetic sine wave and saves it to a wav file."""
|
|
18
|
-
t = np.linspace(0, duration, int(sr * duration), endpoint=False)
|
|
19
|
-
# Simple tone
|
|
20
|
-
data = 0.5 * np.sin(2 * np.pi * freq * t)
|
|
21
|
-
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
22
|
-
sf.write(filepath, data, sr)
|
|
23
|
-
logger.info(f"Generated synthetic audio at {filepath}")
|
|
24
|
-
|
|
25
|
-
def main() -> None:
|
|
26
|
-
"""Run an end-to-end local EchoVector demo."""
|
|
27
|
-
print("=== EchoVector End-to-End Demo ===")
|
|
28
|
-
|
|
29
|
-
# 1. Setup temporary audio directory and build index
|
|
30
|
-
audio_dir = "./demo_audio"
|
|
31
|
-
index_dir = "./demo_index"
|
|
32
|
-
|
|
33
|
-
os.makedirs(audio_dir, exist_ok=True)
|
|
34
|
-
os.makedirs(index_dir, exist_ok=True)
|
|
35
|
-
|
|
36
|
-
# Generate a few synthetic audio clips
|
|
37
|
-
# Clip 1: A short alert/sound (high frequency)
|
|
38
|
-
generate_synthetic_wav(f"{audio_dir}/alert.wav", duration=5.0, freq=880.0)
|
|
39
|
-
# Clip 2: A low tone (bass discussion)
|
|
40
|
-
generate_synthetic_wav(f"{audio_dir}/bass_talk.wav", duration=10.0, freq=110.0)
|
|
41
|
-
|
|
42
|
-
# 2. Instantiate EchoVector
|
|
43
|
-
print("\n--- Initializing EchoVector ---")
|
|
44
|
-
# Use the local backend so the demo runs without GPU access or model downloads.
|
|
45
|
-
ev = EchoVector(store_dir=index_dir, backend="local")
|
|
46
|
-
|
|
47
|
-
# 3. Index the synthetic audio directory
|
|
48
|
-
print("\n--- Indexing Audio ---")
|
|
49
|
-
ev.index(audio_dir)
|
|
50
|
-
|
|
51
|
-
# 4. Search across indexed audio
|
|
52
|
-
print("\n--- Searching the Index ---")
|
|
53
|
-
# Since CLAP maps descriptive text queries to audio features, we query semantically
|
|
54
|
-
query = "high frequency alarm tone"
|
|
55
|
-
print(f"Searching for: '{query}'")
|
|
56
|
-
results = ev.search(query, top_k=2)
|
|
57
|
-
|
|
58
|
-
print("\nSearch Results:")
|
|
59
|
-
for i, r in enumerate(results, 1):
|
|
60
|
-
print(
|
|
61
|
-
f"{i}. File: {r.filepath} | "
|
|
62
|
-
f"Start: {r.timestamp_range.start:.2f}s | "
|
|
63
|
-
f"End: {r.timestamp_range.end:.2f}s | "
|
|
64
|
-
f"Score: {r.score:.4f}"
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
# 5. Index statistics
|
|
68
|
-
print("\n--- Index Statistics ---")
|
|
69
|
-
stats = ev.stats()
|
|
70
|
-
for k, v in stats.items():
|
|
71
|
-
print(f"{k}: {v}")
|
|
72
|
-
|
|
73
|
-
print("\nDemo completed successfully!")
|
|
74
|
-
|
|
75
|
-
if __name__ == "__main__":
|
|
76
|
-
main()
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|