Spaces:
Sleeping
Sleeping
| # Code Generation & Output Format Specification | |
| This document details how the Smart API DevTool packages, displays, and delivers generated code assets and test files to the developer. | |
| --- | |
| ## 1. User Interface Display (Tabbed Preview) | |
| When the LangGraph self-healing agent completes generation, the Web UI renders a tabbed workspace containing five distinct views: | |
| 1. **Overview & Auth Tab**: Displays extracted auth methods and the integration path recommendation (REST vs. SDK). | |
| 2. **Endpoints Explorer Tab**: Shows an interactive dictionary of endpoints (GET, POST, DELETE), headers, query params, and request payloads. | |
| 3. **Wrapper Class Tab**: Displays the syntax-highlighted source code of the generated client wrapper. | |
| 4. **Unit Tests Tab**: Displays the generated testing suite script. | |
| 5. **README Guide Tab**: Displays markdown usage instructions, library dependencies, and instantiation examples. | |
| --- | |
| ## 2. Download Deliverables & File Structure | |
| Developers can download files individually or as a unified bundle. | |
| ### Option A: The Integration Bundle (ZIP) | |
| Clicking the **"Download Integration Bundle (ZIP)"** button packages all generated files into a single ZIP file dynamically in the browser using `JSZip`. The extracted bundle structure varies by language: | |
| #### Python | |
| ```text | |
| my-api-integration/ | |
| βββ README.md # Setup instructions, dependencies, and code import examples | |
| βββ client.py # The generated, type-safe wrapper class | |
| βββ test_client.py # The Pytest test suite for validation (unittest.mock) | |
| ``` | |
| #### JavaScript | |
| ```text | |
| my-api-integration/ | |
| βββ README.md # Setup instructions and CommonJS import examples | |
| βββ client.js # The client class (exported via module.exports = { MyClientClass };) | |
| βββ test_client.test.js # Standalone Node test script using named require and global fetch patch | |
| ``` | |
| #### TypeScript | |
| ```text | |
| my-api-integration/ | |
| βββ README.md # Setup instructions and TS import examples | |
| βββ client.ts # The client class (exported via export class MyClientClass { ... }) | |
| βββ test_client.test.ts # Standalone TS test script using named imports | |
| βββ tsconfig.json # Minimal TypeScript config for sandbox/ts-node runtimes | |
| ``` | |
| #### Go | |
| ```text | |
| my-api-integration/ | |
| βββ README.md # Setup instructions and go package import examples | |
| βββ client.go # Go package source file defining the client struct | |
| βββ client_test.go # Native Go test suite using testing package and httptest.NewServer | |
| βββ go.mod # Temporary Go module name definition | |
| ``` | |
| #### Java | |
| ```text | |
| my-api-integration/ | |
| βββ README.md # Setup instructions and compilation steps | |
| βββ MyAPIClient.java # The Java client class (using java.net.http.HttpClient) | |
| βββ TestClient.java # Standalone Java class with main() method running assertions (-ea) | |
| ``` | |
| --- | |
| ## 3. Reference Output Code Structures | |
| Below are the standard, production-ready structures of generated client wrappers and test suites. | |
| ### Python Client (Requests + Tenacity Retry) | |
| The Python client utilizes `requests.Session` for connection pooling, type hints, custom error wrappers, and `tenacity.Retrying` dynamically at runtime to respect user configurations: | |
| ```python | |
| import requests | |
| from tenacity import Retrying, stop_after_attempt, wait_exponential, retry_if_exception_type | |
| from typing import Dict, Any, Optional | |
| class APIError(Exception): | |
| """Base exception for API errors.""" | |
| pass | |
| class APIRateLimitError(APIError): | |
| """Exception for rate limits (429).""" | |
| pass | |
| class APIServerError(APIError): | |
| """Exception for server-side downtime (5xx).""" | |
| pass | |
| class APIClient: | |
| def __init__(self, api_key: str, base_url: str = "https://api.example.com/v1", max_retries: int = 3): | |
| if not api_key: | |
| raise ValueError("API key cannot be empty.") | |
| self.api_key = api_key | |
| self.base_url = base_url.rstrip("/") | |
| self.max_retries = max_retries | |
| self.session = requests.Session() | |
| self.session.headers.update({ | |
| "Authorization": f"Bearer {self.api_key}", | |
| "Content-Type": "application/json" | |
| }) | |
| def _retry_request(self, func): | |
| """Dynamic tenacity runner to enforce instance-level retry limits.""" | |
| retrier = Retrying( | |
| stop=stop_after_attempt(self.max_retries + 1), | |
| wait=wait_exponential(multiplier=0.5, min=1, max=30), | |
| retry=( | |
| retry_if_exception_type(APIRateLimitError) | | |
| retry_if_exception_type(APIServerError) | |
| ), | |
| reraise=True | |
| ) | |
| return retrier(func) | |
| def _make_request(self, method: str, path: str, json_data=None) -> Dict[str, Any]: | |
| url = f"{self.base_url}/{path.lstrip('/')}" | |
| response = self.session.request(method, url, json=json_data, timeout=10) | |
| if response.status_code == 429: | |
| raise APIRateLimitError(f"Rate limited: {response.text}") | |
| elif response.status_code >= 500: | |
| raise APIServerError(f"Server error: {response.status_code}") | |
| response.raise_for_status() | |
| return response.json() | |
| def get_resource(self, resource_id: str) -> Dict[str, Any]: | |
| return self._retry_request(lambda: self._make_request("GET", f"/resources/{resource_id}")) | |
| ``` | |
| ### JavaScript Client & Test (CommonJS + Async IIFE Test Harness) | |
| The JavaScript client uses named exports, the global `fetch` API, and standard Node.js assertions inside a self-contained sequential test block: | |
| ```javascript | |
| // client.js | |
| class APIClient { | |
| constructor(apiKey) { | |
| if (!apiKey) throw new Error('API key cannot be empty.'); | |
| this.apiKey = apiKey; | |
| this.baseUrl = 'https://api.example.com/v1'; | |
| } | |
| async getResource(resourceId) { | |
| const response = await fetch(`${this.baseUrl}/resources/${resourceId}`, { | |
| method: 'GET', | |
| headers: { | |
| 'Authorization': `Bearer ${this.apiKey}`, | |
| 'Content-Type': 'application/json' | |
| } | |
| }); | |
| if (!response.ok) throw new Error(`HTTP Error ${response.status}`); | |
| return await response.json(); | |
| } | |
| } | |
| module.exports = { APIClient }; | |
| ``` | |
| ```javascript | |
| // test_client.test.js | |
| const assert = require('assert'); | |
| const { APIClient } = require('./client'); | |
| async function runTests() { | |
| const originalFetch = globalThis.fetch; | |
| try { | |
| // Setup local request mock | |
| globalThis.fetch = async (url, options) => { | |
| assert.strictEqual(options.headers['Authorization'], 'Bearer test-key'); | |
| return { | |
| ok: true, | |
| json: async () => ({ id: '123', name: 'Sample' }) | |
| }; | |
| }; | |
| const client = new APIClient('test-key'); | |
| const data = await client.getResource('123'); | |
| assert.deepStrictEqual(data, { id: '123', name: 'Sample' }); | |
| console.log('All tests passed successfully.'); | |
| } catch (error) { | |
| console.error('Test execution failed:', error); | |
| process.exit(1); | |
| } finally { | |
| globalThis.fetch = originalFetch; | |
| } | |
| process.exit(0); | |
| } | |
| runTests(); | |
| ``` | |