image generation function implementation

This commit is contained in:
Desktop
2025-11-12 04:32:42 +05:00
parent 854e4b2d0d
commit 19b4c9faa3
6 changed files with 607 additions and 5 deletions

View File

@@ -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**