Skip to main content

openui-forge-python

OpenUI generative UI with Python FastAPI backend. OpenAI and Anthropic SDK variants.

Quellinformationen

Repository
OthmanAdi/openui-forge
Letzte Quellaktivität
20. Juni 2026 um 02:24
Erkannte Sprache von SKILL.md
Englisch
Sterne
24
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
openui-forge-python
description
OpenUI generative UI with Python FastAPI backend. OpenAI and Anthropic SDK variants.
version
1.2.0
author
OthmanAdi
# OpenUI Forge — Python Build generative UI apps with a React frontend + Python FastAPI backend. Streams OpenAI-compatible NDJSON. ## Activation Triggers - "openui python", "openui fastapi", "openui flask" - "generative ui python", "python streaming ui backend" ## Prerequisites - Node.js >= 22 (24 LTS recommended) + React >= 18.3.1 (19+ recommended) (frontend) - Python >= 3.10 (backend) - `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` set ## Quick Start 1. Create the React frontend and install OpenUI deps: ```bash npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod ``` 2. Generate the system prompt from your component library: ```bash npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt ``` 3. Set up the Python backend (see Full Code below) 4. Run both: frontend on `:3000`, backend on `:8000` ## Full Code ### Backend: `backend/requirements.txt` ``` fastapi>=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 (OpenAI): `backend/main.py` ```python import 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 "data: [DONE]\n\n" return StreamingResponse(generate(), media_type="text/event-stream") ``` ### Backend (Anthropic variant): `backend/main_anthropic.py` ```python import 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": "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") ``` ### Frontend: `app/chat/page.tsx` (or `src/Chat.tsx` for Vite) ```tsx "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 with `openAIAdapter()` on the frontend. `openAIReadableStreamAdapter()` is for NDJSON (no `data:` prefix) and will silently produce no output here. ## System Prompt Generation Generate once, copy to backend directory: ```bash npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt ``` Regenerate after every component change. ## Validation Checklist - [ ] `system-prompt.txt` exists in the backend directory - [ ] CORS allows the frontend origin - [ ] Backend streams `data: {json}\n\n` lines with OpenAI chunk format - [ ] Final chunk has `finish_reason: "stop"` followed by `data: [DONE]` - [ ] Frontend `apiUrl` points to the correct backend URL - [ ] Frontend uses `streamProtocol={openAIAdapter()}` and `openAIMessageFormat` - [ ] `componentLibrary={openuiChatLibrary}` prop passed to `FullScreen` - [ ] CSS import in root layout (`@openuidev/react-ui/components.css`) - [ ] Run backend: `uvicorn main:app --reload --port 8000` ## Error Patterns | 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: [...] }` |
Auf GitHub ansehen