Klean is a web service that uses Vision Language Models (VLM) to automatically evaluate the quality of financial dashboards and reports. Upload a screenshot and receive expert recommendations on readability, visual hierarchy, and UX improvements.
- Dashboard Analysis: Upload financial dashboard screenshots for AI-powered evaluation
- VLM Integration: Leverages GLM-4.5V / Qwen2.5-VL-72B via SiliconFlow API
- Comprehensive Scoring: Evaluates 6 key criteria with weighted scoring:
- Visual Hierarchy (25%)
- Readability (20%)
- Chart Selection (20%)
- Data Context (15%)
- Color Scheme (10%)
- Cognitive Load (10%)
- Actionable Recommendations: Prioritized, specific suggestions with expected impact
- User Authentication: JWT-based auth with user management
- Image Storage: S3-compatible storage (MinIO for local dev, AWS S3 for production)
- RESTful API: FastAPI backend with automatic OpenAPI documentation
- Framework: FastAPI (Python 3.11+)
- Database: PostgreSQL 15+ with SQLAlchemy 2.0 (async)
- Authentication: JWT with passlib + bcrypt
- Image Processing: Pillow, OpenCV
- VLM API: SiliconFlow (GLM-4.5V, Qwen2.5-VL)
- Storage: S3 (AWS) / MinIO (local)
- Migrations: Alembic
- Containerization: Docker + Docker Compose
- Cache/Queue: Redis (for future Celery integration)
- Development: Python virtual environments, uv package manager
klean/
├── backend/
│ ├── app/
│ │ ├── api/
│ │ │ ├── v1/
│ │ │ │ ├── endpoints/
│ │ │ │ │ ├── auth.py # Authentication endpoints
│ │ │ │ │ └── analysis.py # Analysis endpoints
│ │ │ │ └── router.py
│ │ │ └── deps.py # API dependencies
│ │ ├── core/
│ │ │ ├── config.py # Settings management
│ │ │ └── security.py # JWT & password hashing
│ │ ├── db/
│ │ │ ├── base.py # Base models & mixins
│ │ │ └── session.py # Database session
│ │ ├── models/
│ │ │ ├── user.py # User model
│ │ │ ├── analysis.py # Analysis model
│ │ │ ├── training_example.py # Training data model
│ │ │ └── feedback.py # User feedback model
│ │ ├── schemas/
│ │ │ ├── user.py # User schemas
│ │ │ └── analysis.py # Analysis schemas
│ │ ├── services/
│ │ │ ├── storage_service.py # S3 image handling
│ │ │ ├── vlm_service.py # VLM API integration
│ │ │ └── analysis_service.py # Analysis orchestration
│ │ └── main.py # FastAPI app entry point
│ ├── alembic/ # Database migrations
│ ├── tests/ # Test suite
│ ├── pyproject.toml # Dependencies
│ ├── Dockerfile
│ └── .env.example
├── frontend/ # React frontend (TBD)
├── admin/ # Admin panel (TBD)
├── docker-compose.yml
└── README.md
- Python 3.11+
- Docker & Docker Compose
- SiliconFlow API Key (get from siliconflow.cn)
cd /path/to/kleandocker-compose up -d postgres redis minio minio-initThis starts:
- PostgreSQL on port 5432
- Redis on port 6379
- MinIO on ports 9000 (API) and 9001 (Console)
cd backend
cp .env.example .envEdit .env and set:
# Required
SECRET_KEY=your-secret-key-here
JWT_SECRET_KEY=your-jwt-secret-here
SILICONFLOW_API_KEY=your-siliconflow-api-key
# MinIO (for local dev)
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
S3_ENDPOINT_URL=http://localhost:9000
S3_BUCKET_NAME=klean-uploads# Using uv (recommended)
pip install uv
uv pip install -e .
# Or using pip
pip install -e .alembic upgrade headuvicorn app.main:app --reload --port 8000API will be available at:
- API: http://localhost:8000
- Docs: http://localhost:8000/docs
- Health: http://localhost:8000/health
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "yourpassword",
"full_name": "Test User"
}'curl -X POST "http://localhost:8000/api/v1/auth/login?email=user@example.com&password=yourpassword"Copy the access_token from the response.
curl -X POST http://localhost:8000/api/v1/analysis/analyze \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-F "image=@/path/to/dashboard.png" \
-F "dashboard_type=revenue" \
-F "target_audience=executive"curl http://localhost:8000/api/v1/analysis/analyze/{analysis_id} \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"- POST
/api/v1/auth/register- Register new user - POST
/api/v1/auth/login- Login user - GET
/api/v1/auth/me- Get current user
- POST
/api/v1/analysis/analyze- Create analysis- Body:
multipart/form-dataimage: file (PNG, JPEG, PDF)dashboard_type: optional (revenue, p&l, cash_flow, budget, custom)context: optional stringtarget_audience: optional (executive, analyst, stakeholder)
- Body:
- GET
/api/v1/analysis/analyze/{id}- Get analysis by ID - GET
/api/v1/analysis/analyses?page=1&limit=20- List user's analyses
{
"analysis_id": "uuid",
"status": "completed",
"image_url": "https://...",
"thumbnail_url": "https://...",
"results": {
"overall_score": 72,
"category_scores": {
"visual_hierarchy": 85,
"readability": 65,
"chart_selection": 70,
"data_context": 60,
"color_scheme": 90,
"cognitive_load": 75
},
"recommendations": [
{
"priority": "high",
"category": "visual_hierarchy",
"issue": "Key KPIs not prominent",
"suggestion": "Place Total Revenue and Net Profit at top with 24-30px font",
"reasoning": "Users need to understand key metrics within 3 seconds",
"impact": "Improves data comprehension by 40%"
}
],
"overall_assessment": "Dashboard has strong visual design but lacks clear hierarchy..."
},
"processing_time_ms": 2340,
"model_version": "Pro/Qwen/Qwen2-VL-72B-Instruct"
}cd backend
pytest
pytest --cov=app tests/# Linting
ruff check .
# Formatting
ruff format .
# Type checking
mypy .# Create new migration
alembic revision --autogenerate -m "description"
# Apply migrations
alembic upgrade head
# Rollback
alembic downgrade -1- Username:
minioadmin - Password:
minioadmin
- Admin panel for training data management
- Fine-tuning workflow for custom models
- MLflow experiment tracking
- A/B testing for model versions
- Vector database for similarity search
- React frontend with beautiful UI
- Export recommendations to PDF/Figma
- Before/after comparison
- Team workspaces
- Subscription plans
- Multi-language support
- Industry-specific models
- BI tool integrations (Tableau, Power BI)
- Mobile app
See .env.example for all available configuration options.
SECRET_KEY- App secret keyJWT_SECRET_KEY- JWT signing keyDATABASE_URL- PostgreSQL connection stringSILICONFLOW_API_KEY- VLM API key
For local development (MinIO):
S3_ENDPOINT_URL=http://localhost:9000
AWS_ACCESS_KEY_ID=minioadmin
AWS_SECRET_ACCESS_KEY=minioadmin
S3_BUCKET_NAME=klean-uploadsFor production (AWS S3):
S3_ENDPOINT_URL= # Leave empty for AWS
AWS_ACCESS_KEY_ID=your-aws-key
AWS_SECRET_ACCESS_KEY=your-aws-secret
AWS_REGION=us-east-1
S3_BUCKET_NAME=your-bucket-name# Check PostgreSQL is running
docker-compose ps postgres
# Check logs
docker-compose logs postgres# Re-run bucket initialization
docker-compose up minio-init- Verify
SILICONFLOW_API_KEYis set correctly - Check API quota at siliconflow.cn
- Try fallback model in
VLM_MODELsetting
This project follows standard FastAPI best practices:
- Type hints everywhere
- Pydantic for validation
- Async/await for I/O operations
- Repository pattern (coming in Phase 2)
[To be determined]
For questions or feedback, please open an issue on GitHub.
Built with FastAPI, PostgreSQL, and Vision AI