AI_Virtual_Wardrobe / app /api /v1 /tryon.py
SuZeAI
Add chat conversations and try-on history endpoints
8ee0940
Raw
History Blame Contribute Delete
4.65 kB
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.models.tryon import TryOnTask
from app.models.wardrobe import WardrobeItem
from app.schemas.tryon import TryOnTaskCreate, TryOnTaskResponse
from app.api.deps import get_current_user
from app.models.user import User
from app.workers.tasks import run_tryon
import uuid
router = APIRouter()
@router.post("/run", response_model=TryOnTaskResponse, status_code=status.HTTP_201_CREATED)
def trigger_try_on(
task_in: TryOnTaskCreate,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
# 1. Determine selected garment IDs and validate ownership
garment_ids = []
if task_in.garment_item_ids:
garment_ids = task_in.garment_item_ids
elif task_in.garment_item_id:
garment_ids = [task_in.garment_item_id]
if not garment_ids:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Vui lòng chọn ít nhất một trang phục để thử đồ."
)
for gid in garment_ids:
item = db.query(WardrobeItem).filter(
WardrobeItem.id == gid,
WardrobeItem.user_id == current_user.id
).first()
if not item:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Không tìm thấy vật phẩm quần áo phù hợp (ID: {gid})."
)
person_image_url = None
from app.models.body import BodyProfile
if task_in.person_image_base64:
try:
import base64
header = "base64,"
b64_str = task_in.person_image_base64
if header in b64_str:
b64_str = b64_str.split(header)[1]
img_data = base64.b64decode(b64_str)
from app.services.storage import storage_service
filename = f"{uuid.uuid4()}.jpg"
r2_path = f"users/{current_user.id}/body/{filename}"
person_image_url = storage_service.upload_file(img_data, r2_path, "image/jpeg")
# Save/Update persistently to user's BodyProfile
profile = db.query(BodyProfile).filter(BodyProfile.user_id == current_user.id).first()
if profile:
profile.body_image_url = person_image_url
else:
profile = BodyProfile(
user_id=current_user.id,
gender="male",
height_cm=170.0,
weight_kg=60.0,
body_image_url=person_image_url
)
db.add(profile)
db.commit()
except Exception as e:
import logging
logging.error(f"Failed to upload try-on person image: {e}")
else:
# Load from saved profile
profile = db.query(BodyProfile).filter(BodyProfile.user_id == current_user.id).first()
if profile and profile.body_image_url:
person_image_url = profile.body_image_url
else:
person_image_url = None
task = TryOnTask(
user_id=current_user.id,
garment_item_id=garment_ids[0] if garment_ids else None,
garment_item_ids=garment_ids,
person_image_url=person_image_url,
status="PENDING"
)
db.add(task)
db.commit()
db.refresh(task)
# Kích hoạt Celery Task tạo ảnh thử đồ qua image-gen API (bất đồng bộ)
run_tryon.delay(str(task.id))
return task
@router.get("/tasks", response_model=list[TryOnTaskResponse])
def list_try_on_tasks(
limit: int = 50,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""Lịch sử các lần thử đồ của người dùng (mới nhất trước)."""
tasks = (
db.query(TryOnTask)
.filter(TryOnTask.user_id == current_user.id)
.order_by(TryOnTask.created_at.desc())
.limit(limit)
.all()
)
return tasks
@router.get("/tasks/{task_id}", response_model=TryOnTaskResponse)
def get_try_on_task(
task_id: uuid.UUID,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
task = db.query(TryOnTask).filter(
TryOnTask.id == task_id,
TryOnTask.user_id == current_user.id
).first()
if not task:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Không tìm thấy tác vụ thử đồ."
)
return task