From e07913ecd98879efca5d0c6724fdfbfba6212076 Mon Sep 17 00:00:00 2001 From: Max Inno Date: Mon, 2 Feb 2026 08:49:42 +0200 Subject: [PATCH 1/5] feat(ai): add support for List Supported AI Provider Models method --- crowdin_api/api_resources/ai/enums.py | 7 +- crowdin_api/api_resources/ai/resource.py | 63 ++++++++++++++- .../ai/tests/test_ai_resources.py | 77 ++++++++++++++++++- 3 files changed, 143 insertions(+), 4 deletions(-) diff --git a/crowdin_api/api_resources/ai/enums.py b/crowdin_api/api_resources/ai/enums.py index eb0fd85..d9174ec 100644 --- a/crowdin_api/api_resources/ai/enums.py +++ b/crowdin_api/api_resources/ai/enums.py @@ -23,7 +23,7 @@ class EditAIPromptPath(Enum): class AIProviderType(Enum): OPEN_AI = "open_ai" - AZUER_OPEN_AI = "azure_open_ai" + AZURE_OPEN_AI = "azure_open_ai" GOOGLE_GEMINI = "google_gemini" MISTRAL_AI = "mistral_ai" ANTHROPIC = "anthropic" @@ -82,3 +82,8 @@ class ListAiPromptFineTuningJobsOrderBy(Enum): class AiReportFormat(Enum): CSV = "csv" JSON = "json" + + +class ListSupportedAiModelsOrderBy(Enum): + KNOWLEDGE_CUTOFF = "knowledgeCutoff" + RELEASE_DATE = "releaseDate" diff --git a/crowdin_api/api_resources/ai/resource.py b/crowdin_api/api_resources/ai/resource.py index adf325e..8520f35 100644 --- a/crowdin_api/api_resources/ai/resource.py +++ b/crowdin_api/api_resources/ai/resource.py @@ -1,7 +1,7 @@ from typing import Iterable, Optional, Union from crowdin_api.api_resources.abstract.resources import BaseResource -from crowdin_api.api_resources.ai.enums import AIPromptAction, AiPromptFineTuningJobStatus +from crowdin_api.api_resources.ai.enums import AIPromptAction, AiPromptFineTuningJobStatus, AIProviderType from crowdin_api.api_resources.ai.types import ( AddAIPromptRequestScheme, AddAIProviderReqeustScheme, @@ -18,7 +18,7 @@ EditAiSettingsPatch, ) from crowdin_api.sorting import Sorting -from crowdin_api.utils import convert_enum_collection_to_string_if_exists +from crowdin_api.utils import convert_enum_collection_to_string_if_exists, convert_enum_to_string_if_exists class AIResource(BaseResource): @@ -654,6 +654,36 @@ def edit_ai_settings( request_data=patches, ) + def list_supported_ai_provider_models( + self, + user_id: int, + limit: Optional[int] = None, + offset: Optional[int] = None, + provider_type: Optional[AIProviderType] = None, + enabled: Optional[bool] = None, + order_by: Optional[Sorting] = None, + ): + """ + List Supported AI Provider Models + + Link to documentation: + https://support.crowdin.com/developer/api/v2/#tag/AI/operation/api.ai.providers.supported-models.crowdin.getMany + """ + + params={ + "limit": limit, + "offset": offset, + "providerType": convert_enum_to_string_if_exists(provider_type), + "enabled": enabled, + "orderBy": str(order_by) if order_by is not None else None, + } + + return self.requester.request( + method="get", + path=f"users/{user_id}/ai/providers/supported-models", + params=params + ) + class EnterpriseAIResource(BaseResource): """ @@ -1256,3 +1286,32 @@ def edit_ai_settings( path="ai/settings", request_data=patches, ) + + def list_supported_ai_provider_models( + self, + limit: Optional[int] = None, + offset: Optional[int] = None, + provider_type: Optional[AIProviderType] = None, + enabled: Optional[bool] = None, + order_by: Optional[Sorting] = None, + ): + """ + List Supported AI Provider Models + + Link to documentation: + https://support.crowdin.com/developer/enterprise/api/v2/#tag/AI/operation/api.ai.providers.supported-models.enterprise.getMany + """ + + params={ + "limit": limit, + "offset": offset, + "providerType": convert_enum_to_string_if_exists(provider_type), + "enabled": enabled, + "orderBy": str(order_by) if order_by is not None else None, + } + + return self.requester.request( + method="get", + path="ai/providers/supported-models", + params=params + ) diff --git a/crowdin_api/api_resources/ai/tests/test_ai_resources.py b/crowdin_api/api_resources/ai/tests/test_ai_resources.py index 567a3dd..cfd966a 100644 --- a/crowdin_api/api_resources/ai/tests/test_ai_resources.py +++ b/crowdin_api/api_resources/ai/tests/test_ai_resources.py @@ -12,7 +12,7 @@ EditAiCustomPlaceholderPatchPath, AiToolType, AiReportFormat, - EditAiSettingsPatchPath + EditAiSettingsPatchPath, ListSupportedAiModelsOrderBy ) from crowdin_api.api_resources.ai.resource import AIResource, EnterpriseAIResource from crowdin_api.api_resources.ai.types import ( @@ -1065,6 +1065,45 @@ def test_edit_ai_settings(self, m_request, incoming_data, request_params, base_a request_data=request_params, ) + @pytest.mark.parametrize( + "in_params, request_params", + ( + ( + { + "limit": 25, + "offset": 0, + "provider_type": AIProviderType.OPEN_AI, + "enabled": True, + "order_by": Sorting([ + SortingRule(ListSupportedAiModelsOrderBy.KNOWLEDGE_CUTOFF, SortingOrder.DESC) + ]) + }, + { + "limit": 25, + "offset": 0, + "providerType": "open_ai", + "enabled": True, + "orderBy": "knowledgeCutoff desc", + } + ), + ), + ) + @mock.patch("crowdin_api.requester.APIRequester.request") + def test_list_supported_ai_provider_models(self, m_request, in_params, request_params, base_absolut_url): + m_request.return_value = "response" + + user_id = 1 + + resource = self.get_resource(base_absolut_url) + assert resource.list_supported_ai_provider_models(user_id, **in_params) == "response" + + m_request.assert_called_once_with( + method="get", + path=f"users/{user_id}/ai/providers/supported-models", + params=request_params + ) + + class TestEnterpriseAIResources: resource_class = EnterpriseAIResource @@ -2030,3 +2069,39 @@ def test_edit_ai_settings(self, m_request, incoming_data, request_params, base_a path="ai/settings", request_data=request_params, ) + + @pytest.mark.parametrize( + "in_params, request_params", + ( + ( + { + "limit": 25, + "offset": 0, + "provider_type": AIProviderType.OPEN_AI, + "enabled": True, + "order_by": Sorting([ + SortingRule(ListSupportedAiModelsOrderBy.KNOWLEDGE_CUTOFF, SortingOrder.DESC) + ]) + }, + { + "limit": 25, + "offset": 0, + "providerType": "open_ai", + "enabled": True, + "orderBy": "knowledgeCutoff desc", + } + ), + ), + ) + @mock.patch("crowdin_api.requester.APIRequester.request") + def test_list_supported_ai_provider_models(self, m_request, in_params, request_params, base_absolut_url): + m_request.return_value = "response" + + resource = self.get_resource(base_absolut_url) + assert resource.list_supported_ai_provider_models(**in_params) == "response" + + m_request.assert_called_once_with( + method="get", + path=f"ai/providers/supported-models", + params=request_params + ) From 2a65e520b9782fb9770ba70423c0fc6be3631bf7 Mon Sep 17 00:00:00 2001 From: Max Inno Date: Mon, 2 Feb 2026 08:52:42 +0200 Subject: [PATCH 2/5] fix: remove f-string --- crowdin_api/api_resources/ai/tests/test_ai_resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin_api/api_resources/ai/tests/test_ai_resources.py b/crowdin_api/api_resources/ai/tests/test_ai_resources.py index cfd966a..8cdcb50 100644 --- a/crowdin_api/api_resources/ai/tests/test_ai_resources.py +++ b/crowdin_api/api_resources/ai/tests/test_ai_resources.py @@ -2102,6 +2102,6 @@ def test_list_supported_ai_provider_models(self, m_request, in_params, request_p m_request.assert_called_once_with( method="get", - path=f"ai/providers/supported-models", + path="ai/providers/supported-models", params=request_params ) From 08dfb971c22994a93fca8b9bdb683700b081d37b Mon Sep 17 00:00:00 2001 From: Max Inno Date: Mon, 2 Feb 2026 08:55:02 +0200 Subject: [PATCH 3/5] fix: missing whitespace around operator --- crowdin_api/api_resources/ai/resource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin_api/api_resources/ai/resource.py b/crowdin_api/api_resources/ai/resource.py index 8520f35..b90ef3f 100644 --- a/crowdin_api/api_resources/ai/resource.py +++ b/crowdin_api/api_resources/ai/resource.py @@ -670,7 +670,7 @@ def list_supported_ai_provider_models( https://support.crowdin.com/developer/api/v2/#tag/AI/operation/api.ai.providers.supported-models.crowdin.getMany """ - params={ + params = { "limit": limit, "offset": offset, "providerType": convert_enum_to_string_if_exists(provider_type), From 72453ec75d1cf7abfa4f4b68f3e3a614cc9159ce Mon Sep 17 00:00:00 2001 From: Max Inno Date: Mon, 2 Feb 2026 08:56:43 +0200 Subject: [PATCH 4/5] fix: missing whitespace around operator --- crowdin_api/api_resources/ai/resource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin_api/api_resources/ai/resource.py b/crowdin_api/api_resources/ai/resource.py index b90ef3f..38678c2 100644 --- a/crowdin_api/api_resources/ai/resource.py +++ b/crowdin_api/api_resources/ai/resource.py @@ -1302,7 +1302,7 @@ def list_supported_ai_provider_models( https://support.crowdin.com/developer/enterprise/api/v2/#tag/AI/operation/api.ai.providers.supported-models.enterprise.getMany """ - params={ + params = { "limit": limit, "offset": offset, "providerType": convert_enum_to_string_if_exists(provider_type), From 9d5588e6bb6858182c9d2da9f12a0d69447657cd Mon Sep 17 00:00:00 2001 From: Max Inno Date: Mon, 2 Feb 2026 08:58:33 +0200 Subject: [PATCH 5/5] fix: too many blank lines --- crowdin_api/api_resources/ai/tests/test_ai_resources.py | 1 - 1 file changed, 1 deletion(-) diff --git a/crowdin_api/api_resources/ai/tests/test_ai_resources.py b/crowdin_api/api_resources/ai/tests/test_ai_resources.py index 8cdcb50..4002abd 100644 --- a/crowdin_api/api_resources/ai/tests/test_ai_resources.py +++ b/crowdin_api/api_resources/ai/tests/test_ai_resources.py @@ -1104,7 +1104,6 @@ def test_list_supported_ai_provider_models(self, m_request, in_params, request_p ) - class TestEnterpriseAIResources: resource_class = EnterpriseAIResource