erioon 0.0.7__py3-none-any.whl → 0.0.9__py3-none-any.whl
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.
- erioon/auth.py +1 -1
- erioon/client.py +73 -78
- erioon/collection.py +215 -127
- erioon/create.py +265 -0
- erioon/database.py +50 -19
- erioon/delete.py +257 -0
- erioon/functions.py +350 -0
- erioon/ping.py +37 -0
- erioon/read.py +241 -0
- erioon/update.py +123 -0
- {erioon-0.0.7.dist-info → erioon-0.0.9.dist-info}/METADATA +1 -1
- erioon-0.0.9.dist-info/RECORD +15 -0
- erioon-0.0.7.dist-info/RECORD +0 -9
- {erioon-0.0.7.dist-info → erioon-0.0.9.dist-info}/LICENSE +0 -0
- {erioon-0.0.7.dist-info → erioon-0.0.9.dist-info}/WHEEL +0 -0
- {erioon-0.0.7.dist-info → erioon-0.0.9.dist-info}/top_level.txt +0 -0
erioon/collection.py
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
import json
|
2
|
-
import
|
2
|
+
from urllib.parse import urlparse
|
3
|
+
from erioon.read import handle_get_all, handle_get_data, handle_classify_vector
|
4
|
+
from erioon.create import handle_insert_one, handle_insert_many, handle_vector, handle_insert_many_vectors
|
5
|
+
from erioon.delete import handle_delete_one, handle_delete_many
|
6
|
+
from erioon.update import handle_update_query
|
7
|
+
from erioon.ping import handle_connection_ping
|
3
8
|
|
4
9
|
class Collection:
|
5
10
|
def __init__(
|
@@ -10,61 +15,76 @@ class Collection:
|
|
10
15
|
metadata,
|
11
16
|
database,
|
12
17
|
cluster,
|
13
|
-
|
18
|
+
sas_url,
|
14
19
|
):
|
20
|
+
|
15
21
|
"""
|
16
|
-
Initialize a Collection
|
22
|
+
Initialize a Collection object that wraps Erioon collection access.
|
17
23
|
|
18
24
|
Args:
|
19
|
-
user_id (str):
|
20
|
-
db_id
|
21
|
-
coll_id (str):
|
22
|
-
metadata (dict):
|
23
|
-
|
25
|
+
user_id (str): The authenticated user's ID.
|
26
|
+
db_id (str): The database ID.
|
27
|
+
coll_id (str): The collection ID.
|
28
|
+
metadata (dict): Metadata info about this collection (e.g., schema, indexing, etc.).
|
29
|
+
database (str): Name or ID of the database.
|
30
|
+
cluster (str): Cluster name or ID hosting the database.
|
31
|
+
sas_url (str): Full SAS URL used to access the storage container.
|
24
32
|
"""
|
33
|
+
|
25
34
|
self.user_id = user_id
|
26
35
|
self.db_id = db_id
|
27
36
|
self.coll_id = coll_id
|
28
37
|
self.metadata = metadata
|
29
|
-
self.database = database
|
38
|
+
self.database = database
|
30
39
|
self.cluster = cluster
|
31
|
-
self.base_url = base_url.rstrip("/")
|
32
40
|
|
33
|
-
|
34
|
-
|
41
|
+
parsed_url = urlparse(sas_url.rstrip("/"))
|
42
|
+
container_name = parsed_url.path.lstrip("/").split("/")[0]
|
43
|
+
account_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
44
|
+
sas_token = parsed_url.query
|
45
|
+
self.container_url = f"{account_url}/{container_name}?{sas_token}"
|
46
|
+
|
47
|
+
def _print_loading(self):
|
48
|
+
"""Prints a loading message (likely for UX in CLI or SDK usage)."""
|
35
49
|
print("Erioon is loading...")
|
36
|
-
|
50
|
+
|
37
51
|
def _is_read_only(self):
|
52
|
+
"""Check if the current database is marked as read-only."""
|
38
53
|
return self.database == "read"
|
54
|
+
|
55
|
+
def _read_only_response(self):
|
56
|
+
"""Standardized error response for blocked write operations."""
|
57
|
+
return "This user is not allowed to perform write operations.", 403
|
39
58
|
|
40
|
-
|
41
|
-
# ---------- READ ---------- #
|
42
|
-
def get_all(self):
|
59
|
+
def get_all(self, limit=1000000):
|
43
60
|
"""
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
61
|
+
Fetch all records from the collection (up to a limit).
|
62
|
+
|
63
|
+
Args:
|
64
|
+
limit (int): Max number of records to fetch.
|
65
|
+
Returns:
|
66
|
+
list: Collection of records.
|
48
67
|
"""
|
49
68
|
self._print_loading()
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
69
|
+
result, status_code = handle_get_all(
|
70
|
+
user_id=self.user_id,
|
71
|
+
db_id=self.db_id,
|
72
|
+
coll_id=self.coll_id,
|
73
|
+
limit=limit,
|
74
|
+
container_url=self.container_url,
|
75
|
+
)
|
76
|
+
return result
|
57
77
|
|
58
78
|
def get_specific(self, filters: dict | None = None, limit: int = 1000):
|
59
79
|
"""
|
60
|
-
|
61
|
-
|
80
|
+
Fetch records that match specific key-value filters.
|
81
|
+
|
62
82
|
Args:
|
63
|
-
filters (dict):
|
64
|
-
limit (int): Max number of
|
83
|
+
filters (dict): Dictionary of exact match filters.
|
84
|
+
limit (int): Max number of matching records to return.
|
65
85
|
|
66
|
-
|
67
|
-
|
86
|
+
Returns:
|
87
|
+
list: Filtered records from the collection.
|
68
88
|
"""
|
69
89
|
if limit > 500_000:
|
70
90
|
raise ValueError("Limit of 500,000 exceeded")
|
@@ -73,137 +93,205 @@ class Collection:
|
|
73
93
|
if filters is None:
|
74
94
|
filters = {}
|
75
95
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
96
|
+
search_criteria = [{k: v} for k, v in filters.items()]
|
97
|
+
print(search_criteria)
|
98
|
+
|
99
|
+
result, status_code = handle_get_data(
|
100
|
+
user_id=self.user_id,
|
101
|
+
db_id=self.db_id,
|
102
|
+
coll_id=self.coll_id,
|
103
|
+
search_criteria=search_criteria,
|
104
|
+
limit=limit,
|
105
|
+
container_url=self.container_url,
|
106
|
+
)
|
107
|
+
return result
|
84
108
|
|
85
|
-
|
86
|
-
def insert_one(self, document: dict):
|
109
|
+
def insert_one(self, record):
|
87
110
|
"""
|
88
|
-
Insert a single
|
111
|
+
Insert a single record into the collection.
|
89
112
|
|
90
113
|
Args:
|
91
|
-
|
114
|
+
record (dict): Record to insert.
|
92
115
|
|
93
|
-
|
94
|
-
|
95
|
-
result = collection.insert_one(new_doc)
|
116
|
+
Returns:
|
117
|
+
tuple: (response message, HTTP status code)
|
96
118
|
"""
|
97
119
|
if self._is_read_only():
|
98
|
-
return
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
120
|
+
return self._read_only_response()
|
121
|
+
return handle_insert_one(
|
122
|
+
user_id_cont=self.user_id,
|
123
|
+
database=self.db_id,
|
124
|
+
collection=self.coll_id,
|
125
|
+
record=record,
|
126
|
+
container_url=self.container_url,
|
127
|
+
)
|
107
128
|
|
108
|
-
def insert_many(self,
|
129
|
+
def insert_many(self, data):
|
109
130
|
"""
|
110
|
-
Insert multiple
|
131
|
+
Insert multiple records into the collection.
|
111
132
|
|
112
133
|
Args:
|
113
|
-
|
134
|
+
data (list of dicts): Multiple records to insert.
|
114
135
|
|
115
|
-
|
116
|
-
|
117
|
-
result = collection.insert_many(docs)
|
136
|
+
Returns:
|
137
|
+
tuple: (response message, HTTP status code)
|
118
138
|
"""
|
119
|
-
self._print_loading()
|
120
139
|
if self._is_read_only():
|
121
|
-
return
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
140
|
+
return self._read_only_response()
|
141
|
+
return handle_insert_many(
|
142
|
+
user_id_cont=self.user_id,
|
143
|
+
database=self.db_id,
|
144
|
+
collection=self.coll_id,
|
145
|
+
data=data,
|
146
|
+
container_url=self.container_url,
|
147
|
+
)
|
130
148
|
|
131
|
-
|
132
|
-
def delete_one(self, filter_query: dict):
|
149
|
+
def delete_one(self, record_to_delete):
|
133
150
|
"""
|
134
|
-
Delete a single
|
151
|
+
Delete a single record based on its _id or nested key.
|
135
152
|
|
136
153
|
Args:
|
137
|
-
|
154
|
+
record_to_delete (dict): Identification of the record.
|
138
155
|
|
139
|
-
|
140
|
-
|
156
|
+
Returns:
|
157
|
+
tuple: (response message, HTTP status code)
|
141
158
|
"""
|
142
159
|
if self._is_read_only():
|
143
|
-
return
|
160
|
+
return self._read_only_response()
|
161
|
+
return handle_delete_one(
|
162
|
+
user_id=self.user_id,
|
163
|
+
db_id=self.db_id,
|
164
|
+
coll_id=self.coll_id,
|
165
|
+
data_to_delete=record_to_delete,
|
166
|
+
container_url=self.container_url,
|
167
|
+
)
|
168
|
+
|
169
|
+
def delete_many(self, records_to_delete_list, batch_size=10):
|
170
|
+
"""
|
171
|
+
Delete multiple records in batches.
|
172
|
+
|
173
|
+
Args:
|
174
|
+
records_to_delete_list (list): List of record identifiers.
|
175
|
+
batch_size (int): How many to delete at once (for efficiency).
|
176
|
+
|
177
|
+
Returns:
|
178
|
+
tuple: (response message, HTTP status code)
|
179
|
+
"""
|
180
|
+
if self._is_read_only():
|
181
|
+
return self._read_only_response()
|
182
|
+
return handle_delete_many(
|
183
|
+
user_id=self.user_id,
|
184
|
+
db_id=self.db_id,
|
185
|
+
coll_id=self.coll_id,
|
186
|
+
data_to_delete_list=records_to_delete_list,
|
187
|
+
batch_size=batch_size,
|
188
|
+
container_url=self.container_url,
|
189
|
+
)
|
190
|
+
|
191
|
+
def update_query(self, filter_query: dict, update_query: dict):
|
192
|
+
"""
|
193
|
+
Update a record in-place by filtering and applying update logic.
|
194
|
+
|
195
|
+
Args:
|
196
|
+
filter_query (dict): Dict describing what record(s) to match.
|
197
|
+
update_query (dict): Dict describing update operators ($set, $push, $remove).
|
198
|
+
|
199
|
+
Returns:
|
200
|
+
tuple: (response message, HTTP status code)
|
201
|
+
"""
|
202
|
+
if self._is_read_only():
|
203
|
+
return self._read_only_response()
|
204
|
+
return handle_update_query(
|
205
|
+
user_id=self.user_id,
|
206
|
+
db_id=self.db_id,
|
207
|
+
coll_id=self.coll_id,
|
208
|
+
filter_query=filter_query,
|
209
|
+
update_query=update_query,
|
210
|
+
container_url=self.container_url,
|
211
|
+
)
|
144
212
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
response.raise_for_status()
|
149
|
-
return response.json()
|
150
|
-
except requests.HTTPError as e:
|
151
|
-
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
213
|
+
def ping(self):
|
214
|
+
"""
|
215
|
+
Health check / ping to verify collection accessibility.
|
152
216
|
|
153
|
-
|
217
|
+
Returns:
|
218
|
+
tuple: (response message, HTTP status code)
|
154
219
|
"""
|
155
|
-
|
220
|
+
return handle_connection_ping(
|
221
|
+
user_id=self.user_id,
|
222
|
+
db_id=self.db_id,
|
223
|
+
coll_id=self.coll_id,
|
224
|
+
container_url=self.container_url,
|
225
|
+
)
|
226
|
+
|
227
|
+
def insert_one_vector(self, vector_data, metadata):
|
228
|
+
"""
|
229
|
+
Insert a single record into the collection.
|
156
230
|
|
157
231
|
Args:
|
158
|
-
|
232
|
+
record (dict): Record to insert.
|
159
233
|
|
160
|
-
|
161
|
-
|
234
|
+
Returns:
|
235
|
+
tuple: (response message, HTTP status code)
|
162
236
|
"""
|
163
|
-
self._print_loading()
|
164
237
|
if self._is_read_only():
|
165
|
-
return
|
238
|
+
return self._read_only_response()
|
239
|
+
return handle_vector(
|
240
|
+
user_id_cont=self.user_id,
|
241
|
+
database=self.db_id,
|
242
|
+
collection=self.coll_id,
|
243
|
+
vector=vector_data,
|
244
|
+
metadata=metadata,
|
245
|
+
container_url=self.container_url,
|
246
|
+
)
|
166
247
|
|
167
|
-
|
168
|
-
response = requests.delete(url, json=filter_query)
|
169
|
-
try:
|
170
|
-
response.raise_for_status()
|
171
|
-
return response.json()
|
172
|
-
except requests.HTTPError as e:
|
173
|
-
return {"status": "KO", "error": str(e), "response": response.json() if response.content else {}}
|
174
|
-
|
175
|
-
# ---------- UPDATE ---------- #
|
176
|
-
def update_query(self, filter_query: dict, update_query: dict):
|
248
|
+
def insert_many_vectors(self, records):
|
177
249
|
"""
|
178
|
-
|
250
|
+
Insert multiple vector records into the collection.
|
179
251
|
|
180
252
|
Args:
|
181
|
-
|
182
|
-
update_query (dict): Update operations to apply.
|
253
|
+
records (list): List of dicts, each with keys 'vector', 'metadata', and optional '_id'.
|
183
254
|
|
184
|
-
|
185
|
-
|
186
|
-
{"age": {"$gt": 30}},
|
187
|
-
{"$set": {"status": "senior"}}
|
188
|
-
)
|
255
|
+
Returns:
|
256
|
+
tuple: (response message, HTTP status code)
|
189
257
|
"""
|
190
|
-
self._print_loading()
|
191
258
|
if self._is_read_only():
|
192
|
-
return
|
259
|
+
return self._read_only_response()
|
260
|
+
|
261
|
+
return handle_insert_many_vectors(
|
262
|
+
user_id_cont=self.user_id,
|
263
|
+
database=self.db_id,
|
264
|
+
collection=self.coll_id,
|
265
|
+
records=records,
|
266
|
+
container_url=self.container_url,
|
267
|
+
)
|
193
268
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
269
|
+
def classify_vector(self, k=3):
|
270
|
+
"""
|
271
|
+
Retrieve all vector records from the collection and classify them using k-NN.
|
272
|
+
|
273
|
+
Args:
|
274
|
+
k (int): Number of neighbors to use for classification.
|
275
|
+
|
276
|
+
Returns:
|
277
|
+
tuple: (response message, HTTP status code)
|
278
|
+
"""
|
279
|
+
if self._is_read_only():
|
280
|
+
return self._read_only_response()
|
281
|
+
|
282
|
+
return handle_classify_vector(
|
283
|
+
user_id=self.user_id,
|
284
|
+
db_id=self.db_id,
|
285
|
+
coll_id=self.coll_id,
|
286
|
+
container_url=self.container_url,
|
287
|
+
k=k
|
288
|
+
)
|
289
|
+
|
290
|
+
|
291
|
+
def __str__(self):
|
292
|
+
"""Pretty print the collection metadata."""
|
205
293
|
return json.dumps(self.metadata, indent=4)
|
206
294
|
|
207
|
-
def __repr__(self)
|
208
|
-
"""
|
295
|
+
def __repr__(self):
|
296
|
+
"""Simplified representation for debugging or introspection."""
|
209
297
|
return f"<Collection coll_id={self.coll_id}>"
|