Skip to main content

A Python package to generate detailed meal information from natural language descriptions using Generative AI

Project description

Meal Generator

PyPI version License: MIT

A Python package that uses a Generative AI model to parse natural language descriptions of meals and returns a detailed breakdown, including components, estimated weights, and a comprehensive nutrient profile. The module uses an advanced retrieval augmented generation pipeline to enrich results with data validated on Open Food Facts.


Features

  • Natural Language Processing: Understands descriptions of meals like "a bowl of oatmeal with a sliced banana and a drizzle of honey."
  • RAG Validated Results: Uses Open Food Facts to validate known items and their data.
  • Component Breakdown: Identifies individual ingredients within the meal.
  • Nutrient Analysis: Provides estimated nutritional information for each component, including calories, macronutrients, and common allergens.
  • Structured Output: Returns data as organized Python objects for easy integration into your applications.

Documentation

For a complete API reference and more detailed information, please visit the full documentation on Read The Docs.


Installation

Install the package using pip:

pip install meal-generator

You will also need to have a Google Gemini API key. You can set this as an environment variable:

export GEMINI_API_KEY="your-api-key"

Usage

Here is a quick example of how to use the MealGenerator:

from meal_generator import MealGenerator, MealGenerationError

# Initialize the generator (it will use the GEMINI_API_KEY environment variable)
generator = MealGenerator()

meal_description = "A grilled chicken salad with lettuce, tomatoes, cucumbers, and a light vinaigrette dressing."

try:
    # Generate the meal object
    meal = generator.generate_meal(meal_description)

    # Print the meal's aggregated nutrient profile
    print(f"Meal: {meal.name}")
    print(f"Description: {meal.description}")
    print("\n--- Aggregated Nutrients ---")
    print(meal.nutrient_profile)

    # Print details for each component
    print("\n--- Meal Components ---")
    for component in meal.component_list:
        print(f"- {component.name} ({component.quantity}): {component.total_weight}g")
        print(f"  {component.nutrient_profile}")

except MealGenerationError as e:
    print(f"Error generating meal: {e}")
except ValueError as e:
    print(f"Input error: {e}")

Example Input & Output

Here is an example of the data generated from a specific natural language query.

Input String:

"large wrap with half a cup of rice, 100g of chilli, a tablespoon of soured cream"

Resulting meal Object Data:

The code would produce a meal object containing the following structured data:

{
  "meal": {
    "name": "Chilli Con Carne Wrap",
    "description": "A large wheat tortilla wrap filled with chilli con carne, white rice, and a tablespoon of soured cream.",
    "components": [
      {
        "name": "Large Wrap (Wheat Tortilla)",
        "brand": null,
        "quantity": "large wrap",
        "totalWeight": 70.0,
        "nutrientProfile": {
          "energy": 220.0,
          "fats": 5.0,
          "saturated_fats": 1.0,
          "carbohydrates": 38.0,
          "sugars": 1.0,
          "fibre": 2.0,
          "protein": 6.0,
          "salt": 0.8,
          "contains_dairy": false,
          "contains_high_dairy": false,
          "contains_gluten": true,
          "contains_high_gluten": true,
          "contains_histamines": false,
          "contains_high_histamines": false,
          "contains_sulphites": false,
          "contains_high_sulphites": false,
          "contains_salicylates": false,
          "contains_high_salicylates": false,
          "contains_capsaicin": false,
          "contains_high_capsaicin": false,
          "is_processed": true,
          "is_ultra_processed": true
        }
      },
      {
        "name": "Cooked White Rice",
        "brand": null,
        "quantity": "half a cup",
        "totalWeight": 95.0,
        "nutrientProfile": {
          "energy": 125.0,
          "fats": 0.3,
          "saturated_fats": 0.1,
          "carbohydrates": 28.0,
          "sugars": 0.0,
          "fibre": 0.3,
          "protein": 2.5,
          "salt": 0.0,
          "contains_dairy": false,
          "contains_high_dairy": false,
          "contains_gluten": false,
          "contains_high_gluten": false,
          "contains_histamines": false,
          "contains_high_histamines": false,
          "contains_sulphites": false,
          "contains_high_sulphites": false,
          "contains_salicylates": false,
          "contains_high_salicylates": false,
          "contains_capsaicin": false,
          "contains_high_capsaicin": false,
          "is_processed": false,
          "is_ultra_processed": false
        }
      },
      {
        "name": "Chilli (Con Carne/Stew)",
        "brand": null,
        "quantity": "100g",
        "totalWeight": 100.0,
        "nutrientProfile": {
          "energy": 130.0,
          "fats": 6.0,
          "saturated_fats": 2.5,
          "carbohydrates": 10.0,
          "sugars": 3.0,
          "fibre": 4.0,
          "protein": 12.0,
          "salt": 0.6,
          "contains_dairy": false,
          "contains_high_dairy": false,
          "contains_gluten": false,
          "contains_high_gluten": false,
          "contains_histamines": true,
          "contains_high_histamines": false,
          "contains_sulphites": false,
          "contains_high_sulphites": false,
          "contains_salicylates": true,
          "contains_high_salicylates": false,
          "contains_capsaicin": true,
          "contains_high_capsaicin": false,
          "is_processed": true,
          "is_ultra_processed": false
        }
      },
      {
        "name": "Soured Cream",
        "brand": null,
        "quantity": "a tablespoon",
        "totalWeight": 15.0,
        "nutrientProfile": {
          "energy": 35.0,
          "fats": 3.8,
          "saturated_fats": 2.2,
          "carbohydrates": 0.5,
          "sugars": 0.5,
          "fibre": 0.0,
          "protein": 0.5,
          "salt": 0.02,
          "contains_dairy": true,
          "contains_high_dairy": true,
          "contains_gluten": false,
          "contains_high_gluten": false,
          "contains_histamines": true,
          "contains_high_histamines": false,
          "contains_sulphites": false,
          "contains_high_sulphites": false,
          "contains_salicylates": false,
          "contains_high_salicylates": false,
          "contains_capsaicin": false,
          "contains_high_capsaicin": false,
          "is_processed": true,
          "is_ultra_processed": false
        }
      }
    ]
  }
}

Releasing & Versioning

Releases are automated. Every time a pull request is merged into main, the publish workflow runs the tests, then automatically bumps the version, tags the release, and publishes it to PyPI.

The package version is derived from git tags (via hatch-vcs), so there is no version number to edit by hand in pyproject.toml.

How the version is chosen: the bump type is read from the labels on the merged PR, applied on top of the latest vX.Y.Z tag:

PR label Bump Example (v2.1.4 → ...)
major Major v3.0.0
minor Minor v2.2.0
(no label) Patch v2.1.5

So merging is a patch release by default. To cut a minor or major release, add the minor or major label to the PR before it is merged. The workflow then creates the matching vX.Y.Z tag and publishes that version — no commits are pushed back to the protected main branch.


Contributing

Contributions are welcome! Please feel free to submit a pull request or open an issue on the GitHub repository.


License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

meal_generator-2.1.5.tar.gz (20.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

meal_generator-2.1.5-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file meal_generator-2.1.5.tar.gz.

File metadata

  • Download URL: meal_generator-2.1.5.tar.gz
  • Upload date:
  • Size: 20.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for meal_generator-2.1.5.tar.gz
Algorithm Hash digest
SHA256 8cf0d0d89afc45a474c1734bf37bde6905fe8b057ff4f93cc9e1463dcd9bde78
MD5 a7ece635f5a22b365df5b92de9a19254
BLAKE2b-256 23eb0ebffdc2b31362eea5bb8baa747b66bab31340c1d39894edee91da357676

See more details on using hashes here.

Provenance

The following attestation bundles were made for meal_generator-2.1.5.tar.gz:

Publisher: publish-to-pypi.yml on TomMcKenna1/meal-generator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file meal_generator-2.1.5-py3-none-any.whl.

File metadata

  • Download URL: meal_generator-2.1.5-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for meal_generator-2.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 c17da7ebb32900d40f46ed439117a35d905e28c88bcd4abcf38e31224f5a61e0
MD5 a684736673923e14542feb68e7bbbb8c
BLAKE2b-256 06d99fdd5ccd0bbf24fbaac67c772efdc32ecbf934bb6c6ea73d9e87ec2ee4c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for meal_generator-2.1.5-py3-none-any.whl:

Publisher: publish-to-pypi.yml on TomMcKenna1/meal-generator

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page