Skip to main content

plumb

CI Docs

Describe water and wastewater treatment plants as plain, typed Python and get RDF that conforms to the WATR water treatment ontology and ASHRAE 223P, which it builds on. No RDF in user code; real Turtle out.

Bundled ontologies: WATR v0.3.0.rc1 (a release candidate whose terms may still change before 0.3.0), ASHRAE 223P (v1.0.0-2026), and the QUDT units and quantity kinds they use. Domain packages for drinking water, activated sludge (ASM2d), and seawater reverse osmosis come compiled from SHACL.

from plumb import Model, connect, flowsheet
from plumb.qudt import quantity_kinds, units
from plumb.watr import Pump
from plumb.watr.drinking_water import ClarificationStage, CoagulationStage

with Model("urn:example:plant#") as model:
    intake = Pump("intake-pump")
    coagulation = CoagulationStage("coagulation")
    clarifier = ClarificationStage("clarifier")

raw_water = connect(intake, coagulation.inlet, name="raw-water")
connect(coagulation.outlet, clarifier.inlet, name="coagulated-water")
raw_water.sensor("raw-water-flow", kind=quantity_kinds.VolumeFlowRate, unit=units.M3_PER_DAY)

model.save("plant.ttl")      # connection points and pipes are worked out for you
print(model.validate())      # SHACL via shifty; errors name your objects
flowsheet(model).save("plant.svg")

The ontology classes are generated code, so editors and type checkers see everything: completion, ontology definitions on hover, and type errors when a link's range doesn't fit.

Saved models load back as the same objects, and can be searched by class, medium, or role, or walked along the flow:

from plumb.watr import enums

plant = Model.from_graph("plant.ttl")
plant["intake-pump"].find_all_next(through={"medium": enums.values.Fluid_Water})

Install and run the examples

Plumb requires Python 3.12 or newer. From a checkout of this repository, install the project and its dependencies with uv:

uv sync

Then run an example from the repository root:

uv run python examples/watr/treatment/watr_quickstart.py
uv run python examples/watr/asm2d/watertap_asm2d.py
uv run python examples/watr/seawater_ro/watertap_seawater_ro_full.py

Each example prints a short summary and writes its generated Turtle file next to the example script. See examples/ for more scenarios.

Domain configurations and quantities

Reusable equipment layouts and property metadata are defined in RDF and SHACL. The compiler generates typed configurations and immutable value schemas:

from plumb.qudt import QuantityAmount as Q, units
from plumb.watr.asm2d import AerobicStage, AerobicDesign, OxygenOutletState

with Model("urn:example:reactor#") as model:
    reactor = AerobicStage("R5")
    reactor.apply_properties(AerobicDesign(oxygen_transfer_coefficient=10.0))
    reactor.outlet.apply_properties(
        OxygenOutletState(oxygen_concentration=Q(1.91, units.GM_PER_M3))
    )

Bare values use shape-declared units; explicit quantities preserve their units. The same apply_properties(...) API works on equipment, points, and connections. Use subject.quantity(...) for individual values. capability= selects static, observable, or actuatable properties; has_aspect= supplies their interpretation.

See domain extensions, the ASM2d tutorial, and the extension compiler reference. Regenerate the supplied domains with uv run python scripts/generate_example_domains.py.

Development

The Makefile wraps the standard development commands:

make setup          # install development and documentation dependencies
make check          # lint, type checks, and tests
make docs           # build the documentation and execute tutorials
make docs-open      # build and open the HTML documentation
make docs-check     # full documentation build; warnings are errors
make build          # source distribution and wheel, replacing dist/
make dist-check     # build, check metadata, and smoke-test the wheel
make regen          # regenerate the supplied domain packages from local SHACL
make help           # all available targets

Use make test TEST_ARGS="-q tests/test_named_points.py" to select tests. make format formats source while excluding generated ontology output. make clean removes documentation, build output, and tool caches. To release, bump version in pyproject.toml, date the release in CHANGELOG.md, tag the commit v<version>, and publish a GitHub release from the tag. The release workflow runs the checks, builds the distributions, publishes them to PyPI, and attaches them to the release.

To regenerate the committed ontology packages, see docs/codegen.md.

Metadata

Release files for plumb-rdf 0.1.0

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

Source distribution (sdist)

Source distribution for plumb-rdf 0.1.0
File Size Uploaded Provenance
plumb_rdf-0.1.0.tar.gz 2.6 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for plumb-rdf 0.1.0
File Interpreter ABI Platform
plumb_rdf-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 5.2 MB

Release files / plumb_rdf-0.1.0.tar.gz

Download URL plumb_rdf-0.1.0.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
d8199ebeb0ffbb757485b10bb412e0e541e9c56a90159f2e868f6339e38225db
BLAKE2b-256 checksum
How to use checksums
b10f6c427eb7777d4f60aa547b0b32e06e68cada8fc19ce624b989897401c757
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / plumb_rdf-0.1.0-py3-none-any.whl

Download URL plumb_rdf-0.1.0-py3-none-any.whl
Size 2.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
baa37f9c6ca04965bfb257ecc9463686c3a6fa870a3a4989bea66c252d636184
BLAKE2b-256 checksum
How to use checksums
1826c7f72d55ec1d40f6a2e769a2b2e4ac290080f4594658dab6ca836153b9f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for plumb-rdf 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for plumb_rdf-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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