diff --git a/ixmp4/data/abstract/run.py b/ixmp4/data/abstract/run.py index e528f5a5..e79a4554 100644 --- a/ixmp4/data/abstract/run.py +++ b/ixmp4/data/abstract/run.py @@ -137,6 +137,26 @@ def get_default_version(self, model_name: str, scenario_name: str) -> Run: """ ... + def get_by_id(self, id: int) -> Run: + """Retrieves a Run by its id. + + Parameters + ---------- + id : int + Unique integer id. + + Raises + ------ + :class:`ixmp4.data.abstract.Run.NotFound`. + If the Run with `id` does not exist. + + Returns + ------- + :class:`ixmp4.data.abstract.Run`: + The retrieved Run. + """ + ... + def list(self, **kwargs: Unpack[EnumerateKwargs]) -> list[Run]: r"""Lists runs by specified criteria. diff --git a/ixmp4/data/api/run.py b/ixmp4/data/api/run.py index 374d0ebc..184f60c8 100644 --- a/ixmp4/data/api/run.py +++ b/ixmp4/data/api/run.py @@ -67,6 +67,10 @@ def get(self, model_name: str, scenario_name: str, version: int) -> Run: is_default=None, ) + def get_by_id(self, id: int) -> Run: + res = self._get_by_id(id) + return Run(**res) + def enumerate( self, **kwargs: Unpack[abstract.run.EnumerateKwargs] ) -> list[Run] | pd.DataFrame: diff --git a/ixmp4/server/rest/run.py b/ixmp4/server/rest/run.py index 1457db83..ce180027 100644 --- a/ixmp4/server/rest/run.py +++ b/ixmp4/server/rest/run.py @@ -61,3 +61,11 @@ def unset_as_default_version( backend: Backend = Depends(deps.get_backend), ) -> None: backend.runs.unset_as_default_version(id) + + +@router.get("/{id}/", response_model=api.Run) +def get_by_id( + id: int, + backend: Backend = Depends(deps.get_backend), +) -> Run: + return backend.runs.get_by_id(id) diff --git a/tests/data/test_run.py b/tests/data/test_run.py index e9ba4ebf..89de756f 100644 --- a/tests/data/test_run.py +++ b/tests/data/test_run.py @@ -2,6 +2,8 @@ import pytest import ixmp4 +import ixmp4.data +import ixmp4.data.abstract from ixmp4.core.exceptions import NoDefaultRunVersion from ..utils import assert_unordered_equality @@ -55,6 +57,14 @@ def test_get_or_create_run(self, platform: ixmp4.Platform) -> None: run3 = platform.backend.runs.get_or_create("Model", "Scenario") assert run1.id == run3.id + def test_get_run_by_id(self, platform: ixmp4.Platform) -> None: + expected = platform.backend.runs.create("Model", "Scenario") + result = platform.backend.runs.get_by_id(id=expected.id) + assert expected.id == result.id + + with pytest.raises(ixmp4.data.abstract.Run.NotFound): + _ = platform.backend.runs.get_by_id(id=expected.id + 1) + def test_list_run(self, platform: ixmp4.Platform) -> None: run1 = platform.backend.runs.create("Model", "Scenario") platform.backend.runs.create("Model", "Scenario")