mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
The 'cmd' module is introduced to make the CLI easy to use. (#10542)
…pdate comand ### What problem does this PR solve? To make the CLI easy to use. ### 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,14 +16,14 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import base64
|
import base64
|
||||||
|
from cmd import Cmd
|
||||||
|
|
||||||
from Cryptodome.PublicKey import RSA
|
from Cryptodome.PublicKey import RSA
|
||||||
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 typing import Dict, List, Any
|
from typing import Dict, List, Any
|
||||||
from lark import Lark, Transformer, Tree
|
from lark import Lark, Transformer, Tree, Token
|
||||||
import requests
|
import requests
|
||||||
from requests.auth import HTTPBasicAuth
|
from requests.auth import HTTPBasicAuth
|
||||||
from api.common.base64 import encode_to_base64
|
|
||||||
|
|
||||||
GRAMMAR = r"""
|
GRAMMAR = r"""
|
||||||
start: command
|
start: command
|
||||||
@ -100,7 +100,6 @@ NUMBER: /[0-9]+/
|
|||||||
%ignore WS
|
%ignore WS
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class AdminTransformer(Transformer):
|
class AdminTransformer(Transformer):
|
||||||
|
|
||||||
def start(self, items):
|
def start(self, items):
|
||||||
@ -183,7 +182,6 @@ class AdminTransformer(Transformer):
|
|||||||
def meta_args(self, items):
|
def meta_args(self, items):
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
def encrypt(input_string):
|
def encrypt(input_string):
|
||||||
pub = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArq9XTUSeYr2+N1h3Afl/z8Dse/2yD0ZGrKwx+EEEcdsBLca9Ynmx3nIB5obmLlSfmskLpBo0UACBmB5rEjBp2Q2f3AG3Hjd4B+gNCG6BDaawuDlgANIhGnaTLrIqWrrcm4EMzJOnAOI1fgzJRsOOUEfaS318Eq9OVO3apEyCCt0lOQK6PuksduOjVxtltDav+guVAA068NrPYmRNabVKRNLJpL8w4D44sfth5RvZ3q9t+6RTArpEtc5sh5ChzvqPOzKGMXW83C95TxmXqpbK6olN4RevSfVjEAgCydH6HN6OhtOQEcnrU97r9H0iZOWwbw3pVrZiUkuRD1R56Wzs2wIDAQAB\n-----END PUBLIC KEY-----'
|
pub = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArq9XTUSeYr2+N1h3Afl/z8Dse/2yD0ZGrKwx+EEEcdsBLca9Ynmx3nIB5obmLlSfmskLpBo0UACBmB5rEjBp2Q2f3AG3Hjd4B+gNCG6BDaawuDlgANIhGnaTLrIqWrrcm4EMzJOnAOI1fgzJRsOOUEfaS318Eq9OVO3apEyCCt0lOQK6PuksduOjVxtltDav+guVAA068NrPYmRNabVKRNLJpL8w4D44sfth5RvZ3q9t+6RTArpEtc5sh5ChzvqPOzKGMXW83C95TxmXqpbK6olN4RevSfVjEAgCydH6HN6OhtOQEcnrU97r9H0iZOWwbw3pVrZiUkuRD1R56Wzs2wIDAQAB\n-----END PUBLIC KEY-----'
|
||||||
pub_key = RSA.importKey(pub)
|
pub_key = RSA.importKey(pub)
|
||||||
@ -191,13 +189,50 @@ def encrypt(input_string):
|
|||||||
cipher_text = cipher.encrypt(base64.b64encode(input_string.encode('utf-8')))
|
cipher_text = cipher.encrypt(base64.b64encode(input_string.encode('utf-8')))
|
||||||
return base64.b64encode(cipher_text).decode("utf-8")
|
return base64.b64encode(cipher_text).decode("utf-8")
|
||||||
|
|
||||||
|
def encode_to_base64(input_string):
|
||||||
|
base64_encoded = base64.b64encode(input_string.encode('utf-8'))
|
||||||
|
return base64_encoded.decode('utf-8')
|
||||||
|
|
||||||
class AdminCommandParser:
|
class AdminCLI(Cmd):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
self.parser = Lark(GRAMMAR, start='start', parser='lalr', transformer=AdminTransformer())
|
self.parser = Lark(GRAMMAR, start='start', parser='lalr', transformer=AdminTransformer())
|
||||||
self.command_history = []
|
self.command_history = []
|
||||||
|
self.is_interactive = False
|
||||||
|
self.admin_account = "admin@ragflow.io"
|
||||||
|
self.admin_password: str = "admin"
|
||||||
|
self.host: str = ""
|
||||||
|
self.port: int = 0
|
||||||
|
|
||||||
def parse_command(self, command_str: str) -> Dict[str, Any]:
|
intro = r"""Type "\h" for help."""
|
||||||
|
prompt = "admin> "
|
||||||
|
|
||||||
|
def onecmd(self, command: str) -> bool:
|
||||||
|
try:
|
||||||
|
print(f"command: {command}")
|
||||||
|
result = self.parse_command(command)
|
||||||
|
self.execute_command(result)
|
||||||
|
|
||||||
|
if isinstance(result, Tree):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if result.get('type') == 'meta' and result.get('command') in ['q', 'quit', 'exit']:
|
||||||
|
return True
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nUse '\\q' to quit")
|
||||||
|
except EOFError:
|
||||||
|
print("\nGoodbye!")
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def emptyline(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def default(self, line: str) -> bool:
|
||||||
|
return self.onecmd(line)
|
||||||
|
|
||||||
|
def parse_command(self, command_str: str) -> dict[str, str] | Tree[Token]:
|
||||||
if not command_str.strip():
|
if not command_str.strip():
|
||||||
return {'type': 'empty'}
|
return {'type': 'empty'}
|
||||||
|
|
||||||
@ -209,16 +244,6 @@ class AdminCommandParser:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {'type': 'error', 'message': f'Parse error: {str(e)}'}
|
return {'type': 'error', 'message': f'Parse error: {str(e)}'}
|
||||||
|
|
||||||
|
|
||||||
class AdminCLI:
|
|
||||||
def __init__(self):
|
|
||||||
self.parser = AdminCommandParser()
|
|
||||||
self.is_interactive = False
|
|
||||||
self.admin_account = "admin@ragflow.io"
|
|
||||||
self.admin_password: str = "admin"
|
|
||||||
self.host: str = ""
|
|
||||||
self.port: int = 0
|
|
||||||
|
|
||||||
def verify_admin(self, args):
|
def verify_admin(self, args):
|
||||||
|
|
||||||
conn_info = self._parse_connection_args(args)
|
conn_info = self._parse_connection_args(args)
|
||||||
@ -323,7 +348,7 @@ class AdminCLI:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
print(f"command: {command}")
|
print(f"command: {command}")
|
||||||
result = self.parser.parse_command(command)
|
result = self.parse_command(command)
|
||||||
self.execute_command(result)
|
self.execute_command(result)
|
||||||
|
|
||||||
if isinstance(result, Tree):
|
if isinstance(result, Tree):
|
||||||
@ -610,10 +635,17 @@ def main():
|
|||||||
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
|
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
|
||||||
""")
|
""")
|
||||||
if cli.verify_admin(sys.argv):
|
if cli.verify_admin(sys.argv):
|
||||||
cli.run_interactive()
|
cli.cmdloop()
|
||||||
else:
|
else:
|
||||||
|
print(r"""
|
||||||
|
____ ___ ______________ ___ __ _
|
||||||
|
/ __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___
|
||||||
|
/ /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \
|
||||||
|
/ _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / /
|
||||||
|
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
|
||||||
|
""")
|
||||||
if cli.verify_admin(sys.argv):
|
if cli.verify_admin(sys.argv):
|
||||||
cli.run_interactive()
|
cli.cmdloop()
|
||||||
# cli.run_single_command(sys.argv[1:])
|
# cli.run_single_command(sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -179,7 +179,6 @@ class ServiceMgr:
|
|||||||
configs = SERVICE_CONFIGS.configs
|
configs = SERVICE_CONFIGS.configs
|
||||||
for service_id, config in enumerate(configs):
|
for service_id, config in enumerate(configs):
|
||||||
config_dict = config.to_dict()
|
config_dict = config.to_dict()
|
||||||
service_detail = None
|
|
||||||
try:
|
try:
|
||||||
service_detail = ServiceMgr.get_service_details(service_id)
|
service_detail = ServiceMgr.get_service_details(service_id)
|
||||||
if service_detail['alive']:
|
if service_detail['alive']:
|
||||||
|
|||||||
Reference in New Issue
Block a user