chromadb-zerodb 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.
- chromadb_zerodb-0.1.0/.gitignore +6 -0
- chromadb_zerodb-0.1.0/LICENSE +21 -0
- chromadb_zerodb-0.1.0/PKG-INFO +203 -0
- chromadb_zerodb-0.1.0/README.md +175 -0
- chromadb_zerodb-0.1.0/chromadb_zerodb/__init__.py +7 -0
- chromadb_zerodb-0.1.0/chromadb_zerodb/client.py +147 -0
- chromadb_zerodb-0.1.0/chromadb_zerodb/collection.py +328 -0
- chromadb_zerodb-0.1.0/chromadb_zerodb/provision.py +95 -0
- chromadb_zerodb-0.1.0/pyproject.toml +71 -0
- chromadb_zerodb-0.1.0/tests/__init__.py +0 -0
- chromadb_zerodb-0.1.0/tests/test_collection.py +389 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AINative Studio
|
|
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,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chromadb-zerodb
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Chroma-compatible API backed by ZeroDB cloud. No Docker, no server, instant vector DB.
|
|
5
|
+
Project-URL: Homepage, https://github.com/AINative-Studio/chromadb-zerodb
|
|
6
|
+
Project-URL: Documentation, https://docs.ainative.studio
|
|
7
|
+
Project-URL: Repository, https://github.com/AINative-Studio/chromadb-zerodb
|
|
8
|
+
Project-URL: Issues, https://github.com/AINative-Studio/chromadb-zerodb/issues
|
|
9
|
+
Author-email: AINative Studio <hello@ainative.studio>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: ai-database,ainative,auto-provisioning,chroma-alternative,chromadb,chromadb-alternative,claude,cloud-vector-db,cursor,embeddings,free-vector-database,hosted-chroma,milvus-alternative,no-docker,pinecone-alternative,qdrant-alternative,rag,retrieval-augmented-generation,semantic-search,serverless,similarity-search,vector-database,vector-store,weaviate-alternative,windsurf,zerodb
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
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: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Database
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Requires-Dist: requests>=2.28
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# chromadb-zerodb
|
|
30
|
+
|
|
31
|
+
**Chroma-compatible API backed by ZeroDB cloud. No Docker, no server, instant vector DB.**
|
|
32
|
+
|
|
33
|
+
Drop-in replacement for `chromadb` — same `Collection` API, but vectors are stored in ZeroDB cloud. Auto-provisions on first use. Free tier included.
|
|
34
|
+
|
|
35
|
+
## Why?
|
|
36
|
+
|
|
37
|
+
| | chromadb | chromadb-zerodb |
|
|
38
|
+
|---|---------|----------------|
|
|
39
|
+
| **Setup** | Docker server or in-memory (lost on restart) | `pip install` and go |
|
|
40
|
+
| **Persistence** | Requires server config | Cloud-persisted automatically |
|
|
41
|
+
| **Embeddings** | Bring your own | Free BAAI BGE models included |
|
|
42
|
+
| **Scaling** | Self-managed | Managed infrastructure |
|
|
43
|
+
| **Cost** | Server hosting | Free tier, pay as you grow |
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install chromadb-zerodb
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import chromadb_zerodb as chromadb
|
|
55
|
+
|
|
56
|
+
# Auto-provisions a free project on first use
|
|
57
|
+
client = chromadb.Client()
|
|
58
|
+
|
|
59
|
+
# Create a collection
|
|
60
|
+
collection = client.create_collection("my_docs")
|
|
61
|
+
|
|
62
|
+
# Add documents (auto-embedded with free BGE models)
|
|
63
|
+
collection.add(
|
|
64
|
+
documents=[
|
|
65
|
+
"Python is a great programming language",
|
|
66
|
+
"JavaScript powers the web",
|
|
67
|
+
"Rust is fast and memory-safe",
|
|
68
|
+
],
|
|
69
|
+
ids=["doc1", "doc2", "doc3"],
|
|
70
|
+
metadatas=[
|
|
71
|
+
{"topic": "python"},
|
|
72
|
+
{"topic": "javascript"},
|
|
73
|
+
{"topic": "rust"},
|
|
74
|
+
],
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Query by text
|
|
78
|
+
results = collection.query(
|
|
79
|
+
query_texts=["best language for beginners"],
|
|
80
|
+
n_results=2,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
print(results["documents"]) # [["Python is a great...", "JavaScript powers..."]]
|
|
84
|
+
print(results["distances"]) # [[0.05, 0.12]]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Migration from chromadb
|
|
88
|
+
|
|
89
|
+
Change one import:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# Before
|
|
93
|
+
import chromadb
|
|
94
|
+
client = chromadb.Client()
|
|
95
|
+
|
|
96
|
+
# After
|
|
97
|
+
import chromadb_zerodb as chromadb
|
|
98
|
+
client = chromadb.Client()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Everything else stays the same.
|
|
102
|
+
|
|
103
|
+
## Authentication
|
|
104
|
+
|
|
105
|
+
Three ways to authenticate (checked in order):
|
|
106
|
+
|
|
107
|
+
1. **Constructor arguments:**
|
|
108
|
+
```python
|
|
109
|
+
client = chromadb.Client(api_key="zdb_...", project_id="proj_...")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
2. **Environment variables:**
|
|
113
|
+
```bash
|
|
114
|
+
export ZERODB_API_KEY=zdb_...
|
|
115
|
+
export ZERODB_PROJECT_ID=proj_...
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
3. **Auto-provision:** If neither is set, a free project is created automatically. Credentials are cached in `~/.zerodb/credentials.json`.
|
|
119
|
+
|
|
120
|
+
## API Reference
|
|
121
|
+
|
|
122
|
+
### Client
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
client = chromadb.Client(api_key=None, project_id=None, base_url=None)
|
|
126
|
+
|
|
127
|
+
client.create_collection(name, metadata=None) # -> Collection
|
|
128
|
+
client.get_collection(name) # -> Collection
|
|
129
|
+
client.get_or_create_collection(name, metadata=None) # -> Collection
|
|
130
|
+
client.list_collections() # -> List[str]
|
|
131
|
+
client.delete_collection(name) # -> None
|
|
132
|
+
client.heartbeat() # -> int (nanosecond timestamp)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Collection
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
collection.add(
|
|
139
|
+
ids=None, # auto-generated if omitted
|
|
140
|
+
documents=None, # auto-embedded if provided
|
|
141
|
+
embeddings=None, # or pass pre-computed vectors
|
|
142
|
+
metadatas=None,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
collection.query(
|
|
146
|
+
query_texts=None,
|
|
147
|
+
query_embeddings=None,
|
|
148
|
+
n_results=10,
|
|
149
|
+
where=None, # metadata filter
|
|
150
|
+
)
|
|
151
|
+
# Returns: {"ids": [[...]], "documents": [[...]], "metadatas": [[...]], "distances": [[...]]}
|
|
152
|
+
|
|
153
|
+
collection.get(ids=None, where=None)
|
|
154
|
+
# Returns: {"ids": [...], "documents": [...], "metadatas": [...]}
|
|
155
|
+
|
|
156
|
+
collection.update(ids, documents=None, embeddings=None, metadatas=None)
|
|
157
|
+
collection.upsert(ids, documents=None, embeddings=None, metadatas=None)
|
|
158
|
+
collection.delete(ids=None, where=None)
|
|
159
|
+
collection.count() # -> int
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Bring Your Own Embeddings
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
collection.add(
|
|
166
|
+
ids=["id1"],
|
|
167
|
+
embeddings=[[0.1, 0.2, 0.3, ...]], # your vectors
|
|
168
|
+
documents=["the original text"],
|
|
169
|
+
metadatas=[{"source": "my_model"}],
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
collection.query(
|
|
173
|
+
query_embeddings=[[0.1, 0.2, 0.3, ...]],
|
|
174
|
+
n_results=5,
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Metadata Filtering
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
results = collection.query(
|
|
182
|
+
query_texts=["search term"],
|
|
183
|
+
where={"topic": "python"},
|
|
184
|
+
n_results=5,
|
|
185
|
+
)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## How It Works
|
|
189
|
+
|
|
190
|
+
- **Collections** are namespaced via ID prefixes (`collection_name::doc_id`)
|
|
191
|
+
- **Auto-embedding** uses ZeroDB's free BAAI BGE-M3 model
|
|
192
|
+
- **Storage** is ZeroDB's managed vector database (same infra as ZeroDB MCP)
|
|
193
|
+
- **Credentials** are cached at `~/.zerodb/credentials.json`
|
|
194
|
+
|
|
195
|
+
## Links
|
|
196
|
+
|
|
197
|
+
- [ZeroDB Documentation](https://docs.ainative.studio)
|
|
198
|
+
- [ZeroDB MCP Server](https://pypi.org/project/zerodb-mcp/)
|
|
199
|
+
- [AINative Studio](https://ainative.studio)
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# chromadb-zerodb
|
|
2
|
+
|
|
3
|
+
**Chroma-compatible API backed by ZeroDB cloud. No Docker, no server, instant vector DB.**
|
|
4
|
+
|
|
5
|
+
Drop-in replacement for `chromadb` — same `Collection` API, but vectors are stored in ZeroDB cloud. Auto-provisions on first use. Free tier included.
|
|
6
|
+
|
|
7
|
+
## Why?
|
|
8
|
+
|
|
9
|
+
| | chromadb | chromadb-zerodb |
|
|
10
|
+
|---|---------|----------------|
|
|
11
|
+
| **Setup** | Docker server or in-memory (lost on restart) | `pip install` and go |
|
|
12
|
+
| **Persistence** | Requires server config | Cloud-persisted automatically |
|
|
13
|
+
| **Embeddings** | Bring your own | Free BAAI BGE models included |
|
|
14
|
+
| **Scaling** | Self-managed | Managed infrastructure |
|
|
15
|
+
| **Cost** | Server hosting | Free tier, pay as you grow |
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install chromadb-zerodb
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
import chromadb_zerodb as chromadb
|
|
27
|
+
|
|
28
|
+
# Auto-provisions a free project on first use
|
|
29
|
+
client = chromadb.Client()
|
|
30
|
+
|
|
31
|
+
# Create a collection
|
|
32
|
+
collection = client.create_collection("my_docs")
|
|
33
|
+
|
|
34
|
+
# Add documents (auto-embedded with free BGE models)
|
|
35
|
+
collection.add(
|
|
36
|
+
documents=[
|
|
37
|
+
"Python is a great programming language",
|
|
38
|
+
"JavaScript powers the web",
|
|
39
|
+
"Rust is fast and memory-safe",
|
|
40
|
+
],
|
|
41
|
+
ids=["doc1", "doc2", "doc3"],
|
|
42
|
+
metadatas=[
|
|
43
|
+
{"topic": "python"},
|
|
44
|
+
{"topic": "javascript"},
|
|
45
|
+
{"topic": "rust"},
|
|
46
|
+
],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Query by text
|
|
50
|
+
results = collection.query(
|
|
51
|
+
query_texts=["best language for beginners"],
|
|
52
|
+
n_results=2,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
print(results["documents"]) # [["Python is a great...", "JavaScript powers..."]]
|
|
56
|
+
print(results["distances"]) # [[0.05, 0.12]]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Migration from chromadb
|
|
60
|
+
|
|
61
|
+
Change one import:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
# Before
|
|
65
|
+
import chromadb
|
|
66
|
+
client = chromadb.Client()
|
|
67
|
+
|
|
68
|
+
# After
|
|
69
|
+
import chromadb_zerodb as chromadb
|
|
70
|
+
client = chromadb.Client()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Everything else stays the same.
|
|
74
|
+
|
|
75
|
+
## Authentication
|
|
76
|
+
|
|
77
|
+
Three ways to authenticate (checked in order):
|
|
78
|
+
|
|
79
|
+
1. **Constructor arguments:**
|
|
80
|
+
```python
|
|
81
|
+
client = chromadb.Client(api_key="zdb_...", project_id="proj_...")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. **Environment variables:**
|
|
85
|
+
```bash
|
|
86
|
+
export ZERODB_API_KEY=zdb_...
|
|
87
|
+
export ZERODB_PROJECT_ID=proj_...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
3. **Auto-provision:** If neither is set, a free project is created automatically. Credentials are cached in `~/.zerodb/credentials.json`.
|
|
91
|
+
|
|
92
|
+
## API Reference
|
|
93
|
+
|
|
94
|
+
### Client
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
client = chromadb.Client(api_key=None, project_id=None, base_url=None)
|
|
98
|
+
|
|
99
|
+
client.create_collection(name, metadata=None) # -> Collection
|
|
100
|
+
client.get_collection(name) # -> Collection
|
|
101
|
+
client.get_or_create_collection(name, metadata=None) # -> Collection
|
|
102
|
+
client.list_collections() # -> List[str]
|
|
103
|
+
client.delete_collection(name) # -> None
|
|
104
|
+
client.heartbeat() # -> int (nanosecond timestamp)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Collection
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
collection.add(
|
|
111
|
+
ids=None, # auto-generated if omitted
|
|
112
|
+
documents=None, # auto-embedded if provided
|
|
113
|
+
embeddings=None, # or pass pre-computed vectors
|
|
114
|
+
metadatas=None,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
collection.query(
|
|
118
|
+
query_texts=None,
|
|
119
|
+
query_embeddings=None,
|
|
120
|
+
n_results=10,
|
|
121
|
+
where=None, # metadata filter
|
|
122
|
+
)
|
|
123
|
+
# Returns: {"ids": [[...]], "documents": [[...]], "metadatas": [[...]], "distances": [[...]]}
|
|
124
|
+
|
|
125
|
+
collection.get(ids=None, where=None)
|
|
126
|
+
# Returns: {"ids": [...], "documents": [...], "metadatas": [...]}
|
|
127
|
+
|
|
128
|
+
collection.update(ids, documents=None, embeddings=None, metadatas=None)
|
|
129
|
+
collection.upsert(ids, documents=None, embeddings=None, metadatas=None)
|
|
130
|
+
collection.delete(ids=None, where=None)
|
|
131
|
+
collection.count() # -> int
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Bring Your Own Embeddings
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
collection.add(
|
|
138
|
+
ids=["id1"],
|
|
139
|
+
embeddings=[[0.1, 0.2, 0.3, ...]], # your vectors
|
|
140
|
+
documents=["the original text"],
|
|
141
|
+
metadatas=[{"source": "my_model"}],
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
collection.query(
|
|
145
|
+
query_embeddings=[[0.1, 0.2, 0.3, ...]],
|
|
146
|
+
n_results=5,
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Metadata Filtering
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
results = collection.query(
|
|
154
|
+
query_texts=["search term"],
|
|
155
|
+
where={"topic": "python"},
|
|
156
|
+
n_results=5,
|
|
157
|
+
)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## How It Works
|
|
161
|
+
|
|
162
|
+
- **Collections** are namespaced via ID prefixes (`collection_name::doc_id`)
|
|
163
|
+
- **Auto-embedding** uses ZeroDB's free BAAI BGE-M3 model
|
|
164
|
+
- **Storage** is ZeroDB's managed vector database (same infra as ZeroDB MCP)
|
|
165
|
+
- **Credentials** are cached at `~/.zerodb/credentials.json`
|
|
166
|
+
|
|
167
|
+
## Links
|
|
168
|
+
|
|
169
|
+
- [ZeroDB Documentation](https://docs.ainative.studio)
|
|
170
|
+
- [ZeroDB MCP Server](https://pypi.org/project/zerodb-mcp/)
|
|
171
|
+
- [AINative Studio](https://ainative.studio)
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
MIT
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""Chroma-compatible Client backed by ZeroDB cloud."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, List, Optional
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
from chromadb_zerodb.collection import Collection
|
|
10
|
+
from chromadb_zerodb.provision import auto_provision
|
|
11
|
+
|
|
12
|
+
DEFAULT_BASE_URL = "https://api.ainative.studio"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Client:
|
|
16
|
+
"""Chroma-compatible client backed by ZeroDB cloud storage.
|
|
17
|
+
|
|
18
|
+
Drop-in replacement for ``chromadb.Client()`` — no Docker, no server.
|
|
19
|
+
|
|
20
|
+
Usage::
|
|
21
|
+
|
|
22
|
+
import chromadb_zerodb as chromadb
|
|
23
|
+
|
|
24
|
+
client = chromadb.Client()
|
|
25
|
+
collection = client.create_collection("my_docs")
|
|
26
|
+
collection.add(documents=["hello world"], ids=["id1"])
|
|
27
|
+
results = collection.query(query_texts=["hello"], n_results=5)
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
api_key: Optional[str] = None,
|
|
33
|
+
project_id: Optional[str] = None,
|
|
34
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
35
|
+
):
|
|
36
|
+
self._base_url = base_url.rstrip("/")
|
|
37
|
+
|
|
38
|
+
if api_key and project_id:
|
|
39
|
+
self._api_key = api_key
|
|
40
|
+
self._project_id = project_id
|
|
41
|
+
else:
|
|
42
|
+
self._api_key, self._project_id = auto_provision(self._base_url)
|
|
43
|
+
|
|
44
|
+
self._session = requests.Session()
|
|
45
|
+
self._session.headers.update({
|
|
46
|
+
"Authorization": f"Bearer {self._api_key}",
|
|
47
|
+
"X-Project-ID": self._project_id,
|
|
48
|
+
"Content-Type": "application/json",
|
|
49
|
+
"User-Agent": "chromadb-zerodb/0.1.0",
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
# Track collections as namespace prefixes
|
|
53
|
+
self._collections: Dict[str, Dict[str, Any]] = {}
|
|
54
|
+
|
|
55
|
+
def _request(self, method: str, path: str, **kwargs) -> requests.Response:
|
|
56
|
+
"""Make an authenticated API request."""
|
|
57
|
+
url = f"{self._base_url}{path}"
|
|
58
|
+
resp = self._session.request(method, url, timeout=30, **kwargs)
|
|
59
|
+
resp.raise_for_status()
|
|
60
|
+
return resp
|
|
61
|
+
|
|
62
|
+
def create_collection(
|
|
63
|
+
self,
|
|
64
|
+
name: str,
|
|
65
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
66
|
+
) -> Collection:
|
|
67
|
+
"""Create a new collection (or return existing one).
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
name: Collection name. Used as a namespace prefix in ZeroDB.
|
|
71
|
+
metadata: Optional metadata for the collection.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
A Collection instance.
|
|
75
|
+
"""
|
|
76
|
+
self._collections[name] = {"metadata": metadata or {}}
|
|
77
|
+
return Collection(
|
|
78
|
+
name=name,
|
|
79
|
+
metadata=metadata,
|
|
80
|
+
session=self._session,
|
|
81
|
+
base_url=self._base_url,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def get_collection(self, name: str) -> Collection:
|
|
85
|
+
"""Get an existing collection by name.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
name: Collection name.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
A Collection instance.
|
|
92
|
+
"""
|
|
93
|
+
return Collection(
|
|
94
|
+
name=name,
|
|
95
|
+
metadata=self._collections.get(name, {}).get("metadata"),
|
|
96
|
+
session=self._session,
|
|
97
|
+
base_url=self._base_url,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def get_or_create_collection(
|
|
101
|
+
self,
|
|
102
|
+
name: str,
|
|
103
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
104
|
+
) -> Collection:
|
|
105
|
+
"""Get or create a collection.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
name: Collection name.
|
|
109
|
+
metadata: Optional metadata (used only on creation).
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
A Collection instance.
|
|
113
|
+
"""
|
|
114
|
+
if name not in self._collections:
|
|
115
|
+
return self.create_collection(name, metadata)
|
|
116
|
+
return self.get_collection(name)
|
|
117
|
+
|
|
118
|
+
def list_collections(self) -> List[str]:
|
|
119
|
+
"""List all known collection names.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
List of collection name strings.
|
|
123
|
+
"""
|
|
124
|
+
return list(self._collections.keys())
|
|
125
|
+
|
|
126
|
+
def delete_collection(self, name: str) -> None:
|
|
127
|
+
"""Delete a collection and all its vectors.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
name: Collection name to delete.
|
|
131
|
+
"""
|
|
132
|
+
collection = self.get_collection(name)
|
|
133
|
+
collection._delete_all()
|
|
134
|
+
self._collections.pop(name, None)
|
|
135
|
+
|
|
136
|
+
def heartbeat(self) -> int:
|
|
137
|
+
"""Check connectivity to ZeroDB backend.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
Nanosecond timestamp if healthy.
|
|
141
|
+
"""
|
|
142
|
+
import time
|
|
143
|
+
try:
|
|
144
|
+
self._request("GET", "/health")
|
|
145
|
+
return int(time.time() * 1e9)
|
|
146
|
+
except Exception:
|
|
147
|
+
return 0
|