diff --git a/README.md b/README.md index bd790e2..4dfcc4e 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ As of April 7th 2024, the library supports the following [APIs](https://doc.navi | ----------------------------------------- | ----------- | | Coverage | ✅ | | Datasets | ✅ | -| Contributors | ❌ | +| Contributors | ✅ | | Inverted geocoding | ❌ | | Public transportation Objects exploration | ❌ | | Autocomplete on Public Transport objects | ❌ | diff --git a/navitia_client/client/apis/contributors_apis.py b/navitia_client/client/apis/contributors_apis.py new file mode 100644 index 0000000..1d886d3 --- /dev/null +++ b/navitia_client/client/apis/contributors_apis.py @@ -0,0 +1,39 @@ +from typing import Any, Sequence + +from navitia_client.client.apis.api_base_client import ApiBaseClient +from navitia_client.entities.contributor import Contributor + + +class ContributorsApiClient(ApiBaseClient): + @staticmethod + def _get_contributors_from_response( + raw_contributors_response: Any, + ) -> Sequence[Contributor]: + contributors = [] + for contributor in raw_contributors_response: + contributors.append( + Contributor( + id=contributor.get("id"), + name=contributor.get("name"), + license=contributor.get("license"), + website=contributor.get("website"), + ), + ) + + return contributors + + def list_contributors(self, region_id: str) -> Sequence[Contributor]: + results = self.get_navitia_api( + f"{self.base_navitia_url}/coverage/{region_id}/contributors" + ) + raw_results = results.json()["contributors"] + return ContributorsApiClient._get_contributors_from_response(raw_results) + + def get_contributor_on_dataset( + self, region_id: str, dataset_id: str + ) -> Sequence[Contributor]: + results = self.get_navitia_api( + f"{self.base_navitia_url}/coverage/{region_id}/contributors/{dataset_id}" + ) + raw_results = results.json()["contributors"] + return ContributorsApiClient._get_contributors_from_response(raw_results) diff --git a/navitia_client/client/navitia_client.py b/navitia_client/client/navitia_client.py index fbc74a0..ef0a0f8 100644 --- a/navitia_client/client/navitia_client.py +++ b/navitia_client/client/navitia_client.py @@ -1,5 +1,6 @@ from dataclasses import dataclass +from navitia_client.client.apis.contributors_apis import ContributorsApiClient from navitia_client.client.apis.coverage_apis import CoverageApiClient from navitia_client.client.apis.datasets_apis import DatasetsApiClient @@ -22,3 +23,9 @@ def datasets(self) -> DatasetsApiClient: return DatasetsApiClient( auth_token=self.auth_token, base_navitia_url=self.base_navitia_url ) + + @property + def contributors(self) -> ContributorsApiClient: + return ContributorsApiClient( + auth_token=self.auth_token, base_navitia_url=self.base_navitia_url + ) diff --git a/tests/client/apis/test_contributors_apis.py b/tests/client/apis/test_contributors_apis.py new file mode 100644 index 0000000..00b6109 --- /dev/null +++ b/tests/client/apis/test_contributors_apis.py @@ -0,0 +1,75 @@ +from unittest.mock import MagicMock, patch + +import pytest + +from navitia_client.client.apis.contributors_apis import ContributorsApiClient +from navitia_client.entities.contributor import Contributor + + +@pytest.fixture +def contributors_apis(): + return ContributorsApiClient( + auth_token="foobar", base_navitia_url="https://api.navitia.io/v1/" + ) + + +@patch.object(ContributorsApiClient, "get_navitia_api") +def test_list_contributors( + mock_get_navitia_api: MagicMock, contributors_apis: ContributorsApiClient +) -> None: + # Given + mock_response = MagicMock() + mock_response.json.return_value = { + "contributors": [ + { + "id": "foo:foo-piv", + "license": "Private", + "name": "foo Production", + "website": "", + } + ], + } + mock_get_navitia_api.return_value = mock_response + + # When + contributors = contributors_apis.list_contributors(region_id="bar") + + # Then + assert len(contributors) == 1 + assert isinstance(contributors[0], Contributor) + assert contributors[0].name == "foo Production" + assert contributors[0].id == "foo:foo-piv" + assert contributors[0].license == "Private" + assert contributors[0].website == "" + + +@patch.object(ContributorsApiClient, "get_navitia_api") +def test_get_region_by_id( + mock_get_navitia_api: MagicMock, contributors_apis: ContributorsApiClient +) -> None: + # Given + mock_response = MagicMock() + mock_response.json.return_value = { + "contributors": [ + { + "id": "foo:foo-piv", + "license": "Private", + "name": "foo Production", + "website": "", + } + ], + } + mock_get_navitia_api.return_value = mock_response + + # When + contributors = contributors_apis.get_contributor_on_dataset( + region_id="bar", dataset_id="foo:xxx" + ) + + # Then + assert len(contributors) == 1 + assert isinstance(contributors[0], Contributor) + assert contributors[0].name == "foo Production" + assert contributors[0].id == "foo:foo-piv" + assert contributors[0].license == "Private" + assert contributors[0].website == ""