Skip to content

pchs20/diet-dietitian

Repository files navigation

Diet project - Dietitian

Companion optimization service for the Diet project. It exposes a FastAPI endpoint that builds and solves a multi-day diet planning model using Pyomo + SCIP.


1) Project Overview

diet-dietitian is the optimization layer of the broader diet planning system.

Its responsibilities are:

  • receive user diet constraints via HTTP,
  • fetch meals/dishes data from a configurable provider,
  • convert domain data into Pyomo input structures,
  • solve a mixed-integer optimization model,
  • return a JSON diet plan and optimization metadata.

By default, this service consumes data from diet-backend over gRPC.


2) Problem & Vision

This service solves a constrained diet planning problem over a user-defined date range.

The model aims to:

  • minimize total diet cost,
  • satisfy daily nutritional bounds (calories, protein, carbs, fat),
  • enforce dietary preferences (vegetarian, vegan),
  • choose dishes compatible with each meal type,
  • limit repeated dish selections across the whole plan.

The result is a day-by-day plan organized by meal.


3) Architecture and Structure

Project architecture

The codebase follows a layered organization:

  • API (src/app/api)

    • FastAPI router and request/response schemas.
    • Input validation (date range and bounds consistency).
  • Execution (src/app/execution)

    • Process orchestration pipeline:
      • load provider data,
      • build problem data,
      • convert to Pyomo format,
      • instantiate model,
      • solve,
      • extract response.
  • Domain (src/app/domain)

    • Problem entities (Dish, NutritionalRequirements, DietRestrictions, ProblemData).
  • Model (src/app/model)

    • Pyomo AbstractModel definition:
      • sets, parameters, variables,
      • constraints,
      • objective function.
  • Solver (src/app/solver)

    • SCIP discovery and execution.
    • Result status normalization and plan extraction.
  • Services (src/app/services)

    • Pluggable data providers:
      • diet_backend (gRPC, async),
      • simulator (local JSON).
    • Data transformer (pyomo) to shape model input.
  • Config (src/app/settings.py)

    • Pydantic settings for provider and solver configuration.

Runtime flow

  1. POST /optimize-diet receives constraints.
  2. Process gathers days/meals/dishes data.
  3. Data is transformed into Pyomo dictionary format.
  4. Model instance is created and dumped to concrete_model_dump.txt.
  5. SCIP solves the model.
  6. Service returns solver status + objective + plan.

Project structure

.
├── main.py
├── pyproject.toml
├── tox.ini
├── conda-env.yaml
├── src/
│   └── app/
│       ├── api/
│       ├── domain/
│       ├── execution/
│       ├── model/
│       ├── services/
│       │   ├── data_provider/
│       │   └── data_transformer/
│       ├── solver/
│       ├── settings.py
│       └── asgi_app.py
└── tests/

4) Optimization Model

The model is implemented in src/app/model/model.py with Pyomo.

For the full mathematical formulation, see modeling.pdf.

Decision variable

  • Binary variable use_dish_meal_day[dish, meal, day] indicating whether a dish is selected for a meal/day.

Objective

  • Minimize total cost of selected dishes.

Constraints

  • At least one dish per meal/day.
  • Meal suitability (dish can only appear in suitable meal type).
  • Vegetarian/vegan compliance.
  • Daily min/max bounds for calories, protein, carbs, fat.
  • Global maximum number of selections per dish.

5) Data Providers and Integration

Default provider: diet_backend (gRPC)

Uses async gRPC client (grpc.aio) against:

  • DishService.ListDishes
  • MealService.ListMeals

Provider behavior:

  • pulls dishes/meals from backend,
  • adapts protobuf messages into domain entities,
  • feeds optimization pipeline.

Alternative provider: simulator

Reads local file:

  • src/app/services/data_provider/simulator_dishes_db.json

Useful for isolated local testing without backend dependency.


6) Local Setup & Runbook

Prerequisites

  • Python 3.12
  • Poetry
  • SCIP solver executable
  • Optional: Conda (recommended for SCIP binary provisioning)

Solver environment (recommended)

The repo includes conda-env.yaml to install SCIP only:

conda env create -f conda-env.yaml
conda activate scip-solver

Python environment

poetry install

Run API server

python main.py

Server endpoints:

  • API: http://localhost:8000
  • Docs: http://localhost:8000/docs

7) Testing and code quality

Code quality / typing

  • Black, Flake8, Isort
  • Mypy + Pyright configuration included
  • Tox environments for standardized checks

Useful commands

tox
tox -e black
tox -e isort
tox -e black-check,mypy,flake8,pytest

8) Known Limitations

  • Test coverage is currently minimal and should be expanded (API, transformer, solver integration scenarios).
  • Process execution is synchronous from the API route perspective; solver execution is CPU-bound and blocks the request lifecycle.
  • gRPC proto stubs are committed/generated in-repo; regeneration workflow is not yet documented as an explicit script.
  • Optimization feasibility depends on input bounds and available dish catalog.

About

Diet project dietitian

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages