Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
import asyncio
|
|
|
|
|
import logging
|
|
|
|
|
import uuid
|
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
|
from typing import Optional
|
|
|
|
|
|
|
|
|
|
from app.config import settings
|
|
|
|
|
from app.schemas.common import TaskStatus
|
|
|
|
|
from app.services import freepik_client
|
|
|
|
|
from app.services.file_manager import download_result
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
_tasks: dict[str, dict] = {}
|
|
|
|
|
_poll_tasks: dict[str, asyncio.Task] = {}
|
|
|
|
|
|
|
|
|
|
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
def submit(freepik_task_id: str, status_path: str, metadata: Optional[dict] = None) -> str:
|
|
|
|
|
"""Register a Freepik task and start background polling.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
freepik_task_id: The task_id returned by Freepik.
|
|
|
|
|
status_path: The per-endpoint GET path for polling, e.g.
|
|
|
|
|
'/v1/ai/text-to-image/flux-dev/{task-id}'.
|
|
|
|
|
metadata: Optional metadata to attach to the task.
|
|
|
|
|
"""
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
internal_id = str(uuid.uuid4())
|
|
|
|
|
now = datetime.now(timezone.utc)
|
|
|
|
|
_tasks[internal_id] = {
|
|
|
|
|
'task_id': internal_id,
|
|
|
|
|
'freepik_task_id': freepik_task_id,
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
'status_path': status_path,
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
'status': TaskStatus.pending,
|
|
|
|
|
'created_at': now,
|
|
|
|
|
'updated_at': now,
|
|
|
|
|
'progress': None,
|
|
|
|
|
'result_url': None,
|
|
|
|
|
'local_path': None,
|
|
|
|
|
'error': None,
|
|
|
|
|
'metadata': metadata or {},
|
|
|
|
|
}
|
|
|
|
|
_poll_tasks[internal_id] = asyncio.create_task(_poll_loop(internal_id))
|
|
|
|
|
return internal_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_task(task_id: str) -> Optional[dict]:
|
|
|
|
|
return _tasks.get(task_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def list_tasks(
|
|
|
|
|
status: Optional[TaskStatus] = None,
|
|
|
|
|
limit: int = 20,
|
|
|
|
|
offset: int = 0,
|
|
|
|
|
) -> tuple[list[dict], int]:
|
|
|
|
|
tasks = list(_tasks.values())
|
|
|
|
|
if status:
|
|
|
|
|
tasks = [t for t in tasks if t['status'] == status]
|
|
|
|
|
tasks.sort(key=lambda t: t['created_at'], reverse=True)
|
|
|
|
|
total = len(tasks)
|
|
|
|
|
return tasks[offset:offset + limit], total
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def delete_task(task_id: str) -> bool:
|
|
|
|
|
if task_id not in _tasks:
|
|
|
|
|
return False
|
|
|
|
|
poll = _poll_tasks.pop(task_id, None)
|
|
|
|
|
if poll and not poll.done():
|
|
|
|
|
poll.cancel()
|
|
|
|
|
_tasks.pop(task_id, None)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def active_count() -> int:
|
|
|
|
|
return sum(
|
|
|
|
|
1 for t in _tasks.values()
|
|
|
|
|
if t['status'] in (TaskStatus.pending, TaskStatus.processing)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _poll_loop(internal_id: str):
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
"""Poll Freepik API using the per-endpoint status path until done."""
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
task = _tasks.get(internal_id)
|
|
|
|
|
if not task:
|
|
|
|
|
return
|
|
|
|
|
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
status_path = task['status_path']
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
elapsed = 0
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
while elapsed < settings.task_poll_timeout_seconds:
|
|
|
|
|
await asyncio.sleep(settings.task_poll_interval_seconds)
|
|
|
|
|
elapsed += settings.task_poll_interval_seconds
|
|
|
|
|
|
|
|
|
|
try:
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
result = await freepik_client.get_task_status(status_path)
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning(f'Poll error for {internal_id}: {exc}')
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
data = result.get('data', result)
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
fp_status = str(data.get('status', '')).upper()
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
|
|
|
|
|
task['updated_at'] = datetime.now(timezone.utc)
|
|
|
|
|
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
if fp_status in ('CREATED', 'IN_PROGRESS', 'PROCESSING'):
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
task['status'] = TaskStatus.processing
|
|
|
|
|
continue
|
|
|
|
|
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
if fp_status == 'COMPLETED':
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
task['status'] = TaskStatus.completed
|
|
|
|
|
task['progress'] = 1.0
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
# Freepik returns results in data.generated[] (list of URLs)
|
|
|
|
|
generated = data.get('generated', [])
|
|
|
|
|
result_url = generated[0] if generated else None
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
task['result_url'] = result_url
|
|
|
|
|
if result_url:
|
|
|
|
|
try:
|
|
|
|
|
task['local_path'] = await download_result(
|
|
|
|
|
internal_id, result_url
|
|
|
|
|
)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.error(f'Download failed for {internal_id}: {exc}')
|
|
|
|
|
logger.info(f'Task {internal_id} completed')
|
|
|
|
|
return
|
|
|
|
|
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
if fp_status == 'FAILED':
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
task['status'] = TaskStatus.failed
|
|
|
|
|
task['error'] = data.get('error', data.get('message', 'Unknown error'))
|
|
|
|
|
logger.warning(f'Task {internal_id} failed: {task["error"]}')
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Timeout
|
|
|
|
|
task['status'] = TaskStatus.failed
|
|
|
|
|
task['error'] = f'Polling timed out after {settings.task_poll_timeout_seconds}s'
|
|
|
|
|
logger.warning(f'Task {internal_id} timed out')
|
|
|
|
|
|
|
|
|
|
except asyncio.CancelledError:
|
|
|
|
|
logger.info(f'Polling cancelled for {internal_id}')
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
task['status'] = TaskStatus.failed
|
|
|
|
|
task['error'] = str(exc)
|
|
|
|
|
logger.error(f'Unexpected error polling {internal_id}: {exc}')
|
|
|
|
|
finally:
|
|
|
|
|
_poll_tasks.pop(internal_id, None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def handle_webhook_completion(freepik_task_id: str, result_data: dict):
|
|
|
|
|
"""Called when a webhook notification arrives for a completed task."""
|
|
|
|
|
for task in _tasks.values():
|
|
|
|
|
if task['freepik_task_id'] == freepik_task_id:
|
|
|
|
|
task['status'] = TaskStatus.completed
|
|
|
|
|
task['progress'] = 1.0
|
|
|
|
|
task['updated_at'] = datetime.now(timezone.utc)
|
fix: align Freepik API paths with OpenAPI spec
The original implementation used guessed endpoint paths that don't match
the actual Freepik API. Key fixes based on their OpenAPI spec:
- Task polling is per-endpoint (e.g. GET /v1/ai/text-to-image/flux-dev/{task-id})
not a generic /v1/ai/tasks/{id}. freepik_client now returns TaskResult
with status_path, and task_tracker polls using that path.
- Fixed endpoint paths: flux-pro -> flux-pro-v1-1, upscale -> image-upscaler,
relight -> image-relight, style-transfer -> image-style-transfer,
expand -> image-expand/flux-pro, inpaint -> ideogram-image-edit,
remove-background -> beta/remove-background, classifier -> classifier/image,
audio-isolate -> audio-isolation, icon -> text-to-icon
- Fixed video paths: kling -> kling-o1-pro with kling-o1 status path,
minimax -> minimax-hailuo-02-1080p, seedance -> seedance-pro-1080p
- Fixed request schemas to match actual API params (e.g. scale_factor
not scale, reference_image not style_reference, image_url for bg removal)
- Fixed response parsing: status is uppercase (COMPLETED not completed),
results in data.generated[] array, classifier returns [{class_name, probability}]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:26:42 +01:00
|
|
|
generated = result_data.get('generated', [])
|
|
|
|
|
task['result_url'] = generated[0] if generated else None
|
Initial commit: Freepik REST API
FastAPI async wrapper for Freepik cloud AI API supporting image generation
(Mystic, Flux Dev/Pro, SeedReam), video generation (Kling, MiniMax, Seedance),
image editing (upscale, relight, style transfer, expand, inpaint), and
utilities (background removal, classifier, audio isolation). Includes async
task tracking with polling, Docker containerization, and Gitea CI/CD workflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:07:36 +01:00
|
|
|
poll = _poll_tasks.pop(task['task_id'], None)
|
|
|
|
|
if poll and not poll.done():
|
|
|
|
|
poll.cancel()
|
|
|
|
|
logger.info(f'Task {task["task_id"]} completed via webhook')
|
|
|
|
|
break
|