pantryfold
Combine ingredient quantities into one shopping list, then subtract what you already have. No AI, API keys or runtime dependencies. Python 3.10+. MIT licensed.
Install
python -m pip install pantryfold
Use python -m pip install . for a local checkout. The CLI also works as python -m pantryfold.
Python
from pantryfold import Ingredient, shopping_list, format_quantity
required = [Ingredient("milk", 500, "ml"), Ingredient("Milk", 1, "l")]
stock = [Ingredient("milk", 250, "ml")]
items = shopping_list(required, pantry=stock)
assert items == [Ingredient("milk", 1250, "ml")]
assert format_quantity(items[0].quantity) == "1250"
Command line
Create recipe-a.json:
[
{"name": "milk", "quantity": "500", "unit": "ml"},
{"name": "eggs", "quantity": "2", "unit": "pcs"}
]
Create recipe-b.json with the other recipe and pantry.json with items already on hand, using the same format.
pantryfold recipe-a.json recipe-b.json --pantry pantry.json
pantryfold recipe-a.json --scale 2 --format markdown
pantryfold recipe-a.json --aliases aliases.json
Output is JSON by default. Markdown output is a checkbox shopping list. Input files are UTF-8; one input may be a dash to read standard input. Every entry must contain exactly name, quantity and unit. Misspelled fields are rejected. Quantity strings support decimals or fractions such as "1/3".
Matching and units
- Names are case-folded, Unicode NFC-normalized, trimmed, and whitespace is collapsed. The normalized name is used in output.
- Different names are merged only through explicit aliases. For example, aliases.json may contain {"scallion": "green onion"}. Chains are supported; cycles and conflicting aliases are rejected.
- Weight: g and kg. Volume: ml and l. Count: pcs. Common English spellings are accepted, as are 克, 千克, 公斤, 毫升, 升, 个.
- Results use canonical g, ml and pcs units, in first-appearance order.
- Weight and volume are never converted into each other. Milk in g and milk in ml therefore remain separate entries. Cups, teaspoons, ingredient density, nutritional calculations and free-form recipe parsing are outside this release.
- Requirements are merged and scaled FIRST; stock is subtracted once afterward. Surplus stock and zero requirements are omitted from the shopping list. Fractional counts are permitted; quantities are not rounded to shopping packs.
Ingredient(name, quantity, unit) stores an exact Fraction quantity. *shopping_list(ingredients, , pantry=(), scale=1, aliases=None) returns a list of Ingredient objects. format_quantity() writes terminating decimals exactly and leaves other rational values as fractions.
CLI quantities are strings to preserve exact values and can be read back as input. Original files are not modified. Exit status: 0 on success, 2 on invalid data or unreadable files.
Development
python -m pip install -e .
python -m unittest discover -s tests -v
Metadata
Release files for pantryfold 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pantryfold-0.1.0.tar.gz | 6.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pantryfold-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.8 kB
Release files / pantryfold-0.1.0.tar.gz
| Download URL | pantryfold-0.1.0.tar.gz |
|---|---|
| Size | 6.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
219166aa44dcb4b5432f4e790e5db3748285ab53758133ccd6348456ca9c3da7
|
|
BLAKE2b-256 checksum How to use checksums |
51f4a7e574b37153f14d602781b2fae840ea5c22e80b0518ec13999fefada06f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / pantryfold-0.1.0-py3-none-any.whl
| Download URL | pantryfold-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6816851184facf3b87c951d4507fb2ed9c7a21c8d7a09ef99f939305619ec8a0
|
|
BLAKE2b-256 checksum How to use checksums |
797ccf09a8d80c657c7a933a3a9099e0a117dec3282a7e017f76bcf32262a134
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|