VeggieAI is a Flask-based machine learning operations project for vegetable image classification, price lookup, authenticated prediction history, and optional chatbot assistance. The repository is structured as a coursework-ready application with a backend API, Jinja web UI, model service, model registry, tests, CI/CD gates, security checks, and operational documentation.
- Institution: Singapore Polytechnic, School of Computing
- Diploma: Diploma in Applied AI & Analytics
- Module: DevOps & Automation for AI (ST1516), CA2
- Student: Goh Kun Ming, DAAA
- Academic year: AY25/26, Year 2 Semester 2
- Lecturer: Ryan Chia Xueyi
- License: MIT License
- Jinja-rendered web application for login, prediction, price lookup, profile, and history pages.
- Flask backend API for auth, captcha, OTP, prediction records, chat, security headers, and SQLite persistence.
- Separate model service for local registry-based inference smoke tests.
- VegNet model switching for
vegnet-23andvegnet-101. - Optional OpenAI chatbot and Roboflow camera detection integrations.
- Pytest suite covering unit, API, security, and end-to-end flows.
- CI/CD workflows for linting, testing, coverage, model registry validation, security scanning, Docker builds, and deployment gates.
backend/ Flask API, auth, database access, security, business logic
data/ Dataset placeholders and split documentation
db/ SQLite schema and initialization helpers
docs/ Architecture, CI/CD, MLOps, testing, security, runbooks, ADRs
models/ Lightweight model registry packages and manifest
model_service/ Flask model-service API used by local MLOps checks
model_serving/ TensorFlow Serving assets, notebooks, and model export evidence
reports/ Generated reports and evidence outputs
scripts/ Smoke tests, registry validation, RPA helpers
tf_models/ SavedModel artifacts for TensorFlow Serving
webapp/ Jinja templates, static assets, and frontend documentation
Every maintained folder has a local README.md. Generated/runtime folders are documented at their nearest stable parent and excluded from the documentation gate where appropriate.
Create and activate a virtual environment, then install development dependencies:
python -m venv .venv
.venv\Scripts\activate
python -m pip install --upgrade pip
pip install -r backend/requirements-dev.txt
pip install -r model_service/requirements-dev.txtCopy the example environment and adjust secrets:
copy .env.example .envRun the local stack:
python main.pyLocal services:
- Web app and backend API:
http://localhost:5000 - Model service health:
http://localhost:8000/health
copy .env.example .env
docker compose up --buildCompose starts:
backendonhttp://localhost:5000model_serviceonhttp://localhost:8000- SQLite and upload volumes for local runtime state
Use .env.example as the documented baseline. Important settings:
SECRET_KEY,JWT_SECRET,ADMIN_USERNAME,ADMIN_PASSWORDDATABASE_PATH,UPLOAD_DIR,MODELS_ROOTMODEL_SERVICE_URL,MODEL_SERVICE_TIMEOUT_SECVEGGIE_DEFAULT_MODEL,VEGNET_23_URL,VEGNET_101_URL,VEGNET_REMOTE_ENABLEDOPENAI_API_KEY,OPENAI_CHAT_MODELROBOFLOW_API_KEY,ROBOFLOW_MODEL_ID,ROBOFLOW_WORKSPACE,ROBOFLOW_WORKFLOW_IDCAPTCHA_*,OTP_*,SMTP_*SECURITY_HEADERS_ENABLED,FORCE_HTTPS,SESSION_COOKIE_*,CSP_POLICY
Production secrets must be configured in the deployment platform, not committed to the repository.
Run the full suite:
pytestUseful subsets:
pytest -m unit
pytest -m api
pytest -m security
pytest -m e2e
pytest backend/tests
pytest model_service/testsQuality and MLOps checks:
ruff check backend model_service scripts main.py
ruff format --check backend model_service scripts main.py
python scripts/check_readmes.py
python scripts/validate_model_registry.py --models-root models --report reports/model-registry-report.json
python scripts/smoke_serving.py --base-url http://127.0.0.1:8000
python scripts/smoke_webapp.py --base-url http://127.0.0.1:5000Primary automation is defined in .github/workflows/ci.yml. In this repository layout, the root workflow runs with Source-Codes/ as the working directory so only application source, tests, models, and operational docs are part of the GitHub submission.
The CI gates cover:
- Documentation structure check for folder-level READMEs.
- Ruff lint and format checks.
- Backend and model-service pytest suites with coverage artifacts.
- Model registry validation and checksum report generation.
- Runtime smoke checks for the local stack.
- Bandit, pip-audit, and gitleaks security scans.
- Docker image builds for backend and model service.
See docs/cicd.md, docs/mlops.md, and docs/model-governance.md for the operational details.
API responses follow a consistent envelope:
{ "data": {}, "request_id": "..." }or:
{ "error": { "code": "...", "message": "...", "details": {} }, "request_id": "..." }Main endpoints:
POST /api/auth/loginPOST /api/auth/signupPOST /api/auth/otp/verifyGET /api/auth/mePOST /api/predictGET /api/modelsPOST /api/veggie/predictPOST /api/veggie/detectGET /api/veggie/modelsGET /api/veggie/pricesGET /api/veggie/historyPOST /api/chat/messageGET /api/chat/historyDELETE /api/chat/history
Page routes:
//auth/predict/prices/profile/history
docs/architecture.md: service layout, data ownership, inference routing.docs/api-contract.md: API response and route contract.docs/testing.md: pytest strategy and coverage expectations.docs/security.md: security design and scanning.docs/cicd.md: pipeline gates and artifacts.docs/mlops.md: model registry, promotion, monitoring, rollback.docs/runbooks/: local development and service runbooks.CODE_OF_CONDUCT.md,CONTRIBUTING.md,GOVERNANCE.md,SECURITY.md: project governance.
This project is released under the MIT License. See LICENSE.