import json import sys def resolve_ref(spec, ref): """ Resolves a $ref reference in the OpenAPI spec. """ parts = ref.strip('#/').split('/') current = spec for part in parts: if part in current: current = current[part] else: return None return current def format_schema(spec, schema, indent=0): """ Formats a schema definition into a readable string. """ indent_str = ' ' * indent output = [] if 'type' in schema: if schema['type'] == 'object' and 'properties' in schema: output.append(f'{indent_str}Object with properties:\n') for prop_name, prop_details in schema['properties'].items(): prop_type = prop_details.get('type', 'any') prop_desc = prop_details.get('description', 'No description') output.append(f'{indent_str} - `{prop_name}` ({prop_type}): {prop_desc}\n') elif schema['type'] == 'array' and 'items' in schema: output.append(f'{indent_str}Array of:\n') item_schema = schema['items'] if '$ref' in item_schema: ref_schema = resolve_ref(spec, item_schema['$ref']) if ref_schema: output.append(format_schema(spec, ref_schema, indent + 1)) else: output.append(f'{indent_str} Unresolved reference: {item_schema["$ref"]}\n') else: output.append(format_schema(spec, item_schema, indent + 1)) else: output.append(f'{indent_str}{schema["type"]}\n') elif '$ref' in schema: ref_schema = resolve_ref(spec, schema['$ref']) if ref_schema: output.append(format_schema(spec, ref_schema, indent)) else: output.append(f'{indent_str}Unresolved reference: {schema["$ref"]}\n') return ''.join(output) def main(input_file, output_file): """ Main function to process the OpenAPI spec. """ try: with open(input_file, 'r', encoding='utf-8') as f: spec = json.load(f) except FileNotFoundError: print(f"Error: Input file not found at {input_file}") return except json.JSONDecodeError: print(f"Error: Could not decode JSON from {input_file}") return with open(output_file, 'w', encoding='utf-8') as f: f.write("\n\n") f.write(f"# API Summary: {spec.get('info', {}).get('title', 'Untitled API')}\n\n") for path, path_item in spec.get('paths', {}).items(): for method, operation in path_item.items(): f.write(f"<{method.upper()} {path}>\n") summary = operation.get('summary', '') if summary: f.write(f"**Summary:** {summary}\n\n") description = operation.get('description', '') if description: f.write(f"**Description:** {description}\n\n") # Parameters if 'parameters' in operation: f.write("\n") f.write("| Name | In | Required | Type | Description |\n") f.write("|------|----|----------|------|-------------|\n") for param in operation['parameters']: param_name = param.get('name') param_in = param.get('in') param_req = param.get('required', False) param_type = param.get('type', 'N/A') param_desc = param.get('description', '').replace('\n', ' ') if 'schema' in param: param_type = 'object' f.write(f"| `{param_name}` | {param_in} | {param_req} | {param_type} | {param_desc} |\n") f.write("\n") f.write("\n") # Request Body (for 'body' parameters) if 'parameters' in operation: for param in operation['parameters']: if param.get('in') == 'body' and 'schema' in param: f.write("\n") schema_str = format_schema(spec, param['schema']) f.write(schema_str) f.write("```\n\n") f.write("\n") # Form Data (for 'formData' parameters) form_data_params = [p for p in operation.get('parameters', []) if p.get('in') == 'formData'] if form_data_params: f.write("") f.write("| Name | Type | Description |\n") f.write("|------|------|-------------|\n") for param in form_data_params: param_name = param.get('name') param_type = param.get('type', 'N/A') param_desc = param.get('description', '').replace('\n', ' ') f.write(f"| `{param_name}` | {param_type} | {param_desc} |\n") f.write("\n") f.write("") # Responses if 'responses' in operation: f.write("\n") for status_code, response in operation['responses'].items(): f.write(f"- **{status_code}**: {response.get('description', '')}\n") if 'schema' in response: schema_str = format_schema(spec, response['schema'], indent=1) if schema_str.strip(): f.write(f" **Schema:**\n{schema_str}\n") f.write("\n") f.write("---\n\n") f.write(f"") f.write("\n") if __name__ == "__main__": if len(sys.argv) != 3: print("Usage: python process_openapi.py ") else: main(sys.argv[1], sys.argv[2])