- 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
150 lines
4.9 KiB
Python
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)
|
|
|