- MCP Server: Native image display in Cursor/Claude - ComfyUI HTTP API: /anima/health, /anima/schema, /anima/knowledge, /anima/generate - Standalone FastAPI server and CLI tool - Structured prompt system with 14 aspect ratio presets - Expert knowledge base for Anima prompting
80 lines
2.4 KiB
Python
80 lines
2.4 KiB
Python
"""
|
|
独立 FastAPI 服务(不启动 ComfyUI 时单独用)。
|
|
|
|
启动方式(在 ComfyUI-AnimaTool 目录下):
|
|
uvicorn servers.http_server:app --host 127.0.0.1 --port 8000
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any, Dict
|
|
|
|
# 确保能 import 上层 executor
|
|
_PARENT = Path(__file__).resolve().parent.parent
|
|
if str(_PARENT) not in sys.path:
|
|
sys.path.insert(0, str(_PARENT))
|
|
|
|
from fastapi import FastAPI, HTTPException
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import BaseModel, Field
|
|
|
|
from executor import AnimaExecutor, AnimaToolConfig
|
|
|
|
|
|
class GenerateRequest(BaseModel):
|
|
# 允许任意字段(由 tool schema 约束;服务端只做最小校验)
|
|
payload: Dict[str, Any] = Field(default_factory=dict)
|
|
|
|
|
|
def _read_text(path: Path) -> str:
|
|
if not path.exists():
|
|
return ""
|
|
return path.read_text(encoding="utf-8", errors="replace")
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
app = FastAPI(title="Anima Tool API", version="0.1.0")
|
|
|
|
tool_root = Path(__file__).resolve().parent.parent
|
|
knowledge_dir = tool_root / "knowledge"
|
|
schema_path = tool_root / "schemas" / "tool_schema_universal.json"
|
|
|
|
config = AnimaToolConfig()
|
|
executor = AnimaExecutor(config=config)
|
|
|
|
@app.get("/health")
|
|
def health() -> Dict[str, Any]:
|
|
# 不做真实连通性探测(避免阻塞),只返回配置
|
|
return {"status": "ok", "comfyui_url": config.comfyui_url}
|
|
|
|
@app.get("/schema")
|
|
def schema() -> JSONResponse:
|
|
if not schema_path.exists():
|
|
raise HTTPException(status_code=404, detail="schema not found")
|
|
obj = json.loads(schema_path.read_text(encoding="utf-8"))
|
|
return JSONResponse(content=obj)
|
|
|
|
@app.get("/knowledge")
|
|
def knowledge() -> Dict[str, Any]:
|
|
return {
|
|
"anima_expert": _read_text(knowledge_dir / "anima_expert.md"),
|
|
"artist_list": _read_text(knowledge_dir / "artist_list.md"),
|
|
"prompt_examples": _read_text(knowledge_dir / "prompt_examples.md"),
|
|
}
|
|
|
|
@app.post("/generate")
|
|
def generate(req: GenerateRequest) -> Dict[str, Any]:
|
|
payload = req.payload or {}
|
|
try:
|
|
result = executor.generate(payload)
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
return result
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|