Skip to content

Commit 2b04244

Browse files
authored
Merge pull request #1 from d4rkstar/milvus_test
2 parents 8922de5 + 7c3be9d commit 2b04244

File tree

5 files changed

+222
-415
lines changed

5 files changed

+222
-415
lines changed

demos/milvus/milvus_admin_test.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
#
1919

2020
import os
21-
import nuvolaris.testutil as tu
22-
import nuvolaris.config as cfg
23-
from nuvolaris.milvus_admin_client import MilvusAdminClient
24-
from pymilvus import MilvusClient
21+
from nuvolaris.milvus_simple_client import MilvusSimpleClient as MilvusClient
2522

2623
# for this test minioClient should see this env variable
2724
os.environ['MILVUS_ROOT_USER']='root'

nuvolaris/milvus_admin_client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616
# under the License.
1717
#
1818
import logging
19+
1920
import nuvolaris.config as cfg
20-
import nuvolaris.util as util
21-
from pymilvus import MilvusClient, connections, db
21+
from nuvolaris.milvus_simple_client import MilvusSimpleClient as MilvusClient
22+
#from pymilvus import MilvusClient, connections, db
2223

2324
class MilvusAdminClient:
2425
"""

nuvolaris/milvus_simple_client.py

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
#
18+
from types import NoneType
19+
from typing import Optional
20+
21+
import requests
22+
23+
24+
class MilvusSimpleException(Exception):
25+
def __init__(self, code: int, message: str):
26+
self.message = message
27+
self.code = code
28+
29+
def __str__(self):
30+
return f"{self.message} ({self.code})"
31+
32+
33+
class MilvusSimpleClient:
34+
35+
def __init__(self, uri: str, token: str, db_name: str = None):
36+
self.milvus_url = uri
37+
self.token = token
38+
self.db_name = db_name
39+
40+
def _request(self, endpoint: str, json=None, method: str = "POST", api_level="v2"):
41+
headers = {
42+
"Content-Type": "application/json",
43+
"Authorization": f"Bearer {self.token}"
44+
}
45+
url = f"{self.milvus_url}/{api_level}/vectordb/{endpoint}"
46+
if json is None:
47+
json = {}
48+
response = requests.request(method, url, headers=headers, json=json)
49+
response.raise_for_status()
50+
res = response.json()
51+
if type(res.get('data')) is not NoneType:
52+
return res['data']
53+
else:
54+
raise MilvusSimpleException(code=res.get('code'), message=res.get('message'))
55+
56+
def close(self):
57+
pass
58+
59+
# User operations
60+
def create_user(self, user_name: str, password: str):
61+
payload = {"userName": user_name, "password": password}
62+
return self._request("users/create", json=payload)
63+
64+
def describe_user(self, user_name: str):
65+
payload = {"userName": user_name}
66+
return self._request(f"users/describe", json=payload)
67+
68+
def update_password(self, user_name: str, old_password: str, new_password: str):
69+
payload = {"userName": user_name, "password": old_password, "newPassword": new_password}
70+
return self._request("users/update_password", json=payload)
71+
72+
def drop_user(self, user_name: str):
73+
payload = {"userName": user_name}
74+
return self._request(f"users/drop", json=payload)
75+
76+
def list_users(self):
77+
return self._request("users/list")
78+
79+
def grant_role(self, role_name: str, user_name: str, db_name: Optional[str] = None):
80+
payload = {"roleName": role_name, "userName": user_name}
81+
if db_name is not None:
82+
payload["dbName"] = db_name
83+
return self._request(f"users/grant_role", json=payload)
84+
85+
def revoke_role(self, role_name: str, user_name: str, db_name: Optional[str] = None):
86+
payload = {"roleName": role_name, "userName": user_name}
87+
if db_name is not None:
88+
payload["dbName"] = db_name
89+
return self._request(f"users/revoke_role", json=payload)
90+
91+
# Database operations
92+
def alter_database(self, db_name: str, properties: dict):
93+
payload = {"dbName": db_name, "properties": properties}
94+
return self._request("databases/alter", json=payload)
95+
96+
def create_database(self, db_name: str, properties: Optional[dict] = None, **kwargs):
97+
payload = {"dbName": db_name}
98+
if properties is not None:
99+
payload["properties"] = properties
100+
101+
for k, v in kwargs.items():
102+
payload[k] = v
103+
104+
return self._request("databases/create", json=payload)
105+
106+
def describe_database(self, db_name: str):
107+
payload = {"dbName": db_name}
108+
return self._request(f"databases/describe", json=payload)
109+
110+
def drop_database(self, db_name: str):
111+
payload = {"dbName": db_name}
112+
return self._request(f"databases/drop", json=payload)
113+
114+
def list_databases(self):
115+
return self._request(f"databases/list")
116+
117+
# Role operations
118+
def create_role(self, role_name: str, db_name: Optional[str] = None):
119+
payload = {"roleName": role_name}
120+
if db_name is not None:
121+
payload["dbName"] = db_name
122+
123+
return self._request("roles/create", json=payload)
124+
125+
def drop_role(self, role_name: str, db_name: Optional[str] = None):
126+
payload = {"roleName": role_name}
127+
if db_name is not None:
128+
payload["dbName"] = db_name
129+
return self._request(f"roles/drop", json=payload)
130+
131+
def list_roles(self, db_name: Optional[str] = None):
132+
payload = {}
133+
if db_name is not None:
134+
payload["dbName"] = db_name
135+
return self._request(f"roles/list", json=payload)
136+
137+
def describe_role(self, role_name: str, db_name: Optional[str] = None):
138+
payload = {"roleName": role_name}
139+
if db_name is not None:
140+
payload["dbName"] = db_name
141+
return self._request(f"roles/describe", json=payload)
142+
143+
def grant_privilege(self, role_name: str, object_type: str, object_name: str, privilege: str, db_name: Optional[str] = None):
144+
payload = {
145+
"roleName": role_name,
146+
"objectType": object_type,
147+
"objectName": object_name,
148+
"privilege": privilege
149+
}
150+
if db_name is not None:
151+
payload["dbName"] = db_name
152+
return self._request(f"roles/grant_privilege", json=payload)
153+
154+
def revoke_privilege(self, role_name: str, object_type: str, object_name: str, privilege: str, db_name: Optional[str] = None):
155+
payload = {
156+
"roleName": role_name,
157+
"objectType": object_type,
158+
"objectName": object_name,
159+
"privilege": privilege
160+
}
161+
if db_name is not None:
162+
payload["dbName"] = db_name
163+
return self._request(f"roles/revoke_privilege", json=payload)
164+
165+
# Collection operations
166+
167+
def create_collection(self,
168+
collection_name: str,
169+
db_name: Optional[str] = None,
170+
dimension: Optional[int] = None,
171+
primary_field_name: str = "id", # default is "id"
172+
id_type: str = "Int64", # or "string",
173+
vector_field_name: str = "vector", # default is "vector"
174+
metric_type: str = "COSINE",
175+
auto_id: bool = False,
176+
):
177+
if db_name is None:
178+
db_name = self.db_name
179+
180+
payload = {
181+
"dbName": db_name,
182+
"collectionName": collection_name,
183+
"dimension": dimension,
184+
"metricType": metric_type,
185+
"idType": id_type,
186+
"autoID": auto_id,
187+
"primaryFieldName": primary_field_name,
188+
"vectorFieldName": vector_field_name,
189+
}
190+
return self._request(f"collections/create", json=payload)
191+
192+
def drop_collection(self, collection_name: str, db_name: Optional[str] = None, **kwargs):
193+
payload = {
194+
"collectionName": collection_name,
195+
}
196+
if db_name is not None:
197+
payload["dbName"] = db_name
198+
else:
199+
payload["dbName"] = self.db_name
200+
201+
for k, v in kwargs.items():
202+
payload[k] = v
203+
204+
return self._request(f"collections/drop", json=payload)
205+
206+
def list_collections(self, db_name: Optional[str] = None, **kwargs):
207+
payload = {
208+
}
209+
if db_name is not None:
210+
payload["dbName"] = db_name
211+
else:
212+
payload["dbName"] = self.db_name
213+
214+
for k, v in kwargs.items():
215+
payload[k] = v
216+
217+
return self._request(f"collections/list", json=payload)

0 commit comments

Comments
 (0)