apix/backend/routers/meta.py
Khoa.vo 4050f4c853
Some checks are pending
CI / build (18.x) (push) Waiting to run
CI / build (20.x) (push) Waiting to run
v3.1.0: Integrate Meta AI video generation, remove redundant wrapper
- Add backend/services/meta_video_client.py (direct video generation)
- Update routers/meta.py with working /meta/video endpoint
- Delete services/metaai-api/ (~1500 lines removed)
- Simplify docker-compose.yml to single container
- No external service dependencies for Meta AI
2026-01-13 08:02:36 +07:00

150 lines
4.9 KiB
Python

"""
Meta AI Router - Meta AI image and video generation
"""
from fastapi import APIRouter, HTTPException
from models.requests import MetaGenerateRequest, MetaVideoRequest
from models.responses import MetaGenerateResponse, MetaImageResult, MetaVideoResponse, MetaVideoResult, ErrorResponse
from services.meta_client import MetaAIClient
import json
router = APIRouter(prefix="/meta", tags=["Meta AI"])
@router.post(
"/generate",
response_model=MetaGenerateResponse,
responses={
400: {"model": ErrorResponse},
401: {"model": ErrorResponse},
422: {"model": ErrorResponse}
}
)
async def meta_generate(request: MetaGenerateRequest):
"""
Generate images using Meta AI's Imagine model.
- **prompt**: Text description of the image to generate
- **cookies**: Meta AI cookies (optional if using free wrapper)
- **imageCount**: Number of images to generate (1-4)
- **aspectRatio**: portrait, landscape, or square
- **useMetaFreeWrapper**: Use free API wrapper instead of direct Meta AI
- **metaFreeWrapperUrl**: URL of the free wrapper service
"""
# Only check for cookies if NOT using free wrapper
if not request.useMetaFreeWrapper and not request.cookies:
raise HTTPException(
status_code=401,
detail="Meta AI cookies required. Configure in Settings or use Free Wrapper."
)
print(f"[Meta AI Route] Generating images for: \"{request.prompt[:30]}...\" ({request.aspectRatio})")
# Diagnostic: Check cookie count
if request.cookies:
try:
cookies = request.cookies.strip()
if cookies.startswith('['):
parsed = json.loads(cookies)
count = len(parsed) if isinstance(parsed, list) else 0
else:
count = len(cookies.split(';'))
print(f"[Meta AI Route] Received {count} cookies (Free Wrapper: {request.useMetaFreeWrapper})")
except:
print(f"[Meta AI Route] Cookie format: {type(request.cookies)}")
try:
client = MetaAIClient(
cookies=request.cookies or "",
use_free_wrapper=request.useMetaFreeWrapper,
free_wrapper_url=request.metaFreeWrapperUrl or "http://localhost:8000"
)
results = await client.generate(
request.prompt,
request.imageCount,
request.aspectRatio
)
# Download images as base64 for storage
images = []
for img in results:
base64_data = img.data
if not base64_data and img.url:
try:
base64_data = await client.download_as_base64(img.url)
except Exception as e:
print(f"[Meta AI Route] Failed to download image: {e}")
images.append(MetaImageResult(
data=base64_data or "",
url=img.url,
prompt=img.prompt,
model=img.model,
aspectRatio="1:1"
))
valid_images = [img for img in images if img.data or img.url]
if not valid_images:
raise HTTPException(status_code=422, detail="No valid images generated")
return MetaGenerateResponse(success=True, images=valid_images)
except Exception as e:
print(f"[Meta AI Route] Error: {e}")
raise HTTPException(status_code=422, detail=str(e))
@router.post(
"/video",
response_model=MetaVideoResponse,
responses={
400: {"model": ErrorResponse},
401: {"model": ErrorResponse},
500: {"model": ErrorResponse}
}
)
async def meta_video(request: MetaVideoRequest):
"""
Generate video from text prompt using Meta AI's Kadabra engine.
- **prompt**: Text description for video generation
- **cookies**: Meta AI cookies
- **aspectRatio**: portrait, landscape, or square
"""
if not request.cookies:
raise HTTPException(
status_code=401,
detail="Meta AI cookies required for video generation"
)
print(f"[Meta Video Route] Generating video for: \"{request.prompt[:30]}...\"")
try:
from services.meta_video_client import MetaVideoClient
client = MetaVideoClient(cookies=request.cookies)
results = await client.generate_video(
prompt=request.prompt,
wait_before_poll=10,
max_attempts=30,
poll_interval=5
)
videos = [
MetaVideoResult(
url=r.url,
prompt=r.prompt,
model="meta-kadabra"
) for r in results
]
return MetaVideoResponse(success=True, videos=videos)
except Exception as e:
print(f"[Meta Video Route] Error: {e}")
error_message = str(e)
if "expired" in error_message.lower() or "invalid" in error_message.lower():
raise HTTPException(status_code=401, detail=error_message)
raise HTTPException(status_code=500, detail=error_message)