mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-02-02 00:25:06 +08:00
Add ping command to test ping API (#12757)
### What problem does this PR solve? As title. ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
from typing import Any, Dict, Optional, Tuple
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
# from requests.sessions import HTTPAdapter
|
||||||
|
|
||||||
|
|
||||||
class HttpClient:
|
class HttpClient:
|
||||||
@ -85,42 +86,46 @@ class HttpClient:
|
|||||||
) -> requests.Response | dict:
|
) -> requests.Response | dict:
|
||||||
url = self.build_url(path, use_api_base=use_api_base)
|
url = self.build_url(path, use_api_base=use_api_base)
|
||||||
merged_headers = self._headers(auth_kind, headers)
|
merged_headers = self._headers(auth_kind, headers)
|
||||||
timeout: Tuple[float, float] = (self.connect_timeout, self.read_timeout)
|
# timeout: Tuple[float, float] = (self.connect_timeout, self.read_timeout)
|
||||||
|
session = requests.Session()
|
||||||
|
# adapter = HTTPAdapter(pool_connections=100, pool_maxsize=100)
|
||||||
|
# session.mount("http://", adapter)
|
||||||
if iterations > 1:
|
if iterations > 1:
|
||||||
response_list = []
|
response_list = []
|
||||||
total_duration = 0.0
|
total_duration = 0.0
|
||||||
for _ in range(iterations):
|
for _ in range(iterations):
|
||||||
start_time = time.perf_counter()
|
start_time = time.perf_counter()
|
||||||
response = requests.request(
|
response = session.get(url, headers=merged_headers, json=json_body, data=data, stream=stream)
|
||||||
method=method,
|
# response = requests.request(
|
||||||
url=url,
|
# method=method,
|
||||||
headers=merged_headers,
|
# url=url,
|
||||||
json=json_body,
|
# headers=merged_headers,
|
||||||
data=data,
|
# json=json_body,
|
||||||
files=files,
|
# data=data,
|
||||||
params=params,
|
# files=files,
|
||||||
timeout=timeout,
|
# params=params,
|
||||||
stream=stream,
|
# timeout=timeout,
|
||||||
verify=self.verify_ssl,
|
# stream=stream,
|
||||||
)
|
# verify=self.verify_ssl,
|
||||||
|
# )
|
||||||
end_time = time.perf_counter()
|
end_time = time.perf_counter()
|
||||||
total_duration += end_time - start_time
|
total_duration += end_time - start_time
|
||||||
response_list.append(response)
|
response_list.append(response)
|
||||||
return {"duration": total_duration, "response_list": response_list}
|
return {"duration": total_duration, "response_list": response_list}
|
||||||
else:
|
else:
|
||||||
return requests.request(
|
return session.get(url, headers=merged_headers, json=json_body, data=data, stream=stream)
|
||||||
method=method,
|
# return requests.request(
|
||||||
url=url,
|
# method=method,
|
||||||
headers=merged_headers,
|
# url=url,
|
||||||
json=json_body,
|
# headers=merged_headers,
|
||||||
data=data,
|
# json=json_body,
|
||||||
files=files,
|
# data=data,
|
||||||
params=params,
|
# files=files,
|
||||||
timeout=timeout,
|
# params=params,
|
||||||
stream=stream,
|
# timeout=timeout,
|
||||||
verify=self.verify_ssl,
|
# stream=stream,
|
||||||
)
|
# verify=self.verify_ssl,
|
||||||
|
# )
|
||||||
|
|
||||||
def request_json(
|
def request_json(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@ -21,7 +21,9 @@ start: command
|
|||||||
|
|
||||||
command: sql_command | meta_command
|
command: sql_command | meta_command
|
||||||
|
|
||||||
sql_command: list_services
|
sql_command: login_user
|
||||||
|
| ping_server
|
||||||
|
| list_services
|
||||||
| show_service
|
| show_service
|
||||||
| startup_service
|
| startup_service
|
||||||
| shutdown_service
|
| shutdown_service
|
||||||
@ -98,6 +100,7 @@ meta_arg: /[^\\s"']+/ | quoted_string
|
|||||||
|
|
||||||
// command definition
|
// command definition
|
||||||
|
|
||||||
|
LOGIN: "LOGIN"i
|
||||||
REGISTER: "REGISTER"i
|
REGISTER: "REGISTER"i
|
||||||
LIST: "LIST"i
|
LIST: "LIST"i
|
||||||
SERVICES: "SERVICES"i
|
SERVICES: "SERVICES"i
|
||||||
@ -166,7 +169,9 @@ TTS: "TTS"i
|
|||||||
ASYNC: "ASYNC"i
|
ASYNC: "ASYNC"i
|
||||||
SYNC: "SYNC"i
|
SYNC: "SYNC"i
|
||||||
BENCHMARK: "BENCHMARK"i
|
BENCHMARK: "BENCHMARK"i
|
||||||
|
PING: "PING"i
|
||||||
|
|
||||||
|
login_user: LOGIN USER quoted_string ";"
|
||||||
list_services: LIST SERVICES ";"
|
list_services: LIST SERVICES ";"
|
||||||
show_service: SHOW SERVICE NUMBER ";"
|
show_service: SHOW SERVICE NUMBER ";"
|
||||||
startup_service: STARTUP SERVICE NUMBER ";"
|
startup_service: STARTUP SERVICE NUMBER ";"
|
||||||
@ -212,7 +217,8 @@ list_environments: LIST ENVS ";"
|
|||||||
|
|
||||||
benchmark: BENCHMARK NUMBER NUMBER user_statement
|
benchmark: BENCHMARK NUMBER NUMBER user_statement
|
||||||
|
|
||||||
user_statement: show_current_user
|
user_statement: ping_server
|
||||||
|
| show_current_user
|
||||||
| create_model_provider
|
| create_model_provider
|
||||||
| drop_model_provider
|
| drop_model_provider
|
||||||
| set_default_llm
|
| set_default_llm
|
||||||
@ -241,6 +247,7 @@ user_statement: show_current_user
|
|||||||
| import_docs_into_dataset
|
| import_docs_into_dataset
|
||||||
| search_on_datasets
|
| search_on_datasets
|
||||||
|
|
||||||
|
ping_server: PING ";"
|
||||||
show_current_user: SHOW CURRENT USER ";"
|
show_current_user: SHOW CURRENT USER ";"
|
||||||
create_model_provider: CREATE MODEL PROVIDER quoted_string quoted_string ";"
|
create_model_provider: CREATE MODEL PROVIDER quoted_string quoted_string ";"
|
||||||
drop_model_provider: DROP MODEL PROVIDER quoted_string ";"
|
drop_model_provider: DROP MODEL PROVIDER quoted_string ";"
|
||||||
@ -298,6 +305,13 @@ class RAGFlowCLITransformer(Transformer):
|
|||||||
def command(self, items):
|
def command(self, items):
|
||||||
return items[0]
|
return items[0]
|
||||||
|
|
||||||
|
def login_user(self, items):
|
||||||
|
email = items[2].children[0].strip("'\"")
|
||||||
|
return {"type": "login_user", "email": email}
|
||||||
|
|
||||||
|
def ping_server(self, items):
|
||||||
|
return {"type": "ping_server"}
|
||||||
|
|
||||||
def list_services(self, items):
|
def list_services(self, items):
|
||||||
result = {"type": "list_services"}
|
result = {"type": "list_services"}
|
||||||
return result
|
return result
|
||||||
|
|||||||
@ -54,7 +54,6 @@ class RAGFlowCLI(Cmd):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self.parser = Lark(GRAMMAR, start="start", parser="lalr", transformer=RAGFlowCLITransformer())
|
self.parser = Lark(GRAMMAR, start="start", parser="lalr", transformer=RAGFlowCLITransformer())
|
||||||
self.command_history = []
|
self.command_history = []
|
||||||
self.is_interactive = False
|
|
||||||
self.account = "admin@ragflow.io"
|
self.account = "admin@ragflow.io"
|
||||||
self.account_password: str = "admin"
|
self.account_password: str = "admin"
|
||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
@ -212,7 +211,6 @@ class RAGFlowCLI(Cmd):
|
|||||||
print(separator)
|
print(separator)
|
||||||
|
|
||||||
def run_interactive(self, args):
|
def run_interactive(self, args):
|
||||||
self.is_interactive = True
|
|
||||||
if self.verify_auth(args, single_command=False, auth=args["auth"]):
|
if self.verify_auth(args, single_command=False, auth=args["auth"]):
|
||||||
print(r"""
|
print(r"""
|
||||||
____ ___ ______________ ________ ____
|
____ ___ ______________ ________ ____
|
||||||
@ -226,7 +224,6 @@ class RAGFlowCLI(Cmd):
|
|||||||
print("RAGFlow command line interface - Type '\\?' for help, '\\q' to quit")
|
print("RAGFlow command line interface - Type '\\?' for help, '\\q' to quit")
|
||||||
|
|
||||||
def run_single_command(self, args):
|
def run_single_command(self, args):
|
||||||
self.is_interactive = False
|
|
||||||
if self.verify_auth(args, single_command=True, auth=args["auth"]):
|
if self.verify_auth(args, single_command=True, auth=args["auth"]):
|
||||||
command = args["command"]
|
command = args["command"]
|
||||||
result = self.parse_command(command)
|
result = self.parse_command(command)
|
||||||
@ -272,15 +269,15 @@ class RAGFlowCLI(Cmd):
|
|||||||
else:
|
else:
|
||||||
return {"error": "Invalid command"}
|
return {"error": "Invalid command"}
|
||||||
else:
|
else:
|
||||||
|
auth = True
|
||||||
if username is None:
|
if username is None:
|
||||||
print("Error: username (-u) is required in user mode")
|
auth = False
|
||||||
return {"error": "Username required"}
|
|
||||||
return {
|
return {
|
||||||
"host": parsed_args.host,
|
"host": parsed_args.host,
|
||||||
"port": parsed_args.port,
|
"port": parsed_args.port,
|
||||||
"type": parsed_args.type,
|
"type": parsed_args.type,
|
||||||
"username": username,
|
"username": username,
|
||||||
"auth": True
|
"auth": auth
|
||||||
}
|
}
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
return {"error": "Invalid connection arguments"}
|
return {"error": "Invalid connection arguments"}
|
||||||
@ -297,7 +294,7 @@ class RAGFlowCLI(Cmd):
|
|||||||
command_dict = parsed_command
|
command_dict = parsed_command
|
||||||
|
|
||||||
# print(f"Parsed command: {command_dict}")
|
# print(f"Parsed command: {command_dict}")
|
||||||
run_command(self.ragflow_client, command_dict, self.is_interactive)
|
run_command(self.ragflow_client, command_dict)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,9 @@ import urllib.parse
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from http_client import HttpClient
|
from http_client import HttpClient
|
||||||
from lark import Tree
|
from lark import Tree
|
||||||
from user import encrypt_password
|
from user import encrypt_password, login_user
|
||||||
|
|
||||||
|
import getpass
|
||||||
import base64
|
import base64
|
||||||
from Cryptodome.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
|
from Cryptodome.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
|
||||||
from Cryptodome.PublicKey import RSA
|
from Cryptodome.PublicKey import RSA
|
||||||
@ -48,6 +49,31 @@ class RAGFlowClient:
|
|||||||
self.http_client = http_client
|
self.http_client = http_client
|
||||||
self.server_type = server_type
|
self.server_type = server_type
|
||||||
|
|
||||||
|
def login_user(self, command):
|
||||||
|
email : str = command["email"]
|
||||||
|
user_password = getpass.getpass(f"password for {email}: ").strip()
|
||||||
|
try:
|
||||||
|
token = login_user(self.http_client, self.server_type, email, user_password)
|
||||||
|
self.http_client.login_token = token
|
||||||
|
print(f"Login user {email} successfully")
|
||||||
|
except Exception as e:
|
||||||
|
print(str(e))
|
||||||
|
print("Can't access server for login (connection failed)")
|
||||||
|
|
||||||
|
def ping_server(self, command):
|
||||||
|
iterations = command.get("iterations", 1)
|
||||||
|
if iterations > 1:
|
||||||
|
response = self.http_client.request("GET", "/system/ping", use_api_base=False, auth_kind="web",
|
||||||
|
iterations=iterations)
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
response = self.http_client.request("GET", "/system/ping", use_api_base=False, auth_kind="web")
|
||||||
|
if response.status_code == 200 and response.content == b"pong":
|
||||||
|
print("Server is alive")
|
||||||
|
else:
|
||||||
|
print("Server is down")
|
||||||
|
return None
|
||||||
|
|
||||||
def register_user(self, command):
|
def register_user(self, command):
|
||||||
if self.server_type != "user":
|
if self.server_type != "user":
|
||||||
print("This command is only allowed in USER mode")
|
print("This command is only allowed in USER mode")
|
||||||
@ -1222,16 +1248,17 @@ class RAGFlowClient:
|
|||||||
print(separator)
|
print(separator)
|
||||||
|
|
||||||
|
|
||||||
def run_command(client: RAGFlowClient, command_dict: dict, is_interactive: bool):
|
def run_command(client: RAGFlowClient, command_dict: dict):
|
||||||
command_type = command_dict["type"]
|
command_type = command_dict["type"]
|
||||||
|
|
||||||
match command_type:
|
match command_type:
|
||||||
case "benchmark":
|
case "benchmark":
|
||||||
run_benchmark(client, command_dict, is_interactive)
|
run_benchmark(client, command_dict)
|
||||||
|
case "login_user":
|
||||||
|
client.login_user(command_dict)
|
||||||
|
case "ping_server":
|
||||||
|
return client.ping_server(command_dict)
|
||||||
case "register_user":
|
case "register_user":
|
||||||
if is_interactive:
|
|
||||||
print("Register user command is not supported in interactive mode")
|
|
||||||
return
|
|
||||||
client.register_user(command_dict)
|
client.register_user(command_dict)
|
||||||
case "list_services":
|
case "list_services":
|
||||||
client.list_services()
|
client.list_services()
|
||||||
@ -1395,23 +1422,31 @@ Meta Commands:
|
|||||||
print(help_text)
|
print(help_text)
|
||||||
|
|
||||||
|
|
||||||
def run_benchmark(client: RAGFlowClient, command_dict: dict, is_interactive: bool):
|
def run_benchmark(client: RAGFlowClient, command_dict: dict):
|
||||||
concurrency = command_dict.get("concurrency", 1)
|
concurrency = command_dict.get("concurrency", 1)
|
||||||
iterations = command_dict.get("iterations", 1)
|
iterations = command_dict.get("iterations", 1)
|
||||||
command: dict = command_dict["command"]
|
command: dict = command_dict["command"]
|
||||||
command.update({"iterations": iterations})
|
command.update({"iterations": iterations})
|
||||||
|
|
||||||
|
command_type = command["type"]
|
||||||
if concurrency < 1:
|
if concurrency < 1:
|
||||||
print("Concurrency must be greater than 0")
|
print("Concurrency must be greater than 0")
|
||||||
return
|
return
|
||||||
elif concurrency == 1:
|
elif concurrency == 1:
|
||||||
result = run_command(client, command, is_interactive)
|
result = run_command(client, command)
|
||||||
|
success_count: int = 0
|
||||||
response_list = result["response_list"]
|
response_list = result["response_list"]
|
||||||
total_duration = result["duration"]
|
|
||||||
success_count = 0
|
|
||||||
for response in response_list:
|
for response in response_list:
|
||||||
res_json = response.json()
|
match command_type:
|
||||||
if response.status_code == 200 and res_json["code"] == 0:
|
case "ping_server":
|
||||||
success_count += 1
|
if response.status_code == 200:
|
||||||
|
success_count += 1
|
||||||
|
case _:
|
||||||
|
res_json = response.json()
|
||||||
|
if response.status_code == 200 and res_json["code"] == 0:
|
||||||
|
success_count += 1
|
||||||
|
|
||||||
|
total_duration = result["duration"]
|
||||||
qps = iterations / total_duration if total_duration > 0 else None
|
qps = iterations / total_duration if total_duration > 0 else None
|
||||||
print(f"command: {command}, Concurrency: {concurrency}, iterations: {iterations}")
|
print(f"command: {command}, Concurrency: {concurrency}, iterations: {iterations}")
|
||||||
print(
|
print(
|
||||||
@ -1426,8 +1461,7 @@ def run_benchmark(client: RAGFlowClient, command_dict: dict, is_interactive: boo
|
|||||||
executor.submit(
|
executor.submit(
|
||||||
run_command,
|
run_command,
|
||||||
client,
|
client,
|
||||||
command,
|
command
|
||||||
is_interactive
|
|
||||||
): idx
|
): idx
|
||||||
for idx in range(concurrency)
|
for idx in range(concurrency)
|
||||||
}
|
}
|
||||||
@ -1439,9 +1473,14 @@ def run_benchmark(client: RAGFlowClient, command_dict: dict, is_interactive: boo
|
|||||||
for result in results:
|
for result in results:
|
||||||
response_list = result["response_list"]
|
response_list = result["response_list"]
|
||||||
for response in response_list:
|
for response in response_list:
|
||||||
res_json = response.json()
|
match command_type:
|
||||||
if response.status_code == 200 and res_json["code"] == 0:
|
case "ping_server":
|
||||||
success_count += 1
|
if response.status_code == 200:
|
||||||
|
success_count += 1
|
||||||
|
case _:
|
||||||
|
res_json = response.json()
|
||||||
|
if response.status_code == 200 and res_json["code"] == 0:
|
||||||
|
success_count += 1
|
||||||
|
|
||||||
total_duration = end_time - start_time
|
total_duration = end_time - start_time
|
||||||
total_command_count = iterations * concurrency
|
total_command_count = iterations * concurrency
|
||||||
|
|||||||
@ -178,7 +178,7 @@ def healthz():
|
|||||||
|
|
||||||
|
|
||||||
@manager.route("/ping", methods=["GET"]) # noqa: F821
|
@manager.route("/ping", methods=["GET"]) # noqa: F821
|
||||||
def ping():
|
async def ping():
|
||||||
return "pong", 200
|
return "pong", 200
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user