用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/OthmanAdi/openui-forge --skill openui-forge-python命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
OpenUI generative UI with Anthropic Claude SDK backend. Stream conversion to OpenAI NDJSON format.
OpenUI generative UI with C# ASP.NET Core Minimal API backend. Direct OpenAI API SSE streaming via HttpClient on .NET 10.
OpenUI generative UI with Elixir Phoenix backend. Chunked SSE streaming via Plug.Conn and Req.
基于 SOC 职业分类
正在显示 SKILL.md
| name | openui-forge-python |
| description | OpenUI generative UI with Python FastAPI backend. OpenAI and Anthropic SDK variants. |
| version | 1.2.0 |
| author | OthmanAdi |
Build generative UI apps with a React frontend + Python FastAPI backend. Streams OpenAI-compatible NDJSON.
OPENAI_API_KEY or ANTHROPIC_API_KEY setnpm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
:3000, backend on :8000backend/requirements.txtfastapi>=0.115.0
uvicorn>=0.24.0
openai>=2.0
anthropic>=0.111.0
python-dotenv>=1.0.0
The Python >= 3.10 floor comes from fastapi/uvicorn/python-dotenv; openai and anthropic themselves need only Python 3.9.
backend/main.pyimport os
from pathlib import Path
from dotenv import load_dotenv
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from openai import AsyncOpenAI
load_dotenv()
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["POST"],
allow_headers=["*"],
)
# AsyncOpenAI keeps the request from blocking the event loop during streaming.
client = AsyncOpenAI()
SYSTEM_PROMPT = Path("system-prompt.txt").read_text()
@app.post("/api/chat")
async def chat(request: Request):
body = await request.json()
messages = [{"role": "system", "content": SYSTEM_PROMPT}] + body["messages"]
async def generate():
response = await client.chat.completions.create(
model=os.getenv("OPENAI_MODEL", "gpt-5.5"),
stream=True,
messages=messages,
)
async for chunk in response:
data = chunk.model_dump_json()
yield f"data: {data}\n\n"
yield
StreamingResponse(generate(), media_type=)
backend/main_anthropic.pyimport os, json, time
from pathlib import Path
from dotenv import load_dotenv
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from anthropic import AsyncAnthropic
load_dotenv()
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["POST"],
allow_headers=["*"],
)
# AsyncAnthropic mirrors AsyncOpenAI so the stream does not block the loop.
client = AsyncAnthropic()
SYSTEM_PROMPT = Path("system-prompt.txt").read_text()
@app.post("/api/chat")
async def chat(request: Request):
body = await request.json()
stream_id = f"chatcmpl-{int(time.time())}"
async def generate():
async with client.messages.stream(
model=os.getenv("ANTHROPIC_MODEL", "claude-sonnet-4-6"),
max_tokens=4096,
system=SYSTEM_PROMPT,
messages=body["messages"],
) as stream:
async for text in stream.text_stream:
chunk = {"id": stream_id, "object": ,
: [{: , : {: text}, : }]}
done = {: stream_id, : ,
: [{: , : {}, : }]}
StreamingResponse(generate(), media_type=)
app/chat/page.tsx (or src/Chat.tsx for Vite)"use client";
import { FullScreen } from "@openuidev/react-ui";
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import {
openAIAdapter,
openAIMessageFormat,
} from "@openuidev/react-headless";
export default function ChatPage() {
return (
<FullScreen
componentLibrary={openuiChatLibrary}
streamProtocol={openAIAdapter()}
messageFormat={openAIMessageFormat}
apiUrl="http://localhost:8000/api/chat"
/>
);
}
The Python backend emits SSE (
data: {json}\n\n). Pair it withopenAIAdapter()on the frontend.openAIReadableStreamAdapter()is for NDJSON (nodata:prefix) and will silently produce no output here.
Generate once, copy to backend directory:
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
Regenerate after every component change.
system-prompt.txt exists in the backend directorydata: {json}\n\n lines with OpenAI chunk formatfinish_reason: "stop" followed by data: [DONE]apiUrl points to the correct backend URLstreamProtocol={openAIAdapter()} and openAIMessageFormatcomponentLibrary={openuiChatLibrary} prop passed to FullScreen@openuidev/react-ui/components.css)uvicorn main:app --reload --port 8000| Error | Cause | Fix |
|---|---|---|
| CORS blocked | Frontend origin not allowed | Add origin to allow_origins list |
| Connection refused | Backend not running | Start with uvicorn main:app --port 8000 |
| FileNotFoundError | system-prompt.txt missing | Run the CLI generate command |
| Stream not rendering | Backend not sending SSE format | Ensure data: prefix and \n\n after each chunk |
| 422 Unprocessable Entity | Request body missing messages | Check frontend sends { messages: [...] } |