把 apipost 的 md 文档转化成 json数据
APIPost 数据转换工具
功能说明
这个工具可以将 APIPost 导出的项目数据(包含外层响应包装)转换为标准的项目格式(去除外层包装)。
文件说明
需要转化的数据.josn
- 源数据文件(APIPost 导出的md文档的原始数据)toJson.py
- 转换脚本转换后的数据.json
- 转换后的结果文件
数据转换说明
源数据格式
{"code": 0,"msg": "成功","data": {"project_id": "...","name": "...","project": {...},"list": [// API 和文件夹数据]}
}
目标数据格式
{"project_id": "...","name": "...","intro": "","global": {...},"models": [],"apis": [...],"samples": [],"automated_testings": []
}
使用方法
- 确保
需要转化的数据.josn
文件存在于脚本目录中 - 运行转换脚本:
python3 toJson.py
- 转换完成后,结果将保存在
转换后的数据.json
文件中
转换特性
- ✅ 提取项目基本信息(ID、名称等)
- ✅ 提取所有 API 数据(target_type: “api”)
- ✅ 提取文件夹结构(target_type: “folder”)
- ✅ 保持完整的 API 请求/响应结构
- ✅ 生成标准的 global 配置结构
- ✅ 保持环境变量和服务器配置
- ✅ 包含标记(marks)和其他元数据
转换统计示例
转换统计:- 项目ID: ...- 项目名称: ...- API数量: ...- 文件夹数量: ...- 总项目数量: ...- 环境数量: ..
注意事项
- 确保源文件是有效的 JSON 格式
- 脚本会自动创建默认的 global 结构,如果源数据中缺少相关配置
- 转换后的文件可以直接导入到支持标准格式的工具中
错误处理
脚本包含完整的错误处理:
- 文件不存在检测
- JSON 格式验证
- 数据结构验证
- 详细的错误信息输出
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
APIPost 数据转换脚本
将需要转化的数据.josn 转换为目标示例.json 格式
"""import json
import os
from typing import Dict, Any, Listdef load_json_file(file_path: str) -> Dict[str, Any]:"""加载JSON文件"""try:with open(file_path, 'r', encoding='utf-8') as f:return json.load(f)except FileNotFoundError:print(f"错误: 找不到文件 {file_path}")return {}except json.JSONDecodeError as e:print(f"错误: JSON解析失败 - {e}")return {}def save_json_file(data: Dict[str, Any], file_path: str) -> bool:"""保存JSON文件"""try:with open(file_path, 'w', encoding='utf-8') as f:json.dump(data, f, ensure_ascii=False, indent=4)return Trueexcept Exception as e:print(f"错误: 保存文件失败 - {e}")return Falsedef extract_apis_from_list(api_list: List[Dict[str, Any]]) -> List[Dict[str, Any]]:"""从API列表中提取所有API和文件夹"""apis = []for item in api_list:if item.get('target_type') in ['api', 'folder']:# 这是一个API或文件夹,添加到列表中apis.append(item)return apisdef create_default_global_structure() -> Dict[str, Any]:"""创建默认的global结构"""return {"envs": [{"env_id": "1","name": "默认环境","is_private": -1,"sort": 0,"server_list": [{"server_id": "1","name": "默认服务","sort": 0,"uri": ""}],"env_var_list": {}}],"servers": [{"server_id": "1","name": "默认服务","sort": 1000}],"global_vars": {},"global_param": {"header": {"parameter": []},"query": {"parameter": []},"body": {"parameter": []},"cookie": {"parameter": []},"auth": {"type": "noauth","kv": {"key": "", "value": "", "in": ""},"bearer": {"key": ""},"basic": {"username": "", "password": ""},"digest": {"username": "", "password": "", "realm": "", "nonce": "","algorithm": "", "qop": "", "nc": "", "cnonce": "", "opaque": ""},"hawk": {"authId": "", "authKey": "", "algorithm": "", "user": "","nonce": "", "extraData": "", "default": "", "delegation": "","timestamp": "", "includePayloadHash": False},"awsv4": {"accessKey": "", "secretKey": "", "region": "", "service": "","sessionToken": "", "addAuthDataToQuery": False},"ntlm": {"username": "", "password": "", "entity": "", "workstation": "","disableRetryRequest": False},"edgegrid": {"accessToken": "", "clientToken": "", "clientSecret": "","nonce": "", "timestamp": "", "baseURi": "", "headersToSign": ""},"oauth1": {"consumerKey": "", "consumerSecret": "", "signatureMethod": "","addEmptyParamsToSign": False, "includeBodyHash": False,"addParamsToHeader": False, "disableHeaderEncoding": False,"realm": "", "version": "", "nonce": "", "timestamp": "","verifier": "", "callback": "", "tokenSecret": "", "token": ""},"jwt": {"addTokenTo": "", "algorithm": "", "secret": "", "isSecretBase64Encoded": False, "payload": "", "headerPrefix": "","queryParamKey": "", "header": ""},"asap": {"alg": "", "iss": "", "aud": "", "kid": "", "privateKey": "","sub": "", "claims": "", "exp": ""}},"pre_tasks": [],"post_tasks": []},"codes": [],"marks": [{"mark_id": "1","project_id": "0","name": "开发中","color": "#2857FF","is_sys_default": 1,"is_default_mark": 1},{"mark_id": "2","project_id": "0","name": "已完成","color": "#26CEA4","is_sys_default": 1,"is_default_mark": -1},{"mark_id": "3","project_id": "0","name": "需修改","color": "#FFC01E","is_sys_default": 1,"is_default_mark": -1},{"mark_id": "4","project_id": "0","name": "已废弃","color": "#FF2200","is_sys_default": 1,"is_default_mark": -1}],"attributes": [],"mock_custom_rules": [],"db_link": [],"describe_library": [],"custom_func": []}def transform_data(source_data: Dict[str, Any]) -> Dict[str, Any]:"""转换数据格式"""if 'data' not in source_data:print("错误: 源数据中没有找到 'data' 字段")return {}data = source_data['data']project = data.get('project', {})# 从data.list中提取API数据api_list = data.get('list', [])apis = extract_apis_from_list(api_list)# 创建目标格式的数据结构target_data = {"project_id": data.get('project_id', ''),"name": data.get('name', ''),"intro": "","global": project.get('global', create_default_global_structure()),"models": [],"apis": apis,"samples": [],"automated_testings": []}# 如果global结构不完整,使用项目中的其他字段补充或使用默认结构if not target_data["global"] or len(target_data["global"]) < 5:# 尝试从项目数据中提取环境信息if 'envs' in project:target_data["global"]["envs"] = project['envs']if 'servers' in project:target_data["global"]["servers"] = project['servers']if 'marks' in project:target_data["global"]["marks"] = project['marks']# 如果还是不完整,使用默认结构if len(target_data["global"]) < 5:target_data["global"] = create_default_global_structure()return target_datadef main():"""主函数"""current_dir = os.path.dirname(os.path.abspath(__file__))source_file = os.path.join(current_dir, "需要转化的数据.josn")target_file = os.path.join(current_dir, "转换后的数据.json")print("开始转换APIPost数据...")print(f"源文件: {source_file}")print(f"目标文件: {target_file}")# 加载源数据print("正在加载源数据...")source_data = load_json_file(source_file)if not source_data:print("加载源数据失败,程序退出。")return# 转换数据print("正在转换数据格式...")target_data = transform_data(source_data)if not target_data:print("数据转换失败,程序退出。")return# 保存转换后的数据print("正在保存转换后的数据...")if save_json_file(target_data, target_file):print(f"转换成功!转换后的文件已保存为: {target_file}")print(f"转换统计:")print(f" - 项目ID: {target_data.get('project_id', 'N/A')}")print(f" - 项目名称: {target_data.get('name', 'N/A')}")print(f" - API数量: {len([api for api in target_data.get('apis', []) if api.get('target_type') == 'api'])}")print(f" - 文件夹数量: {len([api for api in target_data.get('apis', []) if api.get('target_type') == 'folder'])}")print(f" - 总项目数量: {len(target_data.get('apis', []))}")print(f" - 环境数量: {len(target_data.get('global', {}).get('envs', []))}")else:print("保存文件失败。")if __name__ == "__main__":main()