iflow-mcp_galaxyxieyu_api-auto-test 0.1.0__py3-none-any.whl

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.
atf/utils/helpers.py ADDED
@@ -0,0 +1,155 @@
1
+ """
2
+ 测试数据工厂 - 提供常用的数据生成函数
3
+ 用法: {{ tools.timestamp() }}, {{ tools.uuid() }}, {{ tools.random_int(1, 100) }}
4
+ """
5
+
6
+ import random
7
+ import string
8
+ import time
9
+ import uuid as _uuid
10
+ from datetime import datetime, timedelta
11
+
12
+
13
+ # ==================== 时间相关 ====================
14
+
15
+ def timestamp():
16
+ """当前时间戳(秒)"""
17
+ return int(time.time())
18
+
19
+
20
+ def timestamp_ms():
21
+ """当前时间戳(毫秒)"""
22
+ return int(time.time() * 1000)
23
+
24
+
25
+ def datetime_now(fmt: str = "%Y-%m-%d %H:%M:%S"):
26
+ """当前时间字符串"""
27
+ return datetime.now().strftime(fmt)
28
+
29
+
30
+ def date_today(fmt: str = "%Y-%m-%d"):
31
+ """今天日期"""
32
+ return datetime.now().strftime(fmt)
33
+
34
+
35
+ def date_offset(days: int = 0, fmt: str = "%Y-%m-%d"):
36
+ """偏移日期,days 可为负数"""
37
+ return (datetime.now() + timedelta(days=days)).strftime(fmt)
38
+
39
+
40
+ # ==================== 随机数据 ====================
41
+
42
+ def uuid():
43
+ """生成 UUID"""
44
+ return str(_uuid.uuid4())
45
+
46
+
47
+ def uuid_short():
48
+ """生成短 UUID(8位)"""
49
+ return str(_uuid.uuid4())[:8]
50
+
51
+
52
+ def random_int(min_val: int = 1, max_val: int = 10000):
53
+ """随机整数"""
54
+ return random.randint(min_val, max_val)
55
+
56
+
57
+ def random_float(min_val: float = 0.0, max_val: float = 100.0, precision: int = 2):
58
+ """随机浮点数"""
59
+ return round(random.uniform(min_val, max_val), precision)
60
+
61
+
62
+ def random_str(length: int = 8):
63
+ """随机字符串(字母+数字)"""
64
+ return ''.join(random.choices(string.ascii_letters + string.digits, k=length))
65
+
66
+
67
+ def random_letters(length: int = 8):
68
+ """随机字母"""
69
+ return ''.join(random.choices(string.ascii_letters, k=length))
70
+
71
+
72
+ def random_digits(length: int = 6):
73
+ """随机数字字符串"""
74
+ return ''.join(random.choices(string.digits, k=length))
75
+
76
+
77
+ def random_choice(*items):
78
+ """从给定选项中随机选择"""
79
+ return random.choice(items) if items else None
80
+
81
+
82
+ # ==================== 模拟数据 ====================
83
+
84
+ def fake_email(prefix: str = "test"):
85
+ """生成测试邮箱"""
86
+ return f"{prefix}_{timestamp()}@test.com"
87
+
88
+
89
+ def fake_phone():
90
+ """生成测试手机号(中国)"""
91
+ prefixes = ['138', '139', '150', '151', '152', '158', '159', '186', '187', '188']
92
+ return random.choice(prefixes) + random_digits(8)
93
+
94
+
95
+ def fake_username(prefix: str = "user"):
96
+ """生成测试用户名"""
97
+ return f"{prefix}_{uuid_short()}"
98
+
99
+
100
+ def fake_name():
101
+ """生成随机中文姓名"""
102
+ first_names = ['张', '李', '王', '刘', '陈', '杨', '赵', '黄', '周', '吴']
103
+ last_names = ['伟', '芳', '娜', '敏', '静', '强', '磊', '洋', '勇', '艳', '杰', '娟', '涛', '明', '超']
104
+ return random.choice(first_names) + ''.join(random.choices(last_names, k=random.randint(1, 2)))
105
+
106
+
107
+ def fake_address():
108
+ """生成随机地址"""
109
+ cities = ['北京市', '上海市', '广州市', '深圳市', '杭州市', '成都市', '武汉市', '南京市']
110
+ districts = ['朝阳区', '海淀区', '浦东新区', '天河区', '南山区', '西湖区', '武侯区', '江宁区']
111
+ streets = ['科技路', '创新大道', '人民路', '中山路', '解放路', '建设路']
112
+ return f"{random.choice(cities)}{random.choice(districts)}{random.choice(streets)}{random_int(1, 999)}号"
113
+
114
+
115
+ def fake_id_card():
116
+ """生成测试身份证号(非真实)"""
117
+ area = random_digits(6)
118
+ year = random.randint(1970, 2000)
119
+ month = str(random.randint(1, 12)).zfill(2)
120
+ day = str(random.randint(1, 28)).zfill(2)
121
+ seq = random_digits(3)
122
+ check = random.choice('0123456789X')
123
+ return f"{area}{year}{month}{day}{seq}{check}"
124
+
125
+
126
+ def fake_company():
127
+ """生成测试公司名"""
128
+ prefixes = ['华', '中', '东', '西', '南', '北', '新', '金', '银', '瑞']
129
+ mids = ['科', '创', '智', '信', '达', '联', '通', '盛', '鑫', '源']
130
+ suffixes = ['科技有限公司', '网络有限公司', '信息技术有限公司', '电子商务有限公司']
131
+ return random.choice(prefixes) + random.choice(mids) + random.choice(suffixes)
132
+
133
+
134
+ # ==================== 兼容旧函数 ====================
135
+
136
+ def demo_get_id():
137
+ """兼容旧版本"""
138
+ return random_int(1, 1000)
139
+
140
+
141
+ def demo_func(a=None, b=None, c=None):
142
+ """兼容旧版本"""
143
+ vals = [v for v in [a, b, c] if v is not None]
144
+ return sum(vals) if vals else 0
145
+
146
+
147
+ # ==================== 使用示例 ====================
148
+ if __name__ == '__main__':
149
+ print(f"timestamp: {timestamp()}")
150
+ print(f"uuid: {uuid()}")
151
+ print(f"random_int: {random_int(1, 100)}")
152
+ print(f"fake_email: {fake_email()}")
153
+ print(f"fake_phone: {fake_phone()}")
154
+ print(f"fake_name: {fake_name()}")
155
+ print(f"fake_address: {fake_address()}")
@@ -0,0 +1,409 @@
1
+ Metadata-Version: 2.4
2
+ Name: iflow-mcp_galaxyxieyu_api-auto-test
3
+ Version: 0.1.0
4
+ Summary: API Auto Test Framework with MCP Server
5
+ Author-email: GalaxyXieyu <galaxyxieyu@github.com>
6
+ License: MIT
7
+ Keywords: api,automation,mcp,pytest,testing
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: allure-pytest>=2.13
17
+ Requires-Dist: dingtalkchatbot>=1.5.7
18
+ Requires-Dist: loguru>=0.4.1
19
+ Requires-Dist: mcp>=1.0.0
20
+ Requires-Dist: mysql-connector-python>=8.0.33
21
+ Requires-Dist: pydantic>=2.0
22
+ Requires-Dist: pytest-html>=2.1.1
23
+ Requires-Dist: pytest>=7.0
24
+ Requires-Dist: pyyaml>=6.0
25
+ Requires-Dist: requests>=2.31
26
+ Requires-Dist: urllib3<2
27
+ Description-Content-Type: text/markdown
28
+
29
+ <div align="center">
30
+ <img src="docs/images/mcp-architecture.png" alt="MCP Architecture" width="100%"/>
31
+ </div>
32
+
33
+ # API Auto Test Framework
34
+
35
+ ![Python](https://img.shields.io/badge/python-3.10%2B-blue)
36
+ ![License](https://img.shields.io/badge/license-MIT-green)
37
+ ![pytest](https://img.shields.io/badge/pytest-8.0%2B-yellow)
38
+
39
+ **YAML Declarative API Testing Framework, Optimized for AI Coding Assistants**
40
+
41
+ [Quick Start](#quick-start) | [MCP Integration](#mcp-server-integration) | [YAML Spec](#yaml-test-case-spec) | [Unit Testing](#unit-testing)
42
+
43
+ ---
44
+
45
+ ## Why This Framework?
46
+
47
+ When asking AI to write API tests, you might encounter these issues:
48
+
49
+ **Scenario 1: Repetitive Work**
50
+
51
+ Every time you ask AI to generate tests, you need to re-describe the project structure, authentication method, and assertion style. For 10 API tests, the same fixture and setup code gets generated 10 times.
52
+
53
+ **Scenario 2: Token Black Hole**
54
+
55
+ A simple login API test generates 200 lines of code. You find an assertion is wrong, ask AI to fix it, and it generates another 200 lines. After 3 revisions, you've consumed 2000+ Tokens, and you still end up fixing it manually.
56
+
57
+ **Scenario 3: Debugging Dead Loop**
58
+
59
+ AI-generated tests fail to run. You paste the error message, AI fixes it but still wrong. After 5 rounds of conversation, the problem persists, and you've burned 5000+ Tokens.
60
+
61
+ **This Framework's Solution:**
62
+
63
+ ```
64
+ Traditional: Natural Language -> AI Generates Full Code -> Run Error -> Paste Error -> AI Regenerates -> Loop...
65
+ This Framework: Natural Language -> AI Generates YAML -> Framework Executes -> Locate Issue -> Fix 1 Line YAML
66
+ ```
67
+
68
+ | Metric | Traditional AI | This Framework |
69
+ |--------|---------------|----------------|
70
+ | Test 1 API | ~200 lines code | ~20 lines YAML |
71
+ | Modify Assertion | Regenerate all code | Fix 1-2 lines YAML |
72
+ | 10 API Tests | Repeat setup 10x | Shared config, 0 repeat |
73
+ | Debug Issue | 3-5 rounds avg | Usually 1 round |
74
+
75
+ ---
76
+
77
+ ## Key Features
78
+
79
+ | Feature | Description |
80
+ |---------|-------------|
81
+ | **YAML Declarative Tests** | Test logic separated from execution code, AI generates structured data only |
82
+ | **MCP Server** | Seamless integration with Claude/Cursor and other AI editors |
83
+ | **API Workflow Orchestration** | Multi-step API calls in single file, with data passing and assertions between steps |
84
+ | **Variable Resolution Engine** | Support for cross-step data transfer, global variables, and dynamic function calls |
85
+ | **Auto Authentication** | Token acquisition and refresh handled by framework |
86
+ | **Data Factory** | Built-in mock data generation, no Java dependencies |
87
+ | **Multi-format Reports** | Allure (offline/online), pytest-html (standalone HTML, styled) |
88
+ | **Multi-channel Notifications** | DingTalk, Feishu, WeCom |
89
+ | **Unit Testing** | Python code unit testing with automatic mock dependency injection |
90
+
91
+ ---
92
+
93
+ ## Quick Start
94
+
95
+ ### Installation
96
+
97
+ ```bash
98
+ # 1. Install uv (if not installed)
99
+ curl -LsSf https://astral.sh/uv/install.sh | sh
100
+
101
+ # 2. Install MCP server (recommended: install as a tool)
102
+ uv tool install git+https://github.com/GalaxyXieyu/Api-Test-MCP.git
103
+
104
+ # Verify
105
+ api-auto-test-mcp --help
106
+
107
+ # Manage tools
108
+ uv tool list
109
+ uv tool uninstall api-auto-test # use the tool name shown by `uv tool list`
110
+ ```
111
+
112
+ **Run without installing (uvx):**
113
+
114
+ ```bash
115
+ uvx --from git+https://github.com/GalaxyXieyu/Api-Test-MCP.git api-auto-test-mcp --help
116
+ ```
117
+
118
+ **Common mistake:** `uvx install ...` is **wrong**. `uvx` treats the first word after it as the tool name, so it will try to resolve a package literally named `install` and fail.
119
+
120
+ ### Configure Editor
121
+
122
+ Add the following to your editor's MCP settings:
123
+
124
+ ```json
125
+ {
126
+ "mcpServers": {
127
+ "api-auto-test": {
128
+ "command": "api-auto-test-mcp"
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ | Editor | Config Location |
135
+ |--------|-----------------|
136
+ | Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` |
137
+ | Cursor | Settings -> MCP Servers |
138
+ | VSCode + Continue | `.vscode/mcp.json` |
139
+
140
+ ### Local Development
141
+
142
+ ```bash
143
+ # Recommended with uv
144
+ uv pip install -r requirements.txt
145
+
146
+ # Or with pip
147
+ pip install -r requirements.txt
148
+ ```
149
+
150
+ ### Create Test Case
151
+
152
+ ```yaml
153
+ # tests/cases/user_login.yaml
154
+ testcase:
155
+ name: user_login
156
+ description: User login API test
157
+ host: http://localhost:8000
158
+ steps:
159
+ - id: login
160
+ path: /api/auth/login
161
+ method: POST
162
+ data:
163
+ username: "test_user"
164
+ password: "123456"
165
+ assert:
166
+ - type: status_code
167
+ expected: 200
168
+ - type: equals
169
+ field: data.code
170
+ expected: 0
171
+ ```
172
+
173
+ ### Generate and Run
174
+
175
+ ```bash
176
+ # Generate pytest scripts
177
+ python -m atf.case_generator
178
+
179
+ # Run tests
180
+ pytest tests/scripts/ -v
181
+
182
+ # Generate Allure report
183
+ pytest tests/scripts/ --alluredir=tests/allure-results
184
+ allure serve tests/allure-results
185
+
186
+ # Generate pytest-html report
187
+ pytest tests/scripts/ --html=report.html
188
+ ```
189
+
190
+ ---
191
+
192
+ ## MCP Server Integration
193
+
194
+ Through MCP, AI editors can directly call framework tools to generate and execute tests.
195
+
196
+ ### Efficiency Comparison
197
+
198
+ | Metric | Without MCP | With MCP | Improvement |
199
+ |--------|-------------|----------|-------------|
200
+ | Total Cost | $0.0214 | $0.0099 | **-54%** |
201
+ | API Latency | 11 sec | 4 sec | **-64%** |
202
+ | Output Tokens | 585 | 238 | **-59%** |
203
+ | Cache Read | 42.0k | 21.0k | **-50%** |
204
+
205
+ **Test Scenario**: Same API test generation task (pure consultation/analysis conversation)
206
+
207
+ **Core Advantages**:
208
+ - **54% cost reduction**: MCP directly calls tools, avoiding lengthy code generation context
209
+ - **64% faster API response**: Tool calls are more efficient than natural language interaction
210
+ - **59% less token consumption**: Only necessary parameters needed, no need to repeat project structure
211
+
212
+ ### Available Tools
213
+
214
+ | Tool | Description |
215
+ |------|-------------|
216
+ | `list_testcases` | List test cases |
217
+ | `get_testcase` | Read test case content |
218
+ | `write_testcase` | Create/update test case and generate pytest script |
219
+ | `write_unittest` | Create unit test |
220
+ | `delete_testcase` | Delete test case |
221
+ | `run_tests` | Execute tests |
222
+ | `get_test_results` | Get test execution history |
223
+ | `health_check` | Service health check |
224
+
225
+ ### Usage Example
226
+
227
+ Tell AI:
228
+
229
+ ```
230
+ Create a test for /api/users interface, verify returned user list length > 0
231
+ ```
232
+
233
+ AI will call `write_testcase` to generate YAML and corresponding pytest script.
234
+
235
+ ---
236
+
237
+ ## Project Structure
238
+
239
+ ```
240
+ api-auto-test/
241
+ ├── atf/ # Framework core
242
+ │ ├── core/ # Request, assertion, variable resolution modules
243
+ │ ├── mcp/ # MCP Server implementation
244
+ │ └── handlers/ # Notification, report handlers
245
+ ├── tests/
246
+ │ ├── cases/ # YAML test cases
247
+ │ └── scripts/ # Generated pytest scripts
248
+ ├── config.yaml # Project config (environment, database, notifications)
249
+ └── pyproject.toml
250
+ ```
251
+
252
+ ---
253
+
254
+ ## YAML Test Case Spec
255
+
256
+ ### Basic Structure
257
+
258
+ ```yaml
259
+ testcase:
260
+ name: test_name # Case name, used for filename
261
+ description: Description # Optional
262
+ host: http://localhost:8000 # API host, can also be configured globally in config.yaml
263
+ steps:
264
+ - id: step1 # Step ID, used for later reference
265
+ path: /api/endpoint
266
+ method: POST
267
+ headers:
268
+ Authorization: "Bearer {{ login.data.token }}" # Reference response from other step
269
+ data:
270
+ key: value
271
+ assert:
272
+ - type: status_code
273
+ expected: 200
274
+ - type: equals
275
+ field: data.id
276
+ expected: 1
277
+ ```
278
+
279
+ ### Assertion Types
280
+
281
+ | Type | Description | Example |
282
+ |------|-------------|---------|
283
+ | `status_code` | HTTP status code | `expected: 200` |
284
+ | `equals` | Exact match | `field: data.id, expected: 1` |
285
+ | `contains` | Contains | `field: data.name, expected: "test"` |
286
+ | `length` | Array/string length | `field: data.list, expected: 10` |
287
+ | `regex` | Regex match | `field: data.email, expected: "^\\w+@"` |
288
+
289
+ ### Variable Reference
290
+
291
+ ```yaml
292
+ # Reference response data from other steps
293
+ token: "{{ login.data.token }}"
294
+
295
+ # Reference global config
296
+ host: "{{ merchant.host }}"
297
+
298
+ # Call built-in functions
299
+ timestamp: "{{ tools.get_timestamp() }}"
300
+ uuid: "{{ tools.generate_uuid() }}"
301
+ ```
302
+
303
+ ### Teardown
304
+
305
+ ```yaml
306
+ testcase:
307
+ name: create_and_delete_user
308
+ steps:
309
+ - id: create_user
310
+ path: /api/users
311
+ method: POST
312
+ data:
313
+ name: "test_user"
314
+ teardowns:
315
+ - id: delete_user
316
+ operation_type: api
317
+ path: /api/users/{{ create_user.data.id }}
318
+ method: DELETE
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Unit Testing
324
+
325
+ Support for writing unit tests for Python code, automatically generating test cases through MCP tools.
326
+
327
+ ### Unit Test YAML Format
328
+
329
+ ```yaml
330
+ unittest:
331
+ name: UserService Test
332
+ target:
333
+ module: app.services.user_service
334
+ class: UserService
335
+ function: get_user
336
+ fixtures:
337
+ setup:
338
+ - type: patch
339
+ target: app.services.user_service.UserRepository
340
+ return_value:
341
+ id: 1
342
+ name: "test_user"
343
+ cases:
344
+ - id: test_get_user_success
345
+ description: Test get user success
346
+ inputs:
347
+ args: [1]
348
+ kwargs: {}
349
+ assert:
350
+ - type: equals
351
+ field: result.id
352
+ expected: 1
353
+ - type: equals
354
+ field: result.name
355
+ expected: "test_user"
356
+ ```
357
+
358
+ ### Assertion Types
359
+
360
+ | Type | Description |
361
+ |------|-------------|
362
+ | `equals` | Exact match |
363
+ | `not_equals` | Not equal |
364
+ | `contains` | Contains |
365
+ | `raises` | Expect exception to be raised |
366
+ | `is_none` | Result is None |
367
+ | `is_not_none` | Result is not None |
368
+ | `called_once` | Mock called once |
369
+ | `called_with` | Mock called with specific arguments |
370
+
371
+ ---
372
+
373
+ ## Configuration File
374
+
375
+ ```yaml
376
+ # config.yaml
377
+ projects:
378
+ merchant:
379
+ test:
380
+ host: http://192.168.1.100:8080
381
+ is_need_login: true
382
+ login:
383
+ url: http://192.168.1.100:8080/login
384
+ method: POST
385
+ data:
386
+ username: admin
387
+ password: "123456"
388
+ online:
389
+ host: https://api.example.com
390
+ is_need_login: true
391
+
392
+ notifications:
393
+ dingtalk:
394
+ webhook: "https://oapi.dingtalk.com/robot/send?access_token=xxx"
395
+ secret: "SECxxx"
396
+ ```
397
+
398
+ ---
399
+
400
+ ## License
401
+
402
+ MIT License
403
+
404
+ ---
405
+
406
+ ## Links
407
+
408
+ - [GitHub](https://github.com/GalaxyXieyu/Api-Test-MCP)
409
+ - [Issue Report](https://github.com/GalaxyXieyu/Api-Test-MCP/issues)
@@ -0,0 +1,37 @@
1
+ atf/__init__.py,sha256=QetjM3D_EbtvBwNjUDYwmdrJUun2eBaO1m6St5CWT88,1191
2
+ atf/auth.py,sha256=DCMPDAz1Vnoj7hxuWRRfZ0ug-kb4e9Ey4nnhDVw6LRk,3293
3
+ atf/case_generator.py,sha256=nRTI6WNi3DSvtn7UFZ11utaNLsNJX0wIWSLdRwWNS8E,30026
4
+ atf/conftest.py,sha256=XRUQSHB_UAdLEt3-yPQxm84TQqwZ0yLqxnFMOzi24UA,2219
5
+ atf/mcp_server.py,sha256=GJHBIjpPX8p0xS9bqunjfNurLcWs-gcyS0nNTMbFIa8,4857
6
+ atf/runner.py,sha256=OqFkBUVvfL9nR9LoepmNrq07XK2k3eRDYZJm1qYeZIY,5281
7
+ atf/unit_case_generator.py,sha256=paIAgxv6kCvZJRSiWYlzOFhH8zsXIB7OnAAOOqMc9DY,12464
8
+ atf/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ atf/assets/report.css,sha256=ALlK-Sjom1CntJAfBhnHUmET78-VvJ8HS4cdQed145g,4818
10
+ atf/core/__init__.py,sha256=l1aHMcuadmCsEUuxCQLYEC1A8AZs3fEKJwixDabh120,1007
11
+ atf/core/assert_handler.py,sha256=TyvlOONdEeAZsCLRFjUHrDIrLdOiwwQCiu4hEDbZMK4,14745
12
+ atf/core/config_manager.py,sha256=haCEunh6fd_H5VbScH96vlea2HOT38ItNrWfNG29lr8,3952
13
+ atf/core/globals.py,sha256=7rfXhfpUoK8K3x6i90WKePEgxFEigipzMl1PtCs95RQ,1350
14
+ atf/core/log_manager.py,sha256=sJcVZL2NAVQE5BV4BOCkAMTpGlUa_K4KDq3g12XK25M,1584
15
+ atf/core/login_handler.py,sha256=9Y7b7j_4xGyuswgzzgW58GHSnw-yR91fIOa2aiVYGPc,2363
16
+ atf/core/request_handler.py,sha256=sGV7EXdPJslJEZBGxp4dzrbqTXC9hiz28DF670ccnh0,8035
17
+ atf/core/variable_resolver.py,sha256=QNKIUNPAj6C5JGwSyVnba4YCN2Ur1r459wTxqrZOLkE,6617
18
+ atf/handlers/__init__.py,sha256=ClFew48CqBCtXDt3bG8XLib8_zLVmL0WVrNFGrazCII,252
19
+ atf/handlers/notification_handler.py,sha256=67xQbiPYr8wjq9KGrkgoxnnAnuOjBFrYRD6xybxFB0w,3189
20
+ atf/handlers/report_generator.py,sha256=NA-y_378Gud5oEdtI00B1fiq8TpfpK1jh4oizdTqL2E,6431
21
+ atf/handlers/teardown_handler.py,sha256=93kS2BrO_OilXbhOWgpUkSaZeLyiKrEFtwkl8jGbbsU,3328
22
+ atf/mcp/__init__.py,sha256=fZsU_7U8cOD1nFGAGfDkQkbkqTGP6MIfyQu3V_avYWM,21
23
+ atf/mcp/executor.py,sha256=LE1CowMJJ8tFaeKGJbOSYrKJBBv2E9otl7URDnwAFjI,16112
24
+ atf/mcp/models.py,sha256=_MSSibvcwWwSEHfOsoZPhaCJgkgFfZcWT7TLPf8yS9A,16330
25
+ atf/mcp/utils.py,sha256=OnmGjvk05PD5fzP_IgAIKinKCfAaKkfIOfF7WtjcEOQ,12327
26
+ atf/mcp/tools/__init__.py,sha256=WOt8D_cjUg7poNypfi_C21hfdbitOmXM2VLuyTuLL5I,20
27
+ atf/mcp/tools/health_tool.py,sha256=fvcEh6G0ZU_ERRY2PGZiBvHG0o3eAfGT1edwQXNEFlw,1685
28
+ atf/mcp/tools/metrics_tools.py,sha256=QfmaTzCd1Db-BjrZB6m2zK2IWu21qqVSH1h9t7jXFLI,4451
29
+ atf/mcp/tools/runner_tools.py,sha256=TTUnTrHwvEXe6PWtFqRzXOvdadD_d_jg0jNqhME3D7g,15016
30
+ atf/mcp/tools/testcase_tools.py,sha256=w0XzQzD4IMlbJP7ruJ0Z008lJuB5vruzX1srx1KMrUg,25602
31
+ atf/mcp/tools/unittest_tools.py,sha256=nL5G7gfrU7aCK1glJfcJWp8nu2ykhYmjWpGB3-Lb2h0,7764
32
+ atf/utils/__init__.py,sha256=3WjDRQfBXan1IRUDDZGIy4zFocdvXBV8fPtU1pTuBME,66
33
+ atf/utils/helpers.py,sha256=YyzZpGjI5wUNk7WxujHrTf_QX-8QVfemqOWyYXouF2o,4720
34
+ iflow_mcp_galaxyxieyu_api_auto_test-0.1.0.dist-info/METADATA,sha256=TrL-E8am3fUe7Pm7VMKwL5KX_lfYj23DDO0xbn_C11k,11310
35
+ iflow_mcp_galaxyxieyu_api_auto_test-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
36
+ iflow_mcp_galaxyxieyu_api_auto_test-0.1.0.dist-info/entry_points.txt,sha256=U0JuJR1z3QNxTQO1Un8YSQy1dQvqXkwLwxAd0K13peY,76
37
+ iflow_mcp_galaxyxieyu_api_auto_test-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ iflow-mcp-galaxyxieyu-api-auto-test = atf.mcp_server:main