Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to the RnR Test API #846

Closed
wants to merge 64 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
c22c82a
migrated fastapi wrapper to the troute branch
taddyb Aug 21, 2024
43d4489
Merge pull request #1 from taddyb33/migration
taddyb Aug 24, 2024
c7cc896
ensuring this dir is here
taddyb Aug 24, 2024
a2c826f
added restart files to remove dry conditions for RFC routing
taddyb Aug 24, 2024
4eba8a9
Merge branch 'development' of https://github.com/taddyb33/t-route-dev…
taddyb Aug 24, 2024
60f2c7c
Merge pull request #2 from taddyb33/migration
taddyb Aug 24, 2024
7306c68
Added docs for t-route api release
taddyb Sep 3, 2024
60986b8
Merge branch 'development' of https://github.com/taddyb33/t-route-dev…
taddyb Sep 3, 2024
510386e
linted code?
taddyb Sep 3, 2024
3dfb149
Merge pull request #3 from taddyb33/migration
taddyb Sep 3, 2024
0a6f481
added test files
taddyb Sep 3, 2024
627d57f
Merge pull request #4 from taddyb33/test_docs
taddyb Sep 3, 2024
2cf4c3f
added author name in app/main.py, added specifics to testing README f…
taddyb Sep 6, 2024
81fe066
changed port from 8004 to 8000
taddyb Sep 6, 2024
d0f8575
added the lower colorado forcing and domain files into the api test
taddyb Sep 6, 2024
35e4b6c
Merge branch 'NOAA-OWP:master' into development
taddyb Sep 9, 2024
ffb9f96
if the folder doesn't exist
AminTorabi-NOAA Aug 30, 2024
b28544f
handling edge cases
AminTorabi-NOAA Sep 5, 2024
2ecd279
Update readme.md: removed obsolete no-e option (#843)
JurgenZach-NOAA Sep 6, 2024
2deff3c
Speeding up writing output (#841)
AminTorabi-NOAA Sep 6, 2024
51b2253
Merge branch 'rebase' of https://github.com/taddyb33/t-route-dev into…
taddyb Sep 9, 2024
b3960e0
removing lower colorado duplicated data
taddyb Sep 9, 2024
5e1a004
Merge pull request #5 from taddyb33/rebase
taddyb Sep 9, 2024
884c101
Delete data/troute_restart/.gitkeep
Oct 7, 2024
ea96782
completed general PR comments and formatting
taddyb Oct 7, 2024
7e5dc45
Merge branch 'development' of https://github.com/taddyb33/t-route-dev…
taddyb Oct 7, 2024
4fc70fa
added general LowerColorado Test case for API
taddyb Oct 9, 2024
8ca681a
reorganized dockerfiles
taddyb Oct 21, 2024
7c20da5
updated docs, added README
taddyb Nov 5, 2024
dbb06c5
adding tests for water transfer
taddyb Nov 13, 2024
e75da48
removing the geopackages and adding divergence obs
taddyb Nov 13, 2024
645c574
adding divergence forcings, obs, and config entries
taddyb Nov 14, 2024
8d59167
finished flow divergence
taddyb Nov 14, 2024
aa4e219
adding domain info
taddyb Nov 15, 2024
c8c51a8
finished water transfer work
taddyb Nov 15, 2024
ce78001
cleaned up comments and formatting
taddyb Nov 15, 2024
d2d03ec
added notebook dockerfile for OE testing
taddyb Nov 15, 2024
2243c34
found a bug in discharge calc
taddyb Nov 15, 2024
1304f11
deleting unneccessary files:
taddyb Nov 15, 2024
14059a2
adding saved change to notebook
taddyb Nov 15, 2024
e96ca82
Update dockerfile_notebook.md
taddyb Nov 15, 2024
f62980e
adding support for better last obs handling
taddyb Nov 15, 2024
1ad5ad9
Merge branch 'old-river-lock' of https://github.com/taddyb/t-route in…
taddyb Nov 15, 2024
599329f
Merge branch 'development' of https://github.com/taddyb/t-route into …
taddyb Nov 15, 2024
15022c1
reformatted plots
taddyb Nov 15, 2024
9113a07
squashed merge from development
taddyb Nov 15, 2024
b9270d5
reformatted requirements and .gitignore
taddyb Nov 15, 2024
cdd3a29
reformatting from pull
taddyb Nov 15, 2024
55d92f1
Merge pull request #4 from taddyb/old-river-lock
taddyb Nov 25, 2024
2759195
adding test f files
taddyb Nov 25, 2024
2e5ec75
added pyproject.toml
taddyb Nov 25, 2024
8cfdc97
removing build dir
taddyb Nov 25, 2024
ef0f4b5
fixed the troute-config unit tests
taddyb Nov 25, 2024
fe4794e
added unit tests for network
taddyb Nov 25, 2024
198d6ef
removed old tests and formatted unit tests for t-route routing
taddyb Nov 25, 2024
03cf302
added docs to doc/
taddyb Nov 25, 2024
be96621
added change to allow v2.2 to work
taddyb Nov 25, 2024
98af87f
fixed the v2.2 plotting code
taddyb Nov 25, 2024
2901799
added BMI test, missing two dataframes
taddyb Nov 26, 2024
f9c53c2
adding bmi test
taddyb Nov 26, 2024
def0388
removing utils
taddyb Nov 26, 2024
e09098c
Merge pull request #5 from taddyb/fims_unit_tests
taddyb Nov 26, 2024
c708db8
added changes to t-route API to support v2.2
taddyb Dec 2, 2024
67e0fff
removed __main__ call from init, and fixed the t-route tests
taddyb Dec 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,19 @@ bower_components/
.grunt/
src/vendor/
dist/

# .vscode #
###########
.vscode

# ruff/pycache/pytest #
#######################
.*_cache

# .venv #
#########
.venv

# Build libs #
##############
build/
18 changes: 18 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

if ! docker login --username ${GH_USERNAME} --password ${GH_TOKEN} ghcr.io; then
echo "Error: Failed to login to ghcr.io. Please check your GH_USERNAME and GH_TOKEN env vars"
exit 1
fi

if ! docker build -t ghcr.io/NOAA-OWP/t-route/t-route-api:${TAG} -f Dockerfile.troute_api .; then
echo "Error: Failed to build Docker image. Please check your Dockerfile and build context."
exit 1
fi

if ! docker push ghcr.io/NOAA-OWP/t-route/t-route-api:${TAG}; then
echo "Error: Failed to push Docker image. Please check your TAG env var"
exit 1
fi

echo "Successfully built and pushed Docker image with tag: ${TAG}"
102 changes: 102 additions & 0 deletions doc/api/api_docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# T-Route FastAPI

The following doc is meant to explain the T-Route FastAPI implementation using docker compose and shared volumes.

## Why an API?

T-Route is used in many contexts for hydrological river routing:
- NGEN
- Scientific Python Projects
- Replace and Route (RnR)

In the latest PR for RnR (https://github.com/NOAA-OWP/hydrovis/pull/865), there is an requirement to run T-Route as a service. This service requires an easy way to dynamically create config files, restart flow from Initial Conditions, and run T-Route. To satisfy this requirement, a FastAPI endpoint was created in `/src/app` along with code to dynamically create t-route endpoints.

## Why use shared volumes?

Since T-Route is running in a docker container, there has to be a connection between the directories on your machine and the directories within the container. We're sharing the following folders by default:
- `data/rfc_channel_forcings`
- For storing RnR RFC channel domain forcing files (T-Route inputs)
- `data/rfc_geopackage_data`
- For storing HYFeatures gpkg files
- Indexed by the NHD COMID, also called hf_id. Ex: 2930769 is the hf_id for the CAGM7 RFC forecast point.
- `data/troute_restart`
- For storing TRoute Restart files
- `data/troute_output`
- For outputting results from the T-Route container

## Quickstart
1. From the Root directory, run:
```shell
docker compose --env-file docker/test_troute_api.env -f docker/compose.yaml up --build
```

This will start the T-Route container and run the API on localhost:8004. To view the API spec and swagger docs, visit localhost:8004/docs

2. Submit a request
```shell
curl -X 'GET' \
'http://localhost:8004/api/v1/flow_routing/v4/?lid=CAGM7&feature_id=2930769&hy_id=1074884&initial_start=0&start_time=2024-08-24T00%3A00%3A00&num_forecast_days=5' \
-H 'accept: application/json'
```

This curl command is pinging the flow_routing v4 endpoint `api/v1/flow_routing/v4/` with the following metadata:
```
lid=CAGM7
feature_id=2930769
hy_id=1074884
initial_start=0
start_time=2024-08-24T00:00:00
num_forecast_days=5
```

which informs T-Route which location folder to look at, what feature ID to read a gpkg from, the HY feature_id where flow is starting, the initial start flow for flow restart, start-time of the routing run, and the number of days to forecast.

You can also run the following args from the swagger endpoint:

![alt text](swagger_endpoints.png)

The result for a successful routing is a status 200:
```json
{
"message": "T-Route run successfully",
"lid": "CAGM7",
"feature_id": "2930769"
}
```

and an internal 500 error if there is something wrong.

## Building and pushing to a container registry

To ensure Replace and Route is using the correct version of T-Route, it is recommended a docker container be built, and then pushed to a registry (Dockerhub, GitHub Container Registry, etc). To do this manually for the GitHub container registry, the following commands should be used within a terminal.

```shell
docker login --username ${GH_USERNAME} --password ${GH_TOKEN} ghcr.io
```
- This command will log the user into the GitHub container registry using their credentials

```shell
docker build -t ghcr.io/NOAA-OWP/t-route/t-route-api:${TAG} -f docker/Dockerfile.troute_api
```
- This command builds the T-Route API container using a defined version `${TAG}`

```shell
docker push ghcr.io/NOAA-OWP/t-route/t-route-api:${TAG}
```
- This commands pushes the built T-Route API container to the NOAA-OWP/t-route container registry


The following env variables are used:
- `${GH_USERNAME}`
- your github username
- `${GH_TOKEN}`
- your github access token
- `${TAG} `
- the version tag
- ex: 0.0.2

If you want to build this off a forked version, change the container registry (`/NOAA-OWP/t-route/`) to your user accounts container registry.

## Testing:

See `test/api/README.md` for testing information
Binary file added doc/api/api_spec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/api/swagger_endpoints.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions doc/docker/dockerfile_notebook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Dockerfile.Notebook

This document describes the Docker setup for running JupyterLab with mounted volumes for development and analysis.

## Container Overview

The container provides a JupyterLab environment with:
- Python environment for data analysis
- Web interface accessible via port 8000

This container is a great way to run examples and integrated tests

## Docker Configuration

### Dockerfile
The Dockerfile sets up:
- Base Python environment
- JupyterLab installation
- Volume mount points for data and code
- Port 8000 exposed for web interface
- Working directory configuration

### Getting Started

Build:
```bash
docker build -t troute-notebook -f docker/Dockerfile.notebook .
```

Run:
```bash
docker run -p 8000:8000 troute-notebook
```

Then, take the URL from the output and put that into your browser. An example one is below:
```
http://127.0.0.1:8000/lab?token=<token>
```
50 changes: 50 additions & 0 deletions doc/test/integration_tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Integration Tests

This directory details the integration tests within troute

## Quick Start

```bash
# Run all integration tests
pytest test/

# Run tests from a specific category
pytest test/troute-nwm
pytest test/troute-network/
```

## Test Categories

### Config Tests (`test/troute-config/`)

**Usage:**
- Validating existing Troute example configs
- Testing the Pydantic Config Validations

### Network Tests (`test/troute-network/`)

**Usage:**
- Using YAML files from `NHD` and `HYFeatures` in order to test network creation

### NWM Tests (`test/troute-nwm/`)

**Usage:**
- end to end tests of individual functions within the following functions:
- `main_v03()`
- `main_v04()`

### Routing Tests (`test/troute-routing/`)

**Usage:**
- Integration tests for NHD and HYFeature util functions

### End to End Examples:
##### `test/LowerColorado_TX/`
##### `test/LowerColorado_TX_v4/`
##### `test/LowerColorado_TX_HYFeatures_v22/`

## Adding New Tests

1. Create new test files in the appropriate category directory
2. Use the naming convention `test_*.py` for test files
3. Document any new fixtures in the relevant conftest.py
41 changes: 41 additions & 0 deletions doc/test/unit_tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Unit Tests

This directory details the unit tests within troute

## Quick Start

```bash
# Run tests from a specific category
pytest src/troute-config/
pytest src/troute-routing/
pytest test/troute-network/
```

## Test Categories

### Config Tests (`test/troute-config/`)

**Usage:**
- Validating existing Troute example configs
- Testing the Pydantic Config Validations

### Network Tests (`test/troute-network/`)

**Usage:**
- Using YAML files from `NHD` and `HYFeatures` in order to test network creation

### Routing Tests (`test/troute-routing/`)

**Usage:**
- Integration tests for NHD and HYFeature util functions

### End to End Examples:
##### `test/LowerColorado_TX/`
##### `test/LowerColorado_TX_v4/`
##### `test/LowerColorado_TX_HYFeatures_v22/`

## Adding New Tests

1. Create new test files in the appropriate category directory
2. Use the naming convention `test_*.py` for test files
3. Document any new fixtures in the relevant conftest.py
24 changes: 24 additions & 0 deletions docker/Dockerfile.compose
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM rockylinux:9.2 as rocky-base
RUN yum install -y epel-release
RUN yum install -y netcdf netcdf-fortran netcdf-fortran-devel netcdf-openmpi

RUN yum install -y git cmake python python-devel pip

WORKDIR /t-route/
COPY . /t-route/

RUN ln -s /usr/lib64/gfortran/modules/netcdf.mod /usr/include/openmpi-x86_64/netcdf.mod

ENV PYTHONPATH=/t-route:$PYTHONPATH
RUN pip install uv==0.2.5
RUN uv venv

ENV VIRTUAL_ENV=/t-route/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN uv pip install --no-cache-dir -r /t-route/requirements.txt

RUN ./compiler.sh no-e

WORKDIR "/t-route/src/"
RUN mkdir -p /t-route/data/troute_restart/
29 changes: 29 additions & 0 deletions docker/Dockerfile.notebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM rockylinux:9.2 as rocky-base
RUN yum install -y epel-release
RUN yum install -y netcdf netcdf-fortran netcdf-fortran-devel netcdf-openmpi

RUN yum install -y git cmake python python-devel pip

WORKDIR "/t-route/"

COPY . /t-route/

RUN ln -s /usr/lib64/gfortran/modules/netcdf.mod /usr/include/openmpi-x86_64/netcdf.mod

ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV

# Equivalent to source /opt/venv/bin/activate
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN python -m pip install .
RUN python -m pip install .[jupyter]
RUN python -m pip install .[test]

RUN ./compiler.sh no-e

EXPOSE 8000

# increase max open files soft limit
RUN ulimit -n 10000
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8000", "--no-browser", "--allow-root"]
37 changes: 37 additions & 0 deletions docker/Dockerfile.troute_api
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM rockylinux:9.2 as rocky-base

RUN yum install -y epel-release
RUN yum install -y netcdf netcdf-fortran netcdf-fortran-devel netcdf-openmpi

RUN yum install -y git cmake python python-devel pip

WORKDIR "/t-route/"

# Copy the contents of the parent directory (repository root) into the container
COPY . /t-route/

RUN ln -s /usr/lib64/gfortran/modules/netcdf.mod /usr/include/openmpi-x86_64/netcdf.mod

ENV PYTHONPATH=/t-route:$PYTHONPATH
RUN pip install uv==0.2.5
RUN uv venv

ENV VIRTUAL_ENV=/t-route/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN uv pip install --no-cache-dir -r /t-route/requirements.txt

RUN ./compiler.sh no-e

WORKDIR "/t-route/src/"
RUN mkdir -p /t-route/data/troute_restart/

# Create volume mount points
RUN mkdir -p ${OUTPUT_VOLUME_TARGET} ${DATA_VOLUME_TARGET} ${CORE_VOLUME_TARGET} /t-route/test

# Set the command to run the application
CMD sh -c ". /t-route/.venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port ${PORT}"

# Add healthcheck
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD curl --fail -I http://localhost:${PORT}/health || exit 1
27 changes: 27 additions & 0 deletions docker/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
services:
troute:
build:
context: ..
dockerfile: docker/Dockerfile.compose
ports:
- "${PORT}:${PORT}"
volumes:
- type: bind
source: ${OUTPUT_VOLUME_SOURCE}
target: ${OUTPUT_VOLUME_TARGET}
- type: bind
source: ${DATA_VOLUME_SOURCE}
target: ${DATA_VOLUME_TARGET}
- type: bind
source: ${CORE_VOLUME_SOURCE}
target: ${CORE_VOLUME_TARGET}
- type: bind
source: ${TEST_SOURCE}
target: ${TEST_TARGET}
command: sh -c ". /t-route/.venv/bin/activate && uvicorn app.main:app --host 0.0.0.0 --port ${PORT}"
healthcheck:
test: curl --fail -I http://localhost:${PORT}/health || exit 1
interval: 30s
timeout: 5s
retries: 3
start_period: 5s
Loading