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.
Files changed (20) hide show
  1. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/PKG-INFO +1 -1
  2. http_content_parser-0.0.23/api.yaml +54 -0
  3. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/pyproject.toml +1 -1
  4. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/api_parser.py +126 -32
  5. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/curl_parser.py +80 -2
  6. http_content_parser-0.0.23/src/http_content_parser/postman_parser.py +123 -0
  7. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/tests/test_api_model_parser.py +2 -1
  8. http_content_parser-0.0.23/tests/test_postman.py +61 -0
  9. http_content_parser-0.0.21/src/http_content_parser/postman_parser.py +0 -44
  10. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/.gitignore +0 -0
  11. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/LICENSE +0 -0
  12. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/README.md +0 -0
  13. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/requirements.txt +0 -0
  14. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/__init__.py +0 -0
  15. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/generate_api_file.py +0 -0
  16. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/openapi_parser.py +0 -0
  17. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/param_util.py +0 -0
  18. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/req_data.py +0 -0
  19. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/src/http_content_parser/swagger2_parser.py +0 -0
  20. {http_content_parser-0.0.21 → http_content_parser-0.0.23}/tests/test_curl.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: http_content_parser
3
- Version: 0.0.21
3
+ Version: 0.0.23
4
4
  Summary: parse http's payload and response
5
5
  Author-email: leo <suleiabc@gmail.com>
6
6
  License-File: LICENSE
@@ -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: {}
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "http_content_parser"
7
- version = "0.0.21"
7
+ version = "0.0.23"
8
8
  authors = [{ name = "leo", email = "suleiabc@gmail.com" }]
9
9
  description = "parse http's payload and response"
10
10
  readme = "README.md"
@@ -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 r in line_num_array:
58
- res_dict = curl_parser.split_curl_to_struct(
59
- lines, r[0], r[1], url_filter
60
- )
61
- req_list = res_dict
62
- url_content = curl_parser.parse_url(req_list["original_url"])
63
- req_list["temp_api_label"] = (
64
- self.__replace_api_label_chars(url_content["path"][1:])
65
- + "_"
66
- + req_list["method"]
67
- )
68
- # req_list["header"] = json.dumps(req_list["header"])
69
- if url_content["query_params"]:
70
- req_list["query_param"] = json.dumps(url_content["query_params"])
71
- else:
72
- req_list["query_param"] = {}
73
- req_list["path"] = url_content["path"][1:]
74
- payload_list.append(req_list)
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
- print("check your swagger json")
160
- return
229
+ return []
161
230
  for path, path_info in api_dict.items():
162
- req_data = ReqData()
163
- req_data.path = self.__handle_http_path(path.split("/")[:-1], "/")
164
- req_data.temp_api_label = (
165
- self.__handle_http_path(path.split("/"), "_")
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
- req_data.method = path.split("/")[-1]
170
- req_data.query_param = json.dumps(path_info["query_param"])
171
- req_data.path_param = json.dumps(path_info["path_param"])
172
- req_data.response = json.dumps(path_info.get("response", {}))
173
- req_data.body = json.dumps(path_info["body_param"])
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
 
@@ -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 split_curl_to_struct(self, lines, s, e, url_filter=None) -> dict:
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