.codebuddy/skills/openui-forge-python/SKILL.md
OpenUI generative UI with Python FastAPI backend. OpenAI and Anthropic SDK variants.
npx skillsauth add OthmanAdi/openui-forge openui-forge-pythonInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.104.0
uvicorn>=0.24.0
openai>=1.6.0
anthropic>=0.40.0
python-dotenv>=1.0.0
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 OpenAI
load_dotenv()
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["POST"],
allow_headers=["*"],
)
client = OpenAI()
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"]
response = client.chat.completions.create(
model="gpt-4o", stream=True, messages=messages
)
def generate():
for chunk in response:
data = chunk.model_dump_json()
yield f"data: {data}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
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 Anthropic
load_dotenv()
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["POST"],
allow_headers=["*"],
)
client = Anthropic()
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())}"
def generate():
with client.messages.stream(
model="claude-sonnet-4-20250514",
max_tokens=4096,
system=SYSTEM_PROMPT,
messages=body["messages"],
) as stream:
for text in stream.text_stream:
chunk = {"id": stream_id, "object": "chat.completion.chunk",
"choices": [{"index": 0, "delta": {"content": text}, "finish_reason": None}]}
yield f"data: {json.dumps(chunk)}\n\n"
done = {"id": stream_id, "object": "chat.completion.chunk",
"choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}]}
yield f"data: {json.dumps(done)}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
app/chat/page.tsx (or src/Chat.tsx for Vite)"use client";
import { FullScreen } from "@openuidev/react-ui";
import { openuiLibrary } from "@openuidev/react-ui";
import {
openAIReadableStreamAdapter,
openAIMessageFormat,
} from "@openuidev/react-headless";
export default function ChatPage() {
return (
<FullScreen
componentLibrary={openuiLibrary}
adapter={openAIReadableStreamAdapter}
messageFormat={openAIMessageFormat}
apiUrl="http://localhost:8000/api/chat"
/>
);
}
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 URLopenAIReadableStreamAdapter and openAIMessageFormatuvicorn 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: [...] } |
development
Build generative UI with OpenUI — any LLM provider, any backend language. Scaffold, integrate, validate.
data-ai
使用 OpenUI 构建生成式 UI 应用 — 支持任意 LLM 提供商、任意后端语言。脚手架、集成、验证。
tools
OpenUI generative UI with Vercel AI SDK. streamText, toUIMessageStreamResponse, and tools support.
development
OpenUI generative UI with Rust Axum backend. Async SSE streaming with reqwest and async-stream.