Core
Calculator
Core saponification calculator.
calculate(recipe, *, oil_weight=None, run_validation=True)
Calculate the soap recipe results, including lye, water, and additives.
This function performs the core saponification mathematics. It determines: 1. Lye Amount: Based on the SAP values of the oils and the selected lye type (NaOH, KOH, or Hybrid). 2. Liquids: Calculates water/liquid amount based on the specified mode (ratio, concentration, or % of oils). 3. Additives: Resolves additive amounts and any lye consumption (e.g., for citric acid). 4. Properties: Predicts soap characteristics (hardness, cleansing, etc.) based on fatty acid profiles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
recipe
|
Recipe
|
The completely defined soap recipe. |
required |
oil_weight
|
float
|
An optional override for the total oil weight in grams. If provided, the recipe is scaled to this weight. Defaults to None. |
None
|
run_validation
|
bool
|
If True, runs the |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
RecipeResult |
RecipeResult
|
A dataclass containing all calculation details, including:
- |
Examples:
Models
Core data structures and types.
Additive
Bases: BaseModel
An additive ingredient in a recipe.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the additive. |
amount |
Optional[float]
|
Absolute weight in grams (mutually exclusive with percentage). |
percentage |
Optional[float]
|
Percentage of a base weight (see percent_base). |
percent_base |
PercentBase
|
Which weight the percentage is relative to. |
stage |
Stage
|
Production stage for this additive. |
lye_adjustment |
Optional[float]
|
Manual override for lye consumption. |
notes |
str
|
Optional notes. |
AdditiveInfo
Bases: BaseModel
Database record for an additive with usage and stage info.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the additive. |
category |
str
|
Category (e.g., "Exfoliant", "Colorant"). |
usage |
AdditiveUsage
|
Recommended usage range. |
stage |
str
|
Production stage when the additive is added. |
purpose |
str
|
Brief description of what the additive does. |
lye_adjustment |
float
|
Extra lye consumed per unit (e.g., citric acid). |
notes |
str
|
Optional notes. |
normalize_stage(v)
classmethod
Normalize free-text stage names to Stage enum values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
str
|
Raw stage string from JSON data. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Normalized stage string matching a Stage enum value. |
AdditiveResult
Bases: BaseModel
Calculated result for a single additive, fragrance, or superfat oil.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the ingredient. |
amount |
float
|
Calculated weight in grams. |
stage |
Stage
|
Production stage for this ingredient. |
lye_consumed |
float
|
Extra NaOH consumed by this ingredient (e.g., citric acid). |
notes |
str
|
Optional notes. |
AdditiveUsage
Bases: BaseModel
Recommended usage range for an additive.
Attributes:
| Name | Type | Description |
|---|---|---|
min |
float
|
Minimum recommended amount. |
max |
float
|
Maximum recommended amount. |
unit |
str
|
Unit of measurement (e.g., "tsp"). |
per |
str
|
Weight basis for the rate (e.g., "lb_oils"). |
FattyAcidProfile
Bases: BaseModel
The fatty acid composition of an oil or blend.
Attributes:
| Name | Type | Description |
|---|---|---|
lauric |
float
|
C12:0 — contributes to hardness, cleansing, bubbly lather. |
myristic |
float
|
C14:0 — contributes to hardness, cleansing, bubbly lather. |
palmitic |
float
|
C16:0 — contributes to hardness, stable creamy lather. |
stearic |
float
|
C18:0 — contributes to hardness, stable creamy lather. |
ricinoleic |
float
|
C18:1-OH — conditioning, bubbly, creamy (castor oil). |
oleic |
float
|
C18:1 — conditioning. |
linoleic |
float
|
C18:2 — conditioning. |
linolenic |
float
|
C18:3 — conditioning. |
bubbly
property
Bubbly lather factor (lauric + myristic + ricinoleic).
cleansing
property
Cleansing factor (lauric + myristic).
conditioning
property
Conditioning factor (oleic + linoleic + linolenic + ricinoleic).
creamy
property
Creamy lather factor (palmitic + stearic + ricinoleic).
hard
property
Hardness factor (lauric + myristic + palmitic + stearic).
longevity
property
Longevity factor (palmitic + stearic).
__add__(other)
Combine two fatty acid profiles by summing each acid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
'FattyAcidProfile'
|
The fatty acid profile to add to this one. |
required |
Returns:
| Type | Description |
|---|---|
'FattyAcidProfile'
|
A new FattyAcidProfile with summed values. |
scale(factor)
Scale all fatty acids by a factor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
factor
|
float
|
Multiplicative factor (e.g., 0.5 for 50%). |
required |
Returns:
| Type | Description |
|---|---|
'FattyAcidProfile'
|
A new FattyAcidProfile with scaled values. |
Fragrance
Bases: BaseModel
A fragrance ingredient in a recipe.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the fragrance. |
fragrance_type |
FragranceType
|
Essential oil or fragrance oil. |
amount |
Optional[float]
|
Absolute weight in grams (mutually exclusive with percentage). |
percentage |
Optional[float]
|
Percentage of oil weight. |
max_safe_pct |
Optional[float]
|
IFRA safety limit override. |
stage |
Stage
|
Production stage for this fragrance. |
notes |
str
|
Optional notes. |
Liquid
Bases: BaseModel
A liquid-phase ingredient (water, milk, tea, etc.).
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the liquid. |
percentage |
float
|
Share of the liquid phase (0-100). |
handling_notes |
str
|
Optional preparation notes (e.g., "freeze first"). |
LiquidBreakdown
Bases: BaseModel
Weight breakdown for a single liquid ingredient.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the liquid. |
amount |
float
|
Weight in grams. |
handling_notes |
str
|
Preparation notes (e.g., "freeze first"). |
LyeResult
Bases: BaseModel
Calculated lye amounts for a recipe.
Attributes:
| Name | Type | Description |
|---|---|---|
naoh_amount |
float
|
Grams of NaOH required. |
koh_amount |
float
|
Grams of KOH required. |
total_weight
property
Total combined lye weight in grams.
MoldSpec
Bases: BaseModel
Mold dimensions for batch sizing.
Attributes:
| Name | Type | Description |
|---|---|---|
length |
float
|
Interior length in centimeters. |
width |
float
|
Interior width in centimeters. |
height |
float
|
Interior height in centimeters. |
fill_factor |
float
|
Fraction of mold volume to fill (0.0-1.0). |
estimated_batch_weight
property
Estimate total batch weight assuming oil is approx 65% of total.
volume
property
Interior volume in cubic centimeters.
Oil
Bases: BaseModel
A saponifiable oil or fat with its SAP values and fatty acid profile.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Common name of the oil. |
sap_naoh |
float
|
Grams of NaOH to saponify 1 g of this oil. |
sap_koh |
float
|
Grams of KOH to saponify 1 g of this oil. |
fatty_acids |
FattyAcidProfile
|
Fatty acid composition. |
iodine |
float
|
Iodine value (measure of unsaturation). |
ins |
float
|
INS value. |
notes |
str
|
Optional notes. |
OilEntry
Bases: BaseModel
An oil entry within a recipe, pairing an oil with its blend percentage.
Attributes:
| Name | Type | Description |
|---|---|---|
oil |
Annotated[Oil, WithJsonSchema({'type': 'string'})]
|
The resolved Oil object. |
percentage |
float
|
Percentage of this oil in the blend (0-100). |
PropertyRating
Bases: Enum
Rating for whether a soap property falls within its recommended range.
PropertyValue
Bases: BaseModel
A predicted soap property with its value and acceptable range.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Display name of the property. |
value |
float
|
Predicted numeric value. |
low |
float
|
Lower bound of the recommended range. |
high |
float
|
Upper bound of the recommended range. |
rating |
PropertyRating
|
Whether the value is below, within, or above range. |
Recipe
Bases: BaseModel
A complete soap recipe definition.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Recipe name. |
description |
str
|
Optional description. |
lye_type |
LyeType
|
Alkali type (NaOH, KOH, or Dual). |
naoh_ratio |
float
|
NaOH share for dual-lye recipes (0-100). |
naoh_purity |
float
|
NaOH purity percentage. |
koh_purity |
float
|
KOH purity percentage. |
superfat_pct |
float
|
Lye discount or total superfat percentage. |
water_mode |
WaterCalculationMode
|
How water amount is calculated. |
water_value |
float
|
Numeric value for the chosen water mode. |
liquid_discount_pct |
float
|
Percentage to reduce liquid (for additives that add moisture). |
oils |
List[OilEntry]
|
List of base oils with blend percentages. |
liquids |
List[Liquid]
|
Liquid-phase ingredients. |
additives |
List[Additive]
|
Recipe additives. |
fragrances |
List[Fragrance]
|
Fragrance ingredients. |
superfat_oils |
List[OilEntry]
|
Post-cook superfat oils (HP soap). |
total_oil_weight |
Optional[float]
|
Total oil weight in grams (base + superfat). |
base_oil_weight |
Optional[float]
|
Base oil weight in grams (excludes superfat). |
mold |
Optional[MoldSpec]
|
Optional mold dimensions for batch sizing. |
ignore_warnings |
List[str]
|
Warning codes to suppress. |
notes |
str
|
Free-text notes. |
resolve_oil_weight(override=None)
Determine total oil weight from override, mold, base_oil_weight, or total_oil_weight.
Priority
- Explicit override argument (e.g. from CLI
--oil-weight) - Mold specification
base_oil_weight— back-calculates total using superfat_pcttotal_oil_weight- Fallback: 800 g
RecipeResult
Bases: BaseModel
Complete output of a soap recipe calculation.
Attributes:
| Name | Type | Description |
|---|---|---|
lye |
LyeResult
|
NaOH and KOH amounts. |
total_liquid |
float
|
Total grams of liquid. |
liquid_breakdown |
List[LiquidBreakdown]
|
Per-liquid weight breakdown. |
total_oil_weight |
float
|
Total grams of oil (base + superfat). |
total_batch_weight |
float
|
Final batter weight in grams. |
fatty_acid_profile |
FattyAcidProfile
|
Blended fatty acid profile of the oil mix. |
properties |
SoapProperties
|
Predicted soap quality properties. |
additives |
List[AdditiveResult]
|
Calculated additive results. |
fragrances |
List[AdditiveResult]
|
Calculated fragrance results. |
superfat_oils |
List[AdditiveResult]
|
Calculated post-cook superfat oil results. |
effective_superfat_pct |
float
|
Combined lye discount + superfat oils percentage. |
superfat_analysis |
Optional[SkinFeel]
|
Skin-feel analysis of superfat oils. |
warnings |
List[str]
|
Validation warnings. |
ingredients_by_stage()
Group all ingredients by production stage for instructions.
Returns:
| Type | Description |
|---|---|
Dict[Stage, List[str]]
|
Dictionary mapping each Stage to a list of formatted ingredient strings. |
SkinFeel
Bases: BaseModel
Superfat character profile for post-cook oil blends in soap.
SoapProperties
Bases: BaseModel
Full set of predicted soap properties.
Attributes:
| Name | Type | Description |
|---|---|---|
hardness |
PropertyValue
|
Bar hardness prediction. |
cleansing |
PropertyValue
|
Cleansing strength prediction. |
conditioning |
PropertyValue
|
Skin conditioning prediction. |
bubbly_lather |
PropertyValue
|
Bubbly (big bubble) lather prediction. |
creamy_lather |
PropertyValue
|
Creamy (stable) lather prediction. |
longevity |
PropertyValue
|
Bar longevity prediction. |
iodine |
PropertyValue
|
Iodine value of the oil blend. |
ins |
PropertyValue
|
INS value of the oil blend. |