http-content-parser 0.0.21__tar.gz → 0.0.23__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.
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/PKG-INFO +1 -1
- http_content_parser-0.0.23/api.yaml +54 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/pyproject.toml +1 -1
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/api_parser.py +126 -32
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/curl_parser.py +80 -2
- http_content_parser-0.0.23/src/http_content_parser/postman_parser.py +123 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/tests/test_api_model_parser.py +2 -1
- http_content_parser-0.0.23/tests/test_postman.py +61 -0
- http_content_parser-0.0.21/src/http_content_parser/postman_parser.py +0 -44
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/.gitignore +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/LICENSE +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/README.md +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/requirements.txt +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/__init__.py +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/generate_api_file.py +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/openapi_parser.py +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/param_util.py +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/req_data.py +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/swagger2_parser.py +0 -0
- {http_content_parser-0.0.21 → http_content_parser-0.0.23}/tests/test_curl.py +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
v1_hfw_get_operators_get:
|
|
2
|
+
body: {}
|
|
3
|
+
header: '{"x-tt-env": "boe_env_self_testing_newfeat"}'
|
|
4
|
+
method: get
|
|
5
|
+
original_url: nacmgt-boe.bytedance.net/v1/hfw/get_operators
|
|
6
|
+
path: v1/hfw/get_operators
|
|
7
|
+
path_param: {}
|
|
8
|
+
query_param: {}
|
|
9
|
+
response: {}
|
|
10
|
+
v1_hfw_get_operators_get:
|
|
11
|
+
body: {}
|
|
12
|
+
header: '{"x-tt-env": "boe_env_self_testing_newfeat"}'
|
|
13
|
+
method: get
|
|
14
|
+
original_url: nacmgt-boe.bytedance.net/v1/hfw/get_operators
|
|
15
|
+
path: v1/hfw/get_operators
|
|
16
|
+
path_param: {}
|
|
17
|
+
query_param: {}
|
|
18
|
+
response: {}
|
|
19
|
+
v1_hfw_get_operators_get:
|
|
20
|
+
body: {}
|
|
21
|
+
header: '{"x-tt-env": "boe_env_self_testing_newfeat"}'
|
|
22
|
+
method: get
|
|
23
|
+
original_url: nacmgt-boe.bytedance.net/v1/hfw/get_operators
|
|
24
|
+
path: v1/hfw/get_operators
|
|
25
|
+
path_param: {}
|
|
26
|
+
query_param: {}
|
|
27
|
+
response: {}
|
|
28
|
+
v1_hfw_get_operators_get:
|
|
29
|
+
body: {}
|
|
30
|
+
header: '{"x-tt-env": "boe_env_self_testing_newfeat"}'
|
|
31
|
+
method: get
|
|
32
|
+
original_url: nacmgt-boe.bytedance.net/v1/hfw/get_operators
|
|
33
|
+
path: v1/hfw/get_operators
|
|
34
|
+
path_param: {}
|
|
35
|
+
query_param: {}
|
|
36
|
+
response: {}
|
|
37
|
+
v1_hfw_get_operators_get:
|
|
38
|
+
body: {}
|
|
39
|
+
header: '{"x-tt-env": "boe_env_self_testing_newfeat"}'
|
|
40
|
+
method: get
|
|
41
|
+
original_url: nacmgt-boe.bytedance.net/v1/hfw/get_operators
|
|
42
|
+
path: v1/hfw/get_operators
|
|
43
|
+
path_param: {}
|
|
44
|
+
query_param: {}
|
|
45
|
+
response: {}
|
|
46
|
+
v1_hfw_get_operators_get:
|
|
47
|
+
body: {}
|
|
48
|
+
header: '{"x-tt-env": "boe_env_self_testing_newfeat"}'
|
|
49
|
+
method: get
|
|
50
|
+
original_url: nacmgt-boe.bytedance.net/v1/hfw/get_operators
|
|
51
|
+
path: v1/hfw/get_operators
|
|
52
|
+
path_param: {}
|
|
53
|
+
query_param: {}
|
|
54
|
+
response: {}
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/api_parser.py
RENAMED
|
@@ -34,18 +34,36 @@ class ApiModelParser:
|
|
|
34
34
|
new_payload_list = self.__handle_duplicate_api_label(payload_list)
|
|
35
35
|
return new_payload_list
|
|
36
36
|
|
|
37
|
+
def get_api_list_for_postman(self, json_dict: dict) -> list[dict]:
|
|
38
|
+
payload_list = self.convert_postman_to_list(postman_dict=json_dict)
|
|
39
|
+
# handle duplicate key
|
|
40
|
+
new_payload_list = self.__handle_duplicate_api_label_for_dict(payload_list)
|
|
41
|
+
return new_payload_list
|
|
42
|
+
|
|
37
43
|
def get_api_model_for_swagger(self, json_dict: dict) -> list[ReqData]:
|
|
38
44
|
payload_list = self.convert_swagger_to_model(swagger2_dict=json_dict)
|
|
39
45
|
# handle duplicate key
|
|
40
46
|
new_payload_list = self.__handle_duplicate_api_label(payload_list)
|
|
41
47
|
return new_payload_list
|
|
42
48
|
|
|
49
|
+
def get_api_list_for_swagger(self, json_dict: dict) -> list[dict]:
|
|
50
|
+
payload_list = self.convert_swagger_to_list(swagger2_dict=json_dict)
|
|
51
|
+
# handle duplicate key
|
|
52
|
+
new_payload_list = self.__handle_duplicate_api_label_for_dict(payload_list)
|
|
53
|
+
return new_payload_list
|
|
54
|
+
|
|
43
55
|
def get_api_model_for_openapi(self, json_dict: dict) -> list[ReqData]:
|
|
44
56
|
payload_list = self.convert_openapi_to_model(openapi_dict=json_dict)
|
|
45
57
|
# handle duplicate key
|
|
46
58
|
new_payload_list = self.__handle_duplicate_api_label(payload_list)
|
|
47
59
|
return new_payload_list
|
|
48
60
|
|
|
61
|
+
def get_api_list_for_openapi(self, json_dict: dict) -> list[dict]:
|
|
62
|
+
payload_list = self.convert_openapi_to_list(openapi_dict=json_dict)
|
|
63
|
+
# handle duplicate key
|
|
64
|
+
new_payload_list = self.__handle_duplicate_api_label_for_dict(payload_list)
|
|
65
|
+
return new_payload_list
|
|
66
|
+
|
|
49
67
|
def convert_curl_data_to_list(
|
|
50
68
|
self, curl_file_path: str, url_filter=None
|
|
51
69
|
) -> list[dict]:
|
|
@@ -54,24 +72,26 @@ class ApiModelParser:
|
|
|
54
72
|
with open(curl_file_path, "rt") as f:
|
|
55
73
|
lines = f.readlines()
|
|
56
74
|
line_num_array = curl_parser.get_curl_line_num_scope(lines=lines)
|
|
57
|
-
for
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
for s, e in line_num_array:
|
|
76
|
+
res = curl_parser.split_curl_to_struct(lines, s, e, url_filter)
|
|
77
|
+
url_content = curl_parser.parse_url(res.get("original_url", ""))
|
|
78
|
+
path_str = url_content.get("path", "")[1:]
|
|
79
|
+
method = (res.get("method", "") or "").lower()
|
|
80
|
+
label = self.__replace_api_label_chars(path_str) + "_" + method
|
|
81
|
+
req_data = {
|
|
82
|
+
"path": path_str,
|
|
83
|
+
"header": json.dumps(res.get("header", {})),
|
|
84
|
+
"body": res.get("body", ""),
|
|
85
|
+
"query_param": (
|
|
86
|
+
json.dumps(url_content.get("query_params", {}))
|
|
87
|
+
if url_content.get("query_params")
|
|
88
|
+
else {}
|
|
89
|
+
),
|
|
90
|
+
"original_url": res.get("original_url", ""),
|
|
91
|
+
"method": method,
|
|
92
|
+
"temp_api_label": label,
|
|
93
|
+
}
|
|
94
|
+
payload_list.append(req_data)
|
|
75
95
|
return payload_list
|
|
76
96
|
|
|
77
97
|
def convert_curl_data_to_model(
|
|
@@ -102,6 +122,31 @@ class ApiModelParser:
|
|
|
102
122
|
payload_list.append(req_model)
|
|
103
123
|
return payload_list
|
|
104
124
|
|
|
125
|
+
def convert_postman_to_list(self, postman_dict: dict) -> list[dict]:
|
|
126
|
+
api_infos = parse_postman(postman_dict) or []
|
|
127
|
+
payload_list = []
|
|
128
|
+
for api_info in api_infos:
|
|
129
|
+
path = api_info.get("path", "")
|
|
130
|
+
method = (api_info.get("method", "") or "").lower()
|
|
131
|
+
label = (
|
|
132
|
+
self.__handle_http_path(path.split("/"), "_")
|
|
133
|
+
.replace("{", "")
|
|
134
|
+
.replace("}", "")
|
|
135
|
+
+ "_"
|
|
136
|
+
+ method
|
|
137
|
+
)
|
|
138
|
+
req_data = {
|
|
139
|
+
"path": path,
|
|
140
|
+
"header": json.dumps(api_info.get("header", {})),
|
|
141
|
+
"body": api_info.get("body", {}),
|
|
142
|
+
"query_param": json.dumps(api_info.get("query_param", {})),
|
|
143
|
+
"original_url": api_info.get("url", ""),
|
|
144
|
+
"method": method,
|
|
145
|
+
"temp_api_label": label,
|
|
146
|
+
}
|
|
147
|
+
payload_list.append(req_data)
|
|
148
|
+
return payload_list
|
|
149
|
+
|
|
105
150
|
def convert_postman_to_model(self, postman_dict: dict) -> list[ReqData]:
|
|
106
151
|
api_infos = parse_postman(postman_dict)
|
|
107
152
|
payload_list = []
|
|
@@ -148,29 +193,78 @@ class ApiModelParser:
|
|
|
148
193
|
payload_list.append(req_data)
|
|
149
194
|
return payload_list
|
|
150
195
|
|
|
196
|
+
def convert_swagger_to_list(self, swagger2_dict: dict) -> list[dict]:
|
|
197
|
+
swagger_parser = Swagger2Parser(swagger2_dict)
|
|
198
|
+
api_dict = swagger_parser.get_swagger_api_info()
|
|
199
|
+
if not api_dict:
|
|
200
|
+
return []
|
|
201
|
+
payload_list = []
|
|
202
|
+
for path, path_info in api_dict.items():
|
|
203
|
+
parts = path.split("/")
|
|
204
|
+
path_val = self.__handle_http_path(parts[:-1], "/")
|
|
205
|
+
label_val = (
|
|
206
|
+
self.__handle_http_path(parts, "_").replace("{", "").replace("}", "")
|
|
207
|
+
)
|
|
208
|
+
body_param = path_info.get("body_param", {})
|
|
209
|
+
body_val = next(iter(body_param.values()), {})
|
|
210
|
+
req_data = {
|
|
211
|
+
"path": path_val,
|
|
212
|
+
"temp_api_label": label_val,
|
|
213
|
+
"method": parts[-1],
|
|
214
|
+
"query_param": json.dumps(path_info.get("query_param", {})),
|
|
215
|
+
"path_param": json.dumps(path_info.get("path_param", {})),
|
|
216
|
+
"response": json.dumps(path_info.get("response", {})),
|
|
217
|
+
"body": json.dumps(body_val),
|
|
218
|
+
}
|
|
219
|
+
payload_list.append(req_data)
|
|
220
|
+
return payload_list
|
|
221
|
+
|
|
151
222
|
def convert_openapi_to_model(self, openapi_dict: dict) -> list[ReqData]:
|
|
152
223
|
if not openapi_dict:
|
|
153
|
-
print("openapi dict is null")
|
|
154
224
|
return []
|
|
155
225
|
payload_list = []
|
|
156
226
|
parser = OpenApiParser(openapi_dict)
|
|
157
227
|
api_dict = parser.get_open_api_info()
|
|
158
228
|
if not api_dict:
|
|
159
|
-
|
|
160
|
-
return
|
|
229
|
+
return []
|
|
161
230
|
for path, path_info in api_dict.items():
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
.replace("{", "")
|
|
167
|
-
.replace("}", "")
|
|
231
|
+
parts = path.split("/")
|
|
232
|
+
req = ReqData()
|
|
233
|
+
req.path = self.__handle_http_path(parts[:-1], "/")
|
|
234
|
+
req.temp_api_label = (
|
|
235
|
+
self.__handle_http_path(parts, "_").replace("{", "").replace("}", "")
|
|
168
236
|
)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
237
|
+
req.method = parts[-1]
|
|
238
|
+
req.query_param = json.dumps(path_info.get("query_param", {}))
|
|
239
|
+
req.path_param = json.dumps(path_info.get("path_param", {}))
|
|
240
|
+
req.response = json.dumps(path_info.get("response", {}))
|
|
241
|
+
req.body = json.dumps(path_info.get("body_param", {}))
|
|
242
|
+
payload_list.append(req)
|
|
243
|
+
return payload_list
|
|
244
|
+
|
|
245
|
+
def convert_openapi_to_list(self, openapi_dict: dict) -> list[dict]:
|
|
246
|
+
if not openapi_dict:
|
|
247
|
+
return []
|
|
248
|
+
payload_list = []
|
|
249
|
+
parser = OpenApiParser(openapi_dict)
|
|
250
|
+
api_dict = parser.get_open_api_info()
|
|
251
|
+
if not api_dict:
|
|
252
|
+
return []
|
|
253
|
+
for path, path_info in api_dict.items():
|
|
254
|
+
parts = path.split("/")
|
|
255
|
+
path_val = self.__handle_http_path(parts[:-1], "/")
|
|
256
|
+
label_val = (
|
|
257
|
+
self.__handle_http_path(parts, "_").replace("{", "").replace("}", "")
|
|
258
|
+
)
|
|
259
|
+
req_data = {
|
|
260
|
+
"path": path_val,
|
|
261
|
+
"temp_api_label": label_val,
|
|
262
|
+
"method": parts[-1],
|
|
263
|
+
"query_param": json.dumps(path_info.get("query_param", {})),
|
|
264
|
+
"path_param": json.dumps(path_info.get("path_param", {})),
|
|
265
|
+
"response": json.dumps(path_info.get("response", {})),
|
|
266
|
+
"body": json.dumps(path_info.get("body_param", {})),
|
|
267
|
+
}
|
|
174
268
|
payload_list.append(req_data)
|
|
175
269
|
return payload_list
|
|
176
270
|
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/curl_parser.py
RENAMED
|
@@ -64,7 +64,7 @@ class CurlParser(object):
|
|
|
64
64
|
line_num_array.append([start_num, num])
|
|
65
65
|
return line_num_array
|
|
66
66
|
|
|
67
|
-
def
|
|
67
|
+
def split_curl_to_struct_old(self, lines, s, e, url_filter=None) -> dict:
|
|
68
68
|
req_data = {}
|
|
69
69
|
header = {}
|
|
70
70
|
reduced_lines = self.reduce_curl_data_part(lines=lines, s=s, e=e)
|
|
@@ -109,7 +109,6 @@ class CurlParser(object):
|
|
|
109
109
|
else:
|
|
110
110
|
curl_data = line_i_list[0]
|
|
111
111
|
body = re.sub(r"\n\s*", "", curl_data.replace(" \\\n", ""))
|
|
112
|
-
# body = re.sub(r"\s*", "", curl_data.replace(" \\\n", ""))
|
|
113
112
|
req_data["body"] = body[:-1]
|
|
114
113
|
|
|
115
114
|
if not req_data.get("method"):
|
|
@@ -120,3 +119,82 @@ class CurlParser(object):
|
|
|
120
119
|
req_data["method"] = "get"
|
|
121
120
|
|
|
122
121
|
return req_data
|
|
122
|
+
|
|
123
|
+
def split_curl_to_struct(self, lines, s, e, url_filter=None) -> dict:
|
|
124
|
+
req_data = {}
|
|
125
|
+
header = {}
|
|
126
|
+
|
|
127
|
+
reduced_lines = self.reduce_curl_data_part(lines=lines, s=s, e=e)
|
|
128
|
+
|
|
129
|
+
for line in reduced_lines:
|
|
130
|
+
line = str(line).strip()
|
|
131
|
+
|
|
132
|
+
# ---------------------------
|
|
133
|
+
# 解析 method 和 URL
|
|
134
|
+
# ---------------------------
|
|
135
|
+
if line.startswith("curl"):
|
|
136
|
+
parts = line.split()
|
|
137
|
+
|
|
138
|
+
for part in parts:
|
|
139
|
+
p = part.strip("'\"")
|
|
140
|
+
|
|
141
|
+
# method
|
|
142
|
+
if p.lower() in ["get", "post", "put", "delete"]:
|
|
143
|
+
req_data["method"] = p.lower()
|
|
144
|
+
|
|
145
|
+
# URL
|
|
146
|
+
elif p.startswith("http"):
|
|
147
|
+
req_data["original_url"] = p
|
|
148
|
+
elif "/" in p and "://" not in p: # Postman 样式
|
|
149
|
+
req_data["original_url"] = p
|
|
150
|
+
|
|
151
|
+
# url_filter
|
|
152
|
+
if url_filter and url_filter not in line:
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
# ---------------------------
|
|
156
|
+
# -X METHOD
|
|
157
|
+
# ---------------------------
|
|
158
|
+
elif line.startswith("-X") or " -X " in line:
|
|
159
|
+
# 例如:-X POST
|
|
160
|
+
parts = line.replace("\\", "").split()
|
|
161
|
+
if len(parts) >= 2:
|
|
162
|
+
req_data["method"] = parts[1].strip("'\"").lower()
|
|
163
|
+
|
|
164
|
+
# ---------------------------
|
|
165
|
+
# Header 解析
|
|
166
|
+
# ---------------------------
|
|
167
|
+
elif line.startswith("-H") or "--header" in line:
|
|
168
|
+
# 支持各种写法
|
|
169
|
+
m = re.search(r"'(.+?):\s*(.+?)'", line)
|
|
170
|
+
if m:
|
|
171
|
+
key = m.group(1)
|
|
172
|
+
val = m.group(2)
|
|
173
|
+
header[key] = val
|
|
174
|
+
|
|
175
|
+
# ---------------------------
|
|
176
|
+
# Body 解析
|
|
177
|
+
# ---------------------------
|
|
178
|
+
elif "--data" in line or "--data-raw" in line:
|
|
179
|
+
# 去掉行尾的转义符
|
|
180
|
+
clean = line.replace("\\\n", "").strip()
|
|
181
|
+
|
|
182
|
+
# 提取单引号内容
|
|
183
|
+
m = re.search(r"'(.*)'$", clean)
|
|
184
|
+
if m:
|
|
185
|
+
req_data["body"] = m.group(1)
|
|
186
|
+
else:
|
|
187
|
+
# 兼容无引号情况
|
|
188
|
+
req_data["body"] = clean.split("--data")[-1].strip()
|
|
189
|
+
|
|
190
|
+
# 如果没有 method,则默认 POST
|
|
191
|
+
req_data.setdefault("method", "post")
|
|
192
|
+
|
|
193
|
+
# ---------------------------
|
|
194
|
+
# 最终补齐数据
|
|
195
|
+
# ---------------------------
|
|
196
|
+
req_data.setdefault("method", "get")
|
|
197
|
+
req_data["header"] = header
|
|
198
|
+
req_data.setdefault("original_url", "")
|
|
199
|
+
|
|
200
|
+
return req_data
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
import json
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def parse_postman(json_file: dict) -> list:
|
|
7
|
+
items = json_file.get("item")
|
|
8
|
+
result = []
|
|
9
|
+
|
|
10
|
+
def _collect_vars(obj: dict) -> dict:
|
|
11
|
+
vars_list = obj.get("variable", [])
|
|
12
|
+
m = {}
|
|
13
|
+
for it in vars_list:
|
|
14
|
+
k = it.get("key") or it.get("name")
|
|
15
|
+
v = it.get("value")
|
|
16
|
+
if k:
|
|
17
|
+
m[str(k)] = v if v is not None else ""
|
|
18
|
+
return m
|
|
19
|
+
|
|
20
|
+
root_vars = _collect_vars(json_file)
|
|
21
|
+
pattern = re.compile(r"\{\{([^{}]+)\}\}")
|
|
22
|
+
|
|
23
|
+
def _resolve(s: str, vars_map: dict) -> str:
|
|
24
|
+
if not isinstance(s, str) or not s:
|
|
25
|
+
return s
|
|
26
|
+
|
|
27
|
+
def repl(m):
|
|
28
|
+
key = m.group(1).strip()
|
|
29
|
+
return str(vars_map.get(key, m.group(0)))
|
|
30
|
+
|
|
31
|
+
return pattern.sub(repl, s)
|
|
32
|
+
|
|
33
|
+
def _walk(item_obj: dict, inherited_vars: dict):
|
|
34
|
+
local_vars = _collect_vars(item_obj)
|
|
35
|
+
vars_map = {**inherited_vars, **local_vars}
|
|
36
|
+
child_items = item_obj.get("item")
|
|
37
|
+
if child_items:
|
|
38
|
+
for child in child_items:
|
|
39
|
+
_walk(child, vars_map)
|
|
40
|
+
return
|
|
41
|
+
if not item_obj.get("request"):
|
|
42
|
+
return
|
|
43
|
+
postman_request = item_obj["request"]
|
|
44
|
+
api_info = {}
|
|
45
|
+
api_info["method"] = postman_request.get("method", "")
|
|
46
|
+
headers = postman_request.get("header", [])
|
|
47
|
+
api_info["header"] = {
|
|
48
|
+
hs.get("key"): _resolve((hs.get("value") or ""), vars_map)
|
|
49
|
+
for hs in headers
|
|
50
|
+
if hs.get("key")
|
|
51
|
+
}
|
|
52
|
+
url_obj = postman_request.get("url", {})
|
|
53
|
+
api_info["url"] = _resolve(url_obj.get("raw", ""), vars_map)
|
|
54
|
+
path_list = url_obj.get("path")
|
|
55
|
+
if not path_list:
|
|
56
|
+
return
|
|
57
|
+
api_info["path"] = "/".join([_resolve(p, vars_map) for p in path_list if p])
|
|
58
|
+
api_info["query_param"] = {
|
|
59
|
+
qs.get("key"): _resolve((qs.get("value") or ""), vars_map)
|
|
60
|
+
for qs in url_obj.get("query", [])
|
|
61
|
+
if qs.get("key")
|
|
62
|
+
}
|
|
63
|
+
body_obj = postman_request.get("body")
|
|
64
|
+
body_val = {}
|
|
65
|
+
if body_obj and body_obj.get("mode") in body_obj:
|
|
66
|
+
temp = body_obj[body_obj["mode"]]
|
|
67
|
+
if isinstance(temp, str):
|
|
68
|
+
temp = _resolve(temp.replace("\\n", "").replace("\n", ""), vars_map)
|
|
69
|
+
if temp:
|
|
70
|
+
try:
|
|
71
|
+
temp = json.loads(temp)
|
|
72
|
+
except Exception:
|
|
73
|
+
pass
|
|
74
|
+
body_val = temp
|
|
75
|
+
api_info["body"] = body_val
|
|
76
|
+
result.append(api_info)
|
|
77
|
+
|
|
78
|
+
if items:
|
|
79
|
+
for it in items:
|
|
80
|
+
_walk(it, root_vars)
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
def parse_postman_bak(json_file: dict) -> list:
|
|
84
|
+
# TODO 如果postman中有变量,则无法解析变量的值.
|
|
85
|
+
api_info_list = []
|
|
86
|
+
items = json_file.get("item")
|
|
87
|
+
if items:
|
|
88
|
+
for item in items:
|
|
89
|
+
if item.get("item"):
|
|
90
|
+
api_info_list.extend(parse_postman(item))
|
|
91
|
+
else:
|
|
92
|
+
api_info = {}
|
|
93
|
+
if not item.get("request"):
|
|
94
|
+
continue
|
|
95
|
+
postman_request = item["request"]
|
|
96
|
+
api_info["method"] = postman_request["method"]
|
|
97
|
+
api_info["header"] = {}
|
|
98
|
+
for hs in postman_request["header"]:
|
|
99
|
+
api_info["header"][hs["key"]] = hs["value"]
|
|
100
|
+
api_info["url"] = postman_request["url"]["raw"]
|
|
101
|
+
if not postman_request["url"].get("path"):
|
|
102
|
+
continue
|
|
103
|
+
api_info["path"] = "/".join(postman_request["url"]["path"])
|
|
104
|
+
api_info["query_param"] = {}
|
|
105
|
+
if postman_request["url"].get("query"):
|
|
106
|
+
for qs in postman_request["url"]["query"]:
|
|
107
|
+
api_info["query_param"][qs["key"]] = qs["value"]
|
|
108
|
+
api_info["body"] = {}
|
|
109
|
+
if postman_request.get("body"):
|
|
110
|
+
temp = postman_request["body"][postman_request["body"]["mode"]]
|
|
111
|
+
if isinstance(temp, str):
|
|
112
|
+
# \\n 只会出现在value中,一般是用户自己定义的
|
|
113
|
+
temp = temp.replace("\\n", "").replace("\n", "")
|
|
114
|
+
if temp:
|
|
115
|
+
# parse json string
|
|
116
|
+
try:
|
|
117
|
+
temp = json.loads(temp)
|
|
118
|
+
except json.JSONDecodeError:
|
|
119
|
+
# Not a valid JSON, treat as a plain string
|
|
120
|
+
pass
|
|
121
|
+
api_info["body"] = temp
|
|
122
|
+
api_info_list.append(api_info)
|
|
123
|
+
return api_info_list
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
from http_content_parser.api_parser import ApiModelParser
|
|
2
3
|
|
|
3
4
|
|
|
@@ -7,4 +8,4 @@ api_parser = ApiModelParser()
|
|
|
7
8
|
def test_curl_parser():
|
|
8
9
|
curl_file = "./tmp"
|
|
9
10
|
api_info = api_parser.get_api_list_for_curl(curl_file=curl_file)
|
|
10
|
-
print(api_info)
|
|
11
|
+
print(json.dumps(api_info, indent=4))
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from http_content_parser.postman_parser import parse_postman
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_parse_postman_basic_and_vars():
|
|
7
|
+
collection = {
|
|
8
|
+
"variable": [
|
|
9
|
+
{"key": "host", "value": "api.example.com"},
|
|
10
|
+
{"name": "token", "value": "abc123"},
|
|
11
|
+
],
|
|
12
|
+
"item": [
|
|
13
|
+
{
|
|
14
|
+
"name": "Folder",
|
|
15
|
+
"item": [
|
|
16
|
+
{
|
|
17
|
+
"name": "GetUser",
|
|
18
|
+
"request": {
|
|
19
|
+
"method": "GET",
|
|
20
|
+
"header": [
|
|
21
|
+
{"key": "Authorization", "value": "Bearer {{token}}"}
|
|
22
|
+
],
|
|
23
|
+
"url": {
|
|
24
|
+
"raw": "https://{{host}}/v1/users?id={{uid}}",
|
|
25
|
+
"path": ["v1", "users"],
|
|
26
|
+
"query": [{"key": "id", "value": "{{uid}}"}],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
"variable": [{"key": "uid", "value": "42"}],
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
}
|
|
35
|
+
res = parse_postman(collection)
|
|
36
|
+
assert isinstance(res, list)
|
|
37
|
+
assert len(res) == 1
|
|
38
|
+
item = res[0]
|
|
39
|
+
assert item["method"] == "GET"
|
|
40
|
+
assert item["path"] == "v1/users"
|
|
41
|
+
assert item["url"].startswith("https://api.example.com")
|
|
42
|
+
assert item["query_param"]["id"] == "42"
|
|
43
|
+
assert item["header"]["Authorization"] == "Bearer abc123"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_parse_postman_no_global_accumulate():
|
|
47
|
+
c = {
|
|
48
|
+
"item": [
|
|
49
|
+
{
|
|
50
|
+
"request": {
|
|
51
|
+
"method": "GET",
|
|
52
|
+
"header": [],
|
|
53
|
+
"url": {"raw": "https://x/a", "path": ["a"], "query": []},
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
r1 = parse_postman(c)
|
|
59
|
+
r2 = parse_postman(c)
|
|
60
|
+
assert len(r1) == 1
|
|
61
|
+
assert len(r2) == 1
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# -*- coding: UTF-8 -*-
|
|
2
|
-
import json
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
api_info_list = []
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def parse_postman(json_file: dict) -> list:
|
|
9
|
-
# TODO 如果postman中有变量,则无法解析变量的值.
|
|
10
|
-
items = json_file.get("item")
|
|
11
|
-
if items:
|
|
12
|
-
for item in items:
|
|
13
|
-
if item.get("item"):
|
|
14
|
-
parse_postman(item)
|
|
15
|
-
else:
|
|
16
|
-
api_info = {}
|
|
17
|
-
if not item.get("request"):
|
|
18
|
-
continue
|
|
19
|
-
postman_request = item["request"]
|
|
20
|
-
api_info["method"] = postman_request["method"]
|
|
21
|
-
api_info["header"] = {}
|
|
22
|
-
for hs in postman_request["header"]:
|
|
23
|
-
api_info["header"][hs["key"]] = hs["value"]
|
|
24
|
-
api_info["url"] = postman_request["url"]["raw"]
|
|
25
|
-
if not postman_request["url"].get("path"):
|
|
26
|
-
continue
|
|
27
|
-
api_info["path"] = "/".join(postman_request["url"]["path"])
|
|
28
|
-
api_info["query_param"] = {}
|
|
29
|
-
if postman_request["url"].get("query"):
|
|
30
|
-
for qs in postman_request["url"]["query"]:
|
|
31
|
-
api_info["query_param"][qs["key"]] = qs["value"]
|
|
32
|
-
api_info["body"] = {}
|
|
33
|
-
if postman_request.get("body"):
|
|
34
|
-
temp = postman_request["body"][postman_request["body"]["mode"]]
|
|
35
|
-
if isinstance(temp, str):
|
|
36
|
-
# \\n 只会出现在value中,一般是用户自己定义的
|
|
37
|
-
temp = temp.replace("\\n", "").replace("\n", "")
|
|
38
|
-
if temp:
|
|
39
|
-
# beautify json string
|
|
40
|
-
temp = json.dumps(temp) # 转换为 JSON 格式的字符串
|
|
41
|
-
temp = json.loads(temp)
|
|
42
|
-
api_info["body"] = temp
|
|
43
|
-
api_info_list.append(api_info)
|
|
44
|
-
return api_info_list
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/openapi_parser.py
RENAMED
|
File without changes
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/param_util.py
RENAMED
|
File without changes
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/req_data.py
RENAMED
|
File without changes
|
{http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/swagger2_parser.py
RENAMED
|
File without changes
|
|
File without changes
|