ragflow-cli 0.23.1__tar.gz → 0.25.0.dev5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/PKG-INFO +3 -2
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/README.md +1 -1
- ragflow_cli-0.25.0.dev5/http_client.py +182 -0
- ragflow_cli-0.25.0.dev5/parser.py +663 -0
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/pyproject.toml +6 -3
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/ragflow_cli.egg-info/PKG-INFO +3 -2
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/ragflow_cli.egg-info/SOURCES.txt +5 -1
- ragflow_cli-0.25.0.dev5/ragflow_cli.egg-info/entry_points.txt +2 -0
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/ragflow_cli.egg-info/requires.txt +1 -0
- ragflow_cli-0.25.0.dev5/ragflow_cli.egg-info/top_level.txt +5 -0
- ragflow_cli-0.25.0.dev5/ragflow_cli.py +322 -0
- ragflow_cli-0.25.0.dev5/ragflow_client.py +1690 -0
- ragflow_cli-0.25.0.dev5/user.py +77 -0
- ragflow_cli-0.23.1/admin_client.py +0 -938
- ragflow_cli-0.23.1/ragflow_cli.egg-info/entry_points.txt +0 -2
- ragflow_cli-0.23.1/ragflow_cli.egg-info/top_level.txt +0 -1
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/ragflow_cli.egg-info/dependency_links.txt +0 -0
- {ragflow_cli-0.23.1 → ragflow_cli-0.25.0.dev5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ragflow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.25.0.dev5
|
|
4
4
|
Summary: Admin Service's client of [RAGFlow](https://github.com/infiniflow/ragflow). The Admin Service provides user management and system monitoring.
|
|
5
5
|
Author-email: Lynn <lynn_inf@hotmail.com>
|
|
6
6
|
License: Apache License, Version 2.0
|
|
@@ -10,6 +10,7 @@ Requires-Dist: requests<3.0.0,>=2.30.0
|
|
|
10
10
|
Requires-Dist: beartype<1.0.0,>=0.20.0
|
|
11
11
|
Requires-Dist: pycryptodomex>=3.10.0
|
|
12
12
|
Requires-Dist: lark>=1.1.0
|
|
13
|
+
Requires-Dist: requests-toolbelt>=1.0.0
|
|
13
14
|
|
|
14
15
|
# RAGFlow Admin Service & CLI
|
|
15
16
|
|
|
@@ -61,7 +62,7 @@ It consists of a server-side Service and a command-line client (CLI), both imple
|
|
|
61
62
|
1. Ensure the Admin Service is running.
|
|
62
63
|
2. Install ragflow-cli.
|
|
63
64
|
```bash
|
|
64
|
-
pip install ragflow-cli==0.
|
|
65
|
+
pip install ragflow-cli==0.24.0
|
|
65
66
|
```
|
|
66
67
|
3. Launch the CLI client:
|
|
67
68
|
```bash
|
|
@@ -48,7 +48,7 @@ It consists of a server-side Service and a command-line client (CLI), both imple
|
|
|
48
48
|
1. Ensure the Admin Service is running.
|
|
49
49
|
2. Install ragflow-cli.
|
|
50
50
|
```bash
|
|
51
|
-
pip install ragflow-cli==0.
|
|
51
|
+
pip install ragflow-cli==0.24.0
|
|
52
52
|
```
|
|
53
53
|
3. Launch the CLI client:
|
|
54
54
|
```bash
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
import time
|
|
18
|
+
import json
|
|
19
|
+
import typing
|
|
20
|
+
from typing import Any, Dict, Optional
|
|
21
|
+
|
|
22
|
+
import requests
|
|
23
|
+
# from requests.sessions import HTTPAdapter
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HttpClient:
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
host: str = "127.0.0.1",
|
|
30
|
+
port: int = 9381,
|
|
31
|
+
api_version: str = "v1",
|
|
32
|
+
api_key: Optional[str] = None,
|
|
33
|
+
connect_timeout: float = 5.0,
|
|
34
|
+
read_timeout: float = 60.0,
|
|
35
|
+
verify_ssl: bool = False,
|
|
36
|
+
) -> None:
|
|
37
|
+
self.host = host
|
|
38
|
+
self.port = port
|
|
39
|
+
self.api_version = api_version
|
|
40
|
+
self.api_key = api_key
|
|
41
|
+
self.login_token: str | None = None
|
|
42
|
+
self.connect_timeout = connect_timeout
|
|
43
|
+
self.read_timeout = read_timeout
|
|
44
|
+
self.verify_ssl = verify_ssl
|
|
45
|
+
|
|
46
|
+
def api_base(self) -> str:
|
|
47
|
+
return f"{self.host}:{self.port}/api/{self.api_version}"
|
|
48
|
+
|
|
49
|
+
def non_api_base(self) -> str:
|
|
50
|
+
return f"{self.host}:{self.port}/{self.api_version}"
|
|
51
|
+
|
|
52
|
+
def build_url(self, path: str, use_api_base: bool = True) -> str:
|
|
53
|
+
base = self.api_base() if use_api_base else self.non_api_base()
|
|
54
|
+
if self.verify_ssl:
|
|
55
|
+
return f"https://{base}/{path.lstrip('/')}"
|
|
56
|
+
else:
|
|
57
|
+
return f"http://{base}/{path.lstrip('/')}"
|
|
58
|
+
|
|
59
|
+
def _headers(self, auth_kind: Optional[str], extra: Optional[Dict[str, str]]) -> Dict[str, str]:
|
|
60
|
+
headers = {}
|
|
61
|
+
if auth_kind == "api" and self.api_key:
|
|
62
|
+
headers["Authorization"] = f"Bearer {self.api_key}"
|
|
63
|
+
elif auth_kind == "web" and self.login_token:
|
|
64
|
+
headers["Authorization"] = self.login_token
|
|
65
|
+
elif auth_kind == "admin" and self.login_token:
|
|
66
|
+
headers["Authorization"] = self.login_token
|
|
67
|
+
else:
|
|
68
|
+
pass
|
|
69
|
+
if extra:
|
|
70
|
+
headers.update(extra)
|
|
71
|
+
return headers
|
|
72
|
+
|
|
73
|
+
def request(
|
|
74
|
+
self,
|
|
75
|
+
method: str,
|
|
76
|
+
path: str,
|
|
77
|
+
*,
|
|
78
|
+
use_api_base: bool = True,
|
|
79
|
+
auth_kind: Optional[str] = "api",
|
|
80
|
+
headers: Optional[Dict[str, str]] = None,
|
|
81
|
+
json_body: Optional[Dict[str, Any]] = None,
|
|
82
|
+
data: Any = None,
|
|
83
|
+
files: Any = None,
|
|
84
|
+
params: Optional[Dict[str, Any]] = None,
|
|
85
|
+
stream: bool = False,
|
|
86
|
+
iterations: int = 1,
|
|
87
|
+
) -> requests.Response | dict:
|
|
88
|
+
url = self.build_url(path, use_api_base=use_api_base)
|
|
89
|
+
merged_headers = self._headers(auth_kind, headers)
|
|
90
|
+
# timeout: Tuple[float, float] = (self.connect_timeout, self.read_timeout)
|
|
91
|
+
session = requests.Session()
|
|
92
|
+
# adapter = HTTPAdapter(pool_connections=100, pool_maxsize=100)
|
|
93
|
+
# session.mount("http://", adapter)
|
|
94
|
+
http_function = typing.Any
|
|
95
|
+
match method:
|
|
96
|
+
case "GET":
|
|
97
|
+
http_function = session.get
|
|
98
|
+
case "POST":
|
|
99
|
+
http_function = session.post
|
|
100
|
+
case "PUT":
|
|
101
|
+
http_function = session.put
|
|
102
|
+
case "DELETE":
|
|
103
|
+
http_function = session.delete
|
|
104
|
+
case "PATCH":
|
|
105
|
+
http_function = session.patch
|
|
106
|
+
case _:
|
|
107
|
+
raise ValueError(f"Invalid HTTP method: {method}")
|
|
108
|
+
|
|
109
|
+
if iterations > 1:
|
|
110
|
+
response_list = []
|
|
111
|
+
total_duration = 0.0
|
|
112
|
+
for _ in range(iterations):
|
|
113
|
+
start_time = time.perf_counter()
|
|
114
|
+
response = http_function(url, headers=merged_headers, json=json_body, data=data, stream=stream)
|
|
115
|
+
# response = session.get(url, headers=merged_headers, json=json_body, data=data, stream=stream)
|
|
116
|
+
# response = requests.request(
|
|
117
|
+
# method=method,
|
|
118
|
+
# url=url,
|
|
119
|
+
# headers=merged_headers,
|
|
120
|
+
# json=json_body,
|
|
121
|
+
# data=data,
|
|
122
|
+
# files=files,
|
|
123
|
+
# params=params,
|
|
124
|
+
# stream=stream,
|
|
125
|
+
# verify=self.verify_ssl,
|
|
126
|
+
# )
|
|
127
|
+
end_time = time.perf_counter()
|
|
128
|
+
total_duration += end_time - start_time
|
|
129
|
+
response_list.append(response)
|
|
130
|
+
return {"duration": total_duration, "response_list": response_list}
|
|
131
|
+
else:
|
|
132
|
+
return http_function(url, headers=merged_headers, json=json_body, data=data, stream=stream)
|
|
133
|
+
# return session.get(url, headers=merged_headers, json=json_body, data=data, stream=stream)
|
|
134
|
+
# return requests.request(
|
|
135
|
+
# method=method,
|
|
136
|
+
# url=url,
|
|
137
|
+
# headers=merged_headers,
|
|
138
|
+
# json=json_body,
|
|
139
|
+
# data=data,
|
|
140
|
+
# files=files,
|
|
141
|
+
# params=params,
|
|
142
|
+
# stream=stream,
|
|
143
|
+
# verify=self.verify_ssl,
|
|
144
|
+
# )
|
|
145
|
+
|
|
146
|
+
def request_json(
|
|
147
|
+
self,
|
|
148
|
+
method: str,
|
|
149
|
+
path: str,
|
|
150
|
+
*,
|
|
151
|
+
use_api_base: bool = True,
|
|
152
|
+
auth_kind: Optional[str] = "api",
|
|
153
|
+
headers: Optional[Dict[str, str]] = None,
|
|
154
|
+
json_body: Optional[Dict[str, Any]] = None,
|
|
155
|
+
data: Any = None,
|
|
156
|
+
files: Any = None,
|
|
157
|
+
params: Optional[Dict[str, Any]] = None,
|
|
158
|
+
stream: bool = False,
|
|
159
|
+
) -> Dict[str, Any]:
|
|
160
|
+
response = self.request(
|
|
161
|
+
method,
|
|
162
|
+
path,
|
|
163
|
+
use_api_base=use_api_base,
|
|
164
|
+
auth_kind=auth_kind,
|
|
165
|
+
headers=headers,
|
|
166
|
+
json_body=json_body,
|
|
167
|
+
data=data,
|
|
168
|
+
files=files,
|
|
169
|
+
params=params,
|
|
170
|
+
stream=stream,
|
|
171
|
+
)
|
|
172
|
+
try:
|
|
173
|
+
return response.json()
|
|
174
|
+
except Exception as exc:
|
|
175
|
+
raise ValueError(f"Non-JSON response from {path}: {exc}") from exc
|
|
176
|
+
|
|
177
|
+
@staticmethod
|
|
178
|
+
def parse_json_bytes(raw: bytes) -> Dict[str, Any]:
|
|
179
|
+
try:
|
|
180
|
+
return json.loads(raw.decode("utf-8"))
|
|
181
|
+
except Exception as exc:
|
|
182
|
+
raise ValueError(f"Invalid JSON payload: {exc}") from exc
|