Files
facefusion-api/app/schemas/process.py
Sebastian Krüger 800edc08ea Initial commit: FaceFusion REST API
FastAPI wrapper around FaceFusion v3.5.3 submodule with:
- Sync and async (job-based) processing endpoints
- FaceFusion bridge with manual key registration and Lock-serialized processing
- Multi-target Dockerfile (CPU + CUDA GPU)
- Docker Compose configs for dev, prod-cpu, and prod-gpu
- Gitea CI/CD workflow with dual image builds
- All 11 FaceFusion processors supported via options API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:58:33 +01:00

115 lines
3.2 KiB
Python

from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field
class FaceSwapperOptions(BaseModel):
model: str = 'hyperswap_1a_256'
pixel_boost: Optional[str] = None
weight: float = 0.5
class FaceEnhancerOptions(BaseModel):
model: str = 'gfpgan_1.4'
blend: int = 80
weight: float = 0.5
class FaceEditorOptions(BaseModel):
model: str = 'live_portrait'
eyebrow_direction: Optional[float] = None
eye_gaze_horizontal: Optional[float] = None
eye_gaze_vertical: Optional[float] = None
eye_open_ratio: Optional[float] = None
lip_open_ratio: Optional[float] = None
mouth_grim: Optional[float] = None
mouth_pout: Optional[float] = None
mouth_purse: Optional[float] = None
mouth_smile: Optional[float] = None
mouth_position_horizontal: Optional[float] = None
mouth_position_vertical: Optional[float] = None
head_pitch: Optional[float] = None
head_yaw: Optional[float] = None
head_roll: Optional[float] = None
class LipSyncerOptions(BaseModel):
model: str = 'wav2lip_96'
class AgeModifierOptions(BaseModel):
model: str = 'styleganex_age'
direction: int = 0
class ExpressionRestorerOptions(BaseModel):
model: str = 'live_portrait'
factor: int = 80
class FrameEnhancerOptions(BaseModel):
model: str = 'span_kendata_1x'
blend: int = 80
class FrameColorizerOptions(BaseModel):
model: str = 'ddcolor'
blend: int = 80
size: str = '256x256'
class BackgroundRemoverOptions(BaseModel):
model: str = 'isnet_general_use'
class FaceDetectorOptions(BaseModel):
model: str = 'yolo_face'
size: str = '640x640'
score: float = 0.5
class FaceSelectorOptions(BaseModel):
mode: str = 'reference'
order: str = 'large-small'
gender: Optional[str] = None
race: Optional[str] = None
age_start: Optional[int] = None
age_end: Optional[int] = None
class OutputOptions(BaseModel):
image_quality: int = 80
image_scale: float = 1.0
video_encoder: Optional[str] = None
video_preset: str = 'veryfast'
video_quality: int = 80
video_scale: float = 1.0
video_fps: Optional[float] = None
audio_encoder: Optional[str] = None
audio_quality: int = 80
audio_volume: int = 100
class ProcessingOptions(BaseModel):
processors: List[str] = Field(default_factory=lambda: ['face_swapper'])
face_swapper: Optional[FaceSwapperOptions] = None
face_enhancer: Optional[FaceEnhancerOptions] = None
face_editor: Optional[FaceEditorOptions] = None
lip_syncer: Optional[LipSyncerOptions] = None
age_modifier: Optional[AgeModifierOptions] = None
expression_restorer: Optional[ExpressionRestorerOptions] = None
frame_enhancer: Optional[FrameEnhancerOptions] = None
frame_colorizer: Optional[FrameColorizerOptions] = None
background_remover: Optional[BackgroundRemoverOptions] = None
face_detector: Optional[FaceDetectorOptions] = None
face_selector: Optional[FaceSelectorOptions] = None
output: Optional[OutputOptions] = None
execution_providers: Optional[List[str]] = None
execution_thread_count: Optional[int] = None
video_memory_strategy: Optional[str] = None
class ProcessingResponse(BaseModel):
output_path: str
processing_time: float