ahnlich-client-py 0.0.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.
- ahnlich_client_py-0.0.0/PKG-INFO +708 -0
- ahnlich_client_py-0.0.0/README.md +690 -0
- ahnlich_client_py-0.0.0/VERSION +2 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/__init__.py +5 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/builders/__init__.py +10 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/builders/ai.py +174 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/builders/db.py +163 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/builders/non_blocking/__init__.py +2 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/builders/non_blocking/ai.py +16 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/builders/non_blocking/db.py +16 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/clients/__init__.py +2 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/clients/ai.py +224 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/clients/db.py +224 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/clients/non_blocking/__init__.py +2 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/clients/non_blocking/ai.py +226 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/clients/non_blocking/db.py +225 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/config.py +18 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/exceptions.py +10 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/__init__.py +0 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/ai_query.py +532 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/ai_response.py +461 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/async_base_client.py +90 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/base_client.py +84 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/bincode/__init__.py +77 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/db_query.py +381 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/db_response.py +340 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/pool_wrapper.py +46 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/protocol.py +143 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/serde_binary/__init__.py +418 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/internals/serde_types/__init__.py +75 -0
- ahnlich_client_py-0.0.0/ahnlich_client_py/libs.py +23 -0
- ahnlich_client_py-0.0.0/pyproject.toml +43 -0
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ahnlich-client-py
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: A python client for interacting with Ahnlich DB and AI
|
|
5
|
+
Author: David Onuh
|
|
6
|
+
Author-email: davidonuh1@gmail.com
|
|
7
|
+
Requires-Python: >=3.11,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Requires-Dist: bump2version (>=1.0.1,<2.0.0)
|
|
12
|
+
Requires-Dist: generic-connection-pool (>=0.7.0,<0.8.0)
|
|
13
|
+
Requires-Dist: numpy (>=1.26.4,<2.0.0)
|
|
14
|
+
Requires-Dist: pytest-asyncio (>=0.24.0,<0.25.0)
|
|
15
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
## Ahnlich Client PY
|
|
19
|
+
|
|
20
|
+
A Python client that interacts with both ahnlich DB and AI
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
[](https://github.com/deven96/ahnlich/actions/workflows/test.yml)
|
|
24
|
+
[](https://github.com/deven96/ahnlich/actions/workflows/python_tag_and_deploy.yml)
|
|
25
|
+
|
|
26
|
+
## Usage Overview
|
|
27
|
+
|
|
28
|
+
The following topics are covered:
|
|
29
|
+
* [Installation](#installation)
|
|
30
|
+
* [Package Information](#package-information)
|
|
31
|
+
* [Server Response](#server-response)
|
|
32
|
+
* [Initialization](#initialization)
|
|
33
|
+
* [Client](#client)
|
|
34
|
+
|
|
35
|
+
* [Connection Pooling](#connection-pooling)
|
|
36
|
+
* [Requests - DB](#requests---db)
|
|
37
|
+
* [Ping](#ping)
|
|
38
|
+
* [Info Server](#info-server)
|
|
39
|
+
* [List Connected Clients](#list-connected-clients)
|
|
40
|
+
* [List Stores](#list-stores)
|
|
41
|
+
* [Create Store](#create-store)
|
|
42
|
+
* [Set](#set)
|
|
43
|
+
* [Drop Store](#drop-store)
|
|
44
|
+
* [Get Sim N](#get-sim-n)
|
|
45
|
+
* [Get Key](#get-key)
|
|
46
|
+
* [Get By Predicate](#get-by-predicate)
|
|
47
|
+
* [Create Predicate Index](#create-predicate-index)
|
|
48
|
+
* [Drop Predicate Index](#drop-predicate-index)
|
|
49
|
+
* [Create Non Linear Algorithm Index](#create-non-linear-algorithm-index)
|
|
50
|
+
* [Drop Non Linear Algorithm Index](#drop-non-linear-algorithm-index)
|
|
51
|
+
* [Delete Key](#delete-key)
|
|
52
|
+
* [Delete Predicate](#delete-predicate)
|
|
53
|
+
|
|
54
|
+
* [Requests - AI](#requests---ai)
|
|
55
|
+
* [Ping](#ping-1)
|
|
56
|
+
* [Info Server](#info-server-1)
|
|
57
|
+
* [List Stores](#list-stores-1)
|
|
58
|
+
* [Create Store](#create-store-1)
|
|
59
|
+
* [Set](#set-1)
|
|
60
|
+
* [Drop Store](#drop-store-1)
|
|
61
|
+
* [Get Sim N](#get-sim-n-1)
|
|
62
|
+
* [Get By Predicate](#get-by-predicate-1)
|
|
63
|
+
* [Create Predicate Index](#create-predicate-index-1)
|
|
64
|
+
* [Drop Predicate Index](#drop-predicate-index-1)
|
|
65
|
+
* [Create Non Linear Algorithm Index](#create-non-linear-algorithm-index-1)
|
|
66
|
+
* [Drop Non Linear Algorithm Index](#drop-non-linear-algorithm-index-1)
|
|
67
|
+
* [Delete Key](#delete-key-1)
|
|
68
|
+
|
|
69
|
+
* [Bulk Requests](#bulk-requests)
|
|
70
|
+
* [Client As Context Manager](#client-as-context-manager)
|
|
71
|
+
* [How to Deploy to Artifactory](#deploy-to-artifactory)
|
|
72
|
+
* [Type Meanings](#type-meanings)
|
|
73
|
+
* [Change Log](#change-log)
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
76
|
+
|
|
77
|
+
- Using Poetry
|
|
78
|
+
```bash
|
|
79
|
+
poetry add ahnlich-client-py
|
|
80
|
+
```
|
|
81
|
+
- Using pip
|
|
82
|
+
```bash
|
|
83
|
+
pip3 install ahnlich-client-py
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Package Information
|
|
87
|
+
The ahnlich client has some noteworthy modules that should provide some context
|
|
88
|
+
- Bincode
|
|
89
|
+
- Serde Types
|
|
90
|
+
- Serde Binary
|
|
91
|
+
|
|
92
|
+
The above mentioned are classes generated by `serde_generate` to help represent the primitive rust types and provide a base bincode serialization capabilities
|
|
93
|
+
|
|
94
|
+
- Query: Generated from the spec document, contains all the types used by to send a request to the ahnlich database
|
|
95
|
+
- Server Response: Generated from the spec document, contains all the possible server response.
|
|
96
|
+
- Builders:
|
|
97
|
+
- Exceptions: Possible Client Exceptions
|
|
98
|
+
- Libs: Contains helpers, such as `create_store_key`
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## Server Response
|
|
102
|
+
|
|
103
|
+
All query types have an associating server response, all which can be found
|
|
104
|
+
```py
|
|
105
|
+
from ahnlich_client_py import server_response
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Initialization
|
|
109
|
+
|
|
110
|
+
### Client
|
|
111
|
+
|
|
112
|
+
- Blocking clients
|
|
113
|
+
```py
|
|
114
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
115
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
116
|
+
```
|
|
117
|
+
- Nonblocking clients
|
|
118
|
+
```py
|
|
119
|
+
from ahnlich_client_py.non_blocking_client import AhnlichDBClient
|
|
120
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Connection Pooling
|
|
124
|
+
|
|
125
|
+
The ahnlich client has the ability to reuse connections. Configurations can be changed by overiding the default class initialization.
|
|
126
|
+
|
|
127
|
+
```py
|
|
128
|
+
|
|
129
|
+
@dataclass
|
|
130
|
+
class AhnlichDBPoolSettings:
|
|
131
|
+
idle_timeout: float = 30.0
|
|
132
|
+
max_lifetime: float = 600.0
|
|
133
|
+
min_idle_connections: int = 3
|
|
134
|
+
max_pool_size: int = 10
|
|
135
|
+
enable_background_collector: bool = True
|
|
136
|
+
dispose_batch_size: int = 0
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Where:
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
- **enable_background_collector** -> `defaults 1`: if True starts a background worker that disposes expired and idle connections maintaining requested pool state. If False the connections will be disposed on each connection release.
|
|
143
|
+
|
|
144
|
+
- **idle_timeout** -> `defaults 30.0`: inactivity time (`in seconds`) after which an extra connection will be disposed (a connection considered as extra if the number of endpoint connection exceeds min_idle).
|
|
145
|
+
|
|
146
|
+
- **max_lifetime** -> `defaults 600.0`: number of seconds after which any connection will be disposed.
|
|
147
|
+
|
|
148
|
+
- **min_idle_connections** -> `default 3`: minimum number of connections for the ahnlich db endpoint the pool tries to hold. Connections that exceed that number will be considered as extra and disposed after idle_timeout seconds of inactivity.
|
|
149
|
+
|
|
150
|
+
- **max_pool_size** -> `defaults 10`: maximum number of connections in the pool.
|
|
151
|
+
|
|
152
|
+
- **dispose_batch_size**: maximum number of expired and idle connections to be disposed on connection release (if background collector is started the parameter is ignored).
|
|
153
|
+
|
|
154
|
+
## Requests - DB
|
|
155
|
+
|
|
156
|
+
### Ping
|
|
157
|
+
|
|
158
|
+
```py
|
|
159
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
160
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
161
|
+
|
|
162
|
+
tracing_id = "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01"
|
|
163
|
+
response = client.ping(tracing_id)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Info Server
|
|
167
|
+
|
|
168
|
+
```py
|
|
169
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
170
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
171
|
+
|
|
172
|
+
response = client.info_server()
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### List Connected Clients
|
|
176
|
+
|
|
177
|
+
```py
|
|
178
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
179
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
180
|
+
|
|
181
|
+
response = client.list_clients()
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### List Stores
|
|
185
|
+
|
|
186
|
+
```py
|
|
187
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
188
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
189
|
+
|
|
190
|
+
tracing_id = "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01"
|
|
191
|
+
response = client.list_stores(tracing_id)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Create Store
|
|
195
|
+
|
|
196
|
+
```py
|
|
197
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
198
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
199
|
+
|
|
200
|
+
response = client.create_store(
|
|
201
|
+
store_name = "test store",
|
|
202
|
+
dimension = 5,
|
|
203
|
+
create_predicates = [
|
|
204
|
+
"job"
|
|
205
|
+
],
|
|
206
|
+
error_if_exists=True
|
|
207
|
+
)
|
|
208
|
+
```
|
|
209
|
+
Once store dimension is fixed, all `store_keys` must confirm with said dimension.
|
|
210
|
+
Note we only accept 1 dimensional arrays/vectors of length N.
|
|
211
|
+
Store dimensions is a one dimensional array of length N
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
### Set
|
|
215
|
+
```py
|
|
216
|
+
from libs import create_store_key
|
|
217
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
218
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
219
|
+
|
|
220
|
+
store_key = create_store_key(data=[5.0, 3.0, 4.0, 3.9, 4.9])
|
|
221
|
+
store_value = {"rank": query.MetadataValue__RawString(value="chunin")}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
response = client.set(
|
|
225
|
+
store_name = "test store",
|
|
226
|
+
inputs=[(store_key, store_value)]
|
|
227
|
+
)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
### Drop store
|
|
232
|
+
```py
|
|
233
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
234
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
235
|
+
|
|
236
|
+
response = client.drop_store(
|
|
237
|
+
store_name = "test store",
|
|
238
|
+
error_if_not_exists=True
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
### Get Sim N
|
|
246
|
+
Returns an array of tuple of (store_key, store_value) of Maximum specified N
|
|
247
|
+
|
|
248
|
+
```py
|
|
249
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
250
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
response = client.get_sim_n(
|
|
255
|
+
store_name = "test store",
|
|
256
|
+
search_input = key,
|
|
257
|
+
closest_n = 3,
|
|
258
|
+
algorithm = query.Algorithm__CosineSimilarity(),
|
|
259
|
+
condition = None,
|
|
260
|
+
tracing_id=None,
|
|
261
|
+
)
|
|
262
|
+
```
|
|
263
|
+
<u>*Closest_n is a Nonzero integer value*</u>
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
### Get Key
|
|
268
|
+
Returns an array of tuple of (store_key, store_value)
|
|
269
|
+
|
|
270
|
+
```py
|
|
271
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
272
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
273
|
+
|
|
274
|
+
key = some_store_key
|
|
275
|
+
response = client.get_key(
|
|
276
|
+
store_name = "test store",
|
|
277
|
+
keys=[key]
|
|
278
|
+
)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
### Get By Predicate
|
|
283
|
+
Same as Get_key but returns results based defined conditions
|
|
284
|
+
|
|
285
|
+
```py
|
|
286
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
287
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
288
|
+
|
|
289
|
+
condition = query.PredicateCondition__Value(
|
|
290
|
+
query.Predicate__Equals(
|
|
291
|
+
key="job",
|
|
292
|
+
value=query.MetadataValue__RawString(value="sorcerer")
|
|
293
|
+
)
|
|
294
|
+
)
|
|
295
|
+
response = client.get_by_predicate(
|
|
296
|
+
store_name = "test store",
|
|
297
|
+
condition=conditon
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Create Predicate Index
|
|
302
|
+
```py
|
|
303
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
304
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
305
|
+
|
|
306
|
+
response = client.create_pred_index(
|
|
307
|
+
store_name = "test store",
|
|
308
|
+
predicates=["job", "rank"]
|
|
309
|
+
)
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Drop Predicate Index
|
|
313
|
+
```py
|
|
314
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
315
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
316
|
+
|
|
317
|
+
response = client.drop_pred_index(
|
|
318
|
+
store_name = "test store",
|
|
319
|
+
predicates=["job"],
|
|
320
|
+
error_if_not_exists=True
|
|
321
|
+
)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Create Non Linear Algorithm Index
|
|
325
|
+
```py
|
|
326
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
327
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
328
|
+
|
|
329
|
+
response = client.create_non_linear_algorithm_index(
|
|
330
|
+
store_name = "test store",
|
|
331
|
+
non_linear_indices=[NonLinearAlgorithm__KDTree],
|
|
332
|
+
tracing_id = None
|
|
333
|
+
)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Drop Non Linear Algorithm Index
|
|
337
|
+
```py
|
|
338
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
339
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
340
|
+
|
|
341
|
+
response = client.drop_non_linear_algorithm_index(
|
|
342
|
+
store_name = "test store",
|
|
343
|
+
non_linear_indices=[NonLinearAlgorithm__KDTree],
|
|
344
|
+
error_if_not_exists=True,
|
|
345
|
+
tracing_id = None
|
|
346
|
+
)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
### Delete Key
|
|
351
|
+
```py
|
|
352
|
+
from ahnlich_client_py.libs import create_store_key
|
|
353
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
354
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
store_key = create_store_key(data=[5.0, 3.0, 4.0, 3.9, 4.9])
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
response = client.delete_key(
|
|
362
|
+
store_name = "test store",
|
|
363
|
+
keys=[store_key]
|
|
364
|
+
)
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Delete Predicate
|
|
368
|
+
```py
|
|
369
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
370
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
371
|
+
|
|
372
|
+
condition = query.PredicateCondition__Value(
|
|
373
|
+
query.Predicate__Equals(
|
|
374
|
+
key="job",
|
|
375
|
+
value=query.MetadataValue__RawString(value="sorcerer")
|
|
376
|
+
)
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
response = client.delete_predicate(
|
|
381
|
+
store_name = "test store",
|
|
382
|
+
condition = condition
|
|
383
|
+
)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
## Requests - AI
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
### Ping
|
|
391
|
+
|
|
392
|
+
```py
|
|
393
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
394
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
395
|
+
|
|
396
|
+
response = client.ping(tracing_id)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Info Server
|
|
400
|
+
|
|
401
|
+
```py
|
|
402
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
403
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
404
|
+
|
|
405
|
+
response = client.info_server(tracing_id)
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### List Stores
|
|
409
|
+
|
|
410
|
+
```py
|
|
411
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
412
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
413
|
+
|
|
414
|
+
response = client.list_stores(tracing_id)
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Create Store
|
|
418
|
+
|
|
419
|
+
```py
|
|
420
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
421
|
+
from ahnlich_client_py.internals import ai_query
|
|
422
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
423
|
+
|
|
424
|
+
response = client.create_store(
|
|
425
|
+
store_name = "test store",
|
|
426
|
+
model = ai_query.AIModel__AllMiniLML6V2(),
|
|
427
|
+
store_type = ai_query.AIStoreType__RawString(),
|
|
428
|
+
predicates = [
|
|
429
|
+
"job"
|
|
430
|
+
],
|
|
431
|
+
non_linear_indices= [],
|
|
432
|
+
error_if_exists = True,
|
|
433
|
+
# Store original controls if we choose to store the raw inputs
|
|
434
|
+
# within the DB in order to be able to retrieve the originals again
|
|
435
|
+
# during query, else only store values are returned
|
|
436
|
+
store_original = True,
|
|
437
|
+
tracing_id=None,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
### Set
|
|
444
|
+
```py
|
|
445
|
+
|
|
446
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
447
|
+
from ahnlich_client_py.internals import ai_query
|
|
448
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
449
|
+
|
|
450
|
+
store_inputs = [
|
|
451
|
+
(
|
|
452
|
+
ai_query.StoreInput__RawString("Jordan One"),
|
|
453
|
+
{"brand": ai_query.MetadataValue__RawString("Nike")},
|
|
454
|
+
),
|
|
455
|
+
(
|
|
456
|
+
ai_query.StoreInput__RawString("Yeezey"),
|
|
457
|
+
{"brand": ai_query.MetadataValue__RawString("Adidas")},
|
|
458
|
+
),
|
|
459
|
+
]
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
response = client.set(
|
|
463
|
+
store_name = "test store",
|
|
464
|
+
inputs=store_inputs,
|
|
465
|
+
tracing_id=None
|
|
466
|
+
)
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
### Drop store
|
|
471
|
+
```py
|
|
472
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
473
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
474
|
+
|
|
475
|
+
response = client.drop_store(
|
|
476
|
+
store_name = "test store",
|
|
477
|
+
error_if_not_exists=True,
|
|
478
|
+
tracing_id=None
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
### Get Sim N
|
|
486
|
+
Returns an array of tuple of (store_key, store_value) of Maximum specified N
|
|
487
|
+
|
|
488
|
+
```py
|
|
489
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
490
|
+
from ahnlich_client_py.internals import ai_query
|
|
491
|
+
|
|
492
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
search_input = ai_query.StoreInput__RawString("Jordan")
|
|
496
|
+
|
|
497
|
+
response = client.get_sim_n(
|
|
498
|
+
store_name = "test store",
|
|
499
|
+
search_input = search_input,
|
|
500
|
+
closest_n = 3,
|
|
501
|
+
algorithm = query.Algorithm__CosineSimilarity(),
|
|
502
|
+
condition = None,
|
|
503
|
+
tracing_id=None
|
|
504
|
+
)
|
|
505
|
+
```
|
|
506
|
+
<u>*Closest_n is a Nonzero integer value*</u>
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
### Get By Predicate
|
|
510
|
+
Same as Get_key but returns results based defined conditions
|
|
511
|
+
|
|
512
|
+
```py
|
|
513
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
514
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
515
|
+
|
|
516
|
+
condition = query.PredicateCondition__Value(
|
|
517
|
+
query.Predicate__Equals(
|
|
518
|
+
key="brand",
|
|
519
|
+
value=query.MetadataValue__RawString(value="Nike")
|
|
520
|
+
)
|
|
521
|
+
)
|
|
522
|
+
response = client.get_by_predicate(
|
|
523
|
+
store_name = "test store",
|
|
524
|
+
condition=conditon,
|
|
525
|
+
tracing_id=None,
|
|
526
|
+
)
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### Create Predicate Index
|
|
530
|
+
```py
|
|
531
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
532
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
533
|
+
|
|
534
|
+
response = client.create_pred_index(
|
|
535
|
+
store_name = "test store",
|
|
536
|
+
predicates=["job", "rank"],
|
|
537
|
+
tracing_id=None,
|
|
538
|
+
)
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Drop Predicate Index
|
|
542
|
+
```py
|
|
543
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
544
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
545
|
+
|
|
546
|
+
response = client.drop_pred_index(
|
|
547
|
+
store_name = "test store",
|
|
548
|
+
predicates=["job"],
|
|
549
|
+
error_if_not_exists=True,
|
|
550
|
+
tracing_id=None,
|
|
551
|
+
)
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### Create Non Linear Algorithm Index
|
|
555
|
+
```py
|
|
556
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
557
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
558
|
+
|
|
559
|
+
response = client.create_non_linear_algorithm_index(
|
|
560
|
+
store_name = "test store",
|
|
561
|
+
non_linear_indices=[NonLinearAlgorithm__KDTree],
|
|
562
|
+
tracing_id = None
|
|
563
|
+
)
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Drop Non Linear Algorithm Index
|
|
567
|
+
```py
|
|
568
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
569
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
570
|
+
|
|
571
|
+
response = client.drop_non_linear_algorithm_index(
|
|
572
|
+
store_name = "test store",
|
|
573
|
+
non_linear_indices=[NonLinearAlgorithm__KDTree],
|
|
574
|
+
error_if_not_exists=True,
|
|
575
|
+
tracing_id = None
|
|
576
|
+
)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
### Delete Key
|
|
582
|
+
```py
|
|
583
|
+
|
|
584
|
+
from ahnlich_client_py import AhnlichAIClient
|
|
585
|
+
client = AhnlichAIClient(address="127.0.0.1", port=port)
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
key = ai_query.StoreInput__RawString("Custom Made Jordan 4")
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
response = client.delete_key(
|
|
593
|
+
store_name = "test store",
|
|
594
|
+
keys=[key],
|
|
595
|
+
tracing_id=None
|
|
596
|
+
)
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
## Bulk Requests
|
|
602
|
+
Clients have the ability to send multiple requests at once, and these requests will be handled sequentially. The builder class takes care of this. The response is a list of all individual request responses.
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
```py
|
|
606
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
607
|
+
client = AhnlichDBClient(address="127.0.0.1", port=port)
|
|
608
|
+
|
|
609
|
+
request_builder = client.pipeline()
|
|
610
|
+
request_builder.ping()
|
|
611
|
+
request_builder.info_server()
|
|
612
|
+
request_builder.list_clients()
|
|
613
|
+
request_builder.list_stores()
|
|
614
|
+
|
|
615
|
+
response: server_response.ServerResult = client.exec()
|
|
616
|
+
```
|
|
617
|
+
*Sample applies to the AIclient*
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
## Client As Context Manager
|
|
621
|
+
|
|
622
|
+
The DB and AI client class can be used as a context manager hereby closing the connection pool automatically upon context end.
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
```py
|
|
626
|
+
from ahnlich_client_py import AhnlichDBClient
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
with client.AhnlichDBClient(address="127.0.0.1", port=port) as db_client:
|
|
630
|
+
response: server_response.ServerResult = db_client.ping()
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
However, closing the connection pool can be done by calling `cleanup()` on the client.
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
## Deploy to Artifactory
|
|
638
|
+
|
|
639
|
+
Replace the contents of `MSG_TAG` file with your new tag message
|
|
640
|
+
|
|
641
|
+
From Feature branch, either use the makefile :
|
|
642
|
+
```bash
|
|
643
|
+
make bump-py-client BUMP_RULE=[major, minor, patch]
|
|
644
|
+
```
|
|
645
|
+
or
|
|
646
|
+
```bash
|
|
647
|
+
poetry run bumpversion [major, minor, patch]
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
When Your PR is made, changes in the client version file would trigger a release build to Pypi
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
## Type Meanings
|
|
654
|
+
|
|
655
|
+
- Store Key: A one dimensional vector
|
|
656
|
+
- Store Value: A Dictionary containing texts or binary associated with a storekey
|
|
657
|
+
- Store Predicates: Or Predicate indices are basically indices that improves the filtering of store_values
|
|
658
|
+
- Predicates: These are operations that can be used to filter data(Equals, NotEquals, Contains, etc)
|
|
659
|
+
- PredicateConditions: They are conditions that utilize one predicate or tie Multiple predicates together using the AND, OR or Value operation. Where Value means just a predicate.
|
|
660
|
+
Example:
|
|
661
|
+
Value
|
|
662
|
+
```py
|
|
663
|
+
condition = db_query.PredicateCondition__Value(
|
|
664
|
+
db_query.Predicate__Equals(key="job", value=db_query.MetadataValue__RawString(value="sorcerer"))
|
|
665
|
+
)
|
|
666
|
+
```
|
|
667
|
+
Metadatavalue can also be a binary(list of u8s)
|
|
668
|
+
|
|
669
|
+
```py
|
|
670
|
+
condition = db_query.PredicateCondition__Value(
|
|
671
|
+
db_query.Predicate__Equals(key="image_data", value=db_query.MetadataValue__Image(value=[2,2,3,4,5,6,7]))
|
|
672
|
+
)
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
AND
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
```py
|
|
681
|
+
# And[tuples[predicate_conditions]]
|
|
682
|
+
condition = db_query.PredicateCondition__AND(
|
|
683
|
+
(
|
|
684
|
+
db_query.PredicateCondition__Value(
|
|
685
|
+
db_query.Predicate__Equals(key="job", db_query.MetadataValue__RawString(value="sorcerer"))
|
|
686
|
+
),
|
|
687
|
+
db_query.PredicateCondition__Value(
|
|
688
|
+
db_query.Predicate__Equals(key="rank", value=db_query.MetadataValue__RawString(value="chunin"))
|
|
689
|
+
)
|
|
690
|
+
)
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
- Search Input: A string or binary file that can be stored by the aiproxy. Note, the binary file depends on the supported models used in a store or supported by Ahnlich AI
|
|
696
|
+
|
|
697
|
+
- AIModels: Supported AI models used by ahnlich ai
|
|
698
|
+
- AIStoreType: A type of store to be created. Either a Binary or String
|
|
699
|
+
|
|
700
|
+
## Change Log
|
|
701
|
+
|
|
702
|
+
| Version| Description |
|
|
703
|
+
| -------|:-------------:|
|
|
704
|
+
| 0.0.0 | Base Python clients (Async and Sync) to connect to ahnlich db and AI, with connection pooling and Bincode serialization and deserialization |
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|