Spaces:
Running
Running
| title: Wardrobe Backend API | |
| sdk: gradio | |
| pinned: false | |
| # Wardrobe Backend API | |
| Production backend for Wardrobe Assistant, designed to run on Hugging Face Spaces. | |
| The service provides: | |
| - garment classification from uploaded images, | |
| - wardrobe item persistence, | |
| - AI outfit scoring and recommendation, | |
| - shopping suggestion and product URL extraction, | |
| - lightweight feedback capture for preference signals. | |
| The API is built with FastAPI, uses SQLite for persistence, and integrates external AI providers for inference. | |
| ## Architecture Summary | |
| - Runtime: FastAPI + Uvicorn | |
| - Storage: SQLite (persistent when `/data` is mounted on Hugging Face) | |
| - Inference: Hugging Face-hosted fine-tuned Qwen model (primary); NVIDIA-hosted chat completions used as fallback (default fallback model: `qwen/qwen3.5-122b-a10b`) | |
| - Retrieval: Web scraping pipeline for product discovery (Nike and Zalando logic in code) | |
| Core modules: | |
| - `app.py`: API routes, orchestration, inference calls, scraper flow | |
| - `db.py`: SQLite schema and CRUD/caching helpers | |
| - `scoring.py`: deterministic fallback scoring logic | |
| - `fashion_ai/`: recommendation service and ranking support | |
| ## Repository Contents for Deployment | |
| Upload this backend directory as your Hugging Face Space source (or sync it via Git): | |
| - `app.py` | |
| - `db.py` | |
| - `scoring.py` | |
| - `scraper.py` | |
| - `zalando_scraper.py` | |
| - `requirements.txt` | |
| - `packages.txt` | |
| - `fashion_ai/` | |
| ## Hugging Face Deployment | |
| 1. Create a new Space. | |
| 2. Select `Gradio` SDK. | |
| 3. Use CPU hardware (inference is delegated to external APIs). | |
| 4. Enable Persistent Storage if you want data durability across restarts. | |
| 5. Add the required environment variables. | |
| 6. Deploy the backend files. | |
| ### Required Environment Variables | |
| - `HF_API_KEY`: API key for the primary Hugging Face-hosted fine-tuned Qwen model. | |
| - `NVIDIA_API_KEY`: API key for the NVIDIA inference fallback. | |
| ### Common Optional Environment Variables | |
| Inference and reliability: | |
| - `HF_MODEL_ID` (default: your fine-tuned Qwen model on Hugging Face) | |
| - `HF_INVOKE_URL` (default: Hugging Face Inference API endpoint for the fine-tuned model) | |
| - `NVIDIA_MODEL_ID` (fallback; default: `qwen/qwen3.5-122b-a10b`) | |
| - `NVIDIA_INVOKE_URL` (fallback; default: `https://integrate.api.nvidia.com/v1/chat/completions`) | |
| - `OPENAI_MODEL_ID` (secondary fallback; OpenAI-compatible model ID if both primary and NVIDIA fallback are unavailable) | |
| - `OPENAI_API_KEY` (secondary fallback; required only if OpenAI fallback is enabled) | |
| - `NVIDIA_MAX_TOKENS` (default: `16384`) | |
| - `NVIDIA_REASONING_MAX_TOKENS` (default: `16384`) | |
| - `NVIDIA_TEMPERATURE` (default: `0.60`) | |
| - `NVIDIA_TOP_P` (default: `0.95`) | |
| - `NVIDIA_TIMEOUT_SECONDS` (default: `180`) | |
| - `NVIDIA_MAX_RETRIES` (default: `3`) | |
| - `NVIDIA_RETRY_BACKOFF_SECONDS` (default: `0.8`) | |
| - `NVIDIA_ENABLE_THINKING` (default: `false`) | |
| - `NVIDIA_FALLBACK_MODEL_IDS` (comma-separated fallback list) | |
| Matching and cache: | |
| - `MATCHING_RESULT_CACHE_MAX` (default: `500`) | |
| - `MATCHING_RESULT_CACHE_TTL_SECONDS` (default: `86400`) | |
| Scraper and planner: | |
| - `SCRAPER_DEFAULT_STORE` (default: `nike`) | |
| - `SCRAPER_PLANNER_MODEL_ID` (default: `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning`) | |
| - `SCRAPER_PLANNER_MAX_TOKENS` (default: `800`) | |
| Database path: | |
| - `DB_PATH` (optional override) | |
| When `DB_PATH` is not provided, the app uses: | |
| - `/data/wardrobe.db` if `/data` exists, | |
| - otherwise `./wardrobe.db`. | |
| ## Inference Priority | |
| The service resolves inference providers in the following order: | |
| 1. **Primary** - Fine-tuned Qwen model hosted on Hugging Face (`HF_MODEL_ID`). | |
| 2. **Fallback 1** - NVIDIA-hosted chat completions (`NVIDIA_MODEL_ID`, default: `qwen/qwen3.5-122b-a10b`). Used when the primary model is unavailable or returns an error. | |
| 3. **Fallback 2** - OpenAI-compatible model (`OPENAI_MODEL_ID`). Used when both the primary and NVIDIA fallback are unavailable. | |
| AI-powered routes return a service-level error only when all three providers are exhausted or unconfigured. | |
| ## API Endpoints | |
| Health and service metadata: | |
| - `GET /` | |
| - `GET /health` | |
| Wardrobe ingestion and CRUD: | |
| - `POST /classify` | |
| - `POST /upload` | |
| - `GET /items` | |
| - `PUT /items/{item_id}` | |
| - `DELETE /items/{item_id}` | |
| Outfit intelligence: | |
| - `POST /ai/score-outfit` | |
| - `POST /ai/gap-analysis` | |
| - `POST /ai/recommend-outfits` | |
| - `POST /feedback` | |
| Shopping and scraping: | |
| - `POST /product-urls` | |
| - `POST /suggestions` | |
| - `POST /api/suggestions` | |
| - `POST /scraper/recommend` | |
| - `GET /scraper` | |
| - `GET /image-proxy` | |
| ## Local Development | |
| ### 1. Install dependencies | |
| ```bash | |
| pip install -r requirements.txt | |
| ``` | |
| ### 2. Export environment variables | |
| Linux/macOS: | |
| ```bash | |
| export HF_API_KEY="" | |
| export NVIDIA_API_KEY="" # fallback | |
| export OPENAI_API_KEY="" # secondary fallback, optional | |
| ``` | |
| Windows PowerShell: | |
| ```powershell | |
| $env:HF_API_KEY = "" | |
| $env:NVIDIA_API_KEY = "" # fallback | |
| $env:OPENAI_API_KEY = "" # secondary fallback, optional | |
| ``` | |
| ### 3. Run the API | |
| ```bash | |
| python app.py | |
| ``` | |
| The service starts on `http://0.0.0.0:7860`. | |
| ## Smoke Checks | |
| Health: | |
| ```bash | |
| curl "http://127.0.0.1:7860/health" | |
| ``` | |
| Image classification: | |
| ```bash | |
| curl -X POST "http://127.0.0.1:7860/classify" \ | |
| -F "image=@/path/to/garment.jpg" | |
| ``` | |
| Expected post-deploy health signal: | |
| - `hf_api_configured` should be `"True"` (primary model). | |
| - `nvidia_api_configured` should be `"True"` (fallback model). | |