dakera 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.
- dakera-0.1.0/LICENSE +21 -0
- dakera-0.1.0/PKG-INFO +344 -0
- dakera-0.1.0/README.md +304 -0
- dakera-0.1.0/pyproject.toml +83 -0
- dakera-0.1.0/setup.cfg +4 -0
- dakera-0.1.0/src/dakera/__init__.py +112 -0
- dakera-0.1.0/src/dakera/client.py +1553 -0
- dakera-0.1.0/src/dakera/exceptions.py +77 -0
- dakera-0.1.0/src/dakera/models.py +822 -0
- dakera-0.1.0/src/dakera/py.typed +0 -0
- dakera-0.1.0/src/dakera.egg-info/PKG-INFO +344 -0
- dakera-0.1.0/src/dakera.egg-info/SOURCES.txt +14 -0
- dakera-0.1.0/src/dakera.egg-info/dependency_links.txt +1 -0
- dakera-0.1.0/src/dakera.egg-info/requires.txt +15 -0
- dakera-0.1.0/src/dakera.egg-info/top_level.txt +1 -0
- dakera-0.1.0/tests/test_client.py +443 -0
dakera-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dakera AI
|
|
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.
|
dakera-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dakera
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for Dakera - AI memory platform
|
|
5
|
+
Author: Dakera Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://dakera.ai
|
|
8
|
+
Project-URL: Documentation, https://dakera.ai/docs/python
|
|
9
|
+
Project-URL: Repository, https://github.com/dakera-ai/dakera-py
|
|
10
|
+
Project-URL: Issues, https://github.com/dakera-ai/dakera-py/issues
|
|
11
|
+
Keywords: vector,database,embedding,similarity,search,ai,ml,memory,dakera
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Database
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: requests>=2.28.0
|
|
29
|
+
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
33
|
+
Requires-Dist: responses>=0.23.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: types-requests>=2.28.0; extra == "dev"
|
|
37
|
+
Provides-Extra: async
|
|
38
|
+
Requires-Dist: aiohttp>=3.8.0; extra == "async"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# Dakera Python SDK
|
|
42
|
+
|
|
43
|
+
[](https://github.com/dakera-ai/dakera-py/actions/workflows/ci.yml)
|
|
44
|
+
[](https://pypi.org/project/dakera/)
|
|
45
|
+
[](LICENSE)
|
|
46
|
+
[](https://pypi.org/project/dakera/)
|
|
47
|
+
|
|
48
|
+
Official Python client for [Dakera](https://github.com/dakera/dakera) - a high-performance vector database.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install dakera
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For async support:
|
|
57
|
+
```bash
|
|
58
|
+
pip install dakera[async]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from dakera import DakeraClient
|
|
65
|
+
|
|
66
|
+
# Connect to Dakera
|
|
67
|
+
client = DakeraClient("http://localhost:3000")
|
|
68
|
+
|
|
69
|
+
# Upsert vectors
|
|
70
|
+
client.upsert("my-namespace", vectors=[
|
|
71
|
+
{"id": "vec1", "values": [0.1, 0.2, 0.3], "metadata": {"label": "a"}},
|
|
72
|
+
{"id": "vec2", "values": [0.4, 0.5, 0.6], "metadata": {"label": "b"}},
|
|
73
|
+
])
|
|
74
|
+
|
|
75
|
+
# Query similar vectors
|
|
76
|
+
results = client.query(
|
|
77
|
+
"my-namespace",
|
|
78
|
+
vector=[0.1, 0.2, 0.3],
|
|
79
|
+
top_k=10,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
for result in results.results:
|
|
83
|
+
print(f"{result.id}: {result.score}")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Features
|
|
87
|
+
|
|
88
|
+
- **Vector Operations**: Upsert, query, delete, fetch vectors
|
|
89
|
+
- **Full-Text Search**: Index documents and perform BM25 search
|
|
90
|
+
- **Hybrid Search**: Combine vector and text search with configurable weights
|
|
91
|
+
- **Namespace Management**: Create, list, delete namespaces
|
|
92
|
+
- **Metadata Filtering**: Filter queries by metadata fields
|
|
93
|
+
- **Type Hints**: Full type annotation support
|
|
94
|
+
- **Context Manager**: Automatic connection cleanup
|
|
95
|
+
|
|
96
|
+
## Usage Examples
|
|
97
|
+
|
|
98
|
+
### Vector Operations
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from dakera import DakeraClient, Vector
|
|
102
|
+
|
|
103
|
+
client = DakeraClient("http://localhost:3000")
|
|
104
|
+
|
|
105
|
+
# Using dataclass
|
|
106
|
+
vectors = [
|
|
107
|
+
Vector(id="vec1", values=[0.1, 0.2, 0.3], metadata={"category": "A"}),
|
|
108
|
+
Vector(id="vec2", values=[0.4, 0.5, 0.6], metadata={"category": "B"}),
|
|
109
|
+
]
|
|
110
|
+
client.upsert("my-namespace", vectors)
|
|
111
|
+
|
|
112
|
+
# Using dictionaries
|
|
113
|
+
client.upsert("my-namespace", vectors=[
|
|
114
|
+
{"id": "vec3", "values": [0.7, 0.8, 0.9]},
|
|
115
|
+
])
|
|
116
|
+
|
|
117
|
+
# Query with metadata filter
|
|
118
|
+
results = client.query(
|
|
119
|
+
"my-namespace",
|
|
120
|
+
vector=[0.1, 0.2, 0.3],
|
|
121
|
+
top_k=5,
|
|
122
|
+
filter={"category": {"$eq": "A"}},
|
|
123
|
+
include_metadata=True,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Batch query
|
|
127
|
+
batch_results = client.batch_query("my-namespace", queries=[
|
|
128
|
+
{"vector": [0.1, 0.2, 0.3], "top_k": 5},
|
|
129
|
+
{"vector": [0.4, 0.5, 0.6], "top_k": 3},
|
|
130
|
+
])
|
|
131
|
+
|
|
132
|
+
# Delete vectors
|
|
133
|
+
client.delete("my-namespace", ids=["vec1", "vec2"])
|
|
134
|
+
client.delete("my-namespace", filter={"category": {"$eq": "obsolete"}})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Full-Text Search
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
# Index documents
|
|
141
|
+
client.index_documents("my-namespace", documents=[
|
|
142
|
+
{"id": "doc1", "content": "Machine learning is transforming industries"},
|
|
143
|
+
{"id": "doc2", "content": "Vector databases enable semantic search"},
|
|
144
|
+
])
|
|
145
|
+
|
|
146
|
+
# Search
|
|
147
|
+
results = client.fulltext_search(
|
|
148
|
+
"my-namespace",
|
|
149
|
+
query="machine learning",
|
|
150
|
+
top_k=10,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
for result in results:
|
|
154
|
+
print(f"{result.id}: {result.score}")
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Hybrid Search
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# Combine vector and text search
|
|
161
|
+
results = client.hybrid_search(
|
|
162
|
+
"my-namespace",
|
|
163
|
+
vector=[0.1, 0.2, 0.3], # Embedding of query
|
|
164
|
+
query="machine learning", # Text query
|
|
165
|
+
top_k=10,
|
|
166
|
+
alpha=0.7, # 0 = pure vector, 1 = pure text
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
for result in results:
|
|
170
|
+
print(f"{result.id}: score={result.score}, vector={result.vector_score}, text={result.text_score}")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Namespace Management
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
# Create namespace with specific configuration
|
|
177
|
+
client.create_namespace(
|
|
178
|
+
"embeddings",
|
|
179
|
+
dimensions=384,
|
|
180
|
+
index_type="hnsw",
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# List all namespaces
|
|
184
|
+
namespaces = client.list_namespaces()
|
|
185
|
+
for ns in namespaces:
|
|
186
|
+
print(f"{ns.name}: {ns.vector_count} vectors")
|
|
187
|
+
|
|
188
|
+
# Get namespace info
|
|
189
|
+
info = client.get_namespace("embeddings")
|
|
190
|
+
print(f"Dimensions: {info.dimensions}, Index: {info.index_type}")
|
|
191
|
+
|
|
192
|
+
# Delete namespace
|
|
193
|
+
client.delete_namespace("old-namespace")
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Metadata Filtering
|
|
197
|
+
|
|
198
|
+
Dakera supports rich metadata filtering:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
# Equality
|
|
202
|
+
filter = {"status": {"$eq": "active"}}
|
|
203
|
+
|
|
204
|
+
# Comparison
|
|
205
|
+
filter = {"price": {"$gt": 100, "$lt": 500}}
|
|
206
|
+
|
|
207
|
+
# In list
|
|
208
|
+
filter = {"category": {"$in": ["electronics", "books"]}}
|
|
209
|
+
|
|
210
|
+
# Logical operators
|
|
211
|
+
filter = {
|
|
212
|
+
"$and": [
|
|
213
|
+
{"status": {"$eq": "active"}},
|
|
214
|
+
{"price": {"$lt": 1000}},
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
results = client.query(
|
|
219
|
+
"products",
|
|
220
|
+
vector=query_embedding,
|
|
221
|
+
filter=filter,
|
|
222
|
+
top_k=20,
|
|
223
|
+
)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Error Handling
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from dakera import (
|
|
230
|
+
DakeraClient,
|
|
231
|
+
NotFoundError,
|
|
232
|
+
ValidationError,
|
|
233
|
+
RateLimitError,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
client = DakeraClient("http://localhost:3000")
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
results = client.query("nonexistent", vector=[0.1, 0.2])
|
|
240
|
+
except NotFoundError as e:
|
|
241
|
+
print(f"Namespace not found: {e}")
|
|
242
|
+
except ValidationError as e:
|
|
243
|
+
print(f"Invalid request: {e}")
|
|
244
|
+
except RateLimitError as e:
|
|
245
|
+
print(f"Rate limited, retry after {e.retry_after} seconds")
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Context Manager
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
with DakeraClient("http://localhost:3000") as client:
|
|
252
|
+
client.upsert("my-namespace", vectors=[...])
|
|
253
|
+
results = client.query("my-namespace", vector=[...])
|
|
254
|
+
# Connection automatically closed
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Authentication
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
# With API key
|
|
261
|
+
client = DakeraClient(
|
|
262
|
+
"http://localhost:3000",
|
|
263
|
+
api_key="your-api-key",
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# With custom headers
|
|
267
|
+
client = DakeraClient(
|
|
268
|
+
"http://localhost:3000",
|
|
269
|
+
headers={"X-Custom-Header": "value"},
|
|
270
|
+
)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Configuration
|
|
274
|
+
|
|
275
|
+
| Parameter | Type | Default | Description |
|
|
276
|
+
|-----------|------|---------|-------------|
|
|
277
|
+
| `base_url` | str | required | Dakera server URL |
|
|
278
|
+
| `api_key` | str | None | API key for authentication |
|
|
279
|
+
| `timeout` | float | 30.0 | Request timeout in seconds |
|
|
280
|
+
| `max_retries` | int | 3 | Max retries for failed requests |
|
|
281
|
+
| `headers` | dict | None | Additional HTTP headers |
|
|
282
|
+
|
|
283
|
+
## API Reference
|
|
284
|
+
|
|
285
|
+
### DakeraClient
|
|
286
|
+
|
|
287
|
+
#### Vector Operations
|
|
288
|
+
- `upsert(namespace, vectors)` - Insert or update vectors
|
|
289
|
+
- `query(namespace, vector, top_k, filter, ...)` - Query similar vectors
|
|
290
|
+
- `delete(namespace, ids, filter, delete_all)` - Delete vectors
|
|
291
|
+
- `fetch(namespace, ids)` - Fetch vectors by ID
|
|
292
|
+
- `batch_query(namespace, queries)` - Execute multiple queries
|
|
293
|
+
|
|
294
|
+
#### Full-Text Operations
|
|
295
|
+
- `index_documents(namespace, documents)` - Index documents
|
|
296
|
+
- `fulltext_search(namespace, query, top_k, filter)` - Text search
|
|
297
|
+
- `hybrid_search(namespace, vector, query, alpha, ...)` - Hybrid search
|
|
298
|
+
|
|
299
|
+
#### Namespace Operations
|
|
300
|
+
- `list_namespaces()` - List all namespaces
|
|
301
|
+
- `get_namespace(namespace)` - Get namespace info
|
|
302
|
+
- `create_namespace(namespace, dimensions, index_type)` - Create namespace
|
|
303
|
+
- `delete_namespace(namespace)` - Delete namespace
|
|
304
|
+
|
|
305
|
+
#### Admin Operations
|
|
306
|
+
- `health()` - Check server health
|
|
307
|
+
- `get_index_stats(namespace)` - Get index statistics
|
|
308
|
+
- `compact(namespace)` - Trigger compaction
|
|
309
|
+
- `flush(namespace)` - Flush pending writes
|
|
310
|
+
|
|
311
|
+
## Development
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Install dev dependencies
|
|
315
|
+
pip install -e ".[dev]"
|
|
316
|
+
|
|
317
|
+
# Run tests
|
|
318
|
+
pytest
|
|
319
|
+
|
|
320
|
+
# Type checking
|
|
321
|
+
mypy src/dakera
|
|
322
|
+
|
|
323
|
+
# Linting
|
|
324
|
+
ruff check src/
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Related Repositories
|
|
328
|
+
|
|
329
|
+
| Repository | Description |
|
|
330
|
+
|------------|-------------|
|
|
331
|
+
| [dakera](https://github.com/dakera-ai/dakera) | Core vector database engine (Rust) |
|
|
332
|
+
| [dakera-js](https://github.com/dakera-ai/dakera-js) | TypeScript/JavaScript SDK |
|
|
333
|
+
| [dakera-go](https://github.com/dakera-ai/dakera-go) | Go SDK |
|
|
334
|
+
| [dakera-rs](https://github.com/dakera-ai/dakera-rs) | Rust SDK |
|
|
335
|
+
| [dakera-cli](https://github.com/dakera-ai/dakera-cli) | Command-line interface |
|
|
336
|
+
| [dakera-mcp](https://github.com/dakera-ai/dakera-mcp) | MCP Server for AI agent memory |
|
|
337
|
+
| [dakera-dashboard](https://github.com/dakera-ai/dakera-dashboard) | Admin dashboard (Leptos/WASM) |
|
|
338
|
+
| [dakera-docs](https://github.com/dakera-ai/dakera-docs) | Documentation |
|
|
339
|
+
| [dakera-deploy](https://github.com/dakera-ai/dakera-deploy) | Deployment configs and Docker Compose |
|
|
340
|
+
| [dakera-cortex](https://github.com/dakera-ai/dakera-cortex) | Flagship demo with AI agents |
|
|
341
|
+
|
|
342
|
+
## License
|
|
343
|
+
|
|
344
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
dakera-0.1.0/README.md
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# Dakera Python SDK
|
|
2
|
+
|
|
3
|
+
[](https://github.com/dakera-ai/dakera-py/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/dakera/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://pypi.org/project/dakera/)
|
|
7
|
+
|
|
8
|
+
Official Python client for [Dakera](https://github.com/dakera/dakera) - a high-performance vector database.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install dakera
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
For async support:
|
|
17
|
+
```bash
|
|
18
|
+
pip install dakera[async]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
from dakera import DakeraClient
|
|
25
|
+
|
|
26
|
+
# Connect to Dakera
|
|
27
|
+
client = DakeraClient("http://localhost:3000")
|
|
28
|
+
|
|
29
|
+
# Upsert vectors
|
|
30
|
+
client.upsert("my-namespace", vectors=[
|
|
31
|
+
{"id": "vec1", "values": [0.1, 0.2, 0.3], "metadata": {"label": "a"}},
|
|
32
|
+
{"id": "vec2", "values": [0.4, 0.5, 0.6], "metadata": {"label": "b"}},
|
|
33
|
+
])
|
|
34
|
+
|
|
35
|
+
# Query similar vectors
|
|
36
|
+
results = client.query(
|
|
37
|
+
"my-namespace",
|
|
38
|
+
vector=[0.1, 0.2, 0.3],
|
|
39
|
+
top_k=10,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
for result in results.results:
|
|
43
|
+
print(f"{result.id}: {result.score}")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **Vector Operations**: Upsert, query, delete, fetch vectors
|
|
49
|
+
- **Full-Text Search**: Index documents and perform BM25 search
|
|
50
|
+
- **Hybrid Search**: Combine vector and text search with configurable weights
|
|
51
|
+
- **Namespace Management**: Create, list, delete namespaces
|
|
52
|
+
- **Metadata Filtering**: Filter queries by metadata fields
|
|
53
|
+
- **Type Hints**: Full type annotation support
|
|
54
|
+
- **Context Manager**: Automatic connection cleanup
|
|
55
|
+
|
|
56
|
+
## Usage Examples
|
|
57
|
+
|
|
58
|
+
### Vector Operations
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from dakera import DakeraClient, Vector
|
|
62
|
+
|
|
63
|
+
client = DakeraClient("http://localhost:3000")
|
|
64
|
+
|
|
65
|
+
# Using dataclass
|
|
66
|
+
vectors = [
|
|
67
|
+
Vector(id="vec1", values=[0.1, 0.2, 0.3], metadata={"category": "A"}),
|
|
68
|
+
Vector(id="vec2", values=[0.4, 0.5, 0.6], metadata={"category": "B"}),
|
|
69
|
+
]
|
|
70
|
+
client.upsert("my-namespace", vectors)
|
|
71
|
+
|
|
72
|
+
# Using dictionaries
|
|
73
|
+
client.upsert("my-namespace", vectors=[
|
|
74
|
+
{"id": "vec3", "values": [0.7, 0.8, 0.9]},
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
# Query with metadata filter
|
|
78
|
+
results = client.query(
|
|
79
|
+
"my-namespace",
|
|
80
|
+
vector=[0.1, 0.2, 0.3],
|
|
81
|
+
top_k=5,
|
|
82
|
+
filter={"category": {"$eq": "A"}},
|
|
83
|
+
include_metadata=True,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Batch query
|
|
87
|
+
batch_results = client.batch_query("my-namespace", queries=[
|
|
88
|
+
{"vector": [0.1, 0.2, 0.3], "top_k": 5},
|
|
89
|
+
{"vector": [0.4, 0.5, 0.6], "top_k": 3},
|
|
90
|
+
])
|
|
91
|
+
|
|
92
|
+
# Delete vectors
|
|
93
|
+
client.delete("my-namespace", ids=["vec1", "vec2"])
|
|
94
|
+
client.delete("my-namespace", filter={"category": {"$eq": "obsolete"}})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Full-Text Search
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
# Index documents
|
|
101
|
+
client.index_documents("my-namespace", documents=[
|
|
102
|
+
{"id": "doc1", "content": "Machine learning is transforming industries"},
|
|
103
|
+
{"id": "doc2", "content": "Vector databases enable semantic search"},
|
|
104
|
+
])
|
|
105
|
+
|
|
106
|
+
# Search
|
|
107
|
+
results = client.fulltext_search(
|
|
108
|
+
"my-namespace",
|
|
109
|
+
query="machine learning",
|
|
110
|
+
top_k=10,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
for result in results:
|
|
114
|
+
print(f"{result.id}: {result.score}")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Hybrid Search
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# Combine vector and text search
|
|
121
|
+
results = client.hybrid_search(
|
|
122
|
+
"my-namespace",
|
|
123
|
+
vector=[0.1, 0.2, 0.3], # Embedding of query
|
|
124
|
+
query="machine learning", # Text query
|
|
125
|
+
top_k=10,
|
|
126
|
+
alpha=0.7, # 0 = pure vector, 1 = pure text
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
for result in results:
|
|
130
|
+
print(f"{result.id}: score={result.score}, vector={result.vector_score}, text={result.text_score}")
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Namespace Management
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
# Create namespace with specific configuration
|
|
137
|
+
client.create_namespace(
|
|
138
|
+
"embeddings",
|
|
139
|
+
dimensions=384,
|
|
140
|
+
index_type="hnsw",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# List all namespaces
|
|
144
|
+
namespaces = client.list_namespaces()
|
|
145
|
+
for ns in namespaces:
|
|
146
|
+
print(f"{ns.name}: {ns.vector_count} vectors")
|
|
147
|
+
|
|
148
|
+
# Get namespace info
|
|
149
|
+
info = client.get_namespace("embeddings")
|
|
150
|
+
print(f"Dimensions: {info.dimensions}, Index: {info.index_type}")
|
|
151
|
+
|
|
152
|
+
# Delete namespace
|
|
153
|
+
client.delete_namespace("old-namespace")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Metadata Filtering
|
|
157
|
+
|
|
158
|
+
Dakera supports rich metadata filtering:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
# Equality
|
|
162
|
+
filter = {"status": {"$eq": "active"}}
|
|
163
|
+
|
|
164
|
+
# Comparison
|
|
165
|
+
filter = {"price": {"$gt": 100, "$lt": 500}}
|
|
166
|
+
|
|
167
|
+
# In list
|
|
168
|
+
filter = {"category": {"$in": ["electronics", "books"]}}
|
|
169
|
+
|
|
170
|
+
# Logical operators
|
|
171
|
+
filter = {
|
|
172
|
+
"$and": [
|
|
173
|
+
{"status": {"$eq": "active"}},
|
|
174
|
+
{"price": {"$lt": 1000}},
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
results = client.query(
|
|
179
|
+
"products",
|
|
180
|
+
vector=query_embedding,
|
|
181
|
+
filter=filter,
|
|
182
|
+
top_k=20,
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Error Handling
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from dakera import (
|
|
190
|
+
DakeraClient,
|
|
191
|
+
NotFoundError,
|
|
192
|
+
ValidationError,
|
|
193
|
+
RateLimitError,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
client = DakeraClient("http://localhost:3000")
|
|
197
|
+
|
|
198
|
+
try:
|
|
199
|
+
results = client.query("nonexistent", vector=[0.1, 0.2])
|
|
200
|
+
except NotFoundError as e:
|
|
201
|
+
print(f"Namespace not found: {e}")
|
|
202
|
+
except ValidationError as e:
|
|
203
|
+
print(f"Invalid request: {e}")
|
|
204
|
+
except RateLimitError as e:
|
|
205
|
+
print(f"Rate limited, retry after {e.retry_after} seconds")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Context Manager
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
with DakeraClient("http://localhost:3000") as client:
|
|
212
|
+
client.upsert("my-namespace", vectors=[...])
|
|
213
|
+
results = client.query("my-namespace", vector=[...])
|
|
214
|
+
# Connection automatically closed
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Authentication
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
# With API key
|
|
221
|
+
client = DakeraClient(
|
|
222
|
+
"http://localhost:3000",
|
|
223
|
+
api_key="your-api-key",
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# With custom headers
|
|
227
|
+
client = DakeraClient(
|
|
228
|
+
"http://localhost:3000",
|
|
229
|
+
headers={"X-Custom-Header": "value"},
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Configuration
|
|
234
|
+
|
|
235
|
+
| Parameter | Type | Default | Description |
|
|
236
|
+
|-----------|------|---------|-------------|
|
|
237
|
+
| `base_url` | str | required | Dakera server URL |
|
|
238
|
+
| `api_key` | str | None | API key for authentication |
|
|
239
|
+
| `timeout` | float | 30.0 | Request timeout in seconds |
|
|
240
|
+
| `max_retries` | int | 3 | Max retries for failed requests |
|
|
241
|
+
| `headers` | dict | None | Additional HTTP headers |
|
|
242
|
+
|
|
243
|
+
## API Reference
|
|
244
|
+
|
|
245
|
+
### DakeraClient
|
|
246
|
+
|
|
247
|
+
#### Vector Operations
|
|
248
|
+
- `upsert(namespace, vectors)` - Insert or update vectors
|
|
249
|
+
- `query(namespace, vector, top_k, filter, ...)` - Query similar vectors
|
|
250
|
+
- `delete(namespace, ids, filter, delete_all)` - Delete vectors
|
|
251
|
+
- `fetch(namespace, ids)` - Fetch vectors by ID
|
|
252
|
+
- `batch_query(namespace, queries)` - Execute multiple queries
|
|
253
|
+
|
|
254
|
+
#### Full-Text Operations
|
|
255
|
+
- `index_documents(namespace, documents)` - Index documents
|
|
256
|
+
- `fulltext_search(namespace, query, top_k, filter)` - Text search
|
|
257
|
+
- `hybrid_search(namespace, vector, query, alpha, ...)` - Hybrid search
|
|
258
|
+
|
|
259
|
+
#### Namespace Operations
|
|
260
|
+
- `list_namespaces()` - List all namespaces
|
|
261
|
+
- `get_namespace(namespace)` - Get namespace info
|
|
262
|
+
- `create_namespace(namespace, dimensions, index_type)` - Create namespace
|
|
263
|
+
- `delete_namespace(namespace)` - Delete namespace
|
|
264
|
+
|
|
265
|
+
#### Admin Operations
|
|
266
|
+
- `health()` - Check server health
|
|
267
|
+
- `get_index_stats(namespace)` - Get index statistics
|
|
268
|
+
- `compact(namespace)` - Trigger compaction
|
|
269
|
+
- `flush(namespace)` - Flush pending writes
|
|
270
|
+
|
|
271
|
+
## Development
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
# Install dev dependencies
|
|
275
|
+
pip install -e ".[dev]"
|
|
276
|
+
|
|
277
|
+
# Run tests
|
|
278
|
+
pytest
|
|
279
|
+
|
|
280
|
+
# Type checking
|
|
281
|
+
mypy src/dakera
|
|
282
|
+
|
|
283
|
+
# Linting
|
|
284
|
+
ruff check src/
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Related Repositories
|
|
288
|
+
|
|
289
|
+
| Repository | Description |
|
|
290
|
+
|------------|-------------|
|
|
291
|
+
| [dakera](https://github.com/dakera-ai/dakera) | Core vector database engine (Rust) |
|
|
292
|
+
| [dakera-js](https://github.com/dakera-ai/dakera-js) | TypeScript/JavaScript SDK |
|
|
293
|
+
| [dakera-go](https://github.com/dakera-ai/dakera-go) | Go SDK |
|
|
294
|
+
| [dakera-rs](https://github.com/dakera-ai/dakera-rs) | Rust SDK |
|
|
295
|
+
| [dakera-cli](https://github.com/dakera-ai/dakera-cli) | Command-line interface |
|
|
296
|
+
| [dakera-mcp](https://github.com/dakera-ai/dakera-mcp) | MCP Server for AI agent memory |
|
|
297
|
+
| [dakera-dashboard](https://github.com/dakera-ai/dakera-dashboard) | Admin dashboard (Leptos/WASM) |
|
|
298
|
+
| [dakera-docs](https://github.com/dakera-ai/dakera-docs) | Documentation |
|
|
299
|
+
| [dakera-deploy](https://github.com/dakera-ai/dakera-deploy) | Deployment configs and Docker Compose |
|
|
300
|
+
| [dakera-cortex](https://github.com/dakera-ai/dakera-cortex) | Flagship demo with AI agents |
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT License - see [LICENSE](LICENSE) for details.
|