mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-31 13:03:49 +08:00
Refactor: reformat all code for lefthook using ruff and gofmt (#16585)
This commit is contained in:
@@ -25,14 +25,14 @@ import requests
|
||||
|
||||
class HttpClient:
|
||||
def __init__(
|
||||
self,
|
||||
host: str = "127.0.0.1",
|
||||
port: int = 9381,
|
||||
api_version: str = "v1",
|
||||
api_key: Optional[str] = None,
|
||||
connect_timeout: float = 5.0,
|
||||
read_timeout: float = 60.0,
|
||||
verify_ssl: bool = False,
|
||||
self,
|
||||
host: str = "127.0.0.1",
|
||||
port: int = 9381,
|
||||
api_version: str = "v1",
|
||||
api_key: Optional[str] = None,
|
||||
connect_timeout: float = 5.0,
|
||||
read_timeout: float = 60.0,
|
||||
verify_ssl: bool = False,
|
||||
) -> None:
|
||||
self.host = host
|
||||
self.port = port
|
||||
@@ -71,19 +71,19 @@ class HttpClient:
|
||||
return headers
|
||||
|
||||
def request(
|
||||
self,
|
||||
method: str,
|
||||
path: str,
|
||||
*,
|
||||
use_api_base: bool = True,
|
||||
auth_kind: Optional[str] = "api",
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
json_body: Optional[Dict[str, Any]] = None,
|
||||
data: Any = None,
|
||||
files: Any = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
stream: bool = False,
|
||||
iterations: int = 1,
|
||||
self,
|
||||
method: str,
|
||||
path: str,
|
||||
*,
|
||||
use_api_base: bool = True,
|
||||
auth_kind: Optional[str] = "api",
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
json_body: Optional[Dict[str, Any]] = None,
|
||||
data: Any = None,
|
||||
files: Any = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
stream: bool = False,
|
||||
iterations: int = 1,
|
||||
) -> requests.Response | dict:
|
||||
url = self.build_url(path, use_api_base=use_api_base)
|
||||
merged_headers = self._headers(auth_kind, headers)
|
||||
@@ -144,18 +144,18 @@ class HttpClient:
|
||||
# )
|
||||
|
||||
def request_json(
|
||||
self,
|
||||
method: str,
|
||||
path: str,
|
||||
*,
|
||||
use_api_base: bool = True,
|
||||
auth_kind: Optional[str] = "api",
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
json_body: Optional[Dict[str, Any]] = None,
|
||||
data: Any = None,
|
||||
files: Any = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
stream: bool = False,
|
||||
self,
|
||||
method: str,
|
||||
path: str,
|
||||
*,
|
||||
use_api_base: bool = True,
|
||||
auth_kind: Optional[str] = "api",
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
json_body: Optional[Dict[str, Any]] = None,
|
||||
data: Any = None,
|
||||
files: Any = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
stream: bool = False,
|
||||
) -> Dict[str, Any]:
|
||||
response = self.request(
|
||||
method,
|
||||
|
||||
@@ -336,8 +336,8 @@ reset_default_asr: RESET DEFAULT ASR ";"
|
||||
reset_default_tts: RESET DEFAULT TTS ";"
|
||||
|
||||
list_user_datasets: LIST DATASETS ";"
|
||||
create_user_dataset_with_parser: CREATE DATASET quoted_string WITH EMBEDDING quoted_string PARSER quoted_string ";"
|
||||
create_user_dataset_with_pipeline: CREATE DATASET quoted_string WITH EMBEDDING quoted_string PIPELINE quoted_string ";"
|
||||
create_user_dataset_with_parser: CREATE DATASET quoted_string WITH EMBEDDING quoted_string PARSER quoted_string ";"
|
||||
create_user_dataset_with_pipeline: CREATE DATASET quoted_string WITH EMBEDDING quoted_string PIPELINE quoted_string ";"
|
||||
drop_user_dataset: DROP DATASET quoted_string ";"
|
||||
list_user_dataset_files: LIST FILES OF DATASET quoted_string ";"
|
||||
list_user_dataset_documents: LIST DOCUMENTS OF DATASET quoted_string ";"
|
||||
@@ -640,15 +640,13 @@ class RAGFlowCLITransformer(Transformer):
|
||||
dataset_name = items[2].children[0].strip("'\"")
|
||||
embedding = items[5].children[0].strip("'\"")
|
||||
parser_type = items[7].children[0].strip("'\"")
|
||||
return {"type": "create_user_dataset", "dataset_name": dataset_name, "embedding": embedding,
|
||||
"parser_type": parser_type}
|
||||
return {"type": "create_user_dataset", "dataset_name": dataset_name, "embedding": embedding, "parser_type": parser_type}
|
||||
|
||||
def create_user_dataset_with_pipeline(self, items):
|
||||
dataset_name = items[2].children[0].strip("'\"")
|
||||
embedding = items[5].children[0].strip("'\"")
|
||||
pipeline = items[7].children[0].strip("'\"")
|
||||
return {"type": "create_user_dataset", "dataset_name": dataset_name, "embedding": embedding,
|
||||
"pipeline": pipeline}
|
||||
return {"type": "create_user_dataset", "dataset_name": dataset_name, "embedding": embedding, "pipeline": pipeline}
|
||||
|
||||
def drop_user_dataset(self, items):
|
||||
dataset_name = items[2].children[0].strip("'\"")
|
||||
@@ -666,7 +664,7 @@ class RAGFlowCLITransformer(Transformer):
|
||||
dataset_names = []
|
||||
dataset_names.append(items[4].children[0].strip("'\""))
|
||||
for i in range(5, len(items)):
|
||||
if items[i] and hasattr(items[i], 'children') and items[i].children:
|
||||
if items[i] and hasattr(items[i], "children") and items[i].children:
|
||||
dataset_names.append(items[i].children[0].strip("'\""))
|
||||
return {"type": "list_user_datasets_metadata", "dataset_names": dataset_names}
|
||||
|
||||
@@ -675,7 +673,7 @@ class RAGFlowCLITransformer(Transformer):
|
||||
doc_ids = []
|
||||
if len(items) > 6 and items[6] == "DOCUMENTS":
|
||||
for i in range(7, len(items)):
|
||||
if items[i] and hasattr(items[i], 'children') and items[i].children:
|
||||
if items[i] and hasattr(items[i], "children") and items[i].children:
|
||||
doc_id = items[i].children[0].strip("'\"")
|
||||
doc_ids.append(doc_id)
|
||||
return {"type": "list_user_documents_metadata_summary", "dataset_name": dataset_name, "document_ids": doc_ids}
|
||||
@@ -698,17 +696,17 @@ class RAGFlowCLITransformer(Transformer):
|
||||
dataset_name = None
|
||||
vector_size = None
|
||||
for i, item in enumerate(items):
|
||||
if hasattr(item, 'data') and item.data == 'quoted_string':
|
||||
if hasattr(item, "data") and item.data == "quoted_string":
|
||||
dataset_name = item.children[0].strip("'\"")
|
||||
if hasattr(item, 'type') and item.type == 'NUMBER':
|
||||
if i > 0 and items[i-1].type == 'SIZE' and items[i-2].type == 'VECTOR':
|
||||
if hasattr(item, "type") and item.type == "NUMBER":
|
||||
if i > 0 and items[i - 1].type == "SIZE" and items[i - 2].type == "VECTOR":
|
||||
vector_size = int(item)
|
||||
return {"type": "create_dataset_table", "dataset_name": dataset_name, "vector_size": vector_size}
|
||||
|
||||
def drop_dataset_table(self, items):
|
||||
dataset_name = None
|
||||
for item in items:
|
||||
if hasattr(item, 'data') and item.data == 'quoted_string':
|
||||
if hasattr(item, "data") and item.data == "quoted_string":
|
||||
dataset_name = item.children[0].strip("'\"")
|
||||
return {"type": "drop_dataset_table", "dataset_name": dataset_name}
|
||||
|
||||
@@ -792,7 +790,7 @@ class RAGFlowCLITransformer(Transformer):
|
||||
|
||||
def update_chunk(self, items):
|
||||
def get_quoted_value(item):
|
||||
if hasattr(item, 'children') and item.children:
|
||||
if hasattr(item, "children") and item.children:
|
||||
return item.children[0].strip("'\"")
|
||||
return str(item).strip("'\"")
|
||||
|
||||
@@ -813,16 +811,16 @@ class RAGFlowCLITransformer(Transformer):
|
||||
for i in range(2, len(items)):
|
||||
item = items[i]
|
||||
# Check for FROM token to stop
|
||||
if hasattr(item, 'type') and item.type == 'FROM':
|
||||
if hasattr(item, "type") and item.type == "FROM":
|
||||
break
|
||||
if hasattr(item, 'children') and item.children:
|
||||
if hasattr(item, "children") and item.children:
|
||||
tag = item.children[0].strip("'\"")
|
||||
tags.append(tag)
|
||||
# Find dataset_name: quoted_string after DATASET
|
||||
dataset_name = None
|
||||
for i, item in enumerate(items):
|
||||
# Check if item is a DATASET token
|
||||
if hasattr(item, 'type') and item.type == 'DATASET':
|
||||
if hasattr(item, "type") and item.type == "DATASET":
|
||||
# Next item should be quoted_string
|
||||
dataset_name = items[i + 1].children[0].strip("'\"")
|
||||
break
|
||||
@@ -835,10 +833,10 @@ class RAGFlowCLITransformer(Transformer):
|
||||
|
||||
# Check if it's "REMOVE ALL CHUNKS"
|
||||
for item in items:
|
||||
if hasattr(item, 'type') and item.type == 'ALL':
|
||||
if hasattr(item, "type") and item.type == "ALL":
|
||||
# Find doc_id
|
||||
for j, inner_item in enumerate(items):
|
||||
if hasattr(inner_item, 'type') and inner_item.type == 'DOCUMENT':
|
||||
if hasattr(inner_item, "type") and inner_item.type == "DOCUMENT":
|
||||
doc_id = items[j + 1].children[0].strip("'\"")
|
||||
return {"type": "remove_chunks", "doc_id": doc_id, "delete_all": True}
|
||||
|
||||
@@ -846,12 +844,12 @@ class RAGFlowCLITransformer(Transformer):
|
||||
chunk_ids = []
|
||||
doc_id = None
|
||||
for i, item in enumerate(items):
|
||||
if hasattr(item, 'type') and item.type == 'DOCUMENT':
|
||||
if hasattr(item, "type") and item.type == "DOCUMENT":
|
||||
doc_id = items[i + 1].children[0].strip("'\"")
|
||||
elif hasattr(item, 'children') and item.children:
|
||||
elif hasattr(item, "children") and item.children:
|
||||
val = item.children[0].strip("'\"")
|
||||
# Skip if it's "FROM" or "DOCUMENT"
|
||||
if val.upper() in ['FROM', 'DOCUMENT']:
|
||||
if val.upper() in ["FROM", "DOCUMENT"]:
|
||||
continue
|
||||
chunk_ids.append(val)
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ from user import login_user
|
||||
|
||||
warnings.filterwarnings("ignore", category=getpass.GetPassWarning)
|
||||
|
||||
|
||||
def encrypt(input_string):
|
||||
pub = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArq9XTUSeYr2+N1h3Afl/z8Dse/2yD0ZGrKwx+EEEcdsBLca9Ynmx3nIB5obmLlSfmskLpBo0UACBmB5rEjBp2Q2f3AG3Hjd4B+gNCG6BDaawuDlgANIhGnaTLrIqWrrcm4EMzJOnAOI1fgzJRsOOUEfaS318Eq9OVO3apEyCCt0lOQK6PuksduOjVxtltDav+guVAA068NrPYmRNabVKRNLJpL8w4D44sfth5RvZ3q9t+6RTArpEtc5sh5ChzvqPOzKGMXW83C95TxmXqpbK6olN4RevSfVjEAgCydH6HN6OhtOQEcnrU97r9H0iZOWwbw3pVrZiUkuRD1R56Wzs2wIDAQAB\n-----END PUBLIC KEY-----"
|
||||
pub_key = RSA.importKey(pub)
|
||||
@@ -49,9 +50,6 @@ def encode_to_base64(input_string):
|
||||
return base64_encoded.decode("utf-8")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class RAGFlowCLI(Cmd):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -240,9 +238,9 @@ class RAGFlowCLI(Cmd):
|
||||
print(r"""
|
||||
____ ___ ______________ ________ ____
|
||||
/ __ \/ | / ____/ ____/ /___ _ __ / ____/ / / _/
|
||||
/ /_/ / /| |/ / __/ /_ / / __ \ | /| / / / / / / / /
|
||||
/ _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / /___/ /____/ /
|
||||
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ \____/_____/___/
|
||||
/ /_/ / /| |/ / __/ /_ / / __ \ | /| / / / / / / / /
|
||||
/ _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / /___/ /____/ /
|
||||
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ \____/_____/___/
|
||||
""")
|
||||
self.cmdloop()
|
||||
|
||||
@@ -254,15 +252,13 @@ class RAGFlowCLI(Cmd):
|
||||
result = self.parse_command(command)
|
||||
self.execute_command(result)
|
||||
|
||||
|
||||
def parse_connection_args(self, args: List[str]) -> Dict[str, Any]:
|
||||
parser = argparse.ArgumentParser(description="RAGFlow CLI Client", add_help=False)
|
||||
parser.add_argument("-h", "--host", default="127.0.0.1", help="Admin or RAGFlow service host")
|
||||
parser.add_argument("-p", "--port", type=int, default=9381, help="Admin or RAGFlow service port")
|
||||
parser.add_argument("-w", "--password", default="admin", type=str, help="Superuser password")
|
||||
parser.add_argument("-t", "--type", default="admin", type=str, help="CLI mode, admin or user")
|
||||
parser.add_argument("-u", "--username", default=None,
|
||||
help="Username (email). In admin mode defaults to admin@ragflow.io, in user mode required.")
|
||||
parser.add_argument("-u", "--username", default=None, help="Username (email). In admin mode defaults to admin@ragflow.io, in user mode required.")
|
||||
parser.add_argument("command", nargs="?", help="Single command")
|
||||
try:
|
||||
parsed_args, remaining_args = parser.parse_known_args(args)
|
||||
@@ -274,7 +270,7 @@ class RAGFlowCLI(Cmd):
|
||||
|
||||
if remaining_args:
|
||||
if remaining_args[0] == "command":
|
||||
command_str = ' '.join(remaining_args[1:]) + ';'
|
||||
command_str = " ".join(remaining_args[1:]) + ";"
|
||||
auth = True
|
||||
if remaining_args[1] == "register":
|
||||
auth = False
|
||||
@@ -282,28 +278,14 @@ class RAGFlowCLI(Cmd):
|
||||
if username is None:
|
||||
print("Error: username (-u) is required in user mode")
|
||||
return {"error": "Username required"}
|
||||
return {
|
||||
"host": parsed_args.host,
|
||||
"port": parsed_args.port,
|
||||
"password": parsed_args.password,
|
||||
"type": parsed_args.type,
|
||||
"username": username,
|
||||
"command": command_str,
|
||||
"auth": auth
|
||||
}
|
||||
return {"host": parsed_args.host, "port": parsed_args.port, "password": parsed_args.password, "type": parsed_args.type, "username": username, "command": command_str, "auth": auth}
|
||||
else:
|
||||
return {"error": "Invalid command"}
|
||||
else:
|
||||
auth = True
|
||||
if username is None:
|
||||
auth = False
|
||||
return {
|
||||
"host": parsed_args.host,
|
||||
"port": parsed_args.port,
|
||||
"type": parsed_args.type,
|
||||
"username": username,
|
||||
"auth": auth
|
||||
}
|
||||
return {"host": parsed_args.host, "port": parsed_args.port, "type": parsed_args.type, "username": username, "auth": auth}
|
||||
except SystemExit:
|
||||
return {"error": "Invalid connection arguments"}
|
||||
|
||||
@@ -321,6 +303,7 @@ class RAGFlowCLI(Cmd):
|
||||
# print(f"Parsed command: {command_dict}")
|
||||
run_command(self.ragflow_client, command_dict)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
cli = RAGFlowCLI()
|
||||
|
||||
@@ -71,6 +71,7 @@ class RAGFlowClient:
|
||||
user_password: str = command.get("password")
|
||||
if not user_password:
|
||||
import getpass
|
||||
|
||||
user_password = getpass.getpass("Password: ")
|
||||
try:
|
||||
token = login_user(self.http_client, self.server_type, email, user_password)
|
||||
@@ -86,8 +87,7 @@ class RAGFlowClient:
|
||||
def ping_server(self, command):
|
||||
iterations = command.get("iterations", 1)
|
||||
if iterations > 1:
|
||||
response = self.http_client.request("GET", "/system/ping", use_api_base=True, auth_kind="web",
|
||||
iterations=iterations)
|
||||
response = self.http_client.request("GET", "/system/ping", use_api_base=True, auth_kind="web", iterations=iterations)
|
||||
return response
|
||||
else:
|
||||
response = self.http_client.request("GET", "/system/ping", use_api_base=True, auth_kind="web")
|
||||
@@ -106,8 +106,7 @@ class RAGFlowClient:
|
||||
enc_password = encrypt_password(password)
|
||||
print(f"Register user: {nickname}, email: {username}, password: ******")
|
||||
payload = {"email": username, "nickname": nickname, "password": enc_password}
|
||||
response = self.http_client.request(method="POST", path="/users",
|
||||
json_body=payload, use_api_base=True, auth_kind="web")
|
||||
response = self.http_client.request(method="POST", path="/users", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json["code"] == 0:
|
||||
@@ -135,8 +134,7 @@ class RAGFlowClient:
|
||||
|
||||
service_id: int = command["number"]
|
||||
|
||||
response = self.http_client.request("GET", f"/admin/services/{service_id}", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", f"/admin/services/{service_id}", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
res_data = res_json["data"]
|
||||
@@ -226,9 +224,7 @@ class RAGFlowClient:
|
||||
password_tree: Tree = command["password"]
|
||||
password: str = password_tree.children[0].strip("'\"")
|
||||
print(f"Alter user: {user_name}, password: ******")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name}/password",
|
||||
json_body={"new_password": encrypt_password(password)}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name}/password", json_body={"new_password": encrypt_password(password)}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print(res_json["message"])
|
||||
@@ -247,9 +243,7 @@ class RAGFlowClient:
|
||||
print(f"Create user: {user_name}, password: ******, role: {role}")
|
||||
# enpass1 = encrypt(password)
|
||||
enc_password = encrypt_password(password)
|
||||
response = self.http_client.request(method="POST", path="/admin/users",
|
||||
json_body={"username": user_name, "password": enc_password, "role": role},
|
||||
use_api_base=True, auth_kind="admin")
|
||||
response = self.http_client.request(method="POST", path="/admin/users", json_body={"username": user_name, "password": enc_password, "role": role}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -266,9 +260,7 @@ class RAGFlowClient:
|
||||
activate_status: str = activate_tree.children[0].strip("'\"")
|
||||
if activate_status.lower() in ["on", "off"]:
|
||||
print(f"Alter user {user_name} activate status, turn {activate_status.lower()}.")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name}/activate",
|
||||
json_body={"activate_status": activate_status}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name}/activate", json_body={"activate_status": activate_status}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print(res_json["message"])
|
||||
@@ -283,14 +275,12 @@ class RAGFlowClient:
|
||||
|
||||
user_name_tree: Tree = command["user_name"]
|
||||
user_name: str = user_name_tree.children[0].strip("'\"")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name}/admin", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name}/admin", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print(res_json["message"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to grant {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to grant {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def revoke_admin(self, command):
|
||||
if self.server_type != "admin":
|
||||
@@ -298,14 +288,12 @@ class RAGFlowClient:
|
||||
|
||||
user_name_tree: Tree = command["user_name"]
|
||||
user_name: str = user_name_tree.children[0].strip("'\"")
|
||||
response = self.http_client.request("DELETE", f"/admin/users/{user_name}/admin", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("DELETE", f"/admin/users/{user_name}/admin", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print(res_json["message"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to revoke {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to revoke {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def create_role(self, command):
|
||||
if self.server_type != "admin":
|
||||
@@ -319,10 +307,7 @@ class RAGFlowClient:
|
||||
desc_str = desc_tree.children[0].strip("'\"")
|
||||
|
||||
print(f"create role name: {role_name}, description: {desc_str}")
|
||||
response = self.http_client.request("POST", "/admin/roles",
|
||||
json_body={"role_name": role_name, "description": desc_str},
|
||||
use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("POST", "/admin/roles", json_body={"role_name": role_name, "description": desc_str}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -336,9 +321,7 @@ class RAGFlowClient:
|
||||
role_name_tree: Tree = command["role_name"]
|
||||
role_name: str = role_name_tree.children[0].strip("'\"")
|
||||
print(f"drop role name: {role_name}")
|
||||
response = self.http_client.request("DELETE", f"/admin/roles/{role_name}",
|
||||
use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("DELETE", f"/admin/roles/{role_name}", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -355,24 +338,18 @@ class RAGFlowClient:
|
||||
desc_str: str = desc_tree.children[0].strip("'\"")
|
||||
|
||||
print(f"alter role name: {role_name}, description: {desc_str}")
|
||||
response = self.http_client.request("PUT", f"/admin/roles/{role_name}",
|
||||
json_body={"description": desc_str},
|
||||
use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("PUT", f"/admin/roles/{role_name}", json_body={"description": desc_str}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to update role {role_name} with description: {desc_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to update role {role_name} with description: {desc_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def list_roles(self, command):
|
||||
if self.server_type != "admin":
|
||||
print("This command is only allowed in ADMIN mode")
|
||||
|
||||
response = self.http_client.request("GET", "/admin/roles",
|
||||
use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", "/admin/roles", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -386,9 +363,7 @@ class RAGFlowClient:
|
||||
role_name_tree: Tree = command["role_name"]
|
||||
role_name: str = role_name_tree.children[0].strip("'\"")
|
||||
print(f"show role: {role_name}")
|
||||
response = self.http_client.request("GET", f"/admin/roles/{role_name}/permission",
|
||||
use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", f"/admin/roles/{role_name}/permission", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -409,15 +384,12 @@ class RAGFlowClient:
|
||||
action_str: str = action_tree.children[0].strip("'\"")
|
||||
actions.append(action_str)
|
||||
print(f"grant role_name: {role_name_str}, resource: {resource_str}, actions: {actions}")
|
||||
response = self.http_client.request("POST", f"/admin/roles/{role_name_str}/permission",
|
||||
json_body={"actions": actions, "resource": resource_str}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("POST", f"/admin/roles/{role_name_str}/permission", json_body={"actions": actions, "resource": resource_str}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to grant role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to grant role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def revoke_permission(self, command):
|
||||
if self.server_type != "admin":
|
||||
@@ -433,15 +405,12 @@ class RAGFlowClient:
|
||||
action_str: str = action_tree.children[0].strip("'\"")
|
||||
actions.append(action_str)
|
||||
print(f"revoke role_name: {role_name_str}, resource: {resource_str}, actions: {actions}")
|
||||
response = self.http_client.request("DELETE", f"/admin/roles/{role_name_str}/permission",
|
||||
json_body={"actions": actions, "resource": resource_str}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("DELETE", f"/admin/roles/{role_name_str}/permission", json_body={"actions": actions, "resource": resource_str}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to revoke role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to revoke role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def alter_user_role(self, command):
|
||||
if self.server_type != "admin":
|
||||
@@ -452,15 +421,12 @@ class RAGFlowClient:
|
||||
user_name_tree: Tree = command["user_name"]
|
||||
user_name_str: str = user_name_tree.children[0].strip("'\"")
|
||||
print(f"alter_user_role user_name: {user_name_str}, role_name: {role_name_str}")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name_str}/role",
|
||||
json_body={"role_name": role_name_str}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("PUT", f"/admin/users/{user_name_str}/role", json_body={"role_name": role_name_str}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to alter user: {user_name_str} to role {role_name_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to alter user: {user_name_str} to role {role_name_str}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def show_user_permission(self, command):
|
||||
if self.server_type != "admin":
|
||||
@@ -469,14 +435,12 @@ class RAGFlowClient:
|
||||
user_name_tree: Tree = command["user_name"]
|
||||
user_name_str: str = user_name_tree.children[0].strip("'\"")
|
||||
print(f"show_user_permission user_name: {user_name_str}")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name_str}/permission", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name_str}/permission", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to show user: {user_name_str} permission, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to show user: {user_name_str} permission, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def generate_key(self, command: dict[str, Any]) -> None:
|
||||
if self.server_type != "admin":
|
||||
@@ -485,14 +449,12 @@ class RAGFlowClient:
|
||||
username_tree: Tree = command["user_name"]
|
||||
user_name: str = username_tree.children[0].strip("'\"")
|
||||
print(f"Generating API key for user: {user_name}")
|
||||
response = self.http_client.request("POST", f"/admin/users/{user_name}/keys", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("POST", f"/admin/users/{user_name}/keys", use_api_base=True, auth_kind="admin")
|
||||
res_json: dict[str, Any] = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
else:
|
||||
print(
|
||||
f"Failed to generate key for user {user_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Failed to generate key for user {user_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def list_keys(self, command: dict[str, Any]) -> None:
|
||||
if self.server_type != "admin":
|
||||
@@ -501,8 +463,7 @@ class RAGFlowClient:
|
||||
username_tree: Tree = command["user_name"]
|
||||
user_name: str = username_tree.children[0].strip("'\"")
|
||||
print(f"Listing API keys for user: {user_name}")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name}/keys", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name}/keys", use_api_base=True, auth_kind="admin")
|
||||
res_json: dict[str, Any] = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -520,8 +481,7 @@ class RAGFlowClient:
|
||||
print(f"Dropping API key for user: {user_name}")
|
||||
# URL encode the key to handle special characters
|
||||
encoded_key: str = urllib.parse.quote(key, safe="")
|
||||
response = self.http_client.request("DELETE", f"/admin/users/{user_name}/keys/{encoded_key}", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("DELETE", f"/admin/users/{user_name}/keys/{encoded_key}", use_api_base=True, auth_kind="admin")
|
||||
res_json: dict[str, Any] = response.json()
|
||||
if response.status_code == 200:
|
||||
print(res_json["message"])
|
||||
@@ -534,23 +494,19 @@ class RAGFlowClient:
|
||||
|
||||
var_name = _strip_tree_value(command["var_name"])
|
||||
var_value = _strip_tree_value(command["var_value"])
|
||||
response = self.http_client.request("PUT", "/admin/variables",
|
||||
json_body={"var_name": var_name, "var_value": var_value}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("PUT", "/admin/variables", json_body={"var_name": var_name, "var_value": var_value}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print(res_json["message"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to set variable {var_name} to {var_value}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to set variable {var_name} to {var_value}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def show_variable(self, command):
|
||||
if self.server_type != "admin":
|
||||
print("This command is only allowed in ADMIN mode")
|
||||
|
||||
var_name = _strip_tree_value(command["var_name"])
|
||||
response = self.http_client.request(method="GET", path="/admin/variables", json_body={"var_name": var_name},
|
||||
use_api_base=True, auth_kind="admin")
|
||||
response = self.http_client.request(method="GET", path="/admin/variables", json_body={"var_name": var_name}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -604,8 +560,7 @@ class RAGFlowClient:
|
||||
if self.server_type != "admin":
|
||||
print("This command is only allowed in ADMIN mode")
|
||||
license = command["license"]
|
||||
response = self.http_client.request("POST", "/admin/license", json_body={"license": license}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("POST", "/admin/license", json_body={"license": license}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print("Set license successfully")
|
||||
@@ -617,9 +572,7 @@ class RAGFlowClient:
|
||||
print("This command is only allowed in ADMIN mode")
|
||||
value1 = command["value1"]
|
||||
value2 = command["value2"]
|
||||
response = self.http_client.request("POST", "/admin/license/config",
|
||||
json_body={"value1": value1, "value2": value2}, use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("POST", "/admin/license/config", json_body={"value1": value1, "value2": value2}, use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
print("Set license successfully")
|
||||
@@ -690,8 +643,7 @@ class RAGFlowClient:
|
||||
user_name: str = username_tree.children[0].strip("'\"")
|
||||
print(f"Listing all datasets of user: {user_name}")
|
||||
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name}/datasets", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name}/datasets", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
table_data = res_json["data"]
|
||||
@@ -708,8 +660,7 @@ class RAGFlowClient:
|
||||
username_tree: Tree = command["user_name"]
|
||||
user_name: str = username_tree.children[0].strip("'\"")
|
||||
print(f"Listing all agents of user: {user_name}")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name}/agents", use_api_base=True,
|
||||
auth_kind="admin")
|
||||
response = self.http_client.request("GET", f"/admin/users/{user_name}/agents", use_api_base=True, auth_kind="admin")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
table_data = res_json["data"]
|
||||
@@ -733,8 +684,7 @@ class RAGFlowClient:
|
||||
|
||||
# Step 1: Add provider
|
||||
provider_payload = {"provider_name": provider_name}
|
||||
provider_response = self.http_client.request("PUT", "/providers", json_body=provider_payload,
|
||||
use_api_base=True, auth_kind="web")
|
||||
provider_response = self.http_client.request("PUT", "/providers", json_body=provider_payload, use_api_base=True, auth_kind="web")
|
||||
provider_res = provider_response.json()
|
||||
if provider_response.status_code == 200 and provider_res.get("code") == 0:
|
||||
print(f"Success to add provider {provider_name}")
|
||||
@@ -747,15 +697,8 @@ class RAGFlowClient:
|
||||
return
|
||||
|
||||
# Step 2: Add instance
|
||||
instance_payload = {
|
||||
"instance_name": "default",
|
||||
"api_key": api_key,
|
||||
"region": "default",
|
||||
"base_url": ""
|
||||
}
|
||||
instance_response = self.http_client.request("POST", f"/providers/{provider_name}/instances",
|
||||
json_body=instance_payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
instance_payload = {"instance_name": "default", "api_key": api_key, "region": "default", "base_url": ""}
|
||||
instance_response = self.http_client.request("POST", f"/providers/{provider_name}/instances", json_body=instance_payload, use_api_base=True, auth_kind="web")
|
||||
instance_res = instance_response.json()
|
||||
if instance_response.status_code == 200 and instance_res.get("code") == 0:
|
||||
print(f"Success to add instance for provider {provider_name}")
|
||||
@@ -771,8 +714,7 @@ class RAGFlowClient:
|
||||
print("This command is only allowed in USER mode")
|
||||
return
|
||||
provider_name: str = command["provider_name"]
|
||||
response = self.http_client.request("DELETE", f"/providers/{provider_name}", use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("DELETE", f"/providers/{provider_name}", use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print(f"Success to drop model provider {provider_name}")
|
||||
@@ -810,8 +752,7 @@ class RAGFlowClient:
|
||||
"model_type": model_type,
|
||||
"model_name": model_name,
|
||||
}
|
||||
response = self.http_client.request("PATCH", "/models/default", json_body=payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("PATCH", "/models/default", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print(f"Success to set default {model_type} to {model_id}")
|
||||
@@ -830,8 +771,7 @@ class RAGFlowClient:
|
||||
return
|
||||
|
||||
payload = {"model_type": model_type}
|
||||
response = self.http_client.request("PATCH", "/models/default", json_body=payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("PATCH", "/models/default", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print(f"Success to reset default {model_type}")
|
||||
@@ -861,8 +801,7 @@ class RAGFlowClient:
|
||||
|
||||
iterations = command.get("iterations", 1)
|
||||
if iterations > 1:
|
||||
response = self.http_client.request("GET", "/datasets", use_api_base=True, auth_kind="web",
|
||||
iterations=iterations)
|
||||
response = self.http_client.request("GET", "/datasets", use_api_base=True, auth_kind="web", iterations=iterations)
|
||||
return response
|
||||
else:
|
||||
response = self.http_client.request("GET", "/datasets", use_api_base=True, auth_kind="web")
|
||||
@@ -876,16 +815,12 @@ class RAGFlowClient:
|
||||
def create_user_dataset(self, command):
|
||||
if self.server_type != "user":
|
||||
print("This command is only allowed in USER mode")
|
||||
payload = {
|
||||
"name": command["dataset_name"],
|
||||
"embedding_model": command["embedding"]
|
||||
}
|
||||
payload = {"name": command["dataset_name"], "embedding_model": command["embedding"]}
|
||||
if "parser_id" in command:
|
||||
payload["chunk_method"] = command["parser"]
|
||||
if "pipeline" in command:
|
||||
payload["pipeline_id"] = command["pipeline"]
|
||||
response = self.http_client.request("POST", "/datasets", json_body=payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("POST", "/datasets", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
self._print_table_simple(res_json["data"])
|
||||
@@ -981,8 +916,7 @@ class RAGFlowClient:
|
||||
|
||||
dataset_ids = [dataset_id for _, dataset_id in valid_datasets]
|
||||
kb_ids_param = ",".join(dataset_ids)
|
||||
response = self.http_client.request("GET", f"/kb/get_meta?kb_ids={kb_ids_param}",
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("GET", f"/kb/get_meta?kb_ids={kb_ids_param}", use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code != 200:
|
||||
print(f"Fail to get metadata, code: {res_json.get('code')}, message: {res_json.get('message')}")
|
||||
@@ -996,11 +930,7 @@ class RAGFlowClient:
|
||||
table_data = []
|
||||
for field_name, values_dict in meta.items():
|
||||
for value, docs in values_dict.items():
|
||||
table_data.append({
|
||||
"field": field_name,
|
||||
"value": value,
|
||||
"doc_ids": ", ".join(docs)
|
||||
})
|
||||
table_data.append({"field": field_name, "value": value, "doc_ids": ", ".join(docs)})
|
||||
self._print_table_simple(table_data)
|
||||
|
||||
def list_user_documents_metadata_summary(self, command_dict):
|
||||
@@ -1018,8 +948,7 @@ class RAGFlowClient:
|
||||
payload = {"kb_id": kb_id}
|
||||
if doc_ids:
|
||||
payload["doc_ids"] = doc_ids
|
||||
response = self.http_client.request("POST", "/document/metadata/summary", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", "/document/metadata/summary", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
summary = res_json.get("data", {}).get("summary", {})
|
||||
@@ -1086,16 +1015,11 @@ class RAGFlowClient:
|
||||
"quote": True,
|
||||
"keyword": False,
|
||||
"tts": False,
|
||||
"system": "You are an intelligent assistant. Your primary function is to answer questions based strictly on the provided knowledge base.\n\n **Essential Rules:**\n - Your answer must be derived **solely** from this knowledge base: `{knowledge}`.\n - **When information is available**: Summarize the content to give a detailed answer.\n - **When information is unavailable**: Your response must contain this exact sentence: \"The answer you are looking for is not found in the knowledge base!\"\n - **Always consider** the entire conversation history.",
|
||||
"system": 'You are an intelligent assistant. Your primary function is to answer questions based strictly on the provided knowledge base.\n\n **Essential Rules:**\n - Your answer must be derived **solely** from this knowledge base: `{knowledge}`.\n - **When information is available**: Summarize the content to give a detailed answer.\n - **When information is unavailable**: Your response must contain this exact sentence: "The answer you are looking for is not found in the knowledge base!"\n - **Always consider** the entire conversation history.',
|
||||
"refine_multiturn": False,
|
||||
"use_kg": False,
|
||||
"reasoning": False,
|
||||
"parameters": [
|
||||
{
|
||||
"key": "knowledge",
|
||||
"optional": False
|
||||
}
|
||||
],
|
||||
"parameters": [{"key": "knowledge", "optional": False}],
|
||||
"toc_enhance": False,
|
||||
},
|
||||
"similarity_threshold": 0.2,
|
||||
@@ -1136,8 +1060,7 @@ class RAGFlowClient:
|
||||
# Build payload
|
||||
payload = {"kb_id": dataset_id, "vector_size": vector_size}
|
||||
# Call API
|
||||
response = self.http_client.request("POST", "/kb/doc_engine_table", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", "/kb/doc_engine_table", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print(f"Success to create table for dataset: {dataset_name}")
|
||||
@@ -1155,8 +1078,7 @@ class RAGFlowClient:
|
||||
return
|
||||
# Call API to delete table
|
||||
payload = {"kb_id": dataset_id}
|
||||
response = self.http_client.request("DELETE", "/kb/doc_engine_table", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("DELETE", "/kb/doc_engine_table", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print(f"Success to drop table for dataset: {dataset_name}")
|
||||
@@ -1168,8 +1090,7 @@ class RAGFlowClient:
|
||||
print("This command is only allowed in USER mode")
|
||||
return
|
||||
# Call API to create metadata table
|
||||
response = self.http_client.request("POST", "/tenant/doc_engine_metadata_table",
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", "/tenant/doc_engine_metadata_table", use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print("Success to create metadata table")
|
||||
@@ -1181,8 +1102,7 @@ class RAGFlowClient:
|
||||
print("This command is only allowed in USER mode")
|
||||
return
|
||||
# Call API to delete metadata table
|
||||
response = self.http_client.request("DELETE", "/tenant/doc_engine_metadata_table",
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("DELETE", "/tenant/doc_engine_metadata_table", use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json.get("code") == 0:
|
||||
print("Success to drop metadata table")
|
||||
@@ -1225,8 +1145,7 @@ class RAGFlowClient:
|
||||
|
||||
def _list_chat_sessions(self, dialog_id):
|
||||
"""List all sessions (conversations) for a given dialog."""
|
||||
response = self.http_client.request("GET", f"/chats/{dialog_id}/conversations", use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("GET", f"/chats/{dialog_id}/conversations", use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json["code"] == 0:
|
||||
return res_json["data"]
|
||||
@@ -1242,14 +1161,12 @@ class RAGFlowClient:
|
||||
if dialog_id is None:
|
||||
return
|
||||
payload = {"name": "New conversation"}
|
||||
response = self.http_client.request("POST", f"/chats/{dialog_id}/conversations", json_body=payload,
|
||||
use_api_base=True, auth_kind="web")
|
||||
response = self.http_client.request("POST", f"/chats/{dialog_id}/conversations", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json["code"] == 0:
|
||||
print(f"Success to create chat session for chat: {chat_name}")
|
||||
else:
|
||||
print(
|
||||
f"Fail to create chat session for chat {chat_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to create chat session for chat {chat_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def drop_chat_session(self, command):
|
||||
if self.server_type != "user":
|
||||
@@ -1270,14 +1187,12 @@ class RAGFlowClient:
|
||||
print(f"Chat session '{session_id}' not found in chat '{chat_name}'")
|
||||
return
|
||||
payload = {"ids": to_drop_session_ids}
|
||||
response = self.http_client.request("DELETE", f"/chats/{dialog_id}/conversations", json_body=payload,
|
||||
use_api_base=True, auth_kind="web")
|
||||
response = self.http_client.request("DELETE", f"/chats/{dialog_id}/conversations", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json["code"] == 0:
|
||||
print(f"Success to drop chat session '{session_id}' from chat: {chat_name}")
|
||||
else:
|
||||
print(
|
||||
f"Fail to drop chat session '{session_id}' from chat {chat_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to drop chat session '{session_id}' from chat {chat_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def list_chat_sessions(self, command):
|
||||
if self.server_type != "user":
|
||||
@@ -1305,13 +1220,9 @@ class RAGFlowClient:
|
||||
|
||||
# Prepare payload for completion API
|
||||
# Note: stream parameter is not sent, server defaults to stream=True
|
||||
payload = {
|
||||
"session_id": session_id,
|
||||
"messages": [{"role": "user", "content": message}]
|
||||
}
|
||||
payload = {"session_id": session_id, "messages": [{"role": "user", "content": message}]}
|
||||
|
||||
response = self.http_client.request("POST", "/chat/completions", json_body=payload,
|
||||
use_api_base=True, auth_kind="web", stream=True)
|
||||
response = self.http_client.request("POST", "/chat/completions", json_body=payload, use_api_base=True, auth_kind="web", stream=True)
|
||||
|
||||
if response.status_code != 200:
|
||||
print(f"Fail to chat on session, status code: {response.status_code}")
|
||||
@@ -1322,17 +1233,16 @@ class RAGFlowClient:
|
||||
for line in response.iter_lines():
|
||||
if not line:
|
||||
continue
|
||||
line_str = line.decode('utf-8')
|
||||
if not line_str.startswith('data:'):
|
||||
line_str = line.decode("utf-8")
|
||||
if not line_str.startswith("data:"):
|
||||
continue
|
||||
data_str = line_str[5:].strip()
|
||||
if data_str == '[DONE]':
|
||||
if data_str == "[DONE]":
|
||||
break
|
||||
try:
|
||||
data_json = json.loads(data_str)
|
||||
if data_json.get("code") != 0:
|
||||
print(
|
||||
f"\nFail to chat on session, code: {data_json.get('code')}, message: {data_json.get('message', '')}")
|
||||
print(f"\nFail to chat on session, code: {data_json.get('code')}, message: {data_json.get('message', '')}")
|
||||
return
|
||||
# Check if it's the final message
|
||||
if data_json.get("data") is True:
|
||||
@@ -1416,14 +1326,12 @@ class RAGFlowClient:
|
||||
print(f"Documents {document_names} not found in {dataset_name}")
|
||||
|
||||
payload = {"doc_ids": document_ids, "run": 1}
|
||||
response = self.http_client.request("POST", "/documents/ingest", json_body=payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("POST", "/documents/ingest", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json["code"] == 0:
|
||||
print(f"Success to parse {to_parse_doc_names} of {dataset_name}")
|
||||
else:
|
||||
print(
|
||||
f"Fail to parse documents {res_json["data"]["docs"]}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to parse documents {res_json['data']['docs']}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def parse_dataset(self, command_dict):
|
||||
if self.server_type != "user":
|
||||
@@ -1442,8 +1350,7 @@ class RAGFlowClient:
|
||||
document_ids.append(doc["id"])
|
||||
|
||||
payload = {"doc_ids": document_ids, "run": 1}
|
||||
response = self.http_client.request("POST", "/documents/ingest", json_body=payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("POST", "/documents/ingest", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200 and res_json["code"] == 0:
|
||||
pass
|
||||
@@ -1483,15 +1390,7 @@ class RAGFlowClient:
|
||||
encoder = MultipartEncoder(fields=fields)
|
||||
headers = {"Content-Type": encoder.content_type}
|
||||
response = self.http_client.request(
|
||||
"POST",
|
||||
f"/datasets/{dataset_id}/documents?return_raw_files=true",
|
||||
headers=headers,
|
||||
data=encoder,
|
||||
json_body=None,
|
||||
params=None,
|
||||
stream=False,
|
||||
auth_kind="web",
|
||||
use_api_base=True
|
||||
"POST", f"/datasets/{dataset_id}/documents?return_raw_files=true", headers=headers, data=encoder, json_body=None, params=None, stream=False, auth_kind="web", use_api_base=True
|
||||
)
|
||||
res = response.json()
|
||||
if res.get("code") == 0:
|
||||
@@ -1526,22 +1425,18 @@ class RAGFlowClient:
|
||||
}
|
||||
iterations = command_dict.get("iterations", 1)
|
||||
if iterations > 1:
|
||||
response = self.http_client.request("POST", "/retrieval", json_body=payload, use_api_base=True,
|
||||
auth_kind="web", iterations=iterations)
|
||||
response = self.http_client.request("POST", "/retrieval", json_body=payload, use_api_base=True, auth_kind="web", iterations=iterations)
|
||||
return response
|
||||
else:
|
||||
response = self.http_client.request("POST", "/retrieval", json_body=payload, use_api_base=True,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("POST", "/retrieval", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json["code"] == 0:
|
||||
self._print_table_simple(res_json["data"]["chunks"])
|
||||
else:
|
||||
print(
|
||||
f"Fail to search datasets: {dataset_names}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to search datasets: {dataset_names}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
else:
|
||||
print(
|
||||
f"Fail to search datasets: {dataset_names}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to search datasets: {dataset_names}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
|
||||
def get_chunk(self, command_dict):
|
||||
if self.server_type != "user":
|
||||
@@ -1549,8 +1444,7 @@ class RAGFlowClient:
|
||||
return
|
||||
|
||||
chunk_id = command_dict["chunk_id"]
|
||||
response = self.http_client.request("GET", f"/chunk/get?chunk_id={chunk_id}", use_api_base=False,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("GET", f"/chunk/get?chunk_id={chunk_id}", use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json["code"] == 0:
|
||||
@@ -1568,8 +1462,7 @@ class RAGFlowClient:
|
||||
|
||||
file_path = command_dict["file_path"]
|
||||
payload = {"file_path": file_path}
|
||||
response = self.http_client.request("POST", "/kb/insert_from_file", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", "/kb/insert_from_file", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json["code"] == 0:
|
||||
@@ -1589,8 +1482,7 @@ class RAGFlowClient:
|
||||
|
||||
file_path = command_dict["file_path"]
|
||||
payload = {"file_path": file_path}
|
||||
response = self.http_client.request("POST", "/tenant/insert_metadata_from_file", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", "/tenant/insert_metadata_from_file", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json["code"] == 0:
|
||||
@@ -1617,8 +1509,7 @@ class RAGFlowClient:
|
||||
return
|
||||
|
||||
# Get doc_id from chunk_id via GET /chunk/get
|
||||
response = self.http_client.request("GET", f"/chunk/get?chunk_id={chunk_id}", use_api_base=False,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("GET", f"/chunk/get?chunk_id={chunk_id}", use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code != 200:
|
||||
print(f"Fail to get chunk info, code: {res_json.get('code')}, message: {res_json.get('message')}")
|
||||
@@ -1655,14 +1546,8 @@ class RAGFlowClient:
|
||||
else:
|
||||
print(f"Fail to update chunk, HTTP {response.status_code}")
|
||||
|
||||
def _get_documents_by_ids(self, ids:list[str]):
|
||||
response = self.http_client.request(
|
||||
"POST",
|
||||
"/document/infos",
|
||||
json_body={"doc_ids": ids},
|
||||
use_api_base=False,
|
||||
auth_kind="web"
|
||||
)
|
||||
def _get_documents_by_ids(self, ids: list[str]):
|
||||
response = self.http_client.request("POST", "/document/infos", json_body={"doc_ids": ids}, use_api_base=False, auth_kind="web")
|
||||
|
||||
if response.status_code != 200:
|
||||
return f"Fail to get document info, HTTP {response.status_code}", None
|
||||
@@ -1687,6 +1572,7 @@ class RAGFlowClient:
|
||||
|
||||
# Parse JSON string to dict
|
||||
import json
|
||||
|
||||
try:
|
||||
meta_fields = json.loads(meta_json_str)
|
||||
except json.JSONDecodeError as e:
|
||||
@@ -1713,13 +1599,7 @@ class RAGFlowClient:
|
||||
"meta_fields": meta_fields,
|
||||
}
|
||||
|
||||
response = self.http_client.request(
|
||||
"PATCH",
|
||||
f"/datasets/{dataset_id}/documents/{doc_id}",
|
||||
json_body=payload,
|
||||
use_api_base=True,
|
||||
auth_kind="web"
|
||||
)
|
||||
response = self.http_client.request("PATCH", f"/datasets/{dataset_id}/documents/{doc_id}", json_body=payload, use_api_base=True, auth_kind="web")
|
||||
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
@@ -1747,8 +1627,7 @@ class RAGFlowClient:
|
||||
"tags": tags,
|
||||
}
|
||||
|
||||
response = self.http_client.request("POST", f"/kb/{dataset_id}/rm_tags", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", f"/kb/{dataset_id}/rm_tags", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json.get("code") == 0:
|
||||
@@ -1771,8 +1650,7 @@ class RAGFlowClient:
|
||||
elif command_dict.get("chunk_ids"):
|
||||
payload["chunk_ids"] = command_dict["chunk_ids"]
|
||||
|
||||
response = self.http_client.request("POST", "/chunk/rm", json_body=payload,
|
||||
use_api_base=False, auth_kind="web")
|
||||
response = self.http_client.request("POST", "/chunk/rm", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json.get("code") == 0:
|
||||
@@ -1803,15 +1681,14 @@ class RAGFlowClient:
|
||||
if "available_int" in command_dict:
|
||||
payload["available_int"] = command_dict["available_int"]
|
||||
|
||||
response = self.http_client.request("POST", "/chunk/list", json_body=payload, use_api_base=False,
|
||||
auth_kind="web")
|
||||
response = self.http_client.request("POST", "/chunk/list", json_body=payload, use_api_base=False, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code == 200:
|
||||
if res_json["code"] == 0:
|
||||
chunks = res_json["data"]["chunks"]
|
||||
if chunks:
|
||||
for i, chunk in enumerate(chunks):
|
||||
print(f"\n--- Chunk {i+1} ---")
|
||||
print(f"\n--- Chunk {i + 1} ---")
|
||||
for key, value in chunk.items():
|
||||
print(f" {key}: {value}")
|
||||
else:
|
||||
@@ -1845,7 +1722,7 @@ class RAGFlowClient:
|
||||
all_done = True
|
||||
for doc in docs:
|
||||
if doc.get("run") != "DONE":
|
||||
print(f"Document {doc["name"]} is not done, status: {doc.get("run")}")
|
||||
print(f"Document {doc['name']} is not done, status: {doc.get('run')}")
|
||||
all_done = False
|
||||
break
|
||||
if all_done:
|
||||
@@ -1856,16 +1733,10 @@ class RAGFlowClient:
|
||||
|
||||
def _list_documents(self, dataset_name: str, dataset_id: str):
|
||||
# Use the new RESTful API: GET /api/v1/datasets/<dataset_id>/documents
|
||||
response = self.http_client.request(
|
||||
"GET",
|
||||
f"/datasets/{dataset_id}/documents",
|
||||
use_api_base=True,
|
||||
auth_kind="web"
|
||||
)
|
||||
response = self.http_client.request("GET", f"/datasets/{dataset_id}/documents", use_api_base=True, auth_kind="web")
|
||||
res_json = response.json()
|
||||
if response.status_code != 200:
|
||||
print(
|
||||
f"Fail to list files from dataset {dataset_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
print(f"Fail to list files from dataset {dataset_name}, code: {res_json['code']}, message: {res_json['message']}")
|
||||
return None
|
||||
return res_json["data"]["docs"]
|
||||
|
||||
@@ -2254,22 +2125,14 @@ def run_benchmark(client: RAGFlowClient, command_dict: dict):
|
||||
total_duration = result["duration"]
|
||||
qps = iterations / total_duration if total_duration > 0 else None
|
||||
print(f"command: {command}, Concurrency: {concurrency}, iterations: {iterations}")
|
||||
print(
|
||||
f"total duration: {total_duration:.4f}s, QPS: {qps}, COMMAND_COUNT: {iterations}, SUCCESS: {success_count}, FAILURE: {iterations - success_count}")
|
||||
print(f"total duration: {total_duration:.4f}s, QPS: {qps}, COMMAND_COUNT: {iterations}, SUCCESS: {success_count}, FAILURE: {iterations - success_count}")
|
||||
pass
|
||||
else:
|
||||
results: List[Optional[dict]] = [None] * concurrency
|
||||
mp_context = mp.get_context("spawn")
|
||||
start_time = time.perf_counter()
|
||||
with ProcessPoolExecutor(max_workers=concurrency, mp_context=mp_context) as executor:
|
||||
future_map = {
|
||||
executor.submit(
|
||||
run_command,
|
||||
client,
|
||||
command
|
||||
): idx
|
||||
for idx in range(concurrency)
|
||||
}
|
||||
future_map = {executor.submit(run_command, client, command): idx for idx in range(concurrency)}
|
||||
for future in as_completed(future_map):
|
||||
idx = future_map[future]
|
||||
results[idx] = future.result()
|
||||
@@ -2291,7 +2154,6 @@ def run_benchmark(client: RAGFlowClient, command_dict: dict):
|
||||
total_command_count = iterations * concurrency
|
||||
qps = total_command_count / total_duration if total_duration > 0 else None
|
||||
print(f"command: {command}, Concurrency: {concurrency} , iterations: {iterations}")
|
||||
print(
|
||||
f"total duration: {total_duration:.4f}s, QPS: {qps}, COMMAND_COUNT: {total_command_count}, SUCCESS: {success_count}, FAILURE: {total_command_count - success_count}")
|
||||
print(f"total duration: {total_duration:.4f}s, QPS: {qps}, COMMAND_COUNT: {total_command_count}, SUCCESS: {success_count}, FAILURE: {total_command_count - success_count}")
|
||||
|
||||
pass
|
||||
|
||||
@@ -29,6 +29,7 @@ def encrypt_password(password_plain: str) -> str:
|
||||
import base64
|
||||
from Cryptodome.PublicKey import RSA
|
||||
from Cryptodome.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
|
||||
|
||||
def crypt(line):
|
||||
"""
|
||||
decrypt(crypt(input_string)) == base64(input_string), which frontend and ragflow_cli use.
|
||||
@@ -36,13 +37,11 @@ def encrypt_password(password_plain: str) -> str:
|
||||
pub = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArq9XTUSeYr2+N1h3Afl/z8Dse/2yD0ZGrKwx+EEEcdsBLca9Ynmx3nIB5obmLlSfmskLpBo0UACBmB5rEjBp2Q2f3AG3Hjd4B+gNCG6BDaawuDlgANIhGnaTLrIqWrrcm4EMzJOnAOI1fgzJRsOOUEfaS318Eq9OVO3apEyCCt0lOQK6PuksduOjVxtltDav+guVAA068NrPYmRNabVKRNLJpL8w4D44sfth5RvZ3q9t+6RTArpEtc5sh5ChzvqPOzKGMXW83C95TxmXqpbK6olN4RevSfVjEAgCydH6HN6OhtOQEcnrU97r9H0iZOWwbw3pVrZiUkuRD1R56Wzs2wIDAQAB\n-----END PUBLIC KEY-----"
|
||||
rsa_key = RSA.importKey(pub)
|
||||
cipher = Cipher_pkcs1_v1_5.new(rsa_key)
|
||||
password_base64 = base64.b64encode(line.encode('utf-8')).decode("utf-8")
|
||||
password_base64 = base64.b64encode(line.encode("utf-8")).decode("utf-8")
|
||||
encrypted_password = cipher.encrypt(password_base64.encode())
|
||||
return base64.b64encode(encrypted_password).decode('utf-8')
|
||||
return base64.b64encode(encrypted_password).decode("utf-8")
|
||||
except Exception as exc:
|
||||
raise AuthException(
|
||||
"Password encryption unavailable; install pycryptodomex (uv sync --python 3.13 --group test)."
|
||||
) from exc
|
||||
raise AuthException("Password encryption unavailable; install pycryptodomex (uv sync --python 3.13 --group test).") from exc
|
||||
return crypt(password_plain)
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#
|
||||
|
||||
import time
|
||||
|
||||
start_ts = time.time()
|
||||
|
||||
import os
|
||||
@@ -38,26 +39,24 @@ from common.versions import get_ragflow_version
|
||||
|
||||
stop_event = threading.Event()
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
faulthandler.enable()
|
||||
init_root_logger("admin_service")
|
||||
logging.info(r"""
|
||||
____ ___ ______________ ___ __ _
|
||||
/ __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___
|
||||
____ ___ ______________ ___ __ _
|
||||
/ __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___
|
||||
/ /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \
|
||||
/ _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / /
|
||||
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
|
||||
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
|
||||
""")
|
||||
|
||||
app = Flask(__name__)
|
||||
app.register_blueprint(admin_bp)
|
||||
app.config["SESSION_PERMANENT"] = False
|
||||
app.config["SESSION_TYPE"] = "filesystem"
|
||||
app.config["MAX_CONTENT_LENGTH"] = int(
|
||||
os.environ.get("MAX_CONTENT_LENGTH", 1024 * 1024 * 1024)
|
||||
)
|
||||
app.config["MAX_CONTENT_LENGTH"] = int(os.environ.get("MAX_CONTENT_LENGTH", 1024 * 1024 * 1024))
|
||||
Session(app)
|
||||
logging.info(f'RAGFlow admin version: {get_ragflow_version()}')
|
||||
logging.info(f"RAGFlow admin version: {get_ragflow_version()}")
|
||||
show_configs()
|
||||
login_manager = LoginManager()
|
||||
login_manager.init_app(app)
|
||||
|
||||
@@ -70,9 +70,7 @@ def setup_auth(login_manager):
|
||||
logging.warning(f"Authentication attempt with invalid token format: {len(access_token)} chars")
|
||||
return None
|
||||
|
||||
user = UserService.query(
|
||||
access_token=access_token, status=StatusEnum.VALID.value
|
||||
)
|
||||
user = UserService.query(access_token=access_token, status=StatusEnum.VALID.value)
|
||||
if user:
|
||||
if not user[0].access_token or not user[0].access_token.strip():
|
||||
logging.warning(f"User {user[0].email} has empty access_token in database")
|
||||
@@ -126,19 +124,13 @@ def add_tenant_for_admin(user_info: dict, role: str):
|
||||
"img2txt_id": settings.IMAGE2TEXT_MDL,
|
||||
"rerank_id": settings.RERANK_MDL,
|
||||
}
|
||||
usr_tenant = {
|
||||
"tenant_id": user_info["id"],
|
||||
"user_id": user_info["id"],
|
||||
"invited_by": user_info["id"],
|
||||
"role": role
|
||||
}
|
||||
usr_tenant = {"tenant_id": user_info["id"], "user_id": user_info["id"], "invited_by": user_info["id"], "role": role}
|
||||
|
||||
# tenant_llm = get_init_tenant_llm(user_info["id"])
|
||||
TenantService.insert(**tenant)
|
||||
UserTenantService.insert(**usr_tenant)
|
||||
# TenantLLMService.insert_many(tenant_llm)
|
||||
logging.info(
|
||||
f"Added tenant for email: {user_info['email']}, A default tenant has been set; changing the default models after login is strongly recommended.")
|
||||
logging.info(f"Added tenant for email: {user_info['email']}, A default tenant has been set; changing the default models after login is strongly recommended.")
|
||||
|
||||
|
||||
def check_admin_auth(func):
|
||||
@@ -212,28 +204,17 @@ def login_verify(f):
|
||||
@wraps(f)
|
||||
def decorated(*args, **kwargs):
|
||||
auth = request.authorization
|
||||
if not auth or 'username' not in auth.parameters or 'password' not in auth.parameters:
|
||||
return jsonify({
|
||||
"code": 401,
|
||||
"message": "Authentication required",
|
||||
"data": None
|
||||
}), 200
|
||||
if not auth or "username" not in auth.parameters or "password" not in auth.parameters:
|
||||
return jsonify({"code": 401, "message": "Authentication required", "data": None}), 200
|
||||
|
||||
username = auth.parameters['username']
|
||||
password = auth.parameters['password']
|
||||
username = auth.parameters["username"]
|
||||
password = auth.parameters["password"]
|
||||
try:
|
||||
if not check_admin(username, password):
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"message": "Access denied",
|
||||
"data": None
|
||||
}), 200
|
||||
return jsonify({"code": 500, "message": "Access denied", "data": None}), 200
|
||||
except Exception:
|
||||
logging.exception("An error occurred during admin login verification.")
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"message": "An internal server error occurred."
|
||||
}), 200
|
||||
return jsonify({"code": 500, "message": "An internal server error occurred."}), 200
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -34,8 +34,7 @@ class BaseConfig(BaseModel):
|
||||
detail_func_name: str
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
return {'id': self.id, 'name': self.name, 'host': self.host, 'port': self.port,
|
||||
'service_type': self.service_type}
|
||||
return {"id": self.id, "name": self.name, "host": self.host, "port": self.port, "service_type": self.service_type}
|
||||
|
||||
|
||||
class ServiceConfigs:
|
||||
@@ -63,11 +62,11 @@ class MetaConfig(BaseConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['meta_type'] = self.meta_type
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["meta_type"] = self.meta_type
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -77,21 +76,20 @@ class MySQLConfig(MetaConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['username'] = self.username
|
||||
extra_dict['password'] = self.password
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["username"] = self.username
|
||||
extra_dict["password"] = self.password
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
class PostgresConfig(MetaConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
return result
|
||||
|
||||
|
||||
@@ -100,11 +98,11 @@ class RetrievalConfig(BaseConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['retrieval_type'] = self.retrieval_type
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["retrieval_type"] = self.retrieval_type
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -113,11 +111,11 @@ class InfinityConfig(RetrievalConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['db_name'] = self.db_name
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["db_name"] = self.db_name
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -127,12 +125,12 @@ class ElasticsearchConfig(RetrievalConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['username'] = self.username
|
||||
extra_dict['password'] = self.password
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["username"] = self.username
|
||||
extra_dict["password"] = self.password
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -141,11 +139,11 @@ class MessageQueueConfig(BaseConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['mq_type'] = self.mq_type
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["mq_type"] = self.mq_type
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -155,30 +153,28 @@ class RedisConfig(MessageQueueConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['database'] = self.database
|
||||
extra_dict['password'] = self.password
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["database"] = self.database
|
||||
extra_dict["password"] = self.password
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
class RabbitMQConfig(MessageQueueConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
return result
|
||||
|
||||
|
||||
class RAGFlowServerConfig(BaseConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
return result
|
||||
|
||||
|
||||
@@ -187,9 +183,9 @@ class TaskExecutorConfig(BaseConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
result['extra']['message_queue_type'] = self.message_queue_type
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
result["extra"]["message_queue_type"] = self.message_queue_type
|
||||
return result
|
||||
|
||||
|
||||
@@ -198,11 +194,11 @@ class FileStoreConfig(BaseConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['store_type'] = self.store_type
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["store_type"] = self.store_type
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -212,12 +208,12 @@ class MinioConfig(FileStoreConfig):
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
result = super().to_dict()
|
||||
if 'extra' not in result:
|
||||
result['extra'] = dict()
|
||||
extra_dict = result['extra'].copy()
|
||||
extra_dict['user'] = self.user
|
||||
extra_dict['password'] = self.password
|
||||
result['extra'] = extra_dict
|
||||
if "extra" not in result:
|
||||
result["extra"] = dict()
|
||||
extra_dict = result["extra"].copy()
|
||||
extra_dict["user"] = self.user
|
||||
extra_dict["password"] = self.password
|
||||
result["extra"] = extra_dict
|
||||
return result
|
||||
|
||||
|
||||
@@ -229,106 +225,105 @@ def load_configurations(config_path: str) -> list[BaseConfig]:
|
||||
for k, v in raw_configs.items():
|
||||
match k:
|
||||
case "ragflow":
|
||||
name: str = f'ragflow_{ragflow_count}'
|
||||
host: str = v['host']
|
||||
http_port: int = v['http_port']
|
||||
config = RAGFlowServerConfig(id=id_count, name=name, host=host, port=http_port,
|
||||
service_type="ragflow_server",
|
||||
detail_func_name="check_ragflow_server_alive")
|
||||
name: str = f"ragflow_{ragflow_count}"
|
||||
host: str = v["host"]
|
||||
http_port: int = v["http_port"]
|
||||
config = RAGFlowServerConfig(id=id_count, name=name, host=host, port=http_port, service_type="ragflow_server", detail_func_name="check_ragflow_server_alive")
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "es":
|
||||
name: str = 'elasticsearch'
|
||||
url = v['hosts']
|
||||
name: str = "elasticsearch"
|
||||
url = v["hosts"]
|
||||
parsed = urlparse(url)
|
||||
host: str = parsed.hostname
|
||||
port: int = parsed.port
|
||||
username: str = v.get('username')
|
||||
password: str = v.get('password')
|
||||
config = ElasticsearchConfig(id=id_count, name=name, host=host, port=port, service_type="retrieval",
|
||||
retrieval_type="elasticsearch",
|
||||
username=username, password=password,
|
||||
detail_func_name="get_es_cluster_stats")
|
||||
username: str = v.get("username")
|
||||
password: str = v.get("password")
|
||||
config = ElasticsearchConfig(
|
||||
id=id_count,
|
||||
name=name,
|
||||
host=host,
|
||||
port=port,
|
||||
service_type="retrieval",
|
||||
retrieval_type="elasticsearch",
|
||||
username=username,
|
||||
password=password,
|
||||
detail_func_name="get_es_cluster_stats",
|
||||
)
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
|
||||
case "infinity":
|
||||
name: str = 'infinity'
|
||||
url = v['uri']
|
||||
parts = url.split(':', 1)
|
||||
name: str = "infinity"
|
||||
url = v["uri"]
|
||||
parts = url.split(":", 1)
|
||||
host = parts[0]
|
||||
port = int(parts[1])
|
||||
database: str = v.get('db_name', 'default_db')
|
||||
config = InfinityConfig(id=id_count, name=name, host=host, port=port, service_type="retrieval",
|
||||
retrieval_type="infinity",
|
||||
db_name=database, detail_func_name="get_infinity_status")
|
||||
database: str = v.get("db_name", "default_db")
|
||||
config = InfinityConfig(id=id_count, name=name, host=host, port=port, service_type="retrieval", retrieval_type="infinity", db_name=database, detail_func_name="get_infinity_status")
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "minio_0":
|
||||
name: str = 'minio_0'
|
||||
url = v['host']
|
||||
parts = url.split(':', 1)
|
||||
name: str = "minio_0"
|
||||
url = v["host"]
|
||||
parts = url.split(":", 1)
|
||||
host = parts[0]
|
||||
port = int(parts[1])
|
||||
user = v.get('user')
|
||||
password = v.get('password')
|
||||
config = MinioConfig(id=id_count, name=name, host=host, port=port, user=user, password=password,
|
||||
service_type="file_store",
|
||||
store_type="minio", detail_func_name="check_minio_alive")
|
||||
user = v.get("user")
|
||||
password = v.get("password")
|
||||
config = MinioConfig(id=id_count, name=name, host=host, port=port, user=user, password=password, service_type="file_store", store_type="minio", detail_func_name="check_minio_alive")
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "minio":
|
||||
name: str = 'minio'
|
||||
url = v['host']
|
||||
parts = url.split(':', 1)
|
||||
name: str = "minio"
|
||||
url = v["host"]
|
||||
parts = url.split(":", 1)
|
||||
host = parts[0]
|
||||
port = int(parts[1])
|
||||
user = v.get('user')
|
||||
password = v.get('password')
|
||||
config = MinioConfig(id=id_count, name=name, host=host, port=port, user=user, password=password,
|
||||
service_type="file_store",
|
||||
store_type="minio", detail_func_name="check_minio_alive")
|
||||
user = v.get("user")
|
||||
password = v.get("password")
|
||||
config = MinioConfig(id=id_count, name=name, host=host, port=port, user=user, password=password, service_type="file_store", store_type="minio", detail_func_name="check_minio_alive")
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "redis":
|
||||
name: str = 'redis'
|
||||
url = v['host']
|
||||
parts = url.split(':', 1)
|
||||
name: str = "redis"
|
||||
url = v["host"]
|
||||
parts = url.split(":", 1)
|
||||
host = parts[0]
|
||||
port = int(parts[1])
|
||||
password = v.get('password')
|
||||
db: int = v.get('db')
|
||||
config = RedisConfig(id=id_count, name=name, host=host, port=port, password=password, database=db,
|
||||
service_type="message_queue", mq_type="redis", detail_func_name="get_redis_info")
|
||||
password = v.get("password")
|
||||
db: int = v.get("db")
|
||||
config = RedisConfig(id=id_count, name=name, host=host, port=port, password=password, database=db, service_type="message_queue", mq_type="redis", detail_func_name="get_redis_info")
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "mysql":
|
||||
name: str = 'mysql'
|
||||
host: str = v.get('host')
|
||||
port: int = v.get('port')
|
||||
username = v.get('user')
|
||||
password = v.get('password')
|
||||
config = MySQLConfig(id=id_count, name=name, host=host, port=port, username=username, password=password,
|
||||
service_type="meta_data", meta_type="mysql", detail_func_name="get_mysql_status")
|
||||
name: str = "mysql"
|
||||
host: str = v.get("host")
|
||||
port: int = v.get("port")
|
||||
username = v.get("user")
|
||||
password = v.get("password")
|
||||
config = MySQLConfig(
|
||||
id=id_count, name=name, host=host, port=port, username=username, password=password, service_type="meta_data", meta_type="mysql", detail_func_name="get_mysql_status"
|
||||
)
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "admin":
|
||||
pass
|
||||
case "task_executor":
|
||||
name: str = 'task_executor'
|
||||
host: str = v.get('host', '')
|
||||
port: int = v.get('port', 0)
|
||||
message_queue_type: str = v.get('message_queue_type')
|
||||
config = TaskExecutorConfig(id=id_count, name=name, host=host, port=port, message_queue_type=message_queue_type,
|
||||
service_type="task_executor", detail_func_name="check_task_executor_alive")
|
||||
name: str = "task_executor"
|
||||
host: str = v.get("host", "")
|
||||
port: int = v.get("port", 0)
|
||||
message_queue_type: str = v.get("message_queue_type")
|
||||
config = TaskExecutorConfig(
|
||||
id=id_count, name=name, host=host, port=port, message_queue_type=message_queue_type, service_type="task_executor", detail_func_name="check_task_executor_alive"
|
||||
)
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case "rabbitmq":
|
||||
name: str = 'rabbitmq'
|
||||
host: str = v.get('host')
|
||||
port: int = v.get('port')
|
||||
config = RabbitMQConfig(id=id_count, name=name, host=host, port=port,
|
||||
service_type="message_queue", mq_type="rabbitmq", detail_func_name="check_rabbitmq_alive")
|
||||
name: str = "rabbitmq"
|
||||
host: str = v.get("host")
|
||||
port: int = v.get("port")
|
||||
config = RabbitMQConfig(id=id_count, name=name, host=host, port=port, service_type="message_queue", mq_type="rabbitmq", detail_func_name="check_rabbitmq_alive")
|
||||
configurations.append(config)
|
||||
id_count += 1
|
||||
case _:
|
||||
|
||||
@@ -4,14 +4,17 @@ class AdminException(Exception):
|
||||
self.code = code
|
||||
self.message = message
|
||||
|
||||
|
||||
class UserNotFoundError(AdminException):
|
||||
def __init__(self, username):
|
||||
super().__init__(f"User '{username}' not found", 404)
|
||||
|
||||
|
||||
class UserAlreadyExistsError(AdminException):
|
||||
def __init__(self, username):
|
||||
super().__init__(f"User '{username}' already exists", 409)
|
||||
|
||||
|
||||
class CannotDeleteAdminError(AdminException):
|
||||
def __init__(self):
|
||||
super().__init__("Cannot delete admin account", 403)
|
||||
super().__init__("Cannot delete admin account", 403)
|
||||
|
||||
@@ -17,16 +17,8 @@ from flask import jsonify
|
||||
|
||||
|
||||
def success_response(data=None, message="Success", code=0):
|
||||
return jsonify({
|
||||
"code": code,
|
||||
"message": message,
|
||||
"data": data
|
||||
}), 200
|
||||
return jsonify({"code": code, "message": message, "data": data}), 200
|
||||
|
||||
|
||||
def error_response(message="Error", code=-1, data=None):
|
||||
return jsonify({
|
||||
"code": code,
|
||||
"message": message,
|
||||
"data": data
|
||||
}), 400
|
||||
return jsonify({"code": code, "message": message, "data": data}), 400
|
||||
|
||||
@@ -489,10 +489,7 @@ class SandboxMgr:
|
||||
"""List all available sandbox providers."""
|
||||
result = []
|
||||
for provider_id, metadata in SandboxMgr.PROVIDER_REGISTRY.items():
|
||||
result.append({
|
||||
"id": provider_id,
|
||||
**metadata
|
||||
})
|
||||
result.append({"id": provider_id, **metadata})
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
@@ -635,6 +632,7 @@ class SandboxMgr:
|
||||
config_json = json.dumps(config)
|
||||
SettingsMgr.update_by_name(f"sandbox.{provider_type}", config_json)
|
||||
from agent.sandbox.client import reload_provider
|
||||
|
||||
reload_provider()
|
||||
|
||||
return {"provider_type": provider_type, "config": config}
|
||||
@@ -727,11 +725,7 @@ def main() -> dict:
|
||||
# Build detailed result message
|
||||
success = execution_result.exit_code == 0 and "TEST_PASSED" in execution_result.stdout
|
||||
|
||||
message_parts = [
|
||||
f"Test {success and 'PASSED' or 'FAILED'}",
|
||||
f"Exit code: {execution_result.exit_code}",
|
||||
f"Execution time: {execution_result.execution_time:.2f}s"
|
||||
]
|
||||
message_parts = [f"Test {success and 'PASSED' or 'FAILED'}", f"Exit code: {execution_result.exit_code}", f"Execution time: {execution_result.execution_time:.2f}s"]
|
||||
|
||||
if execution_result.stdout.strip():
|
||||
stdout_preview = execution_result.stdout.strip()[:200]
|
||||
@@ -751,12 +745,13 @@ def main() -> dict:
|
||||
"execution_time": execution_result.execution_time,
|
||||
"stdout": execution_result.stdout,
|
||||
"stderr": execution_result.stderr,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
except AdminException:
|
||||
raise
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
error_details = traceback.format_exc()
|
||||
raise AdminException(f"Connection test failed: {str(e)}\\n\\nStack trace:\\n{error_details}")
|
||||
|
||||
Reference in New Issue
Block a user