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.3 supported-consumer-API 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.

Python 3.11 is the project compatibility baseline, with CI coverage through Python 3.14. Public APIs remain pre-1.0 and may evolve as real consumer applications exercise the engine.

Version 0.3 establishes a supported package-root consumer facade covering both the deterministic forward-result graph and the complete source-reporting and provenance input graph. Its compatibility expectations are documented in the consumer API guide. Reported and target pH use FermUnits' semantic PHValue; calculated working-water pH remains explicitly deferred until a validated reusable model is ready.

Forward-calculator capabilities established 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.3

  • 0.4: curated target/reference profiles and practical treatment materials;
  • 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==0.3.0

or:

python -m pip install water-chemistry-engine==0.3.0

Version 0.3 exposes a supported package-root facade. APIs remain pre-1.0 and may evolve under the consumer API compatibility policy.

Quickstart

This example resolves and blends equal volumes of two reported source waters. Calcium therefore blends from 40 mg/L and 80 mg/L to 60 mg/L:

from fermunits import Q_

from water_chemistry_engine import (
    ForwardWaterSource,
    Ion,
    IonConcentration,
    SourceResolutionPolicy,
    SourceWaterProfile,
    calculate_forward_water,
)

source_a = SourceWaterProfile(
    name="Source A",
    concentrations=(IonConcentration.mg_per_liter(Ion.CALCIUM, 40.0),),
)
source_b = SourceWaterProfile(
    name="Source B",
    concentrations=(IonConcentration.mg_per_liter(Ion.CALCIUM, 80.0),),
)

result = calculate_forward_water(
    (
        ForwardWaterSource(source_a, Q_(1.0, "liter")),
        ForwardWaterSource(source_b, Q_(1.0, "liter")),
    ),
    source_resolution_policy=SourceResolutionPolicy(allow_exact_range_midpoints=False),
)

calcium = result.final_state.concentration_for(Ion.CALCIUM)
assert calcium is not None
print(calcium)

Expected output:

60.0 milligram / liter

The explicit source-resolution policy prevents the example from silently choosing representative values for ranges. See the consumer API guide for the complete supported workflow, including treatments, targets, notices, and audit results.

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;
  • CONSUMER_API.md — supported 0.3 package-root facade and integration guide;
  • 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.3.0.tar.gz (39.6 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.3.0-py3-none-any.whl (55.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: water_chemistry_engine-0.3.0.tar.gz
  • Upload date:
  • Size: 39.6 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.3.0.tar.gz
Algorithm Hash digest
SHA256 d309c1d1b7768b0eb46518c6bec28c03d30b34109263f3b62fd878ca7e649498
MD5 a852bc14637cc1b6638ece1245ef131f
BLAKE2b-256 501c14fd869545d72cb86cb7f081aae549b0a1b97cfb9e3fd01bf57a31acd226

See more details on using hashes here.

Provenance

The following attestation bundles were made for water_chemistry_engine-0.3.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.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for water_chemistry_engine-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 def4dc18c7c120a3a9984cf51749d082643c82fae9d3e43de55bfa3446964811
MD5 1cbd5e69e8ead0ae2440675e1f33c2ce
BLAKE2b-256 ec575bcc4964713dc41be833fe038d73265d29906fc8aab0767efee06122b66f

See more details on using hashes here.

Provenance

The following attestation bundles were made for water_chemistry_engine-0.3.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

This release

0.3.0 This release

2 files

0.2.0

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