Smart-Dev-API-Tool / OutputFormat.md
Yash030's picture
deploy: Hugging Face Space clean release
3ae68d6
|
Raw
History Blame Contribute Delete
7.21 kB
# 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();
```