Skip to main content

Open-Food-Calories

A structured JSON database of 5,000+ foods, dishes, and ingredients, with calories and macronutrients, in French and English.

Live demo: https://chpalitom09-bot.github.io/Open-food-calories/

Table of contents

Overview

  • Coverage: 5,037 entries
  • Structure: 100% schema-validated, bilingual (French / English)
  • Accuracy: cross-referenced against CIQUAL and USDA reference values
Food Open-Food-Calories (kcal/100g) Reference (CIQUAL/USDA) Estimated gap
Riz blanc (cru) 350 350 0%
Riz blanc (cuit) 130 130 0%
Pates (crues) 350 353 ~1%
Pates (cuites) 150 158 ~5%
Blanc de poulet 110 110-120 ~4%
Boeuf hache 5% 125 125-129 ~2%
Huile de noisette 884 900 ~1.7%
Magnum (batonnet) 300 310 ~3%
Pain au lait 300 320-340 ~9%
Saute de porc aux legumes 165 150-170 ~3%

Repository structure

.
├── data/
│   ├── Open-food-calories.json          # current dataset (schema v2)
│   └── Open-food-calories-10_03_26.json # legacy snapshot (schema v1)
├── data-schema.json                     # JSON Schema for the v2 format
├── CLI/
│   ├── ofc_cli.py                       # command-line search tool
│   └── ofc_server.py                    # local REST API server
├── examples/
│   ├── app.py                           # Streamlit demo app
│   └── chek_data.py                     # duplicate-check script
├── index.html                           # static web app (GitHub Pages)
├── API.md                               # API reference
├── CONTRIBUTING.md                      # contribution guidelines
└── LICENSE

The dataset that is actively maintained and used by index.html and every tool in this repository is data/Open-food-calories.json. The -10_03_26 file is kept only as a historical snapshot of the older, flat schema and should not be used for new integrations.

Data format (schema v2)

Every entry in data/Open-food-calories.json follows the schema defined in data-schema.json.

{
  "id": "riz-blanc-cuit",
  "name": {
    "fr": "Riz blanc (cuit)",
    "en": "White rice (cooked)"
  },
  "category": "grains",
  "state": "cooked",
  "type": "solid",
  "kcal_per_100g": 130,
  "protein_g": 2.7,
  "fat_g": 0.3,
  "carbs_g": 28.0,
  "fiber_g": null,
  "sugars_g": null,
  "saturated_fat_g": null,
  "salt_g": null,
  "alcohol_g": null,
  "weight_per_unit": null,
  "emoji": "rice",
  "source": "CIQUAL",
  "confidence": "high"
}
Field Type Description
id string Stable identifier, slug form. Never changes once published.
name.fr string Name in French.
name.en string Name in English.
category string One of: beverages, dairy_eggs, meat, seafood, fruits, vegetables, grains, legumes, nuts_seeds, fats_oils, sweets, condiments, prepared, uncategorized.
state string or null One of: raw, cooked, fried, dried, canned, or null.
type string One of: solid, liquid, unit.
kcal_per_100g number Calories per 100g or 100ml.
protein_g number or null Grams of protein per 100g/ml.
fat_g number or null Grams of fat per 100g/ml.
carbs_g number or null Grams of carbohydrates per 100g/ml.
fiber_g number or null Grams of fiber per 100g/ml.
sugars_g number or null Grams of sugar per 100g/ml.
saturated_fat_g number or null Grams of saturated fat per 100g/ml.
salt_g number or null Grams of salt per 100g/ml.
alcohol_g number or null Grams of alcohol per 100g/ml.
weight_per_unit number or null Average weight in grams of one piece, when the food is typically counted rather than weighed (an egg, an apple). Null if the food is measured by weight.
emoji string Representative icon.
source string or null Origin of the values: CIQUAL, USDA, OFF:<barcode>, estimated, or legacy.
confidence string One of: high, medium, low, unknown.

This schema is a breaking change from the original flat format (name as a plain string, english_name, no id, no macronutrients). Any integration built against the old shape needs to be updated to read name.fr / name.en and, where relevant, the new macronutrient fields.

Data quality report

Total entries: 5,037

Macronutrient coverage:

  • Inherited from the original file: 1,010
  • Added from CIQUAL/USDA: 121
  • Still missing (null): 3,906

By confidence level:

  • unknown: 3,906
  • medium: 1,010
  • high: 121

By category:

Category Entries
uncategorized 779
beverages 679
fruits 542
vegetables 534
meat 425
dairy_eggs 406
grains 367
sweets 338
condiments 271
seafood 255
nuts_seeds 148
legumes 137
prepared 133
fats_oils 23

Known issues:

  • Near-duplicate French names: 776 entries share a name or a close variant (for example multiple cheddar, mozzarella, or oil entries with numeric suffixes). These are distinct products, not errors, but deduplication tooling should account for this.
  • Atwater-inconsistent entries: 119 entries where the declared calorie value diverges noticeably from the value calculated from protein/fat/carb grams (for example carotte: declared 41, calculated 31).
  • Alcohol not accounted for: 69 alcoholic beverages where the calculated calories do not include the contribution of alcohol_g, producing a large gap between declared and calculated values (for example vodka: declared 231, calculated 0).
  • Out-of-range value: 1 entry (epice-mastic-larme-de-mastic) at exactly 1000 kcal/100g, at the edge of the schema's allowed range.

These are tracked for cleanup; contributions that correct any of the above are welcome, see Contributing.

Using the raw JSON

JavaScript

const response = await fetch('./data/Open-food-calories.json');
const foods = await response.json();

const item = foods.find(f => f.name.en === 'White rice (cooked)');

if (item) {
  console.log(`${item.name.fr} has ${item.kcal_per_100g} kcal per 100g.`);
}

const weight = 250;
const totalKcal = (item.kcal_per_100g * weight) / 100;
console.log(`Total: ${totalKcal} kcal for ${weight}g`);

Python

import json

with open('data/Open-food-calories.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

search_term = 'oeuf'
results = [food for food in data if search_term.lower() in food['name']['fr'].lower()]

for r in results:
    if r['weight_per_unit']:
        kcal_unit = (r['kcal_per_100g'] * r['weight_per_unit']) / 100
        print(f"{r['name']['fr']}: {kcal_unit} kcal per unit")
    else:
        print(f"{r['name']['fr']}: {r['kcal_per_100g']} kcal per 100g")

weight_per_unit is null when the food is normally measured by weight (rice, flour), and set to the average weight in grams when the food is normally counted by piece (an egg, an apple). An apple with kcal_per_100g: 52 and weight_per_unit: 150 amounts to 78 kcal per apple.

Command-line tool

CLI/ofc_cli.py is a dependency-free command-line client for the dataset. It resolves data/Open-food-calories.json relative to its own location, so it works whether it is run from the repository root or from inside CLI/.

python3 CLI/ofc_cli.py search pizza
python3 CLI/ofc_cli.py search poulet --lang fr --category meat
python3 CLI/ofc_cli.py get riz-blanc-cuit
python3 CLI/ofc_cli.py get riz-blanc-cuit --json
python3 CLI/ofc_cli.py categories
python3 CLI/ofc_cli.py stats

Options for search:

Option Description
query Search term, matched against the name. Leave empty to list without filtering by name.
--lang fr, en, or any (default). Restricts which name field is matched.
--category Filter by one of the categories listed above.
--type Filter by solid, liquid, or unit.
--limit Maximum number of results (default 15).
--json Output raw JSON instead of formatted text.
--verbose, -v Print full nutritional detail for each result.
--file Override the dataset path.

Local REST API

CLI/ofc_server.py starts a local HTTP server exposing the dataset, using only the Python standard library, no installation required.

python3 CLI/ofc_server.py --port 8000
Route Description
GET /all Returns the full dataset.
GET /search?q=&lang=&category=&type=&limit= Same filters as the CLI search command.
GET /food/<id> Returns a single entry by its id.
GET /categories Returns entry counts per category.

Examples:

curl "http://localhost:8000/search?q=pizza&category=prepared"
curl "http://localhost:8000/food/riz-blanc-cuit"
curl "http://localhost:8000/categories"

Responses are JSON, served with Access-Control-Allow-Origin: *, so the server can be queried directly from a browser-based prototype during development.

Contributing

The goal is to grow this dataset well beyond 5,000 entries while keeping it clean. Contributions of new entries, corrections to the issues listed in Data quality report, and improvements to the tooling are all welcome.

All data changes are made in data/Open-food-calories.json, following the schema described above and validated by data-schema.json. Before opening a pull request:

  • Check for an existing entry with the same or a very similar name before adding a new one.
  • Provide both name.fr and name.en.
  • Set state and type accurately; use liquid for drinks and oils, unit for foods normally counted by piece, solid otherwise.
  • Set weight_per_unit when the food is normally counted by piece, leave it null otherwise.
  • Set source and confidence honestly; use estimated and low/medium rather than guessing a high-confidence value.
  • Validate the JSON syntax before committing.
  • Run python3 CLI/ofc_cli.py stats against the updated file to sanity-check totals and confidence levels before opening the pull request.

See CONTRIBUTING.md for the full process.

License

This project is licensed under the MIT License, see LICENSE for details.

Metadata

Release files for open-food-calories 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for open-food-calories 1.1.1
File Size Uploaded
open_food_calories-1.1.1.tar.gz 199.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for open-food-calories 1.1.1
File Interpreter ABI Platform
open_food_calories-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 402.4 kB

Release files / open_food_calories-1.1.1.tar.gz

Download URL open_food_calories-1.1.1.tar.gz
Size 199.4 kB
Tags Source
SHA-256 checksum
How to use checksums
64558c115abc1287261f7d471b271b0858ee260b565e8b5ab3e90b0c33e18c14
BLAKE2b-256 checksum
How to use checksums
f133513e6af84c02db5c28f9ff4bc9b82b62f06d8e517cfc6270b640daa7b664
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / open_food_calories-1.1.1-py3-none-any.whl

Download URL open_food_calories-1.1.1-py3-none-any.whl
Size 203.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d449349defe3e5e35113a0da26c610af1191b704eccd300da6c493ae8ea19f43
BLAKE2b-256 checksum
How to use checksums
424c8bcfb03b1e50bf0d2d9f485e5a62d75c4296825fce955da55e0cbb17a9ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page