image generation function implementation
This commit is contained in:
@@ -274,3 +274,228 @@ Example:
|
||||
|
||||
**End of Stage 1 Changelog**
|
||||
|
||||
---
|
||||
|
||||
## Stage 2 & 3: Image Generation Execution & Real-Time Progress - Completed ✅
|
||||
|
||||
**Date:** 2025-01-XX
|
||||
**Status:** Completed
|
||||
**Goal:** Execute image generation sequentially and update progress in real-time
|
||||
|
||||
---
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Backend API
|
||||
|
||||
#### Updated: `backend/igny8_core/modules/writer/views.py`
|
||||
- **Added Method: `generate_images()`**
|
||||
- Action decorator: `@action(detail=False, methods=['post'], url_path='generate_images')`
|
||||
- Accepts `ids` (image IDs array) and `content_id` (optional)
|
||||
- Queues `process_image_generation_queue` Celery task
|
||||
- Returns `task_id` for progress tracking
|
||||
- Handles validation errors and execution errors
|
||||
|
||||
### 2. Celery Task
|
||||
|
||||
#### Updated: `backend/igny8_core/ai/tasks.py`
|
||||
- **Added Task: `process_image_generation_queue()`**
|
||||
- Decorator: `@shared_task(bind=True, name='igny8_core.ai.tasks.process_image_generation_queue')`
|
||||
- Parameters: `image_ids`, `account_id`, `content_id`
|
||||
- Loads account from `account_id`
|
||||
- Gets image generation settings from `IntegrationSettings` (provider, model, image_type, etc.)
|
||||
- Gets provider API key from `IntegrationSettings` (OpenAI or Runware)
|
||||
- Gets prompt templates from `PromptRegistry`
|
||||
- Processes images sequentially (one at a time)
|
||||
- For each image:
|
||||
- Updates task meta with current progress
|
||||
- Loads image record from database
|
||||
- Validates prompt exists
|
||||
- Gets content for prompt formatting
|
||||
- Formats prompt using template
|
||||
- Calls `AICore.generate_image()`
|
||||
- Updates `Images` model: `image_url`, `status`
|
||||
- Handles errors per image (continues on failure)
|
||||
- Returns final result with counts and per-image results
|
||||
|
||||
### 3. Frontend API
|
||||
|
||||
#### Updated: `frontend/src/services/api.ts`
|
||||
- **Updated Function: `generateImages()`**
|
||||
- Added `contentId` parameter (optional)
|
||||
- Sends both `ids` and `content_id` to backend
|
||||
- Returns task response with `task_id`
|
||||
|
||||
### 4. Frontend Components
|
||||
|
||||
#### Updated: `frontend/src/pages/Writer/Images.tsx`
|
||||
- **Added State:**
|
||||
- `taskId`: Stores Celery task ID for polling
|
||||
- **Updated Function: `handleGenerateImages()`**
|
||||
- Stage 2: Calls `generateImages()` API after opening modal
|
||||
- Stores `task_id` in state
|
||||
- Handles API errors
|
||||
- **Updated Modal Props:**
|
||||
- Passes `taskId` to `ImageQueueModal`
|
||||
|
||||
#### Updated: `frontend/src/components/common/ImageQueueModal.tsx`
|
||||
- **Added Prop: `taskId`**
|
||||
- Optional string for Celery task ID
|
||||
- **Added Polling Mechanism:**
|
||||
- `useEffect` hook polls task status every 1 second
|
||||
- Endpoint: `/api/v1/system/settings/task_progress/{taskId}/`
|
||||
- Stops polling when task completes (SUCCESS/FAILURE)
|
||||
- **Added Function: `updateQueueFromTaskMeta()`**
|
||||
- Updates queue items from task meta data
|
||||
- Maps `current_image`, `completed`, `failed`, `results` to queue items
|
||||
- Updates status, progress, imageUrl, error for each item
|
||||
- **Added Function: `updateQueueFromTaskResult()`**
|
||||
- Updates queue items from final task result
|
||||
- Sets final status and image URLs
|
||||
- Handles completion state
|
||||
|
||||
### 5. Backend Task Status Endpoint
|
||||
|
||||
#### Existing: `backend/igny8_core/modules/system/integration_views.py`
|
||||
- **Method: `task_progress()`**
|
||||
- Already exists and handles Celery task status polling
|
||||
- Returns task state (PENDING, PROGRESS, SUCCESS, FAILURE)
|
||||
- Returns task meta for progress updates
|
||||
- Returns task result on completion
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
### User Flow:
|
||||
1. User clicks "Generate Images" button
|
||||
2. **Stage 1:** Modal opens immediately with all progress bars
|
||||
3. **Stage 2:** Frontend calls `generate_images()` API
|
||||
4. Backend queues `process_image_generation_queue` Celery task
|
||||
5. **Stage 3:** Frontend polls task status every 1 second
|
||||
6. Celery task processes images sequentially:
|
||||
- Image 1: Load → Format Prompt → Generate → Save
|
||||
- Image 2: Load → Format Prompt → Generate → Save
|
||||
- ... (continues for all images)
|
||||
7. Task updates meta with progress after each image
|
||||
8. Frontend receives updates and updates modal progress bars
|
||||
9. On completion, modal shows final status for all images
|
||||
10. User closes modal → Images list reloads
|
||||
|
||||
### Data Flow:
|
||||
```
|
||||
Frontend (Images.tsx)
|
||||
↓ handleGenerateImages()
|
||||
↓ generateImages() API call
|
||||
Backend (ImagesViewSet.generate_images)
|
||||
↓ process_image_generation_queue.delay()
|
||||
Celery Task (process_image_generation_queue)
|
||||
↓ For each image:
|
||||
↓ Load from DB
|
||||
↓ Get settings (IntegrationSettings)
|
||||
↓ Format prompt (PromptRegistry)
|
||||
↓ AICore.generate_image()
|
||||
↓ Update Images model (image_url, status)
|
||||
↓ Update task meta
|
||||
Frontend (ImageQueueModal)
|
||||
↓ Poll task_progress endpoint
|
||||
↓ Update queue from meta/result
|
||||
↓ Display progress bars
|
||||
```
|
||||
|
||||
### Progress Updates:
|
||||
- **Task Meta Structure:**
|
||||
- `current_image`: Index of image being processed
|
||||
- `total_images`: Total images in queue
|
||||
- `completed`: Number of completed images
|
||||
- `failed`: Number of failed images
|
||||
- `results`: Array of per-image results
|
||||
- **Per-Image Result:**
|
||||
- `image_id`: Image record ID
|
||||
- `status`: 'completed' or 'failed'
|
||||
- `image_url`: Generated image URL (if successful)
|
||||
- `error`: Error message (if failed)
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### Backend:
|
||||
1. ✅ `backend/igny8_core/modules/writer/views.py` (UPDATED)
|
||||
- `generate_images()` method
|
||||
|
||||
2. ✅ `backend/igny8_core/ai/tasks.py` (UPDATED)
|
||||
- `process_image_generation_queue()` task
|
||||
|
||||
### Frontend:
|
||||
1. ✅ `frontend/src/services/api.ts` (UPDATED)
|
||||
- `generateImages()` function
|
||||
|
||||
2. ✅ `frontend/src/pages/Writer/Images.tsx` (UPDATED)
|
||||
- `handleGenerateImages()` function
|
||||
- `taskId` state
|
||||
- Modal props
|
||||
|
||||
3. ✅ `frontend/src/components/common/ImageQueueModal.tsx` (UPDATED)
|
||||
- `taskId` prop
|
||||
- Polling mechanism
|
||||
- `updateQueueFromTaskMeta()` function
|
||||
- `updateQueueFromTaskResult()` function
|
||||
|
||||
---
|
||||
|
||||
## Integration Points
|
||||
|
||||
### Settings Integration:
|
||||
- **IntegrationSettings Model:**
|
||||
- `image_generation` type: Provider, model, image_type, max_in_article_images, etc.
|
||||
- `openai` type: API key, model
|
||||
- `runware` type: API key, model
|
||||
|
||||
### Prompt Templates:
|
||||
- **PromptRegistry:**
|
||||
- `get_image_prompt_template()`: Formats prompt with post_title, image_prompt, image_type
|
||||
- `get_negative_prompt()`: Returns negative prompt for Runware
|
||||
|
||||
### Image Storage:
|
||||
- **Images Model:**
|
||||
- `image_url`: Updated with generated image URL
|
||||
- `status`: Updated to 'generated' or 'failed'
|
||||
- `prompt`: Used for generation (already set)
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [x] API endpoint accepts image IDs and content ID
|
||||
- [x] Celery task queues successfully
|
||||
- [x] Task processes images sequentially
|
||||
- [x] Task reads settings from IntegrationSettings
|
||||
- [x] Task formats prompts using PromptRegistry
|
||||
- [x] Task calls AICore.generate_image() correctly
|
||||
- [x] Task updates Images model with URLs and status
|
||||
- [x] Task updates meta with progress
|
||||
- [x] Frontend polls task status correctly
|
||||
- [x] Modal updates progress bars in real-time
|
||||
- [x] Modal shows generated image thumbnails
|
||||
- [x] Modal handles errors per image
|
||||
- [x] Modal shows completion summary
|
||||
- [x] Images list reloads after modal close
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Images are processed **sequentially** (one at a time) to respect API rate limits
|
||||
- Each image failure is handled independently (doesn't stop other images)
|
||||
- Progress updates are sent via Celery task meta (polled every 1 second)
|
||||
- Task status endpoint already exists and is reused
|
||||
- Integration settings are read from database (not hardcoded)
|
||||
- Prompt templates support fallback if formatting fails
|
||||
- Image URLs are saved directly to Images model
|
||||
- Status is updated to 'generated' or 'failed' per image
|
||||
|
||||
---
|
||||
|
||||
**End of Stage 2 & 3 Changelog**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user