Skip to main content

Water Chemistry Engine

A reusable, scientifically grounded Python engine for characterizing, blending, treating, comparing, and eventually optimizing water for brewing, fermentation, and other validated uses.

The engine is intentionally independent of web frameworks, databases, graphical interfaces, and product-specific persistence. End-user applications consume this package from separate projects.

Project status

The 0.2 deterministic forward-calculator milestone is complete. The engine can resolve reported source-water chemistry, blend multiple characterized sources, apply supported mineral additions, calculate the resulting water, compare it with target/reference criteria, and return auditable contribution, instruction, and notice data.

Version 0.2 also establishes Python 3.11 as the compatibility baseline, with CI coverage on Python 3.11 through 3.14. Public APIs remain pre-1.0 and may evolve as real consumer applications exercise the engine.

Implemented in 0.2

  • source-water and target/reference profile models;
  • preservation of exact values, ranges, bounds, ND, reported statistics, reporting context, source-document metadata, and chlorine/chloramine data;
  • explicit source-resolution policy, including opt-in exact-range midpoints;
  • fixed multi-source blending with conservative unknown propagation;
  • supported mineral-addition stoichiometry and deterministic treatment;
  • source, blend, and final target/reference comparison;
  • combined source/treatment ion-contribution reporting;
  • structured preparation instructions;
  • structured notices for assumptions, unresolved inputs, model limitations, and deferred target-pH calculation.

Planned after 0.2

  • 0.3: supported consumer-facing Python API and integration examples;
  • 0.4: curated target/reference profiles;
  • 0.5–0.6: automatic and ranked treatment optimization;
  • 0.7: reusable working-water pH if a defensible model is ready;
  • 0.8: BeerJSON/FermentationJSON interchange, conformance work, and 1.0 hardening.

AI-assisted document ingestion, accounts, persistence, browser UI, and native application code belong to separate consumer applications rather than this repository.

Repository structure

water-chemistry-engine/
├── src/
│   └── water_chemistry_engine/
├── tests/
├── docs/
├── reference-data/
├── schemas/
├── scripts/
└── test-vectors/

src/water_chemistry_engine

The importable Python engine package, using the standard src/ layout. It owns scientific calculations, domain models, validation, warnings/notices, optimization as it is added, and structured calculation results.

External applications such as web, automation, Mechani-Brew, and future native clients can consume the engine while providing their own interfaces and persistence.

Installation

Water Chemistry Engine requires Python 3.11 or newer. Install the published package with uv or pip:

uv add water-chemistry-engine

or:

python -m pip install water-chemistry-engine

Version 0.2 exposes useful module-level APIs for calculations and domain models. These APIs remain pre-1.0 and may evolve as the supported consumer-facing API is formalized in milestone 0.3.

Quickstart

This example blends equal volumes of two already-resolved water states. Calcium therefore blends from 40 mg/L and 80 mg/L to 60 mg/L:

from fermunits import Q_

from water_chemistry_engine.blending import BlendSource, blend_waters
from water_chemistry_engine.chemical_state import (
    AqueousChemicalState,
    DerivedIonConcentration,
)
from water_chemistry_engine.ions import Ion

source_a = AqueousChemicalState(
    concentrations=(DerivedIonConcentration.mg_per_liter(Ion.CALCIUM, 40.0),)
)
source_b = AqueousChemicalState(
    concentrations=(DerivedIonConcentration.mg_per_liter(Ion.CALCIUM, 80.0),)
)

blend = blend_waters(
    (
        BlendSource("Source A", source_a, Q_(1.0, "liter")),
        BlendSource("Source B", source_b, Q_(1.0, "liter")),
    )
)

calcium = blend.state.concentration_for(Ion.CALCIUM)
assert calcium is not None
print(calcium)

Expected output:

60.0 milligram / liter

Reported source-water values should normally be passed through the engine's explicit source-resolution workflow before blending. The example starts from resolved states to keep the first installed-package example focused.

Development stack

  • Python 3.11+ (CI tests 3.11–3.14; 3.11 is the compatibility baseline)
  • uv
  • FermUnits
  • pytest and Hypothesis
  • Ruff
  • mypy
  • GitHub Actions

Development

Install uv, then run from the repository root. The checked-in .python-version selects the Python 3.11 compatibility baseline:

uv sync --dev
uv run pytest

The full CI gate tests Python 3.11, 3.12, 3.13, and 3.14. It also checks the lockfile, formatting, linting, strict typing against Python 3.11 semantics, and builds the engine distribution.

Documentation

Primary project documents are stored under docs/:

  • WATER_CHEM_DESIGN.md — scientific and architectural design;
  • WATER_CHEM_REFERENCES.md — source and reference register;
  • ROADMAP.md — active engine release path;
  • PROJECT_STRUCTURE.md — repository/package boundaries;
  • reviews/ — point-in-time external review records.

Release history is summarized in CHANGELOG.md.

License

This project is licensed under the Mozilla Public License 2.0.

Download files

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

Source Distribution

water_chemistry_engine-0.2.0.tar.gz (38.0 kB view details)

Uploaded Source

Built Distribution

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

water_chemistry_engine-0.2.0-py3-none-any.whl (53.3 kB view details)

Uploaded Python 3

File details

Details for the file water_chemistry_engine-0.2.0.tar.gz.

File metadata

  • Download URL: water_chemistry_engine-0.2.0.tar.gz
  • Upload date:
  • Size: 38.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for water_chemistry_engine-0.2.0.tar.gz
Algorithm Hash digest
SHA256 650acc0a21bde92d140b21c9f87208dcb3b82547953294542bffeb0fc955e7f1
MD5 91a7efa31f91b97e27b225ac6d592aab
BLAKE2b-256 87caf92a79fb2f6cf5b4c12871329d8c32a42bd5474e2aa96560307c79885fcf

See more details on using hashes here.

Provenance

The following attestation bundles were made for water_chemistry_engine-0.2.0.tar.gz:

Publisher: release.yml on GregRR/water-chemistry-engine

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

File details

Details for the file water_chemistry_engine-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for water_chemistry_engine-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4dfb0558e69c83de968fb95eeb42810be138ad29c0346c9934181c56ebd66ca1
MD5 a4875983dad30005e84a2a4110866d18
BLAKE2b-256 bf5727e0c91ed5a728ce191bb291462148314c0d5af6b819689c48b9c20a951c

See more details on using hashes here.

Provenance

The following attestation bundles were made for water_chemistry_engine-0.2.0-py3-none-any.whl:

Publisher: release.yml on GregRR/water-chemistry-engine

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

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.0 This release

2 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