Metadata-Version: 2.4
Name: shrine
Version: 0.2.0
Summary: SHRINE — Simulation of Hydrology, Reservoirs, and Integrated Network Engine
Author: Jason Lillywhite
License-Expression: MIT
Project-URL: Homepage, https://github.com/jlillywh/SHRINE
Project-URL: Documentation, https://jlillywh.github.io/SHRINE/
Project-URL: Repository, https://github.com/jlillywh/SHRINE
Project-URL: Issues, https://github.com/jlillywh/SHRINE/issues
Project-URL: Changelog, https://github.com/jlillywh/SHRINE/blob/master/CHANGELOG.md
Project-URL: Contributing, https://github.com/jlillywh/SHRINE/blob/master/CONTRIBUTING.md
Project-URL: CodeOfConduct, https://github.com/jlillywh/SHRINE/blob/master/CODE_OF_CONDUCT.md
Project-URL: Governance, https://github.com/jlillywh/SHRINE/blob/master/GOVERNANCE.md
Project-URL: Security, https://github.com/jlillywh/SHRINE/blob/master/SECURITY.md
Keywords: hydrology,water-resources,simulation,reservoir,watershed
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: networkx>=3.0
Requires-Dist: numpy
Requires-Dist: pandas
Requires-Dist: openpyxl>=3.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: pint>=0.23
Requires-Dist: iapws>=1.2
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pre-commit>=3.0; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Requires-Dist: types-PyYAML; extra == "dev"
Requires-Dist: pandas-stubs; extra == "dev"
Requires-Dist: types-networkx; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Provides-Extra: viz
Requires-Dist: matplotlib>=3.7; extra == "viz"
Provides-Extra: hydrology
Requires-Dist: hydrofunctions>=0.2.4; extra == "hydrology"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocstrings[python]>=0.27; extra == "docs"
Dynamic: license-file

[![PyPI version](https://img.shields.io/pypi/v/shrine.svg)](https://pypi.org/project/shrine/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)

# SHRINE

**S**imulation of **H**ydrology, **R**eservoirs, and **I**ntegrated **N**etwork **E**nvironments..

Open-source integrated water-resources modeling library (Python). SHRINE combines legacy domain modules (hydrology, storage, flow networks) with **`shrine.simulation`** for calendar-driven runs, mass balance, scenario files, and structured outputs.

Naming details: [docs/project-name.md](docs/project-name.md).

## Simulation framework (`shrine.simulation`)

The framework is the **only supported path** for new model runs. Import from the package root:

```python
import shrine.simulation as sim
# or
from shrine.simulation import Model, RunController, Clock, WatershedElement
```

**Package versions:** `shrine.__version__` (distribution) and `shrine.simulation.__api_version__` (stable simulation API surface, currently **1.0**). Stability and deprecation rules: [docs/api-stability.md](docs/api-stability.md). Release history: [CHANGELOG.md](CHANGELOG.md); SemVer and maintainer checklist: [docs/releases.md](docs/releases.md). Submodules outside `__all__` are internal unless noted in [extending-elements.md](docs/extending-elements.md).

### Public API

| Category | Symbols |
|----------|---------|
| **Run** | `Model`, `RegisteredElement`, `RunController`, `RunResult`, `RunSession`, `StepResult`, `ElementScheduler` |
| **Time** | `Clock`, `RunContext`, `TimestepContext` |
| **Elements** | `Simulatable`, `WatershedElement`, `CatchmentElement`, `ReservoirElement`, `ClimateRecorderElement`, `StorageLike` |
| **Inputs** | `InputManager`, `InputProvider`, `ConstantInput`, `MonthlyLookupInput`, `StochasticInput` |
| **Flow / balance** | `FlowSolver`, `NetworkXFlowSolver`, `FlowSolveResult`, `MassBalanceCheck`, `MassBalanceReport`, `MassBalanceTerm` |
| **Outputs / scenarios** | `Recorder`, `ScenarioConfig`, `load_scenario_file`, `run_scenario`, `run_scenarios`, `load_and_run` |
| **Metadata / RNG** | `build_run_metadata`, `enrich_run_metadata`, `RunTimer`, `make_rng` |
| **Deprecation** | `warn_api_deprecated` |
| **Errors** | `SimulationError`, `SimulationPhase` |

Capabilities:

- **`Model`** — register elements (watersheds, reservoirs, custom types) with a shared `Clock`
- **`RunController`** — validate → initialize → timestep loop → finalize
- **`InputManager`** — constant, monthly, and stochastic inputs bound by name
- **`Recorder`** — wide `pandas` DataFrame outputs per run
- **Scenarios** — YAML/JSON clock, inputs, and parameter overrides
- **Flow solve** — NetworkX max-flow on graphs owned by `Watershed` adapters
- **Mass balance** — per-timestep verification with `SimulationError` diagnostics

Requirements and phased delivery: [docs/simulation-framework-requirements.md](docs/simulation-framework-requirements.md). Layer diagram: [docs/architecture.md](docs/architecture.md).

## Project layout

| Area | Description |
|------|-------------|
| `src/shrine/simulation/` | Framework: clock, model, run controller, inputs, recorder, scenarios |
| `src/hydrology/` | Catchments, watersheds, networks |
| `src/water_manage/` | Storage, flow networks, operating rules |
| `src/inputs/`, `src/results/` | Tables, time series, `TimeHistory`, charts |
| `examples/` | Runnable demos (climate, watershed, scenarios, stepping) |
| `tests/simulation/` | Framework unit and acceptance tests |
| `docs/` | Guides (see below) |

Library code is under `src/`; run `pip install -e ".[dev]"` before tests or scripts (see [docs/testing.md](docs/testing.md)).

## Prerequisites

- Python **3.10+**
- WSL/Linux or Windows with WSL recommended for `./scripts/run_tests.sh`

## Install

**PyPI:** `pip install shrine` — see [docs/install.md](docs/install.md) (extras, PEP 668, wheel vs clone). **Development:** clone + editable install below.

### From PyPI

```bash
pip install shrine
pip install "shrine[dev,viz,hydrology]"
```

The PyPI wheel includes Python packages and `examples/`; **clone the repo** for bundled `scenarios/` and `./scripts/run_tests.sh`.

### From source *(development)*

```bash
git clone https://github.com/jlillywh/SHRINE.git
cd SHRINE
bash scripts/bootstrap_venv.sh    # .venv + pip install -e ".[dev]"
```

Contributors (tests + plotting + NWIS demo):

```bash
.venv/bin/python3 -m pip install -e ".[dev,viz,hydrology]"
```

On Ubuntu/WSL, use `.venv/bin/python3` and `.venv/bin/pip` — system `pip install` is blocked (PEP 668). See [docs/install.md](docs/install.md).

### Optional dependency extras

Defined in `pyproject.toml` under `[project.optional-dependencies]`. Same extra names for source and PyPI.

| Extra | Purpose | Source | PyPI |
|-------|---------|--------|------|
| *(none)* | Core runtime | `pip install -e .` | `pip install shrine` |
| `dev` | pytest, mypy, ruff, pre-commit | `pip install -e ".[dev]"` | `pip install "shrine[dev]"` |
| `docs` | MkDocs site | `pip install -e ".[docs]"` | `pip install "shrine[docs]"` |
| `viz` | matplotlib | `pip install -e ".[viz]"` | `pip install "shrine[viz]"` |
| `hydrology` | NWIS demo (`examples/nwis_streamflow.py`) | `pip install -e ".[hydrology]"` | `pip install "shrine[hydrology]"` |

**Recommended for contributors:**

```bash
pip install -e ".[dev,viz,hydrology]"
```

**Framework-only CI** (matches `./scripts/run_tests.sh`):

```bash
pip install -e ".[dev]"
```

## Run tests

```bash
./scripts/run_tests.sh
```

Or manually:

```bash
pytest tests/ -v
pytest tests/simulation --cov=shrine.simulation --cov-report=term-missing
```

See [docs/testing.md](docs/testing.md) for layout and troubleshooting (WSL sync, venv, etc.).

## Secrets and credentials

Do **not** commit API keys or `.env` files. Use `GOOGLE_MAPS_API_KEY` for the optional Maps demo, or a local gitignored `data_external/apikey.txt` (see `data_external/apikey.txt.example`). Full guidance: **[docs/secrets-and-repo-hygiene.md](docs/secrets-and-repo-hygiene.md)**. Optional local hook (with venv activated): `pip install -e ".[dev]" && pre-commit install` — gitleaks on commit; CI runs the same scan on push/PR.

## Examples

From the repo root with the venv activated:

```bash
# Climate inputs via framework (no Excel)
python examples/climate_loop.py

# Two catchments → junction → flow solve
python examples/watershed_run.py

# Single catchment, rational runoff (no network)
python examples/catchment_run.py

# Scenario file (JSON/YAML)
python examples/run_from_scenario.py scenarios/baseline_watershed.json

# Tutorial: watershed + monthly scenario + plot (roadmap 3.3)
python examples/tutorial_watershed.py --no-show --output tutorial_plot.png

# Single-timestep debugging
python examples/step_debug.py

# Minimal custom element
python examples/custom_element.py

# USGS NWIS fetch (optional: pip install -e ".[hydrology]")
python examples/nwis_streamflow.py
```

Bundled scenarios: `scenarios/baseline_watershed.json`, `scenarios/wet_year.yaml`.

## Documentation

**Online docs:** [https://jlillywh.github.io/SHRINE/](https://jlillywh.github.io/SHRINE/) (GitHub Pages — enable *Settings → Pages → GitHub Actions* after the first `Docs` workflow run on `master`).

Build locally:

```bash
pip install -e ".[docs]"
mkdocs serve          # http://127.0.0.1:8000
# or: ./scripts/build_docs.sh
```

| Guide | Topic |
|-------|--------|
| [Architecture](https://jlillywh.github.io/SHRINE/architecture/) | **Framework vs domain vs adapters** (diagrams) |
| [Comparison with other tools](https://jlillywh.github.io/SHRINE/comparison/) | SHRINE vs PySWMM, WEAP, ResSim, Spotpy, … (honest scope) |
| [docs/project-name.md](docs/project-name.md) | **SHRINE** naming and acronym |
| [docs/modernization-roadmap.md](docs/modernization-roadmap.md) | Strategic checklist: pythonic OOP, OSS excellence |
| [docs/api-stability.md](docs/api-stability.md) | SemVer, deprecation cycle, public API policy |
| [CHANGELOG.md](CHANGELOG.md) | Release history ([Keep a Changelog](https://keepachangelog.com/)) |
| [GOVERNANCE.md](GOVERNANCE.md) | Maintainer, release manager, lazy consensus |
| [SECURITY.md](SECURITY.md) | Vulnerability reporting and supported versions |
| [docs/releases.md](docs/releases.md) | Versioning policy and maintainer release checklist |
| [docs/simulation-framework-requirements.md](docs/simulation-framework-requirements.md) | Architecture decisions and requirements |
| [docs/extending-elements.md](docs/extending-elements.md) | Adding new `Simulatable` elements |
| [docs/scenarios.md](docs/scenarios.md) | Scenario YAML/JSON |
| [docs/step-debugging.md](docs/step-debugging.md) | `RunController.step()` API |
| [docs/results-recording.md](docs/results-recording.md) | `Recorder` and `TimeHistory` |
| [docs/install.md](docs/install.md) | **Install** — source vs PyPI, extras, PEP 668, wheel vs clone |
| [docs/testing.md](docs/testing.md) | Test suite and CI-style local runs |
| [docs/secrets-and-repo-hygiene.md](docs/secrets-and-repo-hygiene.md) | API keys, `.env`, history purge if a secret was committed |

## Quick API sketch

```python
from shrine.simulation import (
    Clock,
    ConstantInput,
    InputManager,
    Model,
    RunController,
    WatershedElement,
)
from hydrology.watershed import Watershed

ws = Watershed()
ws.add_junction("J1", "sink")
ws.link_catchment("C1", "J1")

model = Model(clock=Clock("1/1/2019", "1/15/2019"))
model.register_watershed("basin", WatershedElement(ws, element_id="basin"))

inputs = InputManager()
inputs.bind("precipitation", ConstantInput(10.0))
inputs.bind("evaporation", ConstantInput(1.0))

result = RunController(model, input_manager=inputs, seed=42).run()
print(result.outputs.head())
```

Legacy scripts (e.g. `global_attributes/test_model.py`) remain for reference; prefer `examples/climate_loop.py` and the framework APIs for new work.

## Contributing

We welcome issues and pull requests. See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, tests, and PR workflow. Please follow the [Code of Conduct](CODE_OF_CONDUCT.md).

## License

MIT License — see [LICENSE](LICENSE).
