如何用Python读取OpenAPI JSON Schema并提取API信息
用Python读取OpenAPI JSON并提取API信息
推荐工具库
处理OpenAPI规范,最实用的Python库是openapi-core,它不仅能验证规范的合法性,还能直接解析并访问规范中的所有结构(包括自动处理$ref引用),比手动解析JSON更可靠。
安装命令:
pip install openapi-core
如果不想依赖第三方库,也可以直接用Python内置的json模块手动解析,只是需要自己处理引用和结构遍历。
示例代码(使用openapi-core)
假设你的OpenAPI JSON文件名为cat_facts_api.json,下面的代码会提取所有API的关键信息:
import json from openapi_core import create_spec def extract_api_info(openapi_file_path): # 读取OpenAPI JSON文件 with open(openapi_file_path, 'r', encoding='utf-8') as f: openapi_dict = json.load(f) # 创建规范对象 spec = create_spec(openapi_dict) api_list = [] # 遍历所有API路径和方法 for path, path_item in spec.paths.items(): for method, operation in path_item.operations.items(): # 提取基础信息 api_info = { "path": path, "method": method.upper(), "operation_id": operation.operation_id, "tags": operation.tags, "summary": operation.summary, "description": operation.description, "parameters": [], "request_body": None, "responses": {} } # 提取参数(包括查询参数、路径参数等) for param in operation.parameters: param_info = { "name": param.name, "location": param.in_, "required": param.required, "description": param.description, "type": param.schema.type.value if param.schema else None } api_info["parameters"].append(param_info) # 提取请求体(如果有) if operation.request_body: content_types = operation.request_body.content # 取第一个内容类型作为示例,可按需调整 for content_type, media_type in content_types.items(): api_info["request_body"] = { "content_type": content_type, "schema": media_type.schema.model_dump() if media_type.schema else None } break # 提取响应信息 for status_code, response in operation.responses.items(): api_info["responses"][status_code] = { "description": response.description, "content": {} } if response.content: for content_type, media_type in response.content.items(): api_info["responses"][status_code]["content"][content_type] = { "schema": media_type.schema.model_dump() if media_type.schema else None } api_list.append(api_info) return api_list # 调用示例 if __name__ == "__main__": api_info_list = extract_api_info("cat_facts_api.json") # 打印第一个API的信息作为示例 import pprint pprint.pprint(api_info_list[0])
手动解析示例(无第三方库)
如果不想安装依赖,用内置json模块手动解析,需要自己处理$ref引用:
import json def resolve_ref(ref, openapi_dict): # 解析$ref引用,比如#/components/schemas/Breed parts = ref.lstrip("#/").split("/") result = openapi_dict for part in parts: result = result[part] return result def extract_api_info_manual(openapi_file_path): with open(openapi_file_path, 'r', encoding='utf-8') as f: openapi_dict = json.load(f) api_list = [] components = openapi_dict.get("components", {}).get("schemas", {}) for path, path_item in openapi_dict["paths"].items(): for method, operation in path_item.items(): api_info = { "path": path, "method": method.upper(), "operation_id": operation.get("operationId"), "tags": operation.get("tags", []), "summary": operation.get("summary"), "description": operation.get("description"), "parameters": [], "request_body": None, "responses": {} } # 提取参数 for param in operation.get("parameters", []): param_info = { "name": param["name"], "location": param["in"], "required": param.get("required", False), "description": param.get("description"), "type": param.get("schema", {}).get("type") } api_info["parameters"].append(param_info) # 提取请求体 if "requestBody" in operation: req_body = operation["requestBody"] content = req_body.get("content", {}) if content: content_type, media_type = next(iter(content.items())) schema = media_type.get("schema", {}) # 处理schema中的引用 if "$ref" in schema: schema = resolve_ref(schema["$ref"], openapi_dict) api_info["request_body"] = { "content_type": content_type, "schema": schema } # 提取响应 for status_code, response in operation.get("responses", {}).items(): resp_info = { "description": response.get("description"), "content": {} } if "content" in response: for content_type, media_type in response["content"].items(): schema = media_type.get("schema", {}) if "$ref" in schema: schema = resolve_ref(schema["$ref"], openapi_dict) resp_info["content"][content_type] = {"schema": schema} api_info["responses"][status_code] = resp_info api_list.append(api_info) return api_list # 调用示例 if __name__ == "__main__": api_info_list = extract_api_info_manual("cat_facts_api.json") import pprint pprint.pprint(api_info_list[1])
说明
- 用
openapi-core的好处是自动处理了规范验证、引用解析,以及规范版本兼容(支持OpenAPI 3.x)。 - 手动解析更灵活,但需要自己处理各种边界情况(比如不同位置的
$ref、可选字段缺失等)。
内容的提问来源于stack exchange,提问作者Prabodha
相关产品推荐
相关产品推荐

