From 1d955507e9013c1c8b45c35efbc6cd047c5ec44d Mon Sep 17 00:00:00 2001 From: Jin Hai Date: Sat, 18 Oct 2025 21:03:22 +0800 Subject: [PATCH] Supports running single command (#10651) ### What problem does this PR solve? ``` $ python admin_client.py -h 0.0.0.0 -p 9381 'list users;' Attempt to access ip: 0.0.0.0, port: 9381 Authentication successful. Run single command: list users; Listing all users +-------------------------------+------------------+-----------+----------+ | create_date | email | is_active | nickname | +-------------------------------+------------------+-----------+----------+ | Thu, 15 Aug 2024 15:35:53 GMT | abc@abc.com | 1 | aaa | | Sat, 08 Jun 2024 16:43:21 GMT | aaaa@aaaa.com | 1 | aaa | | Thu, 15 Aug 2024 15:38:10 GMT | cbde@ccc.com | 1 | ccc | | Tue, 23 Sep 2025 14:07:27 GMT | aaa@aaa.aaa | 1 | aaa | | Thu, 15 Aug 2024 19:44:19 GMT | aa@aa.com | 1 | aa | | Tue, 23 Sep 2025 15:41:36 GMT | admin@ragflow.io | 1 | admin | +-------------------------------+------------------+-----------+----------+ ``` ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: Jin Hai --- admin/client/admin_client.py | 95 ++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/admin/client/admin_client.py b/admin/client/admin_client.py index 7fc8780f6..6df37abe6 100644 --- a/admin/client/admin_client.py +++ b/admin/client/admin_client.py @@ -340,25 +340,26 @@ class AdminCLI(Cmd): except Exception as e: return {'type': 'error', 'message': f'Parse error: {str(e)}'} - def verify_admin(self, args): - - conn_info = self._parse_connection_args(args) - if 'error' in conn_info: - print(f"Error: {conn_info['error']}") - return - - self.host = conn_info['host'] - self.port = conn_info['port'] + def verify_admin(self, arguments: dict, single_command: bool): + self.host = arguments['host'] + self.port = arguments['port'] print(f"Attempt to access ip: {self.host}, port: {self.port}") url = f"http://{self.host}:{self.port}/api/v1/admin/login" + attempt_count = 3 + if single_command: + attempt_count = 1 + try_count = 0 while True: try_count += 1 - if try_count > 3: + if try_count > attempt_count: return False - admin_passwd = input(f"password for {self.admin_account}: ").strip() + if single_command: + admin_passwd = arguments['password'] + else: + admin_passwd = input(f"password for {self.admin_account}: ").strip() try: self.admin_password = encrypt(admin_passwd) response = self.session.post(url, json={'email': self.admin_account, 'password': self.admin_password}) @@ -378,7 +379,7 @@ class AdminCLI(Cmd): print(f"Authentication failed: {error_message}, try again") continue else: - print(f"Bad response,status: {response.status_code}, try again") + print(f"Bad response,status: {response.status_code}, password is wrong") except Exception as e: print(str(e)) print(f"Can't access {self.host}, port: {self.port}") @@ -465,23 +466,31 @@ class AdminCLI(Cmd): print("\nGoodbye!") break - def run_single_command(self, args): - conn_info = self._parse_connection_args(args) - if 'error' in conn_info: - print(f"Error: {conn_info['error']}") - return + def run_single_command(self, command: str): + result = self.parse_command(command) + self.execute_command(result) - def _parse_connection_args(self, args: List[str]) -> Dict[str, Any]: + def parse_connection_args(self, args: List[str]) -> Dict[str, Any]: parser = argparse.ArgumentParser(description='Admin CLI Client', add_help=False) parser.add_argument('-h', '--host', default='localhost', help='Admin service host') parser.add_argument('-p', '--port', type=int, default=8080, help='Admin service port') - + parser.add_argument('-w', '--password', default='admin', type=str, help='Superuser password') + parser.add_argument('command', nargs='?', help='Single command') try: parsed_args, remaining_args = parser.parse_known_args(args) - return { - 'host': parsed_args.host, - 'port': parsed_args.port, - } + if remaining_args: + command = remaining_args[0] + return { + 'host': parsed_args.host, + 'port': parsed_args.port, + 'password': parsed_args.password, + 'command': command + } + else: + return { + 'host': parsed_args.host, + 'port': parsed_args.port, + } except SystemExit: return {'error': 'Invalid connection arguments'} @@ -893,27 +902,29 @@ def main(): cli = AdminCLI() - if len(sys.argv) == 1 or (len(sys.argv) > 1 and sys.argv[1] == '-'): - print(r""" - ____ ___ ______________ ___ __ _ - / __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___ - / /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \ - / _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / / - /_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ - """) - if cli.verify_admin(sys.argv): - cli.cmdloop() + args = cli.parse_connection_args(sys.argv) + if 'error' in args: + print(f"Error: {args['error']}") + return + + if 'command' in args: + if 'password' not in args: + print("Error: password is missing") + return + if cli.verify_admin(args, single_command=True): + command: str = args['command'] + print(f"Run single command: {command}") + cli.run_single_command(command) else: - print(r""" - ____ ___ ______________ ___ __ _ - / __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___ - / /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \ - / _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / / - /_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ - """) - if cli.verify_admin(sys.argv): + if cli.verify_admin(args, single_command=False): + print(r""" + ____ ___ ______________ ___ __ _ + / __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___ + / /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \ + / _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / / + /_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ + """) cli.cmdloop() - # cli.run_single_command(sys.argv[1:]) if __name__ == '__main__':