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>
This commit is contained in:
2026-02-16 14:07:36 +01:00
commit 99c24adfe8
32 changed files with 1814 additions and 0 deletions

0
app/schemas/__init__.py Normal file
View File

39
app/schemas/common.py Normal file
View File

@@ -0,0 +1,39 @@
from datetime import datetime
from enum import Enum
from typing import Optional
from pydantic import BaseModel
class TaskStatus(str, Enum):
pending = 'pending'
processing = 'processing'
completed = 'completed'
failed = 'failed'
class TaskResponse(BaseModel):
task_id: str
status: TaskStatus
created_at: datetime
class TaskDetail(BaseModel):
task_id: str
status: TaskStatus
created_at: datetime
updated_at: datetime
progress: Optional[float] = None
result_url: Optional[str] = None
error: Optional[str] = None
class TaskListResponse(BaseModel):
tasks: list[TaskDetail]
total: int
class ErrorResponse(BaseModel):
error: str
detail: Optional[str] = None
status_code: int

View File

@@ -0,0 +1,41 @@
from typing import Optional
from pydantic import BaseModel, Field
class UpscaleCreativeRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
prompt: Optional[str] = None
scale: Optional[int] = Field(None, ge=2, le=4)
creativity: Optional[float] = Field(None, ge=0.0, le=1.0)
resemblance: Optional[float] = Field(None, ge=0.0, le=1.0)
class UpscalePrecisionRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
scale: Optional[int] = Field(None, ge=2, le=4)
class RelightRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
prompt: Optional[str] = None
light_source: Optional[str] = None
intensity: Optional[float] = Field(None, ge=0.0, le=1.0)
class StyleTransferRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
style_reference: str = Field(..., description='Base64-encoded style reference image')
strength: Optional[float] = Field(None, ge=0.0, le=1.0)
class ExpandRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
prompt: Optional[str] = None
direction: Optional[str] = Field(None, description='Expansion direction')
class InpaintRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
mask: str = Field(..., description='Base64-encoded mask image')
prompt: str = Field(..., min_length=1)

View File

@@ -0,0 +1,35 @@
from typing import Optional
from pydantic import BaseModel, Field
class MysticRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
negative_prompt: Optional[str] = None
resolution: Optional[str] = None
styling: Optional[dict] = None
seed: Optional[int] = None
num_images: Optional[int] = Field(None, ge=1, le=4)
class FluxDevRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
image: Optional[str] = Field(None, description='Base64-encoded image for img2img')
guidance_scale: Optional[float] = Field(None, ge=1.0, le=20.0)
num_images: Optional[int] = Field(None, ge=1, le=4)
seed: Optional[int] = None
class FluxProRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
image: Optional[str] = Field(None, description='Base64-encoded image for img2img')
guidance_scale: Optional[float] = Field(None, ge=1.0, le=20.0)
seed: Optional[int] = None
class SeedreamRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
image: Optional[str] = Field(None, description='Base64-encoded image for img2img')
aspect_ratio: Optional[str] = None
num_images: Optional[int] = Field(None, ge=1, le=4)
seed: Optional[int] = None

13
app/schemas/system.py Normal file
View File

@@ -0,0 +1,13 @@
from pydantic import BaseModel
class HealthResponse(BaseModel):
status: str = 'ok'
class SystemInfoResponse(BaseModel):
api_key_valid: bool
active_tasks: int
cpu_count: int
memory_total: int
memory_available: int

16
app/schemas/utilities.py Normal file
View File

@@ -0,0 +1,16 @@
from typing import Optional
from pydantic import BaseModel, Field
class ClassificationResponse(BaseModel):
is_ai_generated: bool
ai_probability: float
human_probability: float
class IconRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
color: Optional[str] = None
shape: Optional[str] = None
style: Optional[str] = None

View File

@@ -0,0 +1,23 @@
from typing import Optional
from pydantic import BaseModel, Field
class KlingRequest(BaseModel):
image: str = Field(..., description='Base64-encoded image')
prompt: Optional[str] = None
duration: Optional[str] = Field(None, description='5 or 10 seconds')
aspect_ratio: Optional[str] = None
class MinimaxRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
first_frame_image: Optional[str] = Field(None, description='Base64-encoded image')
subject_reference: Optional[str] = Field(None, description='Base64-encoded reference image')
class SeedanceRequest(BaseModel):
prompt: str = Field(..., min_length=1, max_length=4000)
image: Optional[str] = Field(None, description='Base64-encoded image')
duration: Optional[str] = None
resolution: Optional[str] = None