From 90afce192c4462d6cd0ac6c59a3bd4f9903d4850 Mon Sep 17 00:00:00 2001 From: Jin Hai Date: Thu, 12 Mar 2026 11:52:39 +0800 Subject: [PATCH] Add license and fingerprint API hook (#13548) ### What problem does this PR solve? For EE ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: Jin Hai --- admin/client/parser.py | 19 +++++++++++++++++ admin/client/ragflow_client.py | 37 ++++++++++++++++++++++++++++++++++ internal/admin/handler.go | 31 ++++++++++++++++++++++++++++ internal/admin/router.go | 6 ++++++ 4 files changed, 93 insertions(+) diff --git a/admin/client/parser.py b/admin/client/parser.py index 11adfa8157..e82517f16b 100644 --- a/admin/client/parser.py +++ b/admin/client/parser.py @@ -93,6 +93,9 @@ sql_command: login_user | list_chat_sessions | chat_on_session | list_server_configs + | show_fingerprint + | set_license + | show_license | benchmark // meta command definition @@ -178,6 +181,8 @@ PING: "PING"i SESSION: "SESSION"i SESSIONS: "SESSIONS"i SERVER: "SERVER"i +FINGERPRINT: "FINGERPRINT"i +LICENSE: "LICENSE"i login_user: LOGIN USER quoted_string ";" list_services: LIST SERVICES ";" @@ -223,6 +228,10 @@ list_variables: LIST VARS ";" list_configs: LIST CONFIGS ";" list_environments: LIST ENVS ";" +show_fingerprint: SHOW FINGERPRINT ";" +set_license: SET LICENSE quoted_string ";" +show_license: SHOW LICENSE ";" + list_server_configs: LIST SERVER CONFIGS ";" benchmark: BENCHMARK NUMBER NUMBER user_statement @@ -477,6 +486,16 @@ class RAGFlowCLITransformer(Transformer): def list_environments(self, items): return {"type": "list_environments"} + def show_fingerprint(self, items): + return {"type": "show_fingerprint"} + + def set_license(self, items): + license = items[2].children[0].strip("'\"") + return {"type": "set_license", "license": license} + + def show_license(self, items): + return {"type": "show_license"} + def list_server_configs(self, items): return {"type": "list_server_configs"} diff --git a/admin/client/ragflow_client.py b/admin/client/ragflow_client.py index 480d320f10..b59b931bfe 100644 --- a/admin/client/ragflow_client.py +++ b/admin/client/ragflow_client.py @@ -583,6 +583,37 @@ class RAGFlowClient: else: print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") + def show_fingerprint(self, command): + if self.server_type != "admin": + print("This command is only allowed in ADMIN mode") + response = self.http_client.request("GET", "/admin/fingerprint", 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 fingerprint, code: {res_json['code']}, message: {res_json['message']}") + + def set_license(self, command): + 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") + res_json = response.json() + if response.status_code == 200: + print("Set license successfully") + else: + print(f"Fail to set license, code: {res_json['code']}, message: {res_json['message']}") + + def show_license(self, command): + if self.server_type != "admin": + print("This command is only allowed in ADMIN mode") + response = self.http_client.request("GET", "/admin/license", 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 license, code: {res_json['code']}, message: {res_json['message']}") + def list_server_configs(self, command): """List server configs by calling /system/configs API and flattening the JSON response.""" response = self.http_client.request("GET", "/system/configs", use_api_base=False, auth_kind="web") @@ -1514,6 +1545,12 @@ def run_command(client: RAGFlowClient, command_dict: dict): client.list_configs(command_dict) case "list_environments": client.list_environments(command_dict) + case "show_fingerprint": + client.show_fingerprint(command_dict) + case "set_license": + client.set_license(command_dict) + case "show_license": + client.show_license(command_dict) case "list_server_configs": client.list_server_configs(command_dict) case "create_model_provider": diff --git a/internal/admin/handler.go b/internal/admin/handler.go index 542bf491ae..8acbb8cb19 100644 --- a/internal/admin/handler.go +++ b/internal/admin/handler.go @@ -841,6 +841,37 @@ func (h *Handler) GetVersion(c *gin.Context) { success(c, gin.H{"version": version}, "") } +// GetFingerprint handle get system fingerprint +func (h *Handler) GetFingerprint(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{ + "code": common.CodeServerError, + "message": "method not implemented", + }) + return +} + +type SetLicenseHTTPRequest struct { + License string `json:"license" binding:"required"` +} + +// SetLicense to set system license +func (h *Handler) SetLicense(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{ + "code": common.CodeServerError, + "message": "method not implemented", + }) + return +} + +// ShowLicense to get system license +func (h *Handler) ShowLicense(c *gin.Context) { + c.JSON(http.StatusNotImplemented, gin.H{ + "code": common.CodeServerError, + "message": "method not implemented", + }) + return +} + // ListSandboxProviders handle list sandbox providers func (h *Handler) ListSandboxProviders(c *gin.Context) { providers, err := h.service.ListSandboxProviders() diff --git a/internal/admin/router.go b/internal/admin/router.go index 6e2239d4de..f593482505 100644 --- a/internal/admin/router.go +++ b/internal/admin/router.go @@ -111,6 +111,12 @@ func (r *Router) Setup(engine *gin.Engine) { protected.GET("/sandbox/config", r.handler.GetSandboxConfig) protected.POST("/sandbox/config", r.handler.SetSandboxConfig) protected.POST("/sandbox/test", r.handler.TestSandboxConnection) + + // Fingerprint + protected.GET("/fingerprint", r.handler.GetFingerprint) + // License + protected.POST("/license", r.handler.SetLicense) + protected.GET("/license", r.handler.ShowLicense) } }