clens-cli 1.0.1__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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 k4rkie
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,210 @@
1
+ Metadata-Version: 2.3
2
+ Name: clens-cli
3
+ Version: 1.0.1
4
+ Summary: Local semantic image search tool
5
+ Keywords: cli,image search,semantic search,computer vision
6
+ Author: k4rkie
7
+ Author-email: k4rkie <karkeekrish07@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 k4rkie
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Environment :: Console
31
+ Classifier: Intended Audience :: End Users/Desktop
32
+ Classifier: Programming Language :: Python :: 3.14
33
+ Classifier: Topic :: Multimedia :: Graphics
34
+ Requires-Dist: chromadb>=1.5.9
35
+ Requires-Dist: fastapi[standard]>=0.142.2
36
+ Requires-Dist: filetype>=1.2.0
37
+ Requires-Dist: pillow>=12.3.0
38
+ Requires-Dist: sentence-transformers>=6.1.0
39
+ Requires-Dist: torch>=2.14.0
40
+ Requires-Python: >=3.14
41
+ Description-Content-Type: text/markdown
42
+
43
+ <h1 align="center">clens</h1>
44
+
45
+ Clens is a semantic image search tool that allows users
46
+ to index a given directory of images and search through it
47
+ using natural language, search for matching images using
48
+ another image etc. locally on their device.
49
+
50
+ ## Installation
51
+
52
+ Clens currently requires Python 3.14 or newer. The recommended installation
53
+ uses the CPU-only PyTorch packages, so it does not download NVIDIA/CUDA
54
+ libraries on CPU machines.
55
+
56
+ ### Install with uv
57
+
58
+ Install the published package as an isolated command-line tool. The extra
59
+ PyTorch index is needed because CPU-only PyTorch wheels are published there:
60
+
61
+ ```bash
62
+ uv tool install \
63
+ --index https://download.pytorch.org/whl/cpu \
64
+ --default-index https://pypi.org/simple \
65
+ clens-cli
66
+ ```
67
+
68
+ ### Install with pipx
69
+
70
+ `pipx` also installs command-line applications into an isolated environment:
71
+
72
+ ```bash
73
+ pipx install \
74
+ --pip-args="--index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple" \
75
+ clens-cli
76
+ ```
77
+
78
+ After installation, verify the command:
79
+
80
+ ```bash
81
+ clens version
82
+ clens --help
83
+ ```
84
+
85
+ The first indexing or search operation downloads the local CLIP model so may take a few minutes. It is
86
+ cached locally and reused for later runs.
87
+
88
+ ## Usage
89
+
90
+ Clens uses a local background server (FastAPI + ChromaDB + CLIP) to keep embeddings loaded in memory for faster indexing and search.
91
+
92
+ ### 1. Server
93
+
94
+ Before indexing or searching, make sure the clens server is running.
95
+
96
+ Start the server:
97
+ ```bash
98
+ # Start in current shell
99
+ clens server start
100
+
101
+ # Or detach to run in background
102
+ clens server start --detach
103
+ ```
104
+
105
+ > Defaults to `127.0.0.1:6969`. You can pass custom host/port:
106
+ > ```bash
107
+ > clens server start --port 6969 --detach
108
+ > ```
109
+
110
+ Check status or stop:
111
+ ```bash
112
+ # Check if server is running
113
+ clens server status
114
+
115
+ # Stop running server
116
+ clens server stop
117
+ ```
118
+
119
+ ---
120
+
121
+ ### 2. Index a Directory
122
+
123
+ Recursively indexes `.png` and `.jpg` images from a directory and stores embeddings in local ChromaDB:
124
+
125
+ ```bash
126
+ clens index ./Pictures
127
+ ```
128
+ *Indexing may take a few moments depending on the number of images in the directory and your hardware.*
129
+
130
+ ---
131
+
132
+ ### 3. Find Images with Text (`find`)
133
+
134
+ Search indexed images with natural language:
135
+
136
+ ```bash
137
+ clens find "a dog with a hat"
138
+ ```
139
+
140
+ Change number of results with `-c` / `--count` (default is 5):
141
+ ```bash
142
+ clens find "a dog with a hat" -c 10
143
+ ```
144
+
145
+ ---
146
+
147
+ ### 4. Find Matching Images (`match`)
148
+
149
+ Pass an image to find visually and semantically matching images in your indexed directories:
150
+
151
+ ```bash
152
+ clens match ./sample_images/dog.png
153
+ ```
154
+
155
+ Specify number of matches:
156
+ ```bash
157
+ clens match ./sample_images/dog.png -c 3
158
+ ```
159
+
160
+ ---
161
+
162
+ ### 5. Plain Output for Scripts & Piping (`-p`)
163
+
164
+ By default, clens renders an ANSI table with match percentage and clickable file paths. Use `-p` / `--plain` to get raw tab-separated output (`RANK`, `SCORE`, `FILENAME`, `PATH`):
165
+
166
+ ```bash
167
+ # Tab-separated output
168
+ clens find "sunset" -p
169
+
170
+ # Example: pipe top result to xdg-open
171
+ clens find "cat sleeping" -c 1 -p | awk 'NR==2 {print $4}' | xargs xdg-open
172
+ ```
173
+
174
+ ---
175
+
176
+ ### Configuration
177
+
178
+ Clens automatically generates a config file at `~/.config/clens/config.json` (or `$XDG_CONFIG_HOME/clens/config.json`):
179
+
180
+ ```json
181
+ {
182
+ "preferences": {
183
+ "default_host": "127.0.0.1",
184
+ "default_port": 6969
185
+ }
186
+ }
187
+ ```
188
+
189
+ Currently available options:
190
+ * `preferences.default_host`: Default host the server binds to and client commands connect to (default: `"127.0.0.1"`).
191
+ * `preferences.default_port`: Default port used by the server and CLI (default: `6969`).
192
+
193
+ ---
194
+
195
+ ## Commands
196
+
197
+ ```
198
+ clens server start [-H HOST] [-p PORT] [-d] Start clens server (-d to detach)
199
+ clens server status Get server status
200
+ clens server stop Stop running server
201
+ clens index <path> Index a directory of images
202
+ clens find <query_term> [-c COUNT] [-p] Find images by text description
203
+ clens match <image_path> [-c COUNT] [-p] Find images matching an existing image
204
+ clens version Print current version
205
+ ```
206
+
207
+ For indepth info about the program
208
+ ```bash
209
+ clens -h/-help
210
+ ```
@@ -0,0 +1,168 @@
1
+ <h1 align="center">clens</h1>
2
+
3
+ Clens is a semantic image search tool that allows users
4
+ to index a given directory of images and search through it
5
+ using natural language, search for matching images using
6
+ another image etc. locally on their device.
7
+
8
+ ## Installation
9
+
10
+ Clens currently requires Python 3.14 or newer. The recommended installation
11
+ uses the CPU-only PyTorch packages, so it does not download NVIDIA/CUDA
12
+ libraries on CPU machines.
13
+
14
+ ### Install with uv
15
+
16
+ Install the published package as an isolated command-line tool. The extra
17
+ PyTorch index is needed because CPU-only PyTorch wheels are published there:
18
+
19
+ ```bash
20
+ uv tool install \
21
+ --index https://download.pytorch.org/whl/cpu \
22
+ --default-index https://pypi.org/simple \
23
+ clens-cli
24
+ ```
25
+
26
+ ### Install with pipx
27
+
28
+ `pipx` also installs command-line applications into an isolated environment:
29
+
30
+ ```bash
31
+ pipx install \
32
+ --pip-args="--index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple" \
33
+ clens-cli
34
+ ```
35
+
36
+ After installation, verify the command:
37
+
38
+ ```bash
39
+ clens version
40
+ clens --help
41
+ ```
42
+
43
+ The first indexing or search operation downloads the local CLIP model so may take a few minutes. It is
44
+ cached locally and reused for later runs.
45
+
46
+ ## Usage
47
+
48
+ Clens uses a local background server (FastAPI + ChromaDB + CLIP) to keep embeddings loaded in memory for faster indexing and search.
49
+
50
+ ### 1. Server
51
+
52
+ Before indexing or searching, make sure the clens server is running.
53
+
54
+ Start the server:
55
+ ```bash
56
+ # Start in current shell
57
+ clens server start
58
+
59
+ # Or detach to run in background
60
+ clens server start --detach
61
+ ```
62
+
63
+ > Defaults to `127.0.0.1:6969`. You can pass custom host/port:
64
+ > ```bash
65
+ > clens server start --port 6969 --detach
66
+ > ```
67
+
68
+ Check status or stop:
69
+ ```bash
70
+ # Check if server is running
71
+ clens server status
72
+
73
+ # Stop running server
74
+ clens server stop
75
+ ```
76
+
77
+ ---
78
+
79
+ ### 2. Index a Directory
80
+
81
+ Recursively indexes `.png` and `.jpg` images from a directory and stores embeddings in local ChromaDB:
82
+
83
+ ```bash
84
+ clens index ./Pictures
85
+ ```
86
+ *Indexing may take a few moments depending on the number of images in the directory and your hardware.*
87
+
88
+ ---
89
+
90
+ ### 3. Find Images with Text (`find`)
91
+
92
+ Search indexed images with natural language:
93
+
94
+ ```bash
95
+ clens find "a dog with a hat"
96
+ ```
97
+
98
+ Change number of results with `-c` / `--count` (default is 5):
99
+ ```bash
100
+ clens find "a dog with a hat" -c 10
101
+ ```
102
+
103
+ ---
104
+
105
+ ### 4. Find Matching Images (`match`)
106
+
107
+ Pass an image to find visually and semantically matching images in your indexed directories:
108
+
109
+ ```bash
110
+ clens match ./sample_images/dog.png
111
+ ```
112
+
113
+ Specify number of matches:
114
+ ```bash
115
+ clens match ./sample_images/dog.png -c 3
116
+ ```
117
+
118
+ ---
119
+
120
+ ### 5. Plain Output for Scripts & Piping (`-p`)
121
+
122
+ By default, clens renders an ANSI table with match percentage and clickable file paths. Use `-p` / `--plain` to get raw tab-separated output (`RANK`, `SCORE`, `FILENAME`, `PATH`):
123
+
124
+ ```bash
125
+ # Tab-separated output
126
+ clens find "sunset" -p
127
+
128
+ # Example: pipe top result to xdg-open
129
+ clens find "cat sleeping" -c 1 -p | awk 'NR==2 {print $4}' | xargs xdg-open
130
+ ```
131
+
132
+ ---
133
+
134
+ ### Configuration
135
+
136
+ Clens automatically generates a config file at `~/.config/clens/config.json` (or `$XDG_CONFIG_HOME/clens/config.json`):
137
+
138
+ ```json
139
+ {
140
+ "preferences": {
141
+ "default_host": "127.0.0.1",
142
+ "default_port": 6969
143
+ }
144
+ }
145
+ ```
146
+
147
+ Currently available options:
148
+ * `preferences.default_host`: Default host the server binds to and client commands connect to (default: `"127.0.0.1"`).
149
+ * `preferences.default_port`: Default port used by the server and CLI (default: `6969`).
150
+
151
+ ---
152
+
153
+ ## Commands
154
+
155
+ ```
156
+ clens server start [-H HOST] [-p PORT] [-d] Start clens server (-d to detach)
157
+ clens server status Get server status
158
+ clens server stop Stop running server
159
+ clens index <path> Index a directory of images
160
+ clens find <query_term> [-c COUNT] [-p] Find images by text description
161
+ clens match <image_path> [-c COUNT] [-p] Find images matching an existing image
162
+ clens version Print current version
163
+ ```
164
+
165
+ For indepth info about the program
166
+ ```bash
167
+ clens -h/-help
168
+ ```
@@ -0,0 +1,66 @@
1
+ [project]
2
+ name = "clens-cli"
3
+ version = "1.0.1"
4
+ description = "Local semantic image search tool"
5
+ readme = "README.md"
6
+ keywords = [
7
+ "cli",
8
+ "image search",
9
+ "semantic search",
10
+ "computer vision",
11
+ ]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Environment :: Console",
15
+ "Intended Audience :: End Users/Desktop",
16
+ "Programming Language :: Python :: 3.14",
17
+ "Topic :: Multimedia :: Graphics",
18
+ ]
19
+ requires-python = ">=3.14"
20
+ dependencies = [
21
+ "chromadb>=1.5.9",
22
+ "fastapi[standard]>=0.142.2",
23
+ "filetype>=1.2.0",
24
+ "pillow>=12.3.0",
25
+ "sentence-transformers>=6.1.0",
26
+ "torch>=2.14.0",
27
+ ]
28
+
29
+ [[project.authors]]
30
+ name = "k4rkie"
31
+ email = "karkeekrish07@gmail.com"
32
+
33
+ [project.license]
34
+ file = "LICENSE"
35
+
36
+ [project.project-urls]
37
+ Repository = "https://github.com/k4rkie/clens"
38
+
39
+ [project.scripts]
40
+ clens = "clens.cli:cli"
41
+
42
+ [build-system]
43
+ requires = ["uv_build>=0.12.11,<0.13.0"]
44
+ build-backend = "uv_build"
45
+
46
+ [tool.uv.build-backend]
47
+ module-name = "clens"
48
+
49
+ [[tool.uv.index]]
50
+ name = "pytorch-cpu"
51
+ url = "https://download.pytorch.org/whl/cpu"
52
+ explicit = true
53
+
54
+ [tool.uv.sources.torch]
55
+ index = "pytorch-cpu"
56
+
57
+ [tool.pyright]
58
+ exclude = [
59
+ ".venv",
60
+ "venv",
61
+ ".chroma_store",
62
+ "__pycache__",
63
+ ]
64
+
65
+ [dependency-groups]
66
+ dev = ["pytest>=9.1.1"]
@@ -0,0 +1,58 @@
1
+ [project]
2
+ name = "clens-cli"
3
+ version = "1.0.1"
4
+ description = "Local semantic image search tool"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "k4rkie", email = "karkeekrish07@gmail.com" }
8
+ ]
9
+ license = { file = "LICENSE" }
10
+ keywords = ["cli", "image search", "semantic search", "computer vision"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Environment :: Console",
14
+ "Intended Audience :: End Users/Desktop",
15
+ "Programming Language :: Python :: 3.14",
16
+ "Topic :: Multimedia :: Graphics",
17
+ ]
18
+ project-urls = { Repository = "https://github.com/k4rkie/clens" }
19
+ requires-python = ">=3.14"
20
+ dependencies = [
21
+ "chromadb>=1.5.9",
22
+ "fastapi[standard]>=0.142.2",
23
+ "filetype>=1.2.0",
24
+ "pillow>=12.3.0",
25
+ "sentence-transformers>=6.1.0",
26
+ "torch>=2.14.0",
27
+ ]
28
+
29
+ [project.scripts]
30
+ clens = "clens.cli:cli"
31
+
32
+ [build-system]
33
+ requires = ["uv_build>=0.12.11,<0.13.0"]
34
+ build-backend = "uv_build"
35
+
36
+ [tool.uv.build-backend]
37
+ module-name = "clens"
38
+
39
+ [[tool.uv.index]]
40
+ name = "pytorch-cpu"
41
+ url = "https://download.pytorch.org/whl/cpu"
42
+ explicit = true
43
+
44
+ [tool.uv.sources]
45
+ torch = { index = "pytorch-cpu" }
46
+
47
+ [dependency-groups]
48
+ dev = [
49
+ "pytest>=9.1.1",
50
+ ]
51
+
52
+ [tool.pyright]
53
+ exclude = [
54
+ ".venv",
55
+ "venv",
56
+ ".chroma_store",
57
+ "__pycache__",
58
+ ]
File without changes
@@ -0,0 +1,29 @@
1
+ from pydantic import BaseModel, Field
2
+ from pathlib import Path
3
+ from clens.paths import CONFIG_FILE
4
+ import json
5
+
6
+
7
+ class UserPreferences(BaseModel):
8
+ default_host: str = "127.0.0.1"
9
+ default_port: int = 6969
10
+
11
+
12
+ class AppConfig(BaseModel):
13
+ preferences: UserPreferences = Field(default_factory=UserPreferences)
14
+
15
+ @classmethod
16
+ def load_from_file(cls, path: Path = CONFIG_FILE) -> "AppConfig":
17
+ if not path.exists():
18
+ return cls()
19
+ try:
20
+ with open(path, "r") as f:
21
+ data = json.load(f)
22
+ return cls.model_validate(data)
23
+ except Exception:
24
+ return cls()
25
+
26
+ def save_to_file(self, path: Path = CONFIG_FILE) -> None:
27
+ path.parent.mkdir(parents=True, exist_ok=True)
28
+ with open(path, "w") as f:
29
+ f.write(self.model_dump_json(indent=2))