Backend-first, API-driven product description generator with rule-based quality checks.
Built for demos and fast iteration — no database, no auth, just clean prompts and evaluation.
- Generate product descriptions from structured inputs (name, category, features, audience, tone, language)
- Evaluate descriptions with rule-based checks (length, tone, missing fields, CTA, readability)
- Supports Google Gemini (default) and OpenAI (fallback)
- Frontend: React + Vite + Tailwind CSS (minimal, elegant)
- Backend: FastAPI + Pydantic + async LLM calls
Prodzy/
├─ backend/ # FastAPI app
│ ├─ app/
│ │ ├─ routes/ # API endpoints
│ │ ├─ services/ # LLM + evaluation logic
│ │ ├─ schemas/ # Pydantic models
│ │ └─ config.py # Env + settings
│ └─ requirements.txt
├─ frontend/ # React (Vite) UI
│ ├─ src/
│ │ ├─ pages/ # Input.jsx, Result.jsx
│ │ ├─ services/ # api.js
│ │ └─ App.jsx
│ └─ package.json
└─ README.md
-
Create virtual environment
python -m venv .venv source .venv/bin/activate -
Install dependencies
pip install -r backend/requirements.txt
-
Set environment variables
Createbackend/.env:LLM_PROVIDER=gemini GEMINI_API_KEY=YOUR_REAL_KEY GEMINI_MODEL=gemini-1.5-flash
-
Run server
python -m uvicorn backend.app.main:app --reload --host 127.0.0.1 --port 8001
-
Verify
- Open
http://127.0.0.1:8001/docsfor Swagger UI
- Open
-
Install dependencies
cd frontend npm install -
Run dev server
npm run dev
-
Visit
- Usually
http://localhost:5173
- Usually
-
Override backend URL (optional) Create
frontend/.env:VITE_API_BASE_URL=http://127.0.0.1:8001
- Root Directory:
backend - Build Command:
pip install -r requirements.txt - Start Command:
uvicorn app.main:app --host 0.0.0.0 --port $PORT
LLM_PROVIDER=gemini
GEMINI_API_KEY=YOUR_REAL_KEY
GEMINI_MODEL=gemini-1.5-flashGET /health→{"status":"ok"}
- Build:
npm run build - Output:
dist/ - Environment Variable:
VITE_API_BASE_URL=https://your-backend-name.onrender.com
Request
{
"product_name": "Aurora Stainless Steel Water Bottle",
"category": "Drinkware",
"key_features": ["Insulated", "Leak-proof", "750ml"],
"audience": "Gym-goers",
"tone": "premium",
"language": "en",
"prompt_version": "v2"
}Response
{
"description": "...",
"metadata": {
"provider": "gemini",
"model": "gemini-1.5-flash"
}
}Request
{
"description": "...",
"expected_tone": "premium",
"required_terms": ["insulated", "leak-proof"],
"min_length": 120,
"max_length": 180
}Response
{
"score": 82,
"checks": {
"length": "pass",
"tone": "warn",
"missing_info": "pass"
},
"suggestions": [
"Make tone more premium by reducing casual phrases.",
"Add a short usage scenario for gym sessions."
]
}- Open frontend → welcome screen → progress bar → Input page
- Click “Fill the Product Details Form” → form reveals
- Click “Use sample” (demo backup) → fields prefill
- Click “Generate Description” → loading → Result page
- Review:
- Description
- Quality checks (pass/warn)
- Suggestions
- Copy/Regenerate buttons
- Click “Back” → return to Input
-
Port already in use
lsof -ti :8001 | xargs kill -9
-
CORS errors
Add your frontend URL toallow_originsinbackend/app/main.py. -
Invalid API key / quota Frontend will show friendly messages. Ensure real key in backend
.env.
MIT (or company-assessment default — update if required).
- Fork
- Feature branch
- Keep changes minimal and focused
- PR with clear description
Built for demos and fast iteration.
No database, no auth — just prompts, evaluation, and clean UI.