Skip to main content

aquaswmm

A free, open-source (GPL) Python library for EPA SWMM models and storm sewer hydraulics: edit .inp files by table and column, run the EPA engine, read .rpt/.out results, and size pipes with the Rational method, Manning, standard-step HGL/EGL backwater and HEC-22 inlets. A native extension built from Rust, with no Python dependencies and no server.

The library is free to use for any purpose. It shares its readers and engine with the AquaSWMM desktop app, a separate paid product (aquaswmm.com). Nothing here needs the app or a license.

pip install aquaswmm

SWMM models: edit, run, read results

The same readers the AquaSWMM desktop app uses, so a script and the app agree on column names, run validity, and every number read back.

import aquaswmm as aq
import pandas as pd

m = aq.Model.open("site.inp")
pd.DataFrame(m.table("CONDUITS"))          # every row, by column name
m.get("CONDUITS", "C1", "Roughness")       # '0.013'
m.set("CONDUITS", "C1", "Roughness", 0.015)
m.set_option("ROUTING_STEP", "0:00:05")
m.rename("node", "J1", "MH-101")           # and every reference to it
m.validate()                               # the app's model checks

run = m.run("site_n015.inp")               # saves, then runs EPA SWMM
if not run.ok:
    print(run.problem)                     # failed, or blew up (NOT VALID)
run.continuity                             # {'Flow Routing Continuity': 0.015, ...}

res = run.results()                        # or aq.Results("site.out")
pd.DataFrame(res.node_peaks())             # max depth, inflow, flooding
res.link_series("C1", "flow")              # {'time_s': [...], 'value': [...]}
pd.DataFrame(res.froude())                 # Froude at peak flow and max

rep = run.report()                         # or aq.Report("site.rpt")
pd.DataFrame(rep.table("Node Depth Summary"))

Model values are strings, exactly as written in the file: a model keeps every line you did not edit byte for byte, comments and spacing included. aq.engines() lists the EPA SWMM engines found on the machine (set AQUASWMM_SWMM_ENGINE_DIR to add one); run(..., engine=<id>) picks one by the id it lists. A run that fails is returned, not raised — check run.ok.

Inside the desktop app, Tools → Python Terminal binds the current run as m, res and report when this package is installed in that Python.

Site flood forecasts

aquaswmm.forecast keeps a SWMM model running continuously so it carries antecedent conditions (soil moisture, water table, pond levels) from one day to the next, forces it with NOAA MRMS radar rain and HRRR / GEFS forecast rain, corrects it with USGS observations through an ensemble Kalman filter, and reports the probability of exceeding site thresholds.

pip install "aquaswmm[forecast]"     # numpy + eccodes for GRIB2
from aquaswmm.forecast import read_hotstart, spinup, advance

h = read_hotstart("end.hsf", "site.inp")   # SWMM 5.2 hotstart, read against its model
h.variables("groundwater", "S1")           # theta, water_table, flow, max_infil_vol
h.set("node", "Pond", "depth", 3.0, model_units=True)
h.write("edited.hsf")                      # unedited files round-trip byte for byte

s = spinup("site.inp", start, end, rain, runs_dir="runs")   # cold start -> hotstart
s = advance(s, datetime.timedelta(hours=6), rain, runs_dir="runs")

The scheduled job is driven by one TOML site file:

python -m aquaswmm.forecast example > site.toml
python -m aquaswmm.forecast spinup site.toml     # chain observed rain from [spinup] start
python -m aquaswmm.forecast run site.toml        # advance, assimilate, forecast
python -m aquaswmm.forecast hindcast site.toml   # replay past dates, Brier scores

run writes forecast.json, forecast.csv and forecast.html with each threshold's probability of exceedance and first-exceedance times. Hotstart files, continuous runs and the products need only the standard library; GRIB2 decoding and the filter need the forecast extra. The full description, data sources and limits are in the Site forecasts chapter of the manual.

Storm sewer primitives

Float in, float out. Useful for replacing a spreadsheet column.

import aquaswmm as ss

ss.intensity(60, 10, 0.8, 12)          # IDF: i = a/(t+b)^c  ->  5.0607 in/hr
ss.rational_q(0.70, 5.0607, 1.0)       # Q = C i A           ->  3.5425 cfs
ss.manning_capacity(1.25, 0.013, 0.005)  # just-full capacity ->  4.5801 cfs
ss.normal_depth(3.5425, 1.25, 0.013, 0.005)  # -> 0.8254 ft (None if it won't fit)
ss.critical_depth(3.5425, 1.25)
ss.circular_geometry(1.25, 0.8254)
# {'area': 0.8597, 'wetted_perimeter': ..., 'hydraulic_radius': ..., 'top_width': ...}

Pass si=True for metric: the Manning factor becomes 1.0 and g becomes 9.81.

ss.manning_capacity(0.4, 0.013, 0.005, si=True)   # m3/s

Whole networks

import aquaswmm as ss
import pandas as pd

result = ss.analyze_project(ss.demo_project_json())

pipes = pd.DataFrame(result["pipes"])
print(pipes[["id", "design_q", "capacity", "pct_full", "velocity", "hgl_up"]])

nodes = pd.DataFrame(result["nodes"])
print(nodes[nodes.floods])          # anything surcharging to the surface

analyze_file("project.ssproj") reads a file saved by the desktop app, and analyze_ssn(text) takes the plain-text network format:

ss.analyze_ssn("""
IDF        60 10 0.8
TAILWATER  100.5
MINTC      10

NODE N1   inlet    0    0  104.0  110.0  1.0  0.70  12
NODE OUT  outfall  300  0  102.5  108.5

PIPE P1   N1  OUT  300  1.25  0.013
""")

Each pipe dict carries id, from, to, slope, total_ca, tc, travel_time, intensity, design_q, capacity, pct_full, velocity, normal_depth, critical_depth, hgl_up, hgl_dn, and surcharged. Each node dict carries id, tc, rim, hgl, freeboard, and floods.

Constants

K_MANNING_US (1.486), K_MANNING_SI (1.0), G_US (32.2), G_SI (9.81).

The engine uses K = 1.486, the exact unit conversion, matching Autodesk Hydraflow and HEC-22 rather than the rounded 1.49 some spreadsheets use, a 0.27% difference in capacity. The validation page works every number on a reference network by hand.

What this is not

It computes the published equations; it does not decide whether the Rational method suits your site, what C to use, or which storm to design for. Those stay with the engineer sealing the drawing.

License

GPL-3.0-or-later, like the AquaSWMM engine.

Metadata

Release files for aquaswmm 0.12.2

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

Source distribution (sdist)

Source distribution for aquaswmm 0.12.2
File Size Uploaded Provenance
aquaswmm-0.12.2.tar.gz 2.8 MB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for aquaswmm 0.12.2
File Interpreter ABI Platform
aquaswmm-0.12.2-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
aquaswmm-0.12.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
aquaswmm-0.12.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64), macOS 11.0+ ARM64, macOS 10.12+ x86-64 Details

Total release size: 7.0 MB

Release files / aquaswmm-0.12.2.tar.gz

Download URL aquaswmm-0.12.2.tar.gz
Size 2.8 MB
Tags Source
SHA-256 checksum
How to use checksums
89594907129b8c6fed9505174dab5881d4924e6115908bed10079e1cc6c92a2d
BLAKE2b-256 checksum
How to use checksums
d39c1e39d76eb99bba8c7ea666cc1c5671df3f78bb92948538296347da75eff2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 2, 2026.

Transparency log

Release files / aquaswmm-0.12.2-cp39-abi3-win_amd64.whl

Download URL aquaswmm-0.12.2-cp39-abi3-win_amd64.whl
Size 1.7 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
0694b34275a0d61f37b6eebf821b4739ba5b980d0e0f43356a186c38aff72da0
BLAKE2b-256 checksum
How to use checksums
b456a6e7bab09b123802496b34d164c0c7c5613e7c6201f85611ca8c28505ebb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 2, 2026.

Transparency log

Release files / aquaswmm-0.12.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL aquaswmm-0.12.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 969.8 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
3265559d442c02ba55dad9877bfcb0e245100db270093206c2c3e8db272146d2
BLAKE2b-256 checksum
How to use checksums
8de33b6291e1d3e63d5d03bb3001fcdb8a7b9d8119cbe95ea84d5cd8f1a4c5a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 2, 2026.

Transparency log

Release files / aquaswmm-0.12.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL aquaswmm-0.12.2-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 1.5 MB
Tags CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
e6a9d63a430d925d838fa1c11b7b88e682986e7b19b52f1240c2e6ddd31f025f
BLAKE2b-256 checksum
How to use checksums
3d9017358d9e726b5f1852afd17bf5ae8d20afcff3b45cfcab98a900296180a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 2, 2026.

Transparency log

Security for aquaswmm 0.12.2

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 4 files in this release have been uploaded with provenance metadata.

Select from 4 files

Attestation for aquaswmm-0.12.2.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 2, 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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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