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 <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai 2025-10-18 21:03:22 +08:00 committed by GitHub
parent cf09c2260a
commit 1d955507e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -340,25 +340,26 @@ class AdminCLI(Cmd):
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)}'}
def verify_admin(self, args): def verify_admin(self, arguments: dict, single_command: bool):
self.host = arguments['host']
conn_info = self._parse_connection_args(args) self.port = arguments['port']
if 'error' in conn_info:
print(f"Error: {conn_info['error']}")
return
self.host = conn_info['host']
self.port = conn_info['port']
print(f"Attempt to access ip: {self.host}, port: {self.port}") print(f"Attempt to access ip: {self.host}, port: {self.port}")
url = f"http://{self.host}:{self.port}/api/v1/admin/login" url = f"http://{self.host}:{self.port}/api/v1/admin/login"
attempt_count = 3
if single_command:
attempt_count = 1
try_count = 0 try_count = 0
while True: while True:
try_count += 1 try_count += 1
if try_count > 3: if try_count > attempt_count:
return False 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: try:
self.admin_password = encrypt(admin_passwd) self.admin_password = encrypt(admin_passwd)
response = self.session.post(url, json={'email': self.admin_account, 'password': self.admin_password}) 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") print(f"Authentication failed: {error_message}, try again")
continue continue
else: else:
print(f"Bad responsestatus: {response.status_code}, try again") print(f"Bad responsestatus: {response.status_code}, password is wrong")
except Exception as e: except Exception as e:
print(str(e)) print(str(e))
print(f"Can't access {self.host}, port: {self.port}") print(f"Can't access {self.host}, port: {self.port}")
@ -465,23 +466,31 @@ class AdminCLI(Cmd):
print("\nGoodbye!") print("\nGoodbye!")
break break
def run_single_command(self, args): def run_single_command(self, command: str):
conn_info = self._parse_connection_args(args) result = self.parse_command(command)
if 'error' in conn_info: self.execute_command(result)
print(f"Error: {conn_info['error']}")
return
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 = argparse.ArgumentParser(description='Admin CLI Client', add_help=False)
parser.add_argument('-h', '--host', default='localhost', help='Admin service host') 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('-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: try:
parsed_args, remaining_args = parser.parse_known_args(args) parsed_args, remaining_args = parser.parse_known_args(args)
return { if remaining_args:
'host': parsed_args.host, command = remaining_args[0]
'port': parsed_args.port, 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: except SystemExit:
return {'error': 'Invalid connection arguments'} return {'error': 'Invalid connection arguments'}
@ -893,27 +902,29 @@ def main():
cli = AdminCLI() cli = AdminCLI()
if len(sys.argv) == 1 or (len(sys.argv) > 1 and sys.argv[1] == '-'): args = cli.parse_connection_args(sys.argv)
print(r""" if 'error' in args:
____ ___ ______________ ___ __ _ print(f"Error: {args['error']}")
/ __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___ return
/ /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \
/ _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / / if 'command' in args:
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ if 'password' not in args:
""") print("Error: password is missing")
if cli.verify_admin(sys.argv): return
cli.cmdloop() if cli.verify_admin(args, single_command=True):
command: str = args['command']
print(f"Run single command: {command}")
cli.run_single_command(command)
else: else:
print(r""" if cli.verify_admin(args, single_command=False):
____ ___ ______________ ___ __ _ print(r"""
/ __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___ ____ ___ ______________ ___ __ _
/ /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \ / __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___
/ _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / / / /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \
/_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ / _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / /
""") /_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/
if cli.verify_admin(sys.argv): """)
cli.cmdloop() cli.cmdloop()
# cli.run_single_command(sys.argv[1:])
if __name__ == '__main__': if __name__ == '__main__':