diff --git a/CHANGELOG b/CHANGELOG index ffe2d23..124efef 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added + +* New function for retrieving runs by their run folder name. + ### Changes * Change tests to use secure variant of database config that stops logging secrets @@ -23,7 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added -* `validate_runfolder` function to npgtracking.db.retrieval +* `validate_runfolder` function to npgtracking.db.retrieval ## [0.2.0] - 2025-12-12 diff --git a/src/npgtracking/db/retrieval.py b/src/npgtracking/db/retrieval.py index 0ab8cdb..8e53317 100644 --- a/src/npgtracking/db/retrieval.py +++ b/src/npgtracking/db/retrieval.py @@ -129,3 +129,9 @@ def validate_runfolder(session: Session, id_run: int, runfolder_name: str) -> bo if not run: raise ValueError(f"Run with ID {id_run} does not exist.") return run.folder_name == runfolder_name + + +def get_run_by_runfolder(session: Session, run_folder_name: str) -> Run: + return session.execute( + select(Run).where(Run.folder_name == run_folder_name) + ).scalar_one() diff --git a/tests/test_retrieval.py b/tests/test_retrieval.py index 52d01f6..ed77367 100644 --- a/tests/test_retrieval.py +++ b/tests/test_retrieval.py @@ -17,9 +17,11 @@ from pytest import mark as m from pytest import raises +from sqlalchemy.exc import NoResultFound from npgtracking.db.retrieval import ( get_run_by_id, + get_run_by_runfolder, get_runs_by_currentstatus, validate_runfolder, ) @@ -119,3 +121,18 @@ def test_validate_runfolder(self, tracking_session): def test_validate_runfolder_error(self, tracking_session): with raises(ValueError, match="Run with ID 1 does not exist"): validate_runfolder(tracking_session, 1, "430591-20251204_1628") + + @m.context("When retrieving a Run by an invalid runfolder_name") + @m.it("An exception is raised") + def test_run_by_bad_runfolder_name(self, tracking_session): + with raises(NoResultFound): + get_run_by_runfolder(tracking_session, "/not/here") + + with raises(NoResultFound): + get_run_by_runfolder(tracking_session, None) + + @m.context("When retrieving a Run by a valid runfolder_name") + @m.it("A single valid Run object is returned") + def test_run_by_runfolder_name(self, tracking_session): + run = get_run_by_runfolder(tracking_session, "424091-20250823_0117") + assert run.id_run == 50001