Spaces:
Running
Running
| title: AI Virtual Wardrobe | |
| emoji: 👕 | |
| colorFrom: pink | |
| colorTo: indigo | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| # AI Virtual Wardrobe Backend - Trợ lý Thời trang AI | |
| Phần phát triển Backend cho dự án **AI Virtual Wardrobe (Trợ lý thời trang cá nhân bằng AI)** sử dụng framework **FastAPI**, **Celery** để xử lý tác vụ bất đồng bộ, **PostgreSQL** lưu trữ dữ liệu quan hệ và **Qdrant** làm cơ sở dữ liệu vector cho công cụ tìm kiếm sản phẩm thời trang tương đồng. | |
| --- | |
| ## 1. Công nghệ Sử dụng (Tech Stack) | |
| * **Framework chính**: [FastAPI](https://fastapi.tiangolo.com/) (Python 3.11+) | |
| * **Hàng đợi & Xử lý bất đồng bộ**: [Celery](https://docs.celeryq.dev/) + [Redis](https://redis.io/) | |
| * **Cơ sở dữ liệu quan hệ**: [PostgreSQL](https://www.postgresql.org/) + [SQLAlchemy ORM](https://www.sqlalchemy.org/) | |
| * **Cơ sở dữ liệu Vector**: [Qdrant Vector DB](https://qdrant.tech/) | |
| * **Quản lý môi trường**: [uv](https://github.com/astral-sh/uv) (Trình quản lý package Python siêu tốc từ Astral) | |
| * **Bảo mật**: JWT (thông qua cookie HttpOnly), băm mật khẩu trực tiếp bằng thư viện `bcrypt`. | |
| * **AI SDK**: Google Gemini API (`google-generativeai`) cho công cụ gợi ý phối đồ. | |
| --- | |
| ## 2. Cấu trúc Dự án (Project Structure) | |
| ``` | |
| backend/ | |
| ├── app/ | |
| │ ├── api/ # Các Router API | |
| │ │ ├── v1/ # Phiên bản API v1 (auth, wardrobe, body, tryon, recommendations) | |
| │ │ ├── deps.py # Dependencies cho FastAPI (Xác thực JWT...) | |
| │ │ └── router.py # Điểm gom các router con | |
| │ ├── core/ # Cấu hình hệ thống, Database pool & Security | |
| │ │ ├── config.py # Pydantic Settings đọc cấu hình từ môi trường | |
| │ │ ├── database.py # Cấu hình SQLAlchemy engine & session | |
| │ │ └── security.py # Hashing password bằng bcrypt & xử lý mã hóa JWT | |
| │ ├── models/ # SQLAlchemy Database Models (Postgres tables) | |
| │ ├── schemas/ # Pydantic models để validate input/output dữ liệu | |
| │ ├── services/ # Lớp tích hợp dịch vụ bên ngoài (R2, Qdrant, Gemini) | |
| │ │ ├── llm_service.py # Dịch vụ gọi Gemini sinh gợi ý phối đồ | |
| │ │ ├── qdrant_client.py# Dịch vụ thêm/sửa/tìm kiếm vector trên Qdrant | |
| │ │ └── storage.py # Dịch vụ upload/delete tệp tin trên Cloudflare R2 | |
| │ ├── workers/ # Cấu hình Celery Workers xử lý AI nặng | |
| │ │ ├── celery_app.py # Thiết lập Celery | |
| │ │ └── tasks.py # Các tác vụ xử lý YOLOv11 + CLIP, SMPL, CatVTON | |
| │ └── main.py # Cổng chạy chính của API FastAPI | |
| ├── tests/ # Thư mục chứa các script kiểm thử tự động | |
| │ ├── conftest.py # Cấu hình pytest (SQLite Mock DB và Custom ARRAY compiler) | |
| │ └── test_auth.py # Các unit test cho Module Auth & Bảo mật | |
| ├── docker-compose.yml # Cấu hình PostgreSQL, Redis, Qdrant local | |
| ├── pyproject.toml # Quản lý project bằng uv | |
| ├── uv.lock # Lockfile chứa thông tin phiên bản dependencies chính xác | |
| └── requirements.txt # File mô tả các package bổ trợ | |
| ``` | |
| --- | |
| ## 3. Hướng dẫn Cài đặt & Chạy dưới Local | |
| ### Bước 1: Clone dự án và truy cập thư mục backend | |
| ```bash | |
| cd backend | |
| ``` | |
| ### Bước 2: Khởi động các dịch vụ cơ sở dữ liệu qua Docker Compose | |
| Đảm bảo bạn đã cài đặt Docker và Docker Compose. Khởi động PostgreSQL, Redis và Qdrant bằng lệnh: | |
| ```bash | |
| docker compose up -d | |
| ``` | |
| *Lưu ý*: Lệnh này sẽ chạy các cơ sở dữ liệu ở chế độ chạy ngầm (detached mode) trên các cổng: | |
| * PostgreSQL: `5432` | |
| * Redis: `6380` (Cổng mới để tránh xung đột với Redis sẵn có trên máy) | |
| * Qdrant: `6333` | |
| ### Bước 3: Tạo môi trường ảo và cài đặt dependencies bằng `uv` | |
| Nếu chưa có `uv`, bạn có thể cài đặt thông qua script chính thức hoặc pip. Sau đó chạy: | |
| ```bash | |
| # Tạo môi trường ảo (.venv) | |
| uv venv | |
| # Cài đặt tất cả các package đã mô tả trong pyproject.toml | |
| uv sync | |
| ``` | |
| ### Bước 4: Tạo cấu hình môi trường (.env) | |
| Tạo file `.env` tại thư mục `backend/` với cấu hình lưu trữ local như sau (không cần tài khoản Cloudflare R2): | |
| ```env | |
| # Xác thực (JWT) | |
| JWT_SECRET_KEY=94c8e79b294e09f5bb648cf496d66e816a0410ff10a5fcf47f22a57dc2095eb3 | |
| # Chế độ Lưu trữ: "local" (ưu tiên local không cần key) hoặc "r2" (đám mây Cloudflare) | |
| STORAGE_MODE=local | |
| UPLOAD_DIR=uploads | |
| SERVER_HOST_URL=http://localhost:8002 | |
| PORT=8002 | |
| # Các biến R2 chỉ cần thiết khi STORAGE_MODE=r2 (Tùy chọn) | |
| # R2_BUCKET_NAME=wardrobe-bucket | |
| # R2_ACCESS_KEY_ID=your_cloudflare_r2_access_key_id | |
| # R2_SECRET_ACCESS_KEY=your_cloudflare_r2_secret_access_key | |
| # R2_ENDPOINT_URL=https://your-account-id.r2.cloudflarestorage.com | |
| # PostgreSQL & Redis Local | |
| POSTGRES_SERVER=localhost | |
| POSTGRES_USER=postgres | |
| POSTGRES_PASSWORD=development_password_change_me | |
| POSTGRES_DB=wardrobe_db | |
| REDIS_HOST=localhost | |
| REDIS_PORT=6380 | |
| # Google Gemini API | |
| GEMINI_API_KEY=your_gemini_api_key_here | |
| ``` | |
| ### Bước 5: Chạy ứng dụng FastAPI | |
| *Lưu ý*: Bạn phải **truy cập vào thư mục `backend/`** trước khi chạy lệnh để tránh lỗi `ModuleNotFoundError: No module named 'app'`. Ngoài ra, cổng chạy mặc định được lấy từ biến môi trường `PORT` (mặc định là `8002`). | |
| ```bash | |
| cd backend | |
| # 1. Chạy nhanh nhất qua file wrapper (tự động đọc PORT, HOST, RELOAD từ .env) | |
| uv run python main.py | |
| # 2. Hoặc chạy thủ công qua uvicorn lấy PORT từ file .env: | |
| export $(grep -v '^#' .env | xargs) && uv run uvicorn app.main:app --host 0.0.0.0 --port $PORT --workers 4 | |
| ``` | |
| Sau khi chạy thành công: | |
| * Trang tài liệu API tự động (Swagger UI) sẽ có mặt tại: `http://127.0.0.1:8002/docs` | |
| * Tài liệu API dạng ReDoc: `http://127.0.0.1:8002/redoc` | |
| ### Bước 6: Khởi động Celery Worker (Để xử lý tác vụ AI bất đồng bộ) | |
| Mở một terminal mới và chạy lệnh sau từ thư mục `backend/` để lắng nghe các task xử lý ảnh/3D: | |
| ```bash | |
| cd backend | |
| uv run celery -A app.workers.celery_app worker --loglevel=info | |
| ``` | |
| ### Bước 7: Khởi chạy CatVTON Gradio Demo (Chạy thử đồ ảo cục bộ trên GPU) | |
| Tác vụ thử đồ ảo (Virtual Try-On) đã được tích hợp cục bộ qua mô hình **CatVTON** (`zhengchong/CatVTON`). Bạn có thể khởi chạy Gradio demo của CatVTON bằng GPU chỉ định trong `.env` (ví dụ: `CUDA_VISIBLE_DEVICES=2`): | |
| ```bash | |
| cd CatVTON | |
| CUDA_VISIBLE_DEVICES=2 ../backend/.venv/bin/python app.py \ | |
| --output_dir="resource/demo/output" \ | |
| --mixed_precision="bf16" \ | |
| --allow_tf32 | |
| ``` | |
| Giao diện Gradio sẽ hiển thị tại: `http://127.0.0.1:7860`. | |
| --- | |
| ## 4. Kiểm thử Tự động (Testing) | |
| Bộ kiểm thử của hệ thống sử dụng SQLite in-memory để chạy test nhanh chóng mà không cần kết nối tới database Postgres thật. | |
| Để khởi chạy toàn bộ unit tests, thực hiện lệnh (từ thư mục `backend/`): | |
| ```bash | |
| cd backend | |
| uv run python -m pytest tests/ | |
| ``` | |
| --- | |
| ## 5. Các biện pháp Bảo mật đã tích hợp (Security Measures) | |
| 1. **Phòng chống Directory Traversal (Tải file độc hại)**: | |
| * Tên file ảnh tải lên được định dạng lại hoàn toàn dưới dạng UUID ngẫu nhiên. | |
| * Sử dụng hàm `os.path.basename()` để bóc tách lọc bỏ mọi ký tự điều hướng thư mục (`../`, `..\`). | |
| * Xác thực chất lượng ảnh thông qua **Magic Bytes** để tránh việc người dùng đổi tên đuôi file độc hại (ví dụ: `script.sh` -> `script.png`) và tải lên máy chủ. | |
| 2. **Bảo mật JWT qua HttpOnly Cookie**: | |
| * JWT Token không được trả về body phản hồi hoặc lưu ở LocalStorage (để tránh bị đánh cắp qua tấn công XSS). | |
| * Token được ghi thẳng vào Cookie của trình duyệt với cấu hình `HttpOnly`, `Secure` và thuộc tính chống CSRF `SameSite=Lax`. | |
| 3. **Bảo mật Cơ sở dữ liệu**: | |
| * SQLAlchemy ORM tự động parameterized các tham số truyền vào câu lệnh SQL để loại bỏ hoàn toàn nguy cơ tấn công **SQL Injection**. | |
| * Exception handler toàn cục trong [main.py](file:///home/llm/MinhPV/AI_Virtual_Wardrobe/backend/app/main.py) sẽ bắt các lỗi phát sinh ngoài ý muốn và trả về thông báo lỗi chung thân thiện với người dùng, tuyệt đối không trả về Stack Trace chứa cấu trúc bảng hoặc câu lệnh SQL lỗi. | |