144 lines
4.5 KiB
Python
144 lines
4.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Apifox 接口管理工具
|
|
使用方法:
|
|
python apifox_manager.py move <api_id> <folder_id> # 移动接口到指定目录
|
|
python apifox_manager.py list-folders # 列出所有目录
|
|
python apifox_manager.py list-apis <folder_id> # 列出目录下的接口
|
|
"""
|
|
import sys
|
|
import requests
|
|
import json
|
|
|
|
TOKEN = "afxp_fa4137GfIzJtlOCeQHjpCXc83SFWmeAOrZnq"
|
|
PROJECT_ID = "6037107"
|
|
|
|
headers = {
|
|
"X-Apifox-Api-Version": "2024-03-28",
|
|
"Authorization": f"Bearer {TOKEN}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
def list_folders():
|
|
"""列出所有目录"""
|
|
print("\n获取项目目录结构...")
|
|
response = requests.get(
|
|
f"https://api.apifox.com/api/v1/projects/{PROJECT_ID}/api-tree-list",
|
|
headers=headers
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json().get('data', [])
|
|
folders = extract_folders(data)
|
|
|
|
print(f"\n找到 {len(folders)} 个目录:\n")
|
|
for folder in folders:
|
|
indent = " " * folder['level']
|
|
print(f"{indent}[{folder['id']}] {folder['name']}")
|
|
else:
|
|
print(f"错误: {response.status_code}")
|
|
|
|
def extract_folders(node, level=0, folders=None):
|
|
"""递归提取所有目录"""
|
|
if folders is None:
|
|
folders = []
|
|
|
|
if isinstance(node, list):
|
|
for item in node:
|
|
extract_folders(item, level, folders)
|
|
elif isinstance(node, dict):
|
|
if node.get('type') == 'apiDetailFolder':
|
|
folder = node.get('folder', {})
|
|
folders.append({
|
|
'id': folder.get('id'),
|
|
'name': node.get('name'),
|
|
'parentId': folder.get('parentId'),
|
|
'level': level
|
|
})
|
|
|
|
for child in node.get('children', []):
|
|
extract_folders(child, level + 1, folders)
|
|
|
|
return folders
|
|
|
|
def list_apis(folder_id):
|
|
"""列出指定目录下的接口"""
|
|
print(f"\n获取目录 {folder_id} 下的接口...")
|
|
response = requests.get(
|
|
f"https://api.apifox.com/api/v1/projects/{PROJECT_ID}/http-apis",
|
|
headers=headers
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
all_apis = response.json().get('data', [])
|
|
folder_apis = [api for api in all_apis if str(api.get('folderId')) == str(folder_id)]
|
|
|
|
print(f"\n找到 {len(folder_apis)} 个接口:\n")
|
|
for api in folder_apis:
|
|
print(f" [{api['id']}] {api['method'].upper():6s} {api['name']}")
|
|
print(f" {api['path']}")
|
|
else:
|
|
print(f"错误: {response.status_code}")
|
|
|
|
def move_api(api_id, target_folder_id):
|
|
"""移动接口到指定目录"""
|
|
print(f"\n移动接口 {api_id} 到目录 {target_folder_id}...")
|
|
|
|
payload = {"folderId": int(target_folder_id)}
|
|
|
|
response = requests.patch(
|
|
f"https://api.apifox.com/api/v1/projects/{PROJECT_ID}/http-apis/{api_id}",
|
|
headers=headers,
|
|
data=json.dumps(payload).encode('utf-8')
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
print(" [OK] 移动成功!")
|
|
else:
|
|
print(f" [FAIL] {response.status_code}: {response.text[:200]}")
|
|
|
|
def batch_move_apis_to_folder(source_folder_id, target_folder_id):
|
|
"""批量移动接口"""
|
|
print(f"\n批量移动: {source_folder_id} -> {target_folder_id}")
|
|
|
|
# 获取源目录下的所有接口
|
|
response = requests.get(
|
|
f"https://api.apifox.com/api/v1/projects/{PROJECT_ID}/http-apis",
|
|
headers=headers
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
all_apis = response.json().get('data', [])
|
|
apis_to_move = [
|
|
api for api in all_apis
|
|
if str(api.get('folderId')) == str(source_folder_id)
|
|
and '/v2/store/auth/' in api.get('path', '')
|
|
]
|
|
|
|
print(f"找到 {len(apis_to_move)} 个接口需要移动:\n")
|
|
|
|
for api in apis_to_move:
|
|
print(f" 移动: {api['name']}")
|
|
move_api(api['id'], target_folder_id)
|
|
else:
|
|
print(f"错误: {response.status_code}")
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print(__doc__)
|
|
sys.exit(1)
|
|
|
|
command = sys.argv[1]
|
|
|
|
if command == "list-folders":
|
|
list_folders()
|
|
elif command == "list-apis" and len(sys.argv) > 2:
|
|
list_apis(sys.argv[2])
|
|
elif command == "move" and len(sys.argv) > 3:
|
|
move_api(sys.argv[2], sys.argv[3])
|
|
elif command == "batch-move" and len(sys.argv) > 3:
|
|
batch_move_apis_to_folder(sys.argv[2], sys.argv[3])
|
|
else:
|
|
print(__doc__)
|
|
|