diff --git a/README.md b/README.md index a4e3a4e..d8a5207 100644 --- a/README.md +++ b/README.md @@ -87,8 +87,9 @@ From there, it's easy to implement popular design patterns like ([Multi-](https: | [Code Generator](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-code-generator) | ★☆☆ *Beginner* | Generate test cases, implement solutions, and iteratively improve code | | [MCP](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-mcp) | ★☆☆ *Beginner* | Agent using Model Context Protocol for numerical operations | | [A2A](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-a2a) | ★☆☆ *Beginner* | Agent wrapped with A2A protocol for inter-agent communication | -| [Streamlit HITL](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-streamlit-hitl) | ★☆☆ *Beginner* | Streamlit app for human-in-the-loop image generation | -| [FastAPI HITL](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-fastapi-hitl) | ★☆☆ *Beginner* | FastAPI app for async human review loop with SSE | +| [Streamlit FSM](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-streamlit-fsm) | ★☆☆ *Beginner* | Streamlit app with finite state machine for HITL image generation | +| [FastAPI WebSocket](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-fastapi-websocket) | ★☆☆ *Beginner* | Real-time chat interface with streaming LLM responses via WebSocket | +| [FastAPI Background](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-fastapi-background) | ★☆☆ *Beginner* | FastAPI app with background jobs and real-time progress via SSE | | [Voice Chat](https://github.com/The-Pocket/PocketFlow/tree/main/cookbook/pocketflow-voice-chat) | ★☆☆ *Beginner* | An interactive voice chat application with VAD, STT, LLM, and TTS. | diff --git a/cookbook/pocketflow-fastapi-background/README.md b/cookbook/pocketflow-fastapi-background/README.md index db38513..913b5fd 100644 --- a/cookbook/pocketflow-fastapi-background/README.md +++ b/cookbook/pocketflow-fastapi-background/README.md @@ -1,74 +1,81 @@ -# PocketFlow FastAPI Background Job +# PocketFlow FastAPI Background Jobs with Real-time Progress -A minimal example of running PocketFlow workflows as background jobs with real-time progress updates via Server-Sent Events (SSE). +A web application demonstrating PocketFlow workflows running as FastAPI background jobs with real-time progress updates via Server-Sent Events (SSE). + +

+ +

## Features -- Start article generation jobs via REST API -- Real-time granular progress updates via SSE (shows progress for each section) -- Background processing with FastAPI -- Simple three-step workflow: Outline → Content → Style -- Web interface for easy job submission and monitoring +- **Modern Web UI**: Clean interface with real-time progress visualization +- **Background Processing**: Non-blocking article generation using FastAPI BackgroundTasks +- **Server-Sent Events**: Real-time progress streaming without polling +- **Granular Progress**: Section-by-section updates during content generation +- **PocketFlow Integration**: Three-node workflow (Outline → Content → Style) -## Getting Started +## How to Run -1. Install dependencies: -```bash -pip install -r requirements.txt -``` +1. Install Dependencies: + ```bash + pip install -r requirements.txt + ``` 2. Set your OpenAI API key: -```bash -export OPENAI_API_KEY=your_api_key_here + ```bash + export OPENAI_API_KEY=your_api_key_here + ``` + +3. Run the FastAPI Server: + ```bash + python main.py + ``` + +4. Access the Web UI: + Open your browser and navigate to `http://localhost:8000`. + +5. Use the Application: + - Enter an article topic or click suggested topics + - Click "Generate Article" to start background processing + - Watch real-time progress updates with step indicators + - Copy the final article when complete + +## How It Works + +The application uses PocketFlow to define a three-step article generation workflow. FastAPI handles web requests and manages real-time SSE communication for progress updates. + +**PocketFlow Workflow:** + +```mermaid +flowchart LR + A[Generate Outline] --> B[Write Content] + B --> C[Apply Style] ``` -3. Run the server: -```bash -python main.py -``` +1. **`GenerateOutline`**: Creates structured outline with up to 3 sections +2. **`WriteContent` (BatchNode)**: Writes content for each section individually, sending progress updates +3. **`ApplyStyle`**: Polishes the article with conversational tone -## Usage +**FastAPI & SSE Integration:** -### Web Interface (Recommended) +- The `/start-job` endpoint creates a unique job, initializes an SSE queue, and schedules the workflow using `BackgroundTasks` +- Nodes send progress updates to the job-specific `sse_queue` during execution +- The `/progress/{job_id}` endpoint streams real-time updates to the client via Server-Sent Events +- The web UI displays progress with animated bars, step indicators, and detailed status messages -1. Open your browser and go to `http://localhost:8000` -2. Enter an article topic (e.g., "AI Safety", "Climate Change") -3. Click "Generate Article" -4. You'll be redirected to a progress page showing real-time updates -5. The final article will appear when generation is complete - -### API Usage - -#### Start a Job -```bash -curl -X POST "http://localhost:8000/start-job" -d "topic=AI Safety" -H "Content-Type: application/x-www-form-urlencoded" -``` - -Response: -```json -{"job_id": "123e4567-e89b-12d3-a456-426614174000", "topic": "AI Safety", "status": "started"} -``` - -#### Monitor Progress -```bash -curl "http://localhost:8000/progress/123e4567-e89b-12d3-a456-426614174000" -``` - -SSE Stream: -``` -data: {"step": "outline", "progress": 33, "data": {"sections": ["Introduction", "Challenges", "Solutions"]}} -data: {"step": "content", "progress": 44, "data": {"section": "Introduction", "completed_sections": 1, "total_sections": 3}} -data: {"step": "content", "progress": 55, "data": {"section": "Challenges", "completed_sections": 2, "total_sections": 3}} -data: {"step": "content", "progress": 66, "data": {"section": "Solutions", "completed_sections": 3, "total_sections": 3}} -data: {"step": "content", "progress": 66, "data": {"draft_length": 1234, "status": "complete"}} -data: {"step": "complete", "progress": 100, "data": {"final_article": "..."}} -``` +**Progress Updates:** +- 33%: Outline generation complete +- 33-66%: Content writing (individual section updates) +- 66-100%: Style application +- 100%: Article ready ## Files -- `main.py` - FastAPI app with background jobs and SSE -- `flow.py` - PocketFlow workflow definition -- `nodes.py` - Workflow nodes (Outline, Content, Style) -- `utils/call_llm.py` - LLM utility function -- `static/index.html` - Main page for starting jobs -- `static/progress.html` - Progress monitoring page with real-time updates \ No newline at end of file +- [`main.py`](./main.py): FastAPI application with background jobs and SSE endpoints +- [`flow.py`](./flow.py): PocketFlow workflow definition connecting the three nodes +- [`nodes.py`](./nodes.py): Workflow nodes (GenerateOutline, WriteContent BatchNode, ApplyStyle) +- [`utils/call_llm.py`](./utils/call_llm.py): OpenAI LLM utility function +- [`static/index.html`](./static/index.html): Modern job submission form with topic suggestions +- [`static/progress.html`](./static/progress.html): Real-time progress monitoring with animations \ No newline at end of file diff --git a/cookbook/pocketflow-fastapi-background/assets/banner.png b/cookbook/pocketflow-fastapi-background/assets/banner.png new file mode 100644 index 0000000..6230e1a Binary files /dev/null and b/cookbook/pocketflow-fastapi-background/assets/banner.png differ diff --git a/cookbook/pocketflow-fastapi-background/main.py b/cookbook/pocketflow-fastapi-background/main.py index 70dd43a..27e3df7 100644 --- a/cookbook/pocketflow-fastapi-background/main.py +++ b/cookbook/pocketflow-fastapi-background/main.py @@ -18,8 +18,8 @@ active_jobs = {} def run_article_workflow(job_id: str, topic: str): """Run the article workflow in background""" try: - # Create shared store with SSE queue - sse_queue = asyncio.Queue() + # Get the pre-created queue from active_jobs + sse_queue = active_jobs[job_id] shared = { "topic": topic, "sse_queue": sse_queue, @@ -28,9 +28,6 @@ def run_article_workflow(job_id: str, topic: str): "final_article": "" } - # Store the queue for SSE access - active_jobs[job_id] = sse_queue - # Run the workflow flow = create_article_flow() flow.run(shared) @@ -46,6 +43,10 @@ async def start_job(background_tasks: BackgroundTasks, topic: str = Form(...)): """Start a new article generation job""" job_id = str(uuid.uuid4()) + # Create SSE queue and register job immediately + sse_queue = asyncio.Queue() + active_jobs[job_id] = sse_queue + # Start background task background_tasks.add_task(run_article_workflow, job_id, topic) @@ -62,6 +63,9 @@ async def get_progress(job_id: str): sse_queue = active_jobs[job_id] + # Send initial connection confirmation + yield f"data: {json.dumps({'step': 'connected', 'progress': 0, 'data': {'message': 'Connected to job progress'}})}\n\n" + try: while True: # Wait for next progress update diff --git a/cookbook/pocketflow-fastapi-background/static/index.html b/cookbook/pocketflow-fastapi-background/static/index.html index 84fd8e2..fcb8e7d 100644 --- a/cookbook/pocketflow-fastapi-background/static/index.html +++ b/cookbook/pocketflow-fastapi-background/static/index.html @@ -3,120 +3,214 @@ - PocketFlow Article Generator + Article Generator
-

🚀 Article Generator

-
+ +

Generate engaging articles with AI assistance

+ +
- - + +
- + +
- diff --git a/cookbook/pocketflow-fastapi-background/static/progress.html b/cookbook/pocketflow-fastapi-background/static/progress.html index 7b96cac..5367f37 100644 --- a/cookbook/pocketflow-fastapi-background/static/progress.html +++ b/cookbook/pocketflow-fastapi-background/static/progress.html @@ -3,220 +3,478 @@ - Article Generation Progress + Generating Article...
-

📝 Generating Your Article

-
+ +
Generating your article...
+
0%
-
Starting
+
Initializing...
- - - - - - ← Generate Another Article + +
+
+
1
+
Outline
+
+
+
2
+
Content
+
+
+
3
+
Style
+
+
+ +
+
+ + Getting started... +
+
+ Preparing to generate your article. This may take a few moments. +
+
+ +
+

Your Article is Ready! 🎉

+
+
+ + Generate Another +
+
+ +
diff --git a/cookbook/pocketflow-fastapi-background/utils/__init__.py b/cookbook/pocketflow-fastapi-background/utils/__init__.py index 29af1bf..e69de29 100644 --- a/cookbook/pocketflow-fastapi-background/utils/__init__.py +++ b/cookbook/pocketflow-fastapi-background/utils/__init__.py @@ -1 +0,0 @@ -# Utils package for FastAPI Background Job Interface \ No newline at end of file diff --git a/cookbook/pocketflow-streamlit-hitl/README.md b/cookbook/pocketflow-streamlit-fsm/README.md similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/README.md rename to cookbook/pocketflow-streamlit-fsm/README.md diff --git a/cookbook/pocketflow-streamlit-hitl/app.py b/cookbook/pocketflow-streamlit-fsm/app.py similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/app.py rename to cookbook/pocketflow-streamlit-fsm/app.py diff --git a/cookbook/pocketflow-streamlit-hitl/assets/banner.png b/cookbook/pocketflow-streamlit-fsm/assets/banner.png similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/assets/banner.png rename to cookbook/pocketflow-streamlit-fsm/assets/banner.png diff --git a/cookbook/pocketflow-streamlit-hitl/docs/design.md b/cookbook/pocketflow-streamlit-fsm/docs/design.md similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/docs/design.md rename to cookbook/pocketflow-streamlit-fsm/docs/design.md diff --git a/cookbook/pocketflow-streamlit-hitl/flow.py b/cookbook/pocketflow-streamlit-fsm/flow.py similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/flow.py rename to cookbook/pocketflow-streamlit-fsm/flow.py diff --git a/cookbook/pocketflow-streamlit-hitl/nodes.py b/cookbook/pocketflow-streamlit-fsm/nodes.py similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/nodes.py rename to cookbook/pocketflow-streamlit-fsm/nodes.py diff --git a/cookbook/pocketflow-streamlit-hitl/requirements.txt b/cookbook/pocketflow-streamlit-fsm/requirements.txt similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/requirements.txt rename to cookbook/pocketflow-streamlit-fsm/requirements.txt diff --git a/cookbook/pocketflow-streamlit-hitl/utils/__init__.py b/cookbook/pocketflow-streamlit-fsm/utils/__init__.py similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/utils/__init__.py rename to cookbook/pocketflow-streamlit-fsm/utils/__init__.py diff --git a/cookbook/pocketflow-streamlit-hitl/utils/generate_image.py b/cookbook/pocketflow-streamlit-fsm/utils/generate_image.py similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/utils/generate_image.py rename to cookbook/pocketflow-streamlit-fsm/utils/generate_image.py diff --git a/cookbook/pocketflow-streamlit-hitl/utils/test_generated_image.png b/cookbook/pocketflow-streamlit-fsm/utils/test_generated_image.png similarity index 100% rename from cookbook/pocketflow-streamlit-hitl/utils/test_generated_image.png rename to cookbook/pocketflow-streamlit-fsm/utils/test_generated_image.png