From e338bd448908a12a5a7220f8655aeeb7fcde9b7d Mon Sep 17 00:00:00 2001 From: MAlyafeai18 Date: Wed, 6 Dec 2023 18:16:51 +0000 Subject: [PATCH 1/4] init work --- aixplain/enums/__init__.py | 1 + aixplain/enums/sort_by.py | 28 +++++++++++++++++++ aixplain/factories/model_factory.py | 10 +++++-- .../general_assets/asset_functional_test.py | 6 +++- 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 aixplain/enums/sort_by.py diff --git a/aixplain/enums/__init__.py b/aixplain/enums/__init__.py index eaed5a77..857e1aaf 100644 --- a/aixplain/enums/__init__.py +++ b/aixplain/enums/__init__.py @@ -11,3 +11,4 @@ from .privacy import Privacy from .storage_type import StorageType from .supplier import Supplier +from .sort_by import SortBy diff --git a/aixplain/enums/sort_by.py b/aixplain/enums/sort_by.py new file mode 100644 index 00000000..901f3b75 --- /dev/null +++ b/aixplain/enums/sort_by.py @@ -0,0 +1,28 @@ +__author__ = "aiXplain" + +""" +Copyright 2023 The aiXplain SDK authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Author: aiXplain team +Date: March 20th 2023 +Description: + Sort By Enum +""" + +from enum import Enum + + +class SortBy(Enum): + DATE = "date" diff --git a/aixplain/factories/model_factory.py b/aixplain/factories/model_factory.py index f9551381..e16a843c 100644 --- a/aixplain/factories/model_factory.py +++ b/aixplain/factories/model_factory.py @@ -24,7 +24,7 @@ import json import logging from aixplain.modules.model import Model -from aixplain.enums import Function, Language, OwnershipType, Supplier +from aixplain.enums import Function, Language, OwnershipType, Supplier, SortBy from aixplain.utils import config from aixplain.utils.file_utils import _request_with_retry from urllib.parse import urljoin @@ -130,6 +130,7 @@ def _get_assets_from_page( target_languages: Union[Language, List[Language]], is_finetunable: bool = None, ownership: Optional[Tuple[OwnershipType, List[OwnershipType]]] = None, + sort_by: Optional[SortBy] = None ) -> List[Model]: try: url = urljoin(cls.backend_url, f"sdk/models/paginate") @@ -162,6 +163,8 @@ def _get_assets_from_page( if function == Function.TRANSLATION: code = "targetlanguage" lang_filter_params.append({"code": code, "value": target_languages[0].value["language"]}) + if sort_by is not None: + filter_params["sortBy"] = sort_by.value if len(lang_filter_params) != 0: filter_params["ioFilter"] = lang_filter_params if cls.aixplain_key != "": @@ -191,8 +194,9 @@ def list( target_languages: Optional[Union[Language, List[Language]]] = None, is_finetunable: Optional[bool] = None, ownership: Optional[Tuple[OwnershipType, List[OwnershipType]]] = None, + sort_by: Optional[SortBy] = None, page_number: int = 0, - page_size: int = 20, + page_size: int = 20 ) -> List[Model]: """Gets the first k given models based on the provided task and language filters @@ -202,6 +206,7 @@ def list( target_languages (Optional[Union[Language, List[Language]]], optional): language filter of output data. Defaults to None. is_finetunable (Optional[bool], optional): can be finetuned or not. Defaults to None. ownership (Optional[Tuple[OwnershipType, List[OwnershipType]]], optional): Ownership filters (e.g. SUBSCRIBED, OWNER). Defaults to None. + sort_by (Optional[SortBy], optional): sort the retrived models by a specific attrbuite, page_number (int, optional): page number. Defaults to 0. page_size (int, optional): page size. Defaults to 20. @@ -219,6 +224,7 @@ def list( target_languages, is_finetunable, ownership, + sort_by ) return { "results": models, diff --git a/tests/functional/general_assets/asset_functional_test.py b/tests/functional/general_assets/asset_functional_test.py index 0c720fa2..6b56765b 100644 --- a/tests/functional/general_assets/asset_functional_test.py +++ b/tests/functional/general_assets/asset_functional_test.py @@ -4,7 +4,7 @@ load_dotenv() from aixplain.factories import ModelFactory, DatasetFactory, MetricFactory, PipelineFactory from pathlib import Path -from aixplain.enums import Function, OwnershipType, Supplier +from aixplain.enums import Function, OwnershipType, Supplier, SortBy import pytest @@ -80,3 +80,7 @@ def test_model_deletion(): model = ModelFactory.get("640b517694bf816d35a59125") with pytest.raises(Exception): model.delete() + +def test_model_sort(): + models = ModelFactory.list(sort_by = SortBy.DATE)['results'] + assert bool(models) is True \ No newline at end of file From 70a864b61887161d886ea3c5e645f6722f7cca1b Mon Sep 17 00:00:00 2001 From: MAlyafeai18 Date: Wed, 6 Dec 2023 18:18:30 +0000 Subject: [PATCH 2/4] fix spelling --- aixplain/factories/model_factory.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aixplain/factories/model_factory.py b/aixplain/factories/model_factory.py index e16a843c..b66cb6da 100644 --- a/aixplain/factories/model_factory.py +++ b/aixplain/factories/model_factory.py @@ -206,7 +206,7 @@ def list( target_languages (Optional[Union[Language, List[Language]]], optional): language filter of output data. Defaults to None. is_finetunable (Optional[bool], optional): can be finetuned or not. Defaults to None. ownership (Optional[Tuple[OwnershipType, List[OwnershipType]]], optional): Ownership filters (e.g. SUBSCRIBED, OWNER). Defaults to None. - sort_by (Optional[SortBy], optional): sort the retrived models by a specific attrbuite, + sort_by (Optional[SortBy], optional): sort the retrived models by a specific attribute, page_number (int, optional): page number. Defaults to 0. page_size (int, optional): page size. Defaults to 20. From f4ef45aa3362741b3b167e0d37a806ca5b8533b0 Mon Sep 17 00:00:00 2001 From: Thiago Castro Ferreira Date: Wed, 6 Dec 2023 21:48:21 +0000 Subject: [PATCH 3/4] Model sorting methods --- aixplain/enums/__init__.py | 1 + aixplain/enums/sort_by.py | 4 ++- aixplain/enums/sort_order.py | 29 +++++++++++++++++++ aixplain/factories/model_factory.py | 14 +++++---- .../general_assets/asset_functional_test.py | 27 +++++++++++++---- 5 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 aixplain/enums/sort_order.py diff --git a/aixplain/enums/__init__.py b/aixplain/enums/__init__.py index 857e1aaf..4da09643 100644 --- a/aixplain/enums/__init__.py +++ b/aixplain/enums/__init__.py @@ -12,3 +12,4 @@ from .storage_type import StorageType from .supplier import Supplier from .sort_by import SortBy +from .sort_order import SortOrder diff --git a/aixplain/enums/sort_by.py b/aixplain/enums/sort_by.py index 901f3b75..5e3acec8 100644 --- a/aixplain/enums/sort_by.py +++ b/aixplain/enums/sort_by.py @@ -25,4 +25,6 @@ class SortBy(Enum): - DATE = "date" + CREATION_DATE = "createdAt" + PRICE = "normalizedPrice" + POPULARITY = "totalSubscribed" diff --git a/aixplain/enums/sort_order.py b/aixplain/enums/sort_order.py new file mode 100644 index 00000000..85e10f7a --- /dev/null +++ b/aixplain/enums/sort_order.py @@ -0,0 +1,29 @@ +__author__ = "aiXplain" + +""" +Copyright 2023 The aiXplain SDK authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Author: aiXplain team +Date: March 20th 2023 +Description: + Sort By Enum +""" + +from enum import Enum + + +class SortOrder(Enum): + ASCENDING = 1 + DESCENDING = -1 diff --git a/aixplain/factories/model_factory.py b/aixplain/factories/model_factory.py index b66cb6da..0aa9d981 100644 --- a/aixplain/factories/model_factory.py +++ b/aixplain/factories/model_factory.py @@ -24,7 +24,7 @@ import json import logging from aixplain.modules.model import Model -from aixplain.enums import Function, Language, OwnershipType, Supplier, SortBy +from aixplain.enums import Function, Language, OwnershipType, Supplier, SortBy, SortOrder from aixplain.utils import config from aixplain.utils.file_utils import _request_with_retry from urllib.parse import urljoin @@ -130,7 +130,8 @@ def _get_assets_from_page( target_languages: Union[Language, List[Language]], is_finetunable: bool = None, ownership: Optional[Tuple[OwnershipType, List[OwnershipType]]] = None, - sort_by: Optional[SortBy] = None + sort_by: Optional[SortBy] = None, + sort_order: SortOrder = SortOrder.ASCENDING, ) -> List[Model]: try: url = urljoin(cls.backend_url, f"sdk/models/paginate") @@ -147,6 +148,7 @@ def _get_assets_from_page( if isinstance(ownership, OwnershipType) is True: ownership = [ownership] filter_params["ownership"] = [ownership_.value for ownership_ in ownership] + lang_filter_params = [] if source_languages is not None: if isinstance(source_languages, Language): @@ -164,7 +166,7 @@ def _get_assets_from_page( code = "targetlanguage" lang_filter_params.append({"code": code, "value": target_languages[0].value["language"]}) if sort_by is not None: - filter_params["sortBy"] = sort_by.value + filter_params["sort"] = [{"dir": sort_order.value, "field": sort_by.value}] if len(lang_filter_params) != 0: filter_params["ioFilter"] = lang_filter_params if cls.aixplain_key != "": @@ -195,8 +197,9 @@ def list( is_finetunable: Optional[bool] = None, ownership: Optional[Tuple[OwnershipType, List[OwnershipType]]] = None, sort_by: Optional[SortBy] = None, + sort_order: SortOrder = SortOrder.ASCENDING, page_number: int = 0, - page_size: int = 20 + page_size: int = 20, ) -> List[Model]: """Gets the first k given models based on the provided task and language filters @@ -224,7 +227,8 @@ def list( target_languages, is_finetunable, ownership, - sort_by + sort_by, + sort_order, ) return { "results": models, diff --git a/tests/functional/general_assets/asset_functional_test.py b/tests/functional/general_assets/asset_functional_test.py index 6b56765b..561ed529 100644 --- a/tests/functional/general_assets/asset_functional_test.py +++ b/tests/functional/general_assets/asset_functional_test.py @@ -4,7 +4,7 @@ load_dotenv() from aixplain.factories import ModelFactory, DatasetFactory, MetricFactory, PipelineFactory from pathlib import Path -from aixplain.enums import Function, OwnershipType, Supplier, SortBy +from aixplain.enums import Function, Language, OwnershipType, Supplier, SortBy, SortOrder import pytest @@ -63,6 +63,27 @@ def test_model_supplier(): assert model.supplier.value in [desired_supplier.value for desired_supplier in desired_suppliers] +def test_model_sort(): + function = Function.TRANSLATION + src_language = Language.Portuguese + trg_language = Language.English + + models = ModelFactory.list( + function=function, + source_languages=src_language, + target_languages=trg_language, + sort_by=SortBy.PRICE, + sort_order=SortOrder.ASCENDING, + )["results"] + for idx in range(1, len(models)): + prev_model = models[idx - 1] + model = models[idx] + + prev_model_price = prev_model.additional_info["pricing"]["price"] + model_price = model.additional_info["pricing"]["price"] + assert prev_model_price >= model_price + + def test_model_ownership(): models = ModelFactory.list(ownership=OwnershipType.SUBSCRIBED)["results"] for model in models: @@ -80,7 +101,3 @@ def test_model_deletion(): model = ModelFactory.get("640b517694bf816d35a59125") with pytest.raises(Exception): model.delete() - -def test_model_sort(): - models = ModelFactory.list(sort_by = SortBy.DATE)['results'] - assert bool(models) is True \ No newline at end of file From f7d431ff39c829c70afb74619901c263d619d54b Mon Sep 17 00:00:00 2001 From: Thiago Castro Ferreira Date: Wed, 6 Dec 2023 21:49:33 +0000 Subject: [PATCH 4/4] Fix on functional test --- tests/functional/general_assets/asset_functional_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/general_assets/asset_functional_test.py b/tests/functional/general_assets/asset_functional_test.py index 561ed529..56e05609 100644 --- a/tests/functional/general_assets/asset_functional_test.py +++ b/tests/functional/general_assets/asset_functional_test.py @@ -73,7 +73,7 @@ def test_model_sort(): source_languages=src_language, target_languages=trg_language, sort_by=SortBy.PRICE, - sort_order=SortOrder.ASCENDING, + sort_order=SortOrder.DESCENDING, )["results"] for idx in range(1, len(models)): prev_model = models[idx - 1]