API参考文档
1. API概述
1.1 基础信息
基础URL: http://localhost:8000
API版本: v1.0.0
协议: HTTP/HTTPS
数据格式: JSON
字符编码: UTF-8
1.2 认证方式
当前版本支持以下认证方式:
API Key认证(推荐)
Authorization: Bearer your-api-key无认证(开发环境)
- 仅用于开发和测试
- 生产环境建议启用认证
1.3 请求/响应格式
请求格式:
POST /api/v1/generate-ui
Content-Type: application/json
Authorization: Bearer your-api-key
{
"prompt": "黑金风格的电商首页",
"output_format": "json"
}
响应格式:
{
"success": true,
"message": "UI生成成功",
"data": {
"page": {
"name": "home_page",
"theme": "obsidian-gold",
"sections": [...]
}
},
"method": "model",
"timestamp": "2024-01-15T10:30:00Z"
}
1.4 错误处理
错误响应格式:
{
"success": false,
"error": "错误类型",
"message": "详细错误信息",
"code": "ERROR_CODE",
"timestamp": "2024-01-15T10:30:00Z"
}
HTTP状态码:
200- 成功400- 请求参数错误401- 未授权404- 资源不存在429- 请求频率限制500- 服务器内部错误503- 服务不可用
2. 核心端点详解
2.1 UI生成端点
POST /generate-ui
生成UI设计的主要端点。
请求参数:
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
prompt | string | 是 | - | 中文描述Prompt |
output_format | string | 否 | "json" | 输出格式:json, png, vue |
model_path | string | 否 | null | 自定义模型路径 |
lora_path | string | 否 | null | LoRA权重路径 |
use_rules | boolean | 否 | false | 强制使用规则生成 |
请求示例:
curl -X POST "http://localhost:8000/generate-ui" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"prompt": "黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航",
"output_format": "png"
}'
响应示例:
JSON格式响应:
{
"success": true,
"message": "UI-DSL生成成功",
"data": {
"page": {
"name": "home_page",
"theme": "obsidian-gold",
"layout": {
"grid": 12,
"gutter": 16,
"padding": 16,
"bg": "#0E0E0E"
},
"sections": [
{
"type": "topbar",
"props": {
"logo": "品牌",
"actions": ["search", "bell"]
}
},
{
"type": "card-list",
"props": {
"columns": 2,
"card": {
"type": "product-card"
}
}
}
]
}
},
"method": "model"
}
PNG格式响应:
{
"success": true,
"message": "UI图片生成成功",
"data": {
"image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"dsl": {
"page": {...}
}
},
"method": "model"
}
Vue格式响应:
{
"success": true,
"message": "Vue页面生成成功",
"data": {
"vue_content": "<template>\n <view class=\"page\">\n ...\n </view>\n</template>",
"dsl": {
"page": {...}
}
},
"method": "model"
}
错误响应示例:
{
"success": false,
"error": "ValidationError",
"message": "Prompt不能为空",
"code": "INVALID_PROMPT",
"timestamp": "2024-01-15T10:30:00Z"
}
2.2 UI渲染端点
POST /render
将UI-DSL渲染为指定格式。
请求参数:
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
dsl | object | 是 | - | UI-DSL数据 |
output_format | string | 是 | "png" | 输出格式:png, vue |
请求示例:
curl -X POST "http://localhost:8000/render" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"dsl": {
"page": {
"name": "home_page",
"theme": "obsidian-gold",
"sections": [...]
}
},
"output_format": "png"
}'
响应示例:
{
"success": true,
"message": "图片渲染成功",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
}
2.3 健康检查端点
GET /health
检查服务健康状态。
请求示例:
curl -X GET "http://localhost:8000/health"
响应示例:
{
"status": "healthy",
"version": "1.0.0",
"model_loaded": true,
"timestamp": "2024-01-15T10:30:00Z",
"uptime": 3600
}
2.4 模板列表端点
GET /templates
获取可用的页面模板列表。
请求示例:
curl -X GET "http://localhost:8000/templates"
响应示例:
{
"success": true,
"templates": {
"home": {
"name": "首页",
"description": "电商首页模板",
"prompt": "黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航"
},
"detail": {
"name": "详情页",
"description": "商品详情页模板",
"prompt": "黑金风格的商品详情页,顶部轮播图,展示价格、卖家信用和凭证区"
},
"search": {
"name": "搜索页",
"description": "搜索页面模板",
"prompt": "黑金风格的搜索页面,搜索框和筛选条件,单列商品列表"
}
}
}
2.5 主题列表端点
GET /themes
获取可用的主题列表。
请求示例:
curl -X GET "http://localhost:8000/themes"
响应示例:
{
"success": true,
"themes": {
"obsidian-gold": {
"name": "黑金主题",
"description": "高端奢华的黑金配色方案"
},
"silver-white": {
"name": "白银主题",
"description": "简洁优雅的白银配色方案"
},
"minimal": {
"name": "简约主题",
"description": "极简主义的设计风格"
}
}
}
2.6 DSL上传端点
POST /upload-dsl
上传DSL文件进行渲染。
请求参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
file | file | 是 | DSL JSON文件 |
请求示例:
curl -X POST "http://localhost:8000/upload-dsl" \
-H "Authorization: Bearer your-api-key" \
-F "file=@ui_design.json"
响应示例:
{
"success": true,
"message": "DSL文件上传成功",
"dsl": {
"page": {
"name": "home_page",
"theme": "obsidian-gold",
"sections": [...]
}
}
}
2.7 文件下载端点
GET /download/{file_type}/{filename}
下载生成的文件。
路径参数:
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
file_type | string | 是 | 文件类型:image, vue, dsl |
filename | string | 是 | 文件名 |
请求示例:
curl -X GET "http://localhost:8000/download/image/ui_design.png" \
-H "Authorization: Bearer your-api-key" \
--output ui_design.png
响应:
- 成功:返回文件内容
- 失败:返回JSON错误信息
3. 数据模型定义
3.1 请求模型
GenerateUIRequest
class GenerateUIRequest(BaseModel):
prompt: str = Field(..., description="中文Prompt描述", min_length=1, max_length=500)
model_path: Optional[str] = Field(None, description="模型路径")
lora_path: Optional[str] = Field(None, description="LoRA权重路径")
use_rules: bool = Field(False, description="是否强制使用规则生成")
output_format: str = Field("json", description="输出格式", regex="^(json|png|vue)$")
RenderRequest
class RenderRequest(BaseModel):
dsl: Dict[str, Any] = Field(..., description="UI-DSL数据")
output_format: str = Field("png", description="输出格式", regex="^(png|vue)$")
3.2 响应模型
GenerateUIResponse
class GenerateUIResponse(BaseModel):
success: bool
message: str
data: Optional[Dict[str, Any]] = None
method: Optional[str] = None
error: Optional[str] = None
timestamp: Optional[str] = None
RenderResponse
class RenderResponse(BaseModel):
success: bool
message: str
data: Optional[str] = None # Base64编码的图片或Vue代码
error: Optional[str] = None
timestamp: Optional[str] = None
HealthResponse
class HealthResponse(BaseModel):
status: str
version: str
model_loaded: bool
timestamp: Optional[str] = None
uptime: Optional[int] = None
3.3 UI-DSL数据模型
Page结构
class Page(BaseModel):
name: str
theme: str
layout: Layout
sections: List[Section]
class Layout(BaseModel):
grid: int = 12
gutter: int = 16
padding: int = 16
bg: str
class Section(BaseModel):
type: str
props: Dict[str, Any]
4. 错误码定义
4.1 错误码列表
| 错误码 | HTTP状态码 | 描述 | 解决方案 |
|---|---|---|---|
INVALID_PROMPT | 400 | Prompt参数无效 | 检查Prompt格式和长度 |
INVALID_FORMAT | 400 | 输出格式不支持 | 使用支持的格式:json, png, vue |
INVALID_DSL | 400 | DSL格式错误 | 检查DSL结构是否正确 |
MODEL_LOAD_FAILED | 500 | 模型加载失败 | 检查模型路径和权限 |
RENDER_FAILED | 500 | 渲染失败 | 检查渲染器配置 |
RATE_LIMIT_EXCEEDED | 429 | 请求频率超限 | 降低请求频率 |
UNAUTHORIZED | 401 | 未授权访问 | 检查API密钥 |
SERVICE_UNAVAILABLE | 503 | 服务不可用 | 稍后重试或联系管理员 |
4.2 错误处理示例
# Python客户端错误处理
import requests
def generate_ui(prompt: str, api_key: str):
try:
response = requests.post(
"http://localhost:8000/generate-ui",
headers={"Authorization": f"Bearer {api_key}"},
json={"prompt": prompt, "output_format": "json"},
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 400:
error_data = e.response.json()
print(f"请求错误: {error_data['message']}")
elif e.response.status_code == 429:
print("请求频率过高,请稍后重试")
elif e.response.status_code == 500:
print("服务器内部错误,请稍后重试")
else:
print(f"HTTP错误: {e.response.status_code}")
except requests.exceptions.Timeout:
print("请求超时,请稍后重试")
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
5. 使用示例
5.1 cURL示例
生成UI设计:
# 生成JSON格式
curl -X POST "http://localhost:8000/generate-ui" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"prompt": "简约风格的登录页面,包含用户名密码输入框和登录按钮",
"output_format": "json"
}'
# 生成PNG图片
curl -X POST "http://localhost:8000/generate-ui" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"prompt": "黑金风格的电商首页",
"output_format": "png"
}' | jq -r '.data.image' | base64 -d > ui_design.png
# 生成Vue页面
curl -X POST "http://localhost:8000/generate-ui" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"prompt": "白银风格的商品列表页",
"output_format": "vue"
}' | jq -r '.data.vue_content' > product_list.vue
渲染现有DSL:
curl -X POST "http://localhost:8000/render" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"dsl": {
"page": {
"name": "home_page",
"theme": "obsidian-gold",
"sections": [...]
}
},
"output_format": "png"
}'
5.2 Python客户端示例
import requests
import json
import base64
from typing import Dict, Any, Optional
class AIUIClient:
def __init__(self, base_url: str = "http://localhost:8000", api_key: str = None):
self.base_url = base_url
self.headers = {
"Content-Type": "application/json"
}
if api_key:
self.headers["Authorization"] = f"Bearer {api_key}"
def generate_ui(self, prompt: str, output_format: str = "json",
model_path: str = None, use_rules: bool = False) -> Dict[str, Any]:
"""生成UI设计"""
data = {
"prompt": prompt,
"output_format": output_format,
"use_rules": use_rules
}
if model_path:
data["model_path"] = model_path
response = requests.post(
f"{self.base_url}/generate-ui",
headers=self.headers,
json=data,
timeout=30
)
response.raise_for_status()
return response.json()
def render_ui(self, dsl: Dict[str, Any], output_format: str = "png") -> Dict[str, Any]:
"""渲染UI设计"""
data = {
"dsl": dsl,
"output_format": output_format
}
response = requests.post(
f"{self.base_url}/render",
headers=self.headers,
json=data,
timeout=30
)
response.raise_for_status()
return response.json()
def get_templates(self) -> Dict[str, Any]:
"""获取模板列表"""
response = requests.get(f"{self.base_url}/templates", headers=self.headers)
response.raise_for_status()
return response.json()
def get_themes(self) -> Dict[str, Any]:
"""获取主题列表"""
response = requests.get(f"{self.base_url}/themes", headers=self.headers)
response.raise_for_status()
return response.json()
def health_check(self) -> Dict[str, Any]:
"""健康检查"""
response = requests.get(f"{self.base_url}/health", headers=self.headers)
response.raise_for_status()
return response.json()
def save_image(self, image_data: str, filename: str):
"""保存Base64图片"""
image_bytes = base64.b64decode(image_data)
with open(filename, 'wb') as f:
f.write(image_bytes)
def save_vue(self, vue_content: str, filename: str):
"""保存Vue代码"""
with open(filename, 'w', encoding='utf-8') as f:
f.write(vue_content)
# 使用示例
if __name__ == "__main__":
client = AIUIClient(api_key="your-api-key")
# 生成UI设计
result = client.generate_ui(
prompt="黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航",
output_format="png"
)
if result["success"]:
# 保存图片
client.save_image(result["data"]["image"], "ui_design.png")
print("UI设计已保存为 ui_design.png")
else:
print(f"生成失败: {result['message']}")
5.3 JavaScript客户端示例
class AIUIClient {
constructor(baseUrl = 'http://localhost:8000', apiKey = null) {
this.baseUrl = baseUrl;
this.headers = {
'Content-Type': 'application/json'
};
if (apiKey) {
this.headers['Authorization'] = `Bearer ${apiKey}`;
}
}
async generateUI(prompt, outputFormat = 'json', options = {}) {
const data = {
prompt,
output_format: outputFormat,
use_rules: options.useRules || false
};
if (options.modelPath) {
data.model_path = options.modelPath;
}
const response = await fetch(`${this.baseUrl}/generate-ui`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async renderUI(dsl, outputFormat = 'png') {
const data = {
dsl,
output_format: outputFormat
};
const response = await fetch(`${this.baseUrl}/render`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async getTemplates() {
const response = await fetch(`${this.baseUrl}/templates`, {
headers: this.headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async getThemes() {
const response = await fetch(`${this.baseUrl}/themes`, {
headers: this.headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async healthCheck() {
const response = await fetch(`${this.baseUrl}/health`, {
headers: this.headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
saveImage(imageData, filename) {
const link = document.createElement('a');
link.href = `data:image/png;base64,${imageData}`;
link.download = filename;
link.click();
}
saveVue(vueContent, filename) {
const blob = new Blob([vueContent], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
}
}
// 使用示例
async function generateUI() {
const client = new AIUIClient('http://localhost:8000', 'your-api-key');
try {
const result = await client.generateUI(
'黑金风格的电商首页,顶部搜索,中间两列商品卡,底部导航',
'png'
);
if (result.success) {
client.saveImage(result.data.image, 'ui_design.png');
console.log('UI设计已保存');
} else {
console.error('生成失败:', result.message);
}
} catch (error) {
console.error('请求失败:', error);
}
}
// 调用函数
generateUI();
6. 高级用法
6.1 批量处理
# 批量生成UI设计
def batch_generate_ui(client: AIUIClient, prompts: List[str], output_format: str = "json"):
"""批量生成UI设计"""
results = []
for i, prompt in enumerate(prompts):
try:
result = client.generate_ui(prompt, output_format)
results.append({
"index": i,
"prompt": prompt,
"result": result
})
print(f"完成 {i+1}/{len(prompts)}: {prompt[:50]}...")
except Exception as e:
results.append({
"index": i,
"prompt": prompt,
"error": str(e)
})
print(f"失败 {i+1}/{len(prompts)}: {e}")
return results
# 使用示例
prompts = [
"黑金风格的电商首页",
"简约风格的商品详情页",
"白银风格的搜索页面"
]
client = AIUIClient(api_key="your-api-key")
results = batch_generate_ui(client, prompts, "png")
# 保存所有结果
for result in results:
if "result" in result and result["result"]["success"]:
filename = f"ui_design_{result['index']}.png"
client.save_image(result["result"]["data"]["image"], filename)
6.2 异步处理
import asyncio
import aiohttp
async def async_generate_ui(session: aiohttp.ClientSession, prompt: str, api_key: str):
"""异步生成UI设计"""
data = {
"prompt": prompt,
"output_format": "json"
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
async with session.post(
"http://localhost:8000/generate-ui",
json=data,
headers=headers
) as response:
return await response.json()
async def batch_async_generate(prompts: List[str], api_key: str):
"""批量异步生成"""
async with aiohttp.ClientSession() as session:
tasks = [
async_generate_ui(session, prompt, api_key)
for prompt in prompts
]
results = await asyncio.gather(*tasks, return_exceptions=True)
return results
# 使用示例
prompts = [
"黑金风格的电商首页",
"简约风格的商品详情页",
"白银风格的搜索页面"
]
results = asyncio.run(batch_async_generate(prompts, "your-api-key"))
6.3 错误重试机制
import time
from functools import wraps
def retry(max_attempts: int = 3, delay: float = 1.0):
"""重试装饰器"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
last_exception = None
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
last_exception = e
if attempt < max_attempts - 1:
print(f"尝试 {attempt + 1} 失败,{delay}秒后重试...")
time.sleep(delay)
else:
print(f"所有尝试都失败了: {e}")
raise last_exception
return wrapper
return decorator
class RobustAIUIClient(AIUIClient):
@retry(max_attempts=3, delay=2.0)
def generate_ui(self, prompt: str, output_format: str = "json", **kwargs):
"""带重试的UI生成"""
return super().generate_ui(prompt, output_format, **kwargs)
@retry(max_attempts=3, delay=1.0)
def render_ui(self, dsl: Dict[str, Any], output_format: str = "png"):
"""带重试的UI渲染"""
return super().render_ui(dsl, output_format)
通过以上API参考文档,开发者可以全面了解AI UI生成系统的API接口,并能够快速集成到自己的应用中。