Contributing
Development setup
git clone https://github.com/mansurjisan/nos-utils.git
cd nos-utils
pip install -e ".[full,dev]"
Running tests
The test suite uses only synthetic fixtures defined in
tests/conftest.py – no external data downloads are needed and the
whole suite runs in a few seconds.
pytest tests/ -q # full suite (206 tests)
pytest tests/ -q -k gfs # only GFS tests
pytest tests/ -q -k stofs # only STOFS-3D-ATL tests
pytest --cov=nos_utils --cov-report=html
Code style
Follow PEP 8.
Type-annotate public APIs.
Use Google-style docstrings on new classes and public methods (Napoleon is configured in
docs/conf.py).Run the formatters / linters before opening a PR:
black nos_utils/ tests/ flake8 nos_utils/ tests/
Adding a new processor
Create
nos_utils/forcing/my_processor.pysubclassingForcingProcessor.Implement
process()and return aForcingResult– populatesuccess,output_files,metadata, anderrors.Export it from
nos_utils/forcing/__init__.pyand add it to__all__.Wire it into
PrepOrchestratorif it should run as part of the standard prep pipeline.Add unit tests in
tests/test_my_processor.py. Reuse the synthetic GRIB2 / NetCDF fixtures fromconftest.pywhere possible.Add an RST stub under
docs/api/and include it in the toctree.
PR workflow
Open PRs against
main.Include a short summary of the change, the testing that was done, and any validation results (e.g. RMSE vs Fortran reference for numerical changes).
CI runs the full pytest suite on every PR. Please make sure
pytest tests/ -qpasses locally before requesting review.For WCOSS2-only changes (paths, modules, etc.) note it explicitly in the PR description so reviewers know the change cannot be validated in CI.