Skip to content

Commit 059c76b

Browse files
Merge pull request #41 from epsilla-cloud/auto-embedding
Support auto embedding
2 parents d0973bc + eea2779 commit 059c76b

File tree

6 files changed

+211
-15
lines changed

6 files changed

+211
-15
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python
2+
# -*- coding:utf-8 -*-
3+
4+
# Try this simple example for epsilla cloud
5+
# 1. create project and db on epsilla cloud
6+
# 2. create a table with schema in db
7+
# 3. get the api key with project id, run this program
8+
9+
import sys
10+
11+
from pyepsilla import cloud
12+
13+
# Connect to Epsilla Cloud
14+
client = cloud.Client(
15+
project_id="7a68814c-f839-4a67-9ec6-93c027c865e6",
16+
api_key="epsilla-cloud-api-key",
17+
)
18+
19+
# Connect to Vectordb
20+
db = client.vectordb(db_id="6accafb1-476d-43b0-aa64-12ebfbf7442d")
21+
22+
23+
# Create a table with schema
24+
status_code, response = db.create_table(
25+
table_name="MyTable",
26+
table_fields=[
27+
{"name": "ID", "dataType": "INT", "primaryKey": True},
28+
{"name": "Doc", "dataType": "STRING"},
29+
],
30+
indices=[
31+
{"name": "Index", "field": "Doc"},
32+
]
33+
)
34+
print(status_code, response)
35+
36+
37+
# Insert new vector records into table
38+
status_code, response = db.insert(
39+
table_name="MyTable",
40+
records=[
41+
{"ID": 1, "Doc": "The garden was blooming with vibrant flowers, attracting butterflies and bees with their sweet nectar."},
42+
{"ID": 2, "Doc": "In the busy city streets, people rushed to and fro, hardly noticing the beauty of the day."},
43+
{"ID": 3, "Doc": "The library was a quiet haven, filled with the scent of old books and the soft rustling of pages."},
44+
{"ID": 4, "Doc": "High in the mountains, the air was crisp and clear, revealing breathtaking views of the valley below."},
45+
{"ID": 5, "Doc": "At the beach, children played joyfully in the sand, building castles and chasing the waves."},
46+
{"ID": 6, "Doc": "Deep in the forest, a deer cautiously stepped out, its ears alert for any signs of danger."},
47+
{"ID": 7, "Doc": "The old town's historical architecture spoke volumes about its rich cultural past."},
48+
{"ID": 8, "Doc": "Night fell, and the sky was a canvas of stars, shining brightly in the moon's soft glow."},
49+
{"ID": 9, "Doc": "A cozy cafe on the corner served the best hot chocolate, warming the hands and hearts of its visitors."},
50+
{"ID": 10, "Doc": "The artist's studio was cluttered but inspiring, filled with unfinished canvases and vibrant paints."},
51+
],
52+
)
53+
print(status_code, response)
54+
55+
# Query Vectors with specific response field, otherwise it will return all fields
56+
status_code, response = db.query(
57+
table_name="MyTable",
58+
query_text="Where can I find a serene environment, ideal for relaxation and introspection?",
59+
)
60+
print(status_code, response)
61+
62+
63+
# Delete specific records from table
64+
status_code, response = db.delete(table_name="MyTable", primary_keys=[4, 5])
65+
status_code, response = db.delete(table_name="MyTable", filter="Doc <> 'A cozy cafe on the corner served the best hot chocolate, warming the hands and hearts of its visitors.'")
66+
print(status_code, response)
67+
68+
# Drop table
69+
status_code, response = db.drop_table(table_name="MyTable")
70+
print(status_code, response)
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env python
2+
# -*- coding:utf-8 -*-
3+
4+
# Try this simple example
5+
# 1. docker run --pull=always -d -p 8888:8888 epsilla/vectordb
6+
# 2. pip3 install --upgrade pyepsilla
7+
# 3. python3 simple_example.py
8+
#
9+
10+
from pyepsilla import vectordb
11+
12+
# Connect to Epsilla VectorDB
13+
client = vectordb.Client(protocol="http", host="127.0.0.1", port="8888")
14+
15+
# You can also use Epsilla Cloud
16+
# client = vectordb.Client(protocol='https', host='demo.epsilla.com', port='443')
17+
18+
# Load DB with path
19+
## pay attention to change db_path to persistent volume for production environment
20+
status_code, response = client.load_db(db_name="MyDB", db_path="/data/epsilla_demo")
21+
print(response)
22+
23+
# Set DB to current DB
24+
client.use_db(db_name="MyDB")
25+
26+
# Create a table with schema in current DB
27+
status_code, response = client.create_table(
28+
table_name="MyTable",
29+
table_fields=[
30+
{"name": "ID", "dataType": "INT", "primaryKey": True},
31+
{"name": "Doc", "dataType": "STRING"},
32+
],
33+
indices=[
34+
{"name": "Index", "field": "Doc"},
35+
]
36+
)
37+
print(response)
38+
39+
# Get a list of table names in current DB
40+
status_code, response = client.list_tables()
41+
print(response)
42+
43+
# Insert new vector records into table
44+
status_code, response = client.insert(
45+
table_name="MyTable",
46+
records=[
47+
{"ID": 1, "Doc": "The garden was blooming with vibrant flowers, attracting butterflies and bees with their sweet nectar."},
48+
{"ID": 2, "Doc": "In the busy city streets, people rushed to and fro, hardly noticing the beauty of the day."},
49+
{"ID": 3, "Doc": "The library was a quiet haven, filled with the scent of old books and the soft rustling of pages."},
50+
{"ID": 4, "Doc": "High in the mountains, the air was crisp and clear, revealing breathtaking views of the valley below."},
51+
{"ID": 5, "Doc": "At the beach, children played joyfully in the sand, building castles and chasing the waves."},
52+
{"ID": 6, "Doc": "Deep in the forest, a deer cautiously stepped out, its ears alert for any signs of danger."},
53+
{"ID": 7, "Doc": "The old town's historical architecture spoke volumes about its rich cultural past."},
54+
{"ID": 8, "Doc": "Night fell, and the sky was a canvas of stars, shining brightly in the moon's soft glow."},
55+
{"ID": 9, "Doc": "A cozy cafe on the corner served the best hot chocolate, warming the hands and hearts of its visitors."},
56+
{"ID": 10, "Doc": "The artist's studio was cluttered but inspiring, filled with unfinished canvases and vibrant paints."},
57+
],
58+
)
59+
print(response)
60+
61+
# Query Vectors with specific response field
62+
status_code, response = client.query(
63+
table_name="MyTable",
64+
query_text="Where can I find a serene environment, ideal for relaxation and introspection?",
65+
response_fields=["Doc"],
66+
with_distance=True,
67+
limit=3
68+
)
69+
print(response)
70+
71+
# Query Vectors without specific response field, then it will return all fields
72+
status_code, response = client.query(
73+
table_name="MyTable",
74+
query_text="Where can I find a serene environment, ideal for relaxation and introspection?",
75+
)
76+
print(response)
77+
78+
# Get Vectors
79+
status_code, response = client.get(table_name="MyTable", limit=2)
80+
print(response)
81+
82+
# status_code, response = client.delete(table_name="MyTable", ids=[3])
83+
status_code, response = client.delete(table_name="MyTable", primary_keys=[1, 3, 4])
84+
# status_code, response = client.delete(table_name="MyTable", filter="Doc <> 'San Francisco'")
85+
print(response)
86+
87+
88+
# Drop table
89+
status_code, response = client.drop_table("MyTable")
90+
print(response)
91+
92+
# Unload db
93+
status_code, response = client.unload_db("MyDB")
94+
print(response)

pyepsilla/cloud/client.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717

1818
class Client(object):
19-
def __init__(self, project_id: str, api_key: str):
19+
def __init__(self, project_id: str, api_key: str, headers: dict = None):
2020
self._project_id = project_id
2121
self._apikey = api_key
2222
self._baseurl = "https://dispatch.epsilla.com/api/v3/project/{}".format(
@@ -28,6 +28,8 @@ def __init__(self, project_id: str, api_key: str):
2828
"Connection": "close",
2929
"X-API-Key": api_key,
3030
}
31+
if headers is not None:
32+
self._header.update(headers)
3133

3234
def validate(self):
3335
res = requests.get(
@@ -85,7 +87,7 @@ def vectordb(self, db_id: str):
8587

8688

8789
class Vectordb(Client):
88-
def __init__(self, project_id: str, db_id: str, api_key: str, public_endpoint: str):
90+
def __init__(self, project_id: str, db_id: str, api_key: str, public_endpoint: str, headers: dict = None):
8991
self._project_id = project_id
9092
self._db_id = db_id
9193
self._api_key = api_key
@@ -94,6 +96,8 @@ def __init__(self, project_id: str, db_id: str, api_key: str, public_endpoint: s
9496
self._public_endpoint, self._project_id, self._db_id
9597
)
9698
self._header = {"Content-type": "application/json", "X-API-Key": self._api_key}
99+
if headers is not None:
100+
self._header.update(headers)
97101

98102
# List table
99103
def list_tables(self):
@@ -107,13 +111,15 @@ def list_tables(self):
107111
return status_code, body
108112

109113
# Create table
110-
def create_table(self, table_name: str, table_fields: list[str] = None):
114+
def create_table(self, table_name: str, table_fields: list[dict] = None, indices: list[dict] = None):
111115
if self._db_id is None:
112116
raise Exception("[ERROR] db_id is None!")
113117
if table_fields is None:
114118
table_fields = []
115119
req_url = "{}/table/create".format(self._baseurl)
116120
req_data = {"name": table_name, "fields": table_fields}
121+
if indices is not None:
122+
req_data["indices"] = indices
117123
res = requests.post(
118124
url=req_url, data=json.dumps(req_data), headers=self._header, verify=False
119125
)
@@ -152,6 +158,8 @@ def insert(self, table_name: str, records: list[dict]):
152158
def query(
153159
self,
154160
table_name: str,
161+
query_text: str = None,
162+
query_index: str = None,
155163
query_field: str = None,
156164
query_vector: Union[list, dict] = None,
157165
response_fields: Optional[list] = None,
@@ -161,6 +169,10 @@ def query(
161169
):
162170
req_url = "{}/data/query".format(self._baseurl)
163171
req_data = {"table": table_name}
172+
if query_text is not None:
173+
req_data["query"] = query_text
174+
if query_index is not None:
175+
req_data["queryIndex"] = query_index
164176
if query_field != None:
165177
req_data["queryField"] = query_field
166178
if query_vector != None:

pyepsilla/enterprise/client.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class DbModel(BaseModel):
2525

2626

2727
class Client(cloud.Client):
28-
def __init__(self, base_url: str, project_id: Optional[str] = "default"):
28+
def __init__(self, base_url: str, project_id: Optional[str] = "default", headers: dict = None):
2929
self._project_id = project_id
3030
self._baseurl = f"{base_url}/api/v3/project/{project_id}"
3131
self._timeout = 10
@@ -34,6 +34,8 @@ def __init__(self, base_url: str, project_id: Optional[str] = "default"):
3434
"Connection": "close",
3535
"accept": "application/json",
3636
}
37+
if headers is not None:
38+
self._header.update(headers)
3739
self._db = None
3840

3941
def hello(self):
@@ -173,13 +175,15 @@ def list_tables(self):
173175
return status_code, body
174176

175177
# Create table
176-
def create_table(self, table_name: str, table_fields: list[str] = None):
178+
def create_table(self, table_name: str, table_fields: list[dict] = None, indices: list[dict] = None):
177179
if self._db_id is None:
178180
raise Exception("[ERROR] db_id is None!")
179181
if table_fields is None:
180182
table_fields = []
181183
req_url = "{}/table/create".format(self._baseurl)
182-
req_data = {"table_name": table_name, "fields": table_fields}
184+
req_data = {"name": table_name, "fields": table_fields}
185+
if indices is not None:
186+
req_data["indices"] = indices
183187
res = requests.post(
184188
url=req_url, data=json.dumps(req_data), headers=self._header, verify=False
185189
)
@@ -222,6 +226,8 @@ def insert(self, table_name: str, records: list[dict]):
222226
def query(
223227
self,
224228
table_name: str,
229+
query_text: str = None,
230+
query_index: str = None,
225231
query_field: str = None,
226232
query_vector: Union[list, dict] = None,
227233
response_fields: Optional[list] = None,
@@ -231,6 +237,10 @@ def query(
231237
):
232238
req_url = "{}/data/query".format(self._baseurl)
233239
req_data = {"table": table_name}
240+
if query_text is not None:
241+
req_data["query"] = query_text
242+
if query_index is not None:
243+
req_data["queryIndex"] = query_index
234244
if query_field != None:
235245
req_data["queryField"] = query_field
236246
if query_vector != None:

pyepsilla/vectordb/client.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
class Client:
1919
def __init__(
20-
self, protocol: str = "http", host: str = "localhost", port: str = "8888"
20+
self, protocol: str = "http", host: str = "localhost", port: str = "8888", headers: dict = None
2121
):
2222
self._protocol = protocol
2323
self._host = host
@@ -26,6 +26,8 @@ def __init__(
2626
self._db = None
2727
self._timeout = 10
2828
self._header = {"Content-type": "application/json", "Connection": "close"}
29+
if headers is not None:
30+
self._header.update(headers)
2931
self.check_networking()
3032

3133
def check_networking(self):
@@ -100,13 +102,15 @@ def unload_db(self, db_name: str):
100102
res.close()
101103
return status_code, body
102104

103-
def create_table(self, table_name: str, table_fields: list[str] = None):
105+
def create_table(self, table_name: str, table_fields: list[dict] = None, indices: list[dict] = None):
104106
if self._db is None:
105107
raise Exception("[ERROR] Please use_db() first!")
106108
if table_fields is None:
107109
table_fields = []
108110
req_url = "{}/api/{}/schema/tables".format(self._baseurl, self._db)
109111
req_data = {"name": table_name, "fields": table_fields}
112+
if indices is not None:
113+
req_data["indices"] = indices
110114
res = requests.post(
111115
url=req_url, data=json.dumps(req_data), headers=self._header, verify=False
112116
)
@@ -203,29 +207,35 @@ def rebuild(self, timeout: int = 7200):
203207
def query(
204208
self,
205209
table_name: str,
206-
query_field: str = "",
210+
query_text: str = None,
211+
query_index: str = None,
212+
query_field: str = None,
207213
query_vector: Union[list, dict] = None,
208214
response_fields: list = None,
209-
limit: int = 1,
215+
limit: int = 2,
210216
filter: str = "",
211217
with_distance: bool = False,
212218
):
213219
if self._db is None:
214220
raise Exception("[ERROR] Please use_db() first!")
215-
if query_vector is None:
216-
query_vector = []
217221
if response_fields is None:
218222
response_fields = []
219223
req_url = "{}/api/{}/data/query".format(self._baseurl, self._db)
220224
req_data = {
221225
"table": table_name,
222-
"queryField": query_field,
223-
"queryVector": query_vector,
224226
"response": response_fields,
225227
"limit": limit,
226228
"filter": filter,
227229
"withDistance": with_distance,
228230
}
231+
if query_text is not None:
232+
req_data["query"] = query_text
233+
if query_index is not None:
234+
req_data["queryIndex"] = query_index
235+
if query_field is not None:
236+
req_data["queryField"] = query_field
237+
if query_vector is not None:
238+
req_data["queryVector"] = query_vector
229239
res = requests.post(
230240
url=req_url, data=json.dumps(req_data), headers=self._header, verify=False
231241
)

pyepsilla/vectordb/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.7"
1+
__version__ = "0.3.0"

0 commit comments

Comments
 (0)