From 697322c3b21998e3219cb1e794e7ab04d768025f Mon Sep 17 00:00:00 2001 From: Robert Fujara Date: Thu, 23 Oct 2025 15:38:06 +0200 Subject: [PATCH 1/5] Fix recipe validation rate limiting and connector metadata handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add automatic retry logic for 429 (Too Many Requests) errors with exponential backoff to handle API rate limits during recipe validation. Enable retries by default with 3 attempts using rate-limit-friendly timing (1s start, 120s max, 2x backoff factor). Fix validator trigger/action validation that was broken due to data structure mismatch. Convert connector actions and triggers from list format to dict format for proper validation. Improve data pill validation to handle different pill types (output, refs, project_property) with type-specific required field validation. Add comprehensive test coverage for retry behavior and update existing tests to work with new retry configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/.openapi-generator/VERSION | 2 +- src/workato_platform/__init__.py | 45 ++++ .../cli/commands/recipes/validator.py | 107 +++++++-- .../client/workato_api/__init__.py | 110 ++++++++- .../client/workato_api/api/__init__.py | 27 ++- .../client/workato_api/api_client.py | 5 +- .../client/workato_api/models/__init__.py | 84 ++++++- .../client/workato_api/models/data_table.py | 3 +- .../workato_api/models/data_table_column.py | 3 +- .../workato_api/models/data_table_relation.py | 7 +- .../client/workato_api_README.md | 2 +- tests/unit/commands/recipes/test_validator.py | 14 +- tests/unit/test_retry_429.py | 215 ++++++++++++++++++ tests/unit/test_workato_client.py | 43 ++++ 14 files changed, 630 insertions(+), 37 deletions(-) create mode 100644 tests/unit/test_retry_429.py diff --git a/src/.openapi-generator/VERSION b/src/.openapi-generator/VERSION index e465da4..368fd8f 100644 --- a/src/.openapi-generator/VERSION +++ b/src/.openapi-generator/VERSION @@ -1 +1 @@ -7.14.0 +7.15.0 diff --git a/src/workato_platform/__init__.py b/src/workato_platform/__init__.py index 86b5e26..9f6ff2f 100644 --- a/src/workato_platform/__init__.py +++ b/src/workato_platform/__init__.py @@ -4,6 +4,8 @@ from typing import Any +import aiohttp_retry # type: ignore[import-not-found] + try: from workato_platform._version import __version__ @@ -25,6 +27,46 @@ from workato_platform.client.workato_api.configuration import Configuration +def _configure_retry_with_429_support( + rest_client: Any, configuration: Configuration +) -> None: + """ + Configure REST client to retry on 429 (Too Many Requests) errors. + + This patches the auto-generated REST client to add 429 to the list of + retryable status codes with appropriate exponential backoff for rate limiting. + + Args: + rest_client: The RESTClientObject instance to configure + configuration: The Configuration object containing retry settings + """ + # Enable retries by default if not explicitly set + if configuration.retries is None: + configuration.retries = 3 + + # Update the retries setting on the REST client + rest_client.retries = configuration.retries + + # Force recreation of retry_client with 429 support + if rest_client.retry_client is not None: + rest_client.retry_client = None + + # The retry_client will be lazily created on first request with our patched settings + # We need to pre-create it here to ensure 429 support + if rest_client.retries is not None: + rest_client.retry_client = aiohttp_retry.RetryClient( + client_session=rest_client.pool_manager, + retry_options=aiohttp_retry.ExponentialRetry( + attempts=rest_client.retries, + factor=2.0, + start_timeout=1.0, # Increased from default 0.1s for rate limiting + max_timeout=120.0, # 2 minutes max + statuses={429}, # Add 429 Too Many Requests + retry_all_server_errors=True, # Keep 5xx errors + ), + ) + + class Workato: """Wrapper class that provides easy access to all Workato API endpoints.""" @@ -45,6 +87,9 @@ def __init__(self, configuration: Configuration): ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 ) + # Configure retry logic with 429 (Too Many Requests) support + _configure_retry_with_429_support(rest_client, configuration) + # Initialize all API endpoints self.projects_api = ProjectsApi(self._api_client) self.properties_api = PropertiesApi(self._api_client) diff --git a/src/workato_platform/cli/commands/recipes/validator.py b/src/workato_platform/cli/commands/recipes/validator.py index 2932c57..c6afc38 100644 --- a/src/workato_platform/cli/commands/recipes/validator.py +++ b/src/workato_platform/cli/commands/recipes/validator.py @@ -430,6 +430,7 @@ def _load_cached_connectors(self) -> bool: # Check cache age cache_age = time.time() - self._cache_file.stat().st_mtime + if cache_age > (self._cache_ttl_hours * 3600): return False # Cache expired @@ -581,13 +582,22 @@ async def _load_builtin_connectors(self) -> None: provider_name = platform_connector.name.lower() self.known_adapters.add(provider_name) + # Convert List[ConnectorAction] to dict for JSON serialization + # and validation. The validation logic expects dicts (calls .keys()), + # so we convert: List[ConnectorAction] -> {action.name: action.to_dict()} self.connector_metadata[provider_name] = { "type": "platform", "name": platform_connector.name, "deprecated": platform_connector.deprecated, "categories": platform_connector.categories, - "triggers": platform_connector.triggers, - "actions": platform_connector.actions, + "triggers": { + trigger.name: trigger.to_dict() + for trigger in platform_connector.triggers + }, + "actions": { + action.name: action.to_dict() + for action in platform_connector.actions + }, } # Fetch custom connectors @@ -603,12 +613,15 @@ async def _load_builtin_connectors(self) -> None: ) ) self.known_adapters.add(provider_name) + # Note: Custom connector trigger/action parsing is not implemented + # Using empty dicts for consistency with platform connector structure self.connector_metadata[provider_name] = { "type": "custom", "name": custom_connector.name, "code": code_response.data.code, - "triggers": [], # Not Implemented - "actions": [], # Not Implemented + "categories": [], # Custom connectors don't have categories + "triggers": {}, # Not Implemented - would need to parse code + "actions": {}, # Not Implemented - would need to parse code } # Save to cache for next time @@ -1225,26 +1238,70 @@ def check_value(value: Any, field_path: list[str] | None = None) -> None: # Parse the JSON structure dp_data = json.loads(dp_json) - # Validate required fields - required_fields = ["pill_type", "provider", "line", "path"] - for required_field in required_fields: - if required_field not in dp_data: - errors.append( - ValidationError( - message=( - f"Data pill missing required field " - f"'{required_field}' in step " - f"{line_number}" - ), - error_type=ErrorType.INPUT_INVALID_BY_ADAPTER, - line_number=line_number, - field_path=field_path + ["_dp"], - ) + # Validate required fields based on pill_type + pill_type = dp_data.get("pill_type") + + # All data pills must have pill_type + if not pill_type: + errors.append( + ValidationError( + message=( + "Data pill missing required field " + f"'pill_type' in step {line_number}" + ), + error_type=ErrorType.INPUT_INVALID_BY_ADAPTER, + line_number=line_number, + field_path=field_path + ["_dp"], ) + ) + else: + # Validate based on pill_type + if pill_type in ("output", "refs"): + # Output/refs pills need provider, line, path + required = ["provider", "line", "path"] + for field in required: + if field not in dp_data: + errors.append( + ValidationError( + message=( + f"Data pill with pill_type " + f"'{pill_type}' missing " + f"required field '{field}' " + f"in step {line_number}" + ), + error_type=( + ErrorType.INPUT_INVALID_BY_ADAPTER + ), + line_number=line_number, + field_path=field_path + ["_dp"], + ) + ) + elif pill_type == "project_property": + # Project property pills need property_name + if "property_name" not in dp_data: + errors.append( + ValidationError( + message=( + "Data pill with pill_type " + "'project_property' missing " + f"required field 'property_name' " + f"in step {line_number}" + ), + error_type=( + ErrorType.INPUT_INVALID_BY_ADAPTER + ), + line_number=line_number, + field_path=field_path + ["_dp"], + ) + ) + # Other pill types (e.g., "lookup", "variable") + # can be added here as needed - # Validate provider/line references exist + # Validate provider/line references exist (only for + # output/refs pills) if ( - "provider" in dp_data + pill_type in ("output", "refs") + and "provider" in dp_data and "line" in dp_data and not self._step_exists( dp_data["provider"], dp_data["line"] @@ -1264,9 +1321,11 @@ def check_value(value: Any, field_path: list[str] | None = None) -> None: ) ) - # Validate path is an array - if "path" in dp_data and not isinstance( - dp_data["path"], list + # Validate path is an array (only for output/refs pills) + if ( + pill_type in ("output", "refs") + and "path" in dp_data + and not isinstance(dp_data["path"], list) ): errors.append( ValidationError( diff --git a/src/workato_platform/client/workato_api/__init__.py b/src/workato_platform/client/workato_api/__init__.py index a328b6c..95e3a40 100644 --- a/src/workato_platform/client/workato_api/__init__.py +++ b/src/workato_platform/client/workato_api/__init__.py @@ -107,7 +107,109 @@ "ValidationErrorErrorsValue", ] -# import apis into sdk package +if __import__("typing").TYPE_CHECKING: + # import apis into sdk package + from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi as APIPlatformApi + from workato_platform.client.workato_api.api.connections_api import ConnectionsApi as ConnectionsApi + from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi as ConnectorsApi + from workato_platform.client.workato_api.api.data_tables_api import DataTablesApi as DataTablesApi + from workato_platform.client.workato_api.api.export_api import ExportApi as ExportApi + from workato_platform.client.workato_api.api.folders_api import FoldersApi as FoldersApi + from workato_platform.client.workato_api.api.packages_api import PackagesApi as PackagesApi + from workato_platform.client.workato_api.api.projects_api import ProjectsApi as ProjectsApi + from workato_platform.client.workato_api.api.properties_api import PropertiesApi as PropertiesApi + from workato_platform.client.workato_api.api.recipes_api import RecipesApi as RecipesApi + from workato_platform.client.workato_api.api.users_api import UsersApi as UsersApi + + # import ApiClient + from workato_platform.client.workato_api.api_response import ApiResponse as ApiResponse + from workato_platform.client.workato_api.api_client import ApiClient as ApiClient + from workato_platform.client.workato_api.configuration import Configuration as Configuration + from workato_platform.client.workato_api.exceptions import OpenApiException as OpenApiException + from workato_platform.client.workato_api.exceptions import ApiTypeError as ApiTypeError + from workato_platform.client.workato_api.exceptions import ApiValueError as ApiValueError + from workato_platform.client.workato_api.exceptions import ApiKeyError as ApiKeyError + from workato_platform.client.workato_api.exceptions import ApiAttributeError as ApiAttributeError + from workato_platform.client.workato_api.exceptions import ApiException as ApiException + + # import models into sdk package + from workato_platform.client.workato_api.models.api_client import ApiClient as ApiClient + from workato_platform.client.workato_api.models.api_client_api_collections_inner import ApiClientApiCollectionsInner as ApiClientApiCollectionsInner + from workato_platform.client.workato_api.models.api_client_api_policies_inner import ApiClientApiPoliciesInner as ApiClientApiPoliciesInner + from workato_platform.client.workato_api.models.api_client_create_request import ApiClientCreateRequest as ApiClientCreateRequest + from workato_platform.client.workato_api.models.api_client_list_response import ApiClientListResponse as ApiClientListResponse + from workato_platform.client.workato_api.models.api_client_response import ApiClientResponse as ApiClientResponse + from workato_platform.client.workato_api.models.api_collection import ApiCollection as ApiCollection + from workato_platform.client.workato_api.models.api_collection_create_request import ApiCollectionCreateRequest as ApiCollectionCreateRequest + from workato_platform.client.workato_api.models.api_endpoint import ApiEndpoint as ApiEndpoint + from workato_platform.client.workato_api.models.api_key import ApiKey as ApiKey + from workato_platform.client.workato_api.models.api_key_create_request import ApiKeyCreateRequest as ApiKeyCreateRequest + from workato_platform.client.workato_api.models.api_key_list_response import ApiKeyListResponse as ApiKeyListResponse + from workato_platform.client.workato_api.models.api_key_response import ApiKeyResponse as ApiKeyResponse + from workato_platform.client.workato_api.models.asset import Asset as Asset + from workato_platform.client.workato_api.models.asset_reference import AssetReference as AssetReference + from workato_platform.client.workato_api.models.connection import Connection as Connection + from workato_platform.client.workato_api.models.connection_create_request import ConnectionCreateRequest as ConnectionCreateRequest + from workato_platform.client.workato_api.models.connection_update_request import ConnectionUpdateRequest as ConnectionUpdateRequest + from workato_platform.client.workato_api.models.connector_action import ConnectorAction as ConnectorAction + from workato_platform.client.workato_api.models.connector_version import ConnectorVersion as ConnectorVersion + from workato_platform.client.workato_api.models.create_export_manifest_request import CreateExportManifestRequest as CreateExportManifestRequest + from workato_platform.client.workato_api.models.create_folder_request import CreateFolderRequest as CreateFolderRequest + from workato_platform.client.workato_api.models.custom_connector import CustomConnector as CustomConnector + from workato_platform.client.workato_api.models.custom_connector_code_response import CustomConnectorCodeResponse as CustomConnectorCodeResponse + from workato_platform.client.workato_api.models.custom_connector_code_response_data import CustomConnectorCodeResponseData as CustomConnectorCodeResponseData + from workato_platform.client.workato_api.models.custom_connector_list_response import CustomConnectorListResponse as CustomConnectorListResponse + from workato_platform.client.workato_api.models.data_table import DataTable as DataTable + from workato_platform.client.workato_api.models.data_table_column import DataTableColumn as DataTableColumn + from workato_platform.client.workato_api.models.data_table_column_request import DataTableColumnRequest as DataTableColumnRequest + from workato_platform.client.workato_api.models.data_table_create_request import DataTableCreateRequest as DataTableCreateRequest + from workato_platform.client.workato_api.models.data_table_create_response import DataTableCreateResponse as DataTableCreateResponse + from workato_platform.client.workato_api.models.data_table_list_response import DataTableListResponse as DataTableListResponse + from workato_platform.client.workato_api.models.data_table_relation import DataTableRelation as DataTableRelation + from workato_platform.client.workato_api.models.delete_project403_response import DeleteProject403Response as DeleteProject403Response + from workato_platform.client.workato_api.models.error import Error as Error + from workato_platform.client.workato_api.models.export_manifest_request import ExportManifestRequest as ExportManifestRequest + from workato_platform.client.workato_api.models.export_manifest_response import ExportManifestResponse as ExportManifestResponse + from workato_platform.client.workato_api.models.export_manifest_response_result import ExportManifestResponseResult as ExportManifestResponseResult + from workato_platform.client.workato_api.models.folder import Folder as Folder + from workato_platform.client.workato_api.models.folder_assets_response import FolderAssetsResponse as FolderAssetsResponse + from workato_platform.client.workato_api.models.folder_assets_response_result import FolderAssetsResponseResult as FolderAssetsResponseResult + from workato_platform.client.workato_api.models.folder_creation_response import FolderCreationResponse as FolderCreationResponse + from workato_platform.client.workato_api.models.import_results import ImportResults as ImportResults + from workato_platform.client.workato_api.models.o_auth_url_response import OAuthUrlResponse as OAuthUrlResponse + from workato_platform.client.workato_api.models.o_auth_url_response_data import OAuthUrlResponseData as OAuthUrlResponseData + from workato_platform.client.workato_api.models.open_api_spec import OpenApiSpec as OpenApiSpec + from workato_platform.client.workato_api.models.package_details_response import PackageDetailsResponse as PackageDetailsResponse + from workato_platform.client.workato_api.models.package_details_response_recipe_status_inner import PackageDetailsResponseRecipeStatusInner as PackageDetailsResponseRecipeStatusInner + from workato_platform.client.workato_api.models.package_response import PackageResponse as PackageResponse + from workato_platform.client.workato_api.models.picklist_request import PicklistRequest as PicklistRequest + from workato_platform.client.workato_api.models.picklist_response import PicklistResponse as PicklistResponse + from workato_platform.client.workato_api.models.platform_connector import PlatformConnector as PlatformConnector + from workato_platform.client.workato_api.models.platform_connector_list_response import PlatformConnectorListResponse as PlatformConnectorListResponse + from workato_platform.client.workato_api.models.project import Project as Project + from workato_platform.client.workato_api.models.recipe import Recipe as Recipe + from workato_platform.client.workato_api.models.recipe_config_inner import RecipeConfigInner as RecipeConfigInner + from workato_platform.client.workato_api.models.recipe_connection_update_request import RecipeConnectionUpdateRequest as RecipeConnectionUpdateRequest + from workato_platform.client.workato_api.models.recipe_list_response import RecipeListResponse as RecipeListResponse + from workato_platform.client.workato_api.models.recipe_start_response import RecipeStartResponse as RecipeStartResponse + from workato_platform.client.workato_api.models.runtime_user_connection_create_request import RuntimeUserConnectionCreateRequest as RuntimeUserConnectionCreateRequest + from workato_platform.client.workato_api.models.runtime_user_connection_response import RuntimeUserConnectionResponse as RuntimeUserConnectionResponse + from workato_platform.client.workato_api.models.runtime_user_connection_response_data import RuntimeUserConnectionResponseData as RuntimeUserConnectionResponseData + from workato_platform.client.workato_api.models.success_response import SuccessResponse as SuccessResponse + from workato_platform.client.workato_api.models.upsert_project_properties_request import UpsertProjectPropertiesRequest as UpsertProjectPropertiesRequest + from workato_platform.client.workato_api.models.user import User as User + from workato_platform.client.workato_api.models.validation_error import ValidationError as ValidationError + from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue as ValidationErrorErrorsValue + +else: + from lazy_imports import LazyModule, as_package, load + + load( + LazyModule( + *as_package(__file__), + ("__version__", __version__), + ("__all__", __all__), + """# import apis into sdk package from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi as APIPlatformApi from workato_platform.client.workato_api.api.connections_api import ConnectionsApi as ConnectionsApi from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi as ConnectorsApi @@ -199,3 +301,9 @@ from workato_platform.client.workato_api.models.user import User as User from workato_platform.client.workato_api.models.validation_error import ValidationError as ValidationError from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue as ValidationErrorErrorsValue + +""", + name=__name__, + doc=__doc__, + ) + ) diff --git a/src/workato_platform/client/workato_api/api/__init__.py b/src/workato_platform/client/workato_api/api/__init__.py index a0e5380..4e41a38 100644 --- a/src/workato_platform/client/workato_api/api/__init__.py +++ b/src/workato_platform/client/workato_api/api/__init__.py @@ -1,6 +1,26 @@ # flake8: noqa -# import apis into api package +if __import__("typing").TYPE_CHECKING: + # import apis into api package + from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi + from workato_platform.client.workato_api.api.connections_api import ConnectionsApi + from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi + from workato_platform.client.workato_api.api.data_tables_api import DataTablesApi + from workato_platform.client.workato_api.api.export_api import ExportApi + from workato_platform.client.workato_api.api.folders_api import FoldersApi + from workato_platform.client.workato_api.api.packages_api import PackagesApi + from workato_platform.client.workato_api.api.projects_api import ProjectsApi + from workato_platform.client.workato_api.api.properties_api import PropertiesApi + from workato_platform.client.workato_api.api.recipes_api import RecipesApi + from workato_platform.client.workato_api.api.users_api import UsersApi + +else: + from lazy_imports import LazyModule, as_package, load + + load( + LazyModule( + *as_package(__file__), + """# import apis into api package from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi from workato_platform.client.workato_api.api.connections_api import ConnectionsApi from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi @@ -13,3 +33,8 @@ from workato_platform.client.workato_api.api.recipes_api import RecipesApi from workato_platform.client.workato_api.api.users_api import UsersApi +""", + name=__name__, + doc=__doc__, + ) + ) diff --git a/src/workato_platform/client/workato_api/api_client.py b/src/workato_platform/client/workato_api/api_client.py index dcb076b..3c8bd2b 100644 --- a/src/workato_platform/client/workato_api/api_client.py +++ b/src/workato_platform/client/workato_api/api_client.py @@ -21,6 +21,7 @@ import os import re import tempfile +import uuid from urllib.parse import quote from typing import Tuple, Optional, List, Dict, Union @@ -359,6 +360,8 @@ def sanitize_for_serialization(self, obj): return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): return obj + elif isinstance(obj, uuid.UUID): + return str(obj) elif isinstance(obj, list): return [ self.sanitize_for_serialization(sub_obj) for sub_obj in obj @@ -411,7 +414,7 @@ def deserialize(self, response_text: str, response_type: str, content_type: Opti data = json.loads(response_text) except ValueError: data = response_text - elif re.match(r'^application/(json|[\w!#$&.+-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE): + elif re.match(r'^application/(json|[\w!#$&.+\-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE): if response_text == "": data = "" else: diff --git a/src/workato_platform/client/workato_api/models/__init__.py b/src/workato_platform/client/workato_api/models/__init__.py index e0ad6ae..7d4a8e8 100644 --- a/src/workato_platform/client/workato_api/models/__init__.py +++ b/src/workato_platform/client/workato_api/models/__init__.py @@ -13,7 +13,83 @@ """ # noqa: E501 -# import models into model package +if __import__("typing").TYPE_CHECKING: + # import models into model package + from workato_platform.client.workato_api.models.api_client import ApiClient + from workato_platform.client.workato_api.models.api_client_api_collections_inner import ApiClientApiCollectionsInner + from workato_platform.client.workato_api.models.api_client_api_policies_inner import ApiClientApiPoliciesInner + from workato_platform.client.workato_api.models.api_client_create_request import ApiClientCreateRequest + from workato_platform.client.workato_api.models.api_client_list_response import ApiClientListResponse + from workato_platform.client.workato_api.models.api_client_response import ApiClientResponse + from workato_platform.client.workato_api.models.api_collection import ApiCollection + from workato_platform.client.workato_api.models.api_collection_create_request import ApiCollectionCreateRequest + from workato_platform.client.workato_api.models.api_endpoint import ApiEndpoint + from workato_platform.client.workato_api.models.api_key import ApiKey + from workato_platform.client.workato_api.models.api_key_create_request import ApiKeyCreateRequest + from workato_platform.client.workato_api.models.api_key_list_response import ApiKeyListResponse + from workato_platform.client.workato_api.models.api_key_response import ApiKeyResponse + from workato_platform.client.workato_api.models.asset import Asset + from workato_platform.client.workato_api.models.asset_reference import AssetReference + from workato_platform.client.workato_api.models.connection import Connection + from workato_platform.client.workato_api.models.connection_create_request import ConnectionCreateRequest + from workato_platform.client.workato_api.models.connection_update_request import ConnectionUpdateRequest + from workato_platform.client.workato_api.models.connector_action import ConnectorAction + from workato_platform.client.workato_api.models.connector_version import ConnectorVersion + from workato_platform.client.workato_api.models.create_export_manifest_request import CreateExportManifestRequest + from workato_platform.client.workato_api.models.create_folder_request import CreateFolderRequest + from workato_platform.client.workato_api.models.custom_connector import CustomConnector + from workato_platform.client.workato_api.models.custom_connector_code_response import CustomConnectorCodeResponse + from workato_platform.client.workato_api.models.custom_connector_code_response_data import CustomConnectorCodeResponseData + from workato_platform.client.workato_api.models.custom_connector_list_response import CustomConnectorListResponse + from workato_platform.client.workato_api.models.data_table import DataTable + from workato_platform.client.workato_api.models.data_table_column import DataTableColumn + from workato_platform.client.workato_api.models.data_table_column_request import DataTableColumnRequest + from workato_platform.client.workato_api.models.data_table_create_request import DataTableCreateRequest + from workato_platform.client.workato_api.models.data_table_create_response import DataTableCreateResponse + from workato_platform.client.workato_api.models.data_table_list_response import DataTableListResponse + from workato_platform.client.workato_api.models.data_table_relation import DataTableRelation + from workato_platform.client.workato_api.models.delete_project403_response import DeleteProject403Response + from workato_platform.client.workato_api.models.error import Error + from workato_platform.client.workato_api.models.export_manifest_request import ExportManifestRequest + from workato_platform.client.workato_api.models.export_manifest_response import ExportManifestResponse + from workato_platform.client.workato_api.models.export_manifest_response_result import ExportManifestResponseResult + from workato_platform.client.workato_api.models.folder import Folder + from workato_platform.client.workato_api.models.folder_assets_response import FolderAssetsResponse + from workato_platform.client.workato_api.models.folder_assets_response_result import FolderAssetsResponseResult + from workato_platform.client.workato_api.models.folder_creation_response import FolderCreationResponse + from workato_platform.client.workato_api.models.import_results import ImportResults + from workato_platform.client.workato_api.models.o_auth_url_response import OAuthUrlResponse + from workato_platform.client.workato_api.models.o_auth_url_response_data import OAuthUrlResponseData + from workato_platform.client.workato_api.models.open_api_spec import OpenApiSpec + from workato_platform.client.workato_api.models.package_details_response import PackageDetailsResponse + from workato_platform.client.workato_api.models.package_details_response_recipe_status_inner import PackageDetailsResponseRecipeStatusInner + from workato_platform.client.workato_api.models.package_response import PackageResponse + from workato_platform.client.workato_api.models.picklist_request import PicklistRequest + from workato_platform.client.workato_api.models.picklist_response import PicklistResponse + from workato_platform.client.workato_api.models.platform_connector import PlatformConnector + from workato_platform.client.workato_api.models.platform_connector_list_response import PlatformConnectorListResponse + from workato_platform.client.workato_api.models.project import Project + from workato_platform.client.workato_api.models.recipe import Recipe + from workato_platform.client.workato_api.models.recipe_config_inner import RecipeConfigInner + from workato_platform.client.workato_api.models.recipe_connection_update_request import RecipeConnectionUpdateRequest + from workato_platform.client.workato_api.models.recipe_list_response import RecipeListResponse + from workato_platform.client.workato_api.models.recipe_start_response import RecipeStartResponse + from workato_platform.client.workato_api.models.runtime_user_connection_create_request import RuntimeUserConnectionCreateRequest + from workato_platform.client.workato_api.models.runtime_user_connection_response import RuntimeUserConnectionResponse + from workato_platform.client.workato_api.models.runtime_user_connection_response_data import RuntimeUserConnectionResponseData + from workato_platform.client.workato_api.models.success_response import SuccessResponse + from workato_platform.client.workato_api.models.upsert_project_properties_request import UpsertProjectPropertiesRequest + from workato_platform.client.workato_api.models.user import User + from workato_platform.client.workato_api.models.validation_error import ValidationError + from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue + +else: + from lazy_imports import LazyModule, as_package, load + + load( + LazyModule( + *as_package(__file__), + """# import models into model package from workato_platform.client.workato_api.models.api_client import ApiClient from workato_platform.client.workato_api.models.api_client_api_collections_inner import ApiClientApiCollectionsInner from workato_platform.client.workato_api.models.api_client_api_policies_inner import ApiClientApiPoliciesInner @@ -81,3 +157,9 @@ from workato_platform.client.workato_api.models.user import User from workato_platform.client.workato_api.models.validation_error import ValidationError from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue + +""", + name=__name__, + doc=__doc__, + ) + ) diff --git a/src/workato_platform/client/workato_api/models/data_table.py b/src/workato_platform/client/workato_api/models/data_table.py index daac153..dd1048c 100644 --- a/src/workato_platform/client/workato_api/models/data_table.py +++ b/src/workato_platform/client/workato_api/models/data_table.py @@ -20,6 +20,7 @@ from datetime import datetime from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr from typing import Any, ClassVar, Dict, List +from uuid import UUID from workato_platform.client.workato_api.models.data_table_column import DataTableColumn from typing import Optional, Set from typing_extensions import Self @@ -28,7 +29,7 @@ class DataTable(BaseModel): """ DataTable """ # noqa: E501 - id: StrictStr + id: UUID name: StrictStr var_schema: List[DataTableColumn] = Field(alias="schema") folder_id: StrictInt diff --git a/src/workato_platform/client/workato_api/models/data_table_column.py b/src/workato_platform/client/workato_api/models/data_table_column.py index e9eb3ea..3bb7b48 100644 --- a/src/workato_platform/client/workato_api/models/data_table_column.py +++ b/src/workato_platform/client/workato_api/models/data_table_column.py @@ -19,6 +19,7 @@ from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator from typing import Any, ClassVar, Dict, List, Optional +from uuid import UUID from workato_platform.client.workato_api.models.data_table_relation import DataTableRelation from typing import Optional, Set from typing_extensions import Self @@ -30,7 +31,7 @@ class DataTableColumn(BaseModel): type: StrictStr name: StrictStr optional: StrictBool - field_id: StrictStr + field_id: UUID hint: Optional[StrictStr] default_value: Optional[Any] = Field(description="Default value matching the column type") metadata: Dict[str, Any] diff --git a/src/workato_platform/client/workato_api/models/data_table_relation.py b/src/workato_platform/client/workato_api/models/data_table_relation.py index 86a4e00..4e60838 100644 --- a/src/workato_platform/client/workato_api/models/data_table_relation.py +++ b/src/workato_platform/client/workato_api/models/data_table_relation.py @@ -17,8 +17,9 @@ import re # noqa: F401 import json -from pydantic import BaseModel, ConfigDict, StrictStr +from pydantic import BaseModel, ConfigDict from typing import Any, ClassVar, Dict, List +from uuid import UUID from typing import Optional, Set from typing_extensions import Self @@ -26,8 +27,8 @@ class DataTableRelation(BaseModel): """ DataTableRelation """ # noqa: E501 - table_id: StrictStr - field_id: StrictStr + table_id: UUID + field_id: UUID __properties: ClassVar[List[str]] = ["table_id", "field_id"] model_config = ConfigDict( diff --git a/src/workato_platform/client/workato_api_README.md b/src/workato_platform/client/workato_api_README.md index ec0490f..6c460a8 100644 --- a/src/workato_platform/client/workato_api_README.md +++ b/src/workato_platform/client/workato_api_README.md @@ -5,7 +5,7 @@ The `workato_platform.client.workato_api` package is automatically generated by - API version: 1.0.0 - Package version: 1.0.0 -- Generator version: 7.14.0 +- Generator version: 7.15.0 - Build package: org.openapitools.codegen.languages.PythonClientCodegen For more information, please visit [https://docs.workato.com](https://docs.workato.com) diff --git a/tests/unit/commands/recipes/test_validator.py b/tests/unit/commands/recipes/test_validator.py index 5f6e398..a25ce85 100644 --- a/tests/unit/commands/recipes/test_validator.py +++ b/tests/unit/commands/recipes/test_validator.py @@ -1110,11 +1110,21 @@ async def test_load_builtin_connectors_from_api(validator: RecipeValidator) -> N """Test loading connectors from API when cache fails""" # Mock API responses mock_platform_response = MagicMock() + + # Create mock ConnectorAction objects + mock_trigger = Mock() + mock_trigger.name = "webhook" + mock_trigger.to_dict = Mock(return_value={"name": "webhook", "title": "Webhook"}) + + mock_action = Mock() + mock_action.name = "get" + mock_action.to_dict = Mock(return_value={"name": "get", "title": "GET request"}) + platform_connector = Mock( deprecated=False, categories=["Data"], - triggers={"webhook": {}}, - actions={"get": {}}, + triggers=[mock_trigger], + actions=[mock_action], ) platform_connector.name = "HTTP" mock_platform_response.items = [platform_connector] diff --git a/tests/unit/test_retry_429.py b/tests/unit/test_retry_429.py new file mode 100644 index 0000000..874f90e --- /dev/null +++ b/tests/unit/test_retry_429.py @@ -0,0 +1,215 @@ +"""Tests for 429 retry configuration in Workato API client.""" + +from unittest.mock import Mock, patch + +import pytest + + +class TestRetry429Configuration: + """Test that 429 (Too Many Requests) errors are properly configured for retry.""" + + def test_retries_enabled_by_default(self) -> None: + """Test that retries are enabled by default when not explicitly set.""" + try: + from workato_platform import Workato + + with patch("workato_platform.ApiClient") as mock_api_client: + mock_configuration = Mock() + mock_configuration.retries = None # Not explicitly set + + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + + Workato(mock_configuration) + + # Should be set to default value of 3 + assert mock_configuration.retries == 3 + assert mock_rest_client.retries == 3 + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") + + def test_custom_retry_count_preserved(self) -> None: + """Test that explicitly set retry count is preserved.""" + try: + from workato_platform import Workato + + with patch("workato_platform.ApiClient") as mock_api_client: + mock_configuration = Mock() + mock_configuration.retries = 5 # Custom value + + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + + Workato(mock_configuration) + + # Should keep custom value + assert mock_configuration.retries == 5 + assert mock_rest_client.retries == 5 + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") + + def test_retry_client_created_with_429_support(self) -> None: + """Test that retry client is created with 429 status code support.""" + try: + from workato_platform import Workato + + with ( + patch("workato_platform.ApiClient") as mock_api_client, + patch("aiohttp_retry.RetryClient"), + patch("aiohttp_retry.ExponentialRetry") as mock_exponential_retry, + ): + mock_configuration = Mock() + mock_configuration.retries = None + + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + + Workato(mock_configuration) + + # Verify ExponentialRetry was called with correct parameters + mock_exponential_retry.assert_called_once() + call_kwargs = mock_exponential_retry.call_args[1] + + assert call_kwargs["attempts"] == 3 + assert call_kwargs["factor"] == 2.0 + assert call_kwargs["start_timeout"] == 1.0 + assert call_kwargs["max_timeout"] == 120.0 + assert call_kwargs["statuses"] == {429} + assert call_kwargs["retry_all_server_errors"] is True + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") + + def test_exponential_backoff_timing(self) -> None: + """Test that exponential backoff uses correct timing for rate limiting.""" + try: + from workato_platform import Workato + + with ( + patch("workato_platform.ApiClient") as mock_api_client, + patch("aiohttp_retry.ExponentialRetry") as mock_exponential_retry, + ): + mock_configuration = Mock() + mock_configuration.retries = 3 + + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + + Workato(mock_configuration) + + # Verify timing parameters + call_kwargs = mock_exponential_retry.call_args[1] + assert call_kwargs["start_timeout"] == 1.0 # 1 second (not 0.1s) + assert call_kwargs["max_timeout"] == 120.0 # 2 minutes + assert call_kwargs["factor"] == 2.0 # 2x backoff + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") + + def test_configure_retry_helper_function(self) -> None: + """Test the _configure_retry_with_429_support helper function directly.""" + try: + from workato_platform import _configure_retry_with_429_support + + with ( + patch("aiohttp_retry.RetryClient") as mock_retry_client, + patch("aiohttp_retry.ExponentialRetry"), + ): + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + + mock_configuration = Mock() + mock_configuration.retries = None + + _configure_retry_with_429_support(mock_rest_client, mock_configuration) + + # Verify retries were set to default + assert mock_configuration.retries == 3 + assert mock_rest_client.retries == 3 + + # Verify retry client was created + mock_retry_client.assert_called_once() + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") + + def test_retry_client_recreated_if_exists(self) -> None: + """Test that existing retry_client is recreated with new config.""" + try: + from workato_platform import _configure_retry_with_429_support + + with ( + patch("aiohttp_retry.RetryClient") as mock_retry_client, + ): + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = Mock() # Pre-existing retry client + + mock_configuration = Mock() + mock_configuration.retries = 5 + + _configure_retry_with_429_support(mock_rest_client, mock_configuration) + + # Old retry_client should be set to None + # New retry_client should be created + mock_retry_client.assert_called_once() + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") + + def test_server_errors_still_retried(self) -> None: + """Test that 5xx server errors are still retried alongside 429.""" + try: + from workato_platform import Workato + + with ( + patch("workato_platform.ApiClient") as mock_api_client, + patch("aiohttp_retry.ExponentialRetry") as mock_exponential_retry, + ): + mock_configuration = Mock() + mock_configuration.retries = 3 + + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + + Workato(mock_configuration) + + # Verify retry_all_server_errors is True + call_kwargs = mock_exponential_retry.call_args[1] + assert call_kwargs["retry_all_server_errors"] is True + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") diff --git a/tests/unit/test_workato_client.py b/tests/unit/test_workato_client.py index b5632a0..ea5ea56 100644 --- a/tests/unit/test_workato_client.py +++ b/tests/unit/test_workato_client.py @@ -64,14 +64,24 @@ def test_workato_api_endpoints_structure(self) -> None: # Create mock configuration with proper SSL attributes with ( patch("workato_platform.Configuration") as mock_config, + patch("workato_platform.ApiClient") as mock_api_client, ): mock_configuration = Mock() mock_configuration.connection_pool_maxsize = 10 mock_configuration.ssl_ca_cert = None mock_configuration.ca_cert_data = None mock_configuration.cert_file = None + mock_configuration.retries = None mock_config.return_value = mock_configuration + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + client = Workato(mock_configuration) # Check that expected API endpoints exist as attributes @@ -276,3 +286,36 @@ def test_workato_all_api_endpoints_initialized(self) -> None: except ImportError: pytest.skip("Workato class not available due to missing dependencies") + + def test_workato_retry_429_configured(self) -> None: + """Test that retry logic with 429 support is configured.""" + try: + from workato_platform import Workato + + with ( + patch("workato_platform.ApiClient") as mock_api_client, + patch("aiohttp_retry.RetryClient") as mock_retry_client, + ): + mock_configuration = Mock() + mock_configuration.retries = None # Should default to 3 + + mock_client_instance = Mock() + mock_rest_client = Mock() + mock_rest_client.pool_manager = Mock() + mock_rest_client.retry_client = None + mock_rest_client.ssl_context = Mock() + + mock_api_client.return_value = mock_client_instance + mock_client_instance.rest_client = mock_rest_client + + Workato(mock_configuration) + + # Verify retries were enabled + assert mock_configuration.retries == 3 + assert mock_rest_client.retries == 3 + + # Verify RetryClient was created + mock_retry_client.assert_called_once() + + except ImportError: + pytest.skip("Workato class not available due to missing dependencies") From 5cdb309b1efab5cce1482c7e6161a3998db0c130 Mon Sep 17 00:00:00 2001 From: Robert Fujara Date: Thu, 23 Oct 2025 15:59:05 +0200 Subject: [PATCH 2/5] Fix ConnectorAction model validation error for null title field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the OpenAPI spec to make the ConnectorAction.title field optional and nullable, reflecting the actual API behavior where some connector actions/triggers return null for this field. Also added lazy-imports dependency required by the auto-generated OpenAPI client code. Changes: - Updated ConnectorAction schema in workato-api-spec.yaml - Added lazy-imports>=0.3.1 to pyproject.toml dependencies - Regenerated OpenAPI client with updated spec 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pyproject.toml | 1 + .../client/workato_api/docs/ConnectorAction.md | 2 +- .../client/workato_api/models/connector_action.py | 9 +++++++-- uv.lock | 11 +++++++++++ workato-api-spec.yaml | 2 +- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 343a243..32bf22f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ dependencies = [ "keyring>=25.6.0", "ruff==0.13.0", "urllib3>=2.5.0", + "lazy-imports>=0.3.1", ] [project.optional-dependencies] diff --git a/src/workato_platform/client/workato_api/docs/ConnectorAction.md b/src/workato_platform/client/workato_api/docs/ConnectorAction.md index 760d8cc..dbc4713 100644 --- a/src/workato_platform/client/workato_api/docs/ConnectorAction.md +++ b/src/workato_platform/client/workato_api/docs/ConnectorAction.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **name** | **str** | | -**title** | **str** | | +**title** | **str** | | [optional] **deprecated** | **bool** | | **bulk** | **bool** | | **batch** | **bool** | | diff --git a/src/workato_platform/client/workato_api/models/connector_action.py b/src/workato_platform/client/workato_api/models/connector_action.py index 34a9726..7fa08f3 100644 --- a/src/workato_platform/client/workato_api/models/connector_action.py +++ b/src/workato_platform/client/workato_api/models/connector_action.py @@ -18,7 +18,7 @@ import json from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr -from typing import Any, ClassVar, Dict, List +from typing import Any, ClassVar, Dict, List, Optional from typing import Optional, Set from typing_extensions import Self @@ -27,7 +27,7 @@ class ConnectorAction(BaseModel): ConnectorAction """ # noqa: E501 name: StrictStr - title: StrictStr + title: Optional[StrictStr] = None deprecated: StrictBool bulk: StrictBool batch: StrictBool @@ -72,6 +72,11 @@ def to_dict(self) -> Dict[str, Any]: exclude=excluded_fields, exclude_none=True, ) + # set to None if title (nullable) is None + # and model_fields_set contains the field + if self.title is None and "title" in self.model_fields_set: + _dict['title'] = None + return _dict @classmethod diff --git a/uv.lock b/uv.lock index 9e56840..a71d65d 100644 --- a/uv.lock +++ b/uv.lock @@ -807,6 +807,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085, upload-time = "2024-12-25T15:26:44.377Z" }, ] +[[package]] +name = "lazy-imports" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/1c/6675601691fd6007021e8e95cfcb83e6d11067de3d7ecde0d0de970324c8/lazy_imports-1.0.1.tar.gz", hash = "sha256:7d3e4b1547cb574ec7ef3c47a074673e2612330b2b50bf7eec939f2c393fc261", size = 24484, upload-time = "2025-08-09T07:15:55.353Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/37/c84d7fec58dec38564574dec8f94bb1db788598fe397f116a9d6a86d3055/lazy_imports-1.0.1-py3-none-any.whl", hash = "sha256:eb5accc33bf9987e5197e79476bbeb960b74a2c16619bdf41281b3240f730846", size = 18896, upload-time = "2025-08-09T07:15:53.7Z" }, +] + [[package]] name = "license-expression" version = "30.4.4" @@ -1718,6 +1727,7 @@ dependencies = [ { name = "dependency-injector" }, { name = "inquirer" }, { name = "keyring" }, + { name = "lazy-imports" }, { name = "packaging" }, { name = "pydantic" }, { name = "python-dateutil" }, @@ -1773,6 +1783,7 @@ requires-dist = [ { name = "dependency-injector", specifier = ">=4.41.0" }, { name = "inquirer", specifier = ">=3.1.0" }, { name = "keyring", specifier = ">=25.6.0" }, + { name = "lazy-imports", specifier = ">=0.3.1" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.0.0" }, { name = "packaging", specifier = ">=21.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.0.0" }, diff --git a/workato-api-spec.yaml b/workato-api-spec.yaml index 7a0e922..60257ab 100644 --- a/workato-api-spec.yaml +++ b/workato-api-spec.yaml @@ -2454,7 +2454,6 @@ components: type: object required: - name - - title - deprecated - bulk - batch @@ -2464,6 +2463,7 @@ components: example: "new_entry" title: type: string + nullable: true example: "New entry" deprecated: type: boolean From 4779083fd4b4317bb192facd60344c1b97427d71 Mon Sep 17 00:00:00 2001 From: Robert Fujara Date: Thu, 23 Oct 2025 16:15:48 +0200 Subject: [PATCH 3/5] Fix mypy configuration consistency between local and CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add aiohttp-retry to pre-commit mypy additional_dependencies - Remove unused type ignore comment for aiohttp_retry import - Ensures both local pre-commit and GitHub Actions mypy use same config 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .pre-commit-config.yaml | 1 + src/workato_platform/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f404495..794ba02 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,7 @@ repos: dependency-injector>=4.41.0, inquirer>=3.1.0, aiohttp>=3.8.0, + aiohttp-retry>=2.8.0, python-dateutil>=2.8.0, typing-extensions>=4.0.0, pytest>=7.0.0, diff --git a/src/workato_platform/__init__.py b/src/workato_platform/__init__.py index 9f6ff2f..88d7111 100644 --- a/src/workato_platform/__init__.py +++ b/src/workato_platform/__init__.py @@ -4,7 +4,7 @@ from typing import Any -import aiohttp_retry # type: ignore[import-not-found] +import aiohttp_retry try: From 25f219ed6255c616082f1fc43e3d4e1277f69757 Mon Sep 17 00:00:00 2001 From: Robert Fujara Date: Fri, 24 Oct 2025 09:32:04 +0200 Subject: [PATCH 4/5] Fix typo in custom connectors variable name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed 'customer_connectores_response' to 'custom_connectors_response' in recipe validator to correctly reflect the variable's purpose and improve code readability. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/workato_platform/cli/commands/recipes/validator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workato_platform/cli/commands/recipes/validator.py b/src/workato_platform/cli/commands/recipes/validator.py index c6afc38..b6447fb 100644 --- a/src/workato_platform/cli/commands/recipes/validator.py +++ b/src/workato_platform/cli/commands/recipes/validator.py @@ -601,11 +601,11 @@ async def _load_builtin_connectors(self) -> None: } # Fetch custom connectors - customer_connectores_response = ( + custom_connectors_response = ( await self.workato_api_client.connectors_api.list_custom_connectors() ) - for custom_connector in customer_connectores_response.result: + for custom_connector in custom_connectors_response.result: provider_name = custom_connector.name.lower() code_response = ( await self.workato_api_client.connectors_api.get_custom_connector_code( From 7b3238763b7ea72cd54fb78de515f7b470326283 Mon Sep 17 00:00:00 2001 From: Robert Fujara Date: Fri, 24 Oct 2025 10:16:25 +0200 Subject: [PATCH 5/5] Remove lazy-imports dependency and fix ShadowingWarning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upgraded openapi-generator-cli to 7.16.0 and disabled lazy imports to: 1. Eliminate the lazy-imports dependency (supply-chain security concern) 2. Resolve ShadowingWarning about ApiClient naming conflict The lazy-imports package was causing a ShadowingWarning due to ApiClient being imported from both workato_api.models.api_client and workato_api.api_client. By removing lazy-imports entirely, both issues are resolved. Changes: - Upgraded openapi-generator-cli from 7.15.0 to 7.16.0 - Added lazyImports: false to openapi-config.yaml - Removed lazy-imports>=0.3.1 from project dependencies - Regenerated OpenAPI client with lazy imports disabled - Generated code now uses direct imports instead of lazy loading The trade-off of slightly slower import times is acceptable for our API size in exchange for reduced dependencies and security surface area. All tests, linting, and type checking pass. Resolves DEVP-287: Document lazy-imports dependency purpose and usage Resolves DEVP-289: Fix ShadowingWarning from lazy-imports when running CLI 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- openapi-config.yaml | 1 + pyproject.toml | 3 +- src/.openapi-generator/VERSION | 2 +- .../client/workato_api/__init__.py | 109 +----------------- .../client/workato_api/api/__init__.py | 27 +---- .../client/workato_api/api_client.py | 8 +- .../client/workato_api/models/__init__.py | 84 +------------- .../client/workato_api_README.md | 2 +- uv.lock | 19 +-- 9 files changed, 15 insertions(+), 240 deletions(-) diff --git a/openapi-config.yaml b/openapi-config.yaml index 1530afc..56fb6ce 100644 --- a/openapi-config.yaml +++ b/openapi-config.yaml @@ -5,3 +5,4 @@ packageVersion: 1.0.0 packageUrl: https://github.com/workato/workato-platform-cli hideGenerationTimestamp: true generateSourceCodeOnly: true +lazyImports: false diff --git a/pyproject.toml b/pyproject.toml index 32bf22f..2775e9d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,6 @@ dependencies = [ "keyring>=25.6.0", "ruff==0.13.0", "urllib3>=2.5.0", - "lazy-imports>=0.3.1", ] [project.optional-dependencies] @@ -237,7 +236,7 @@ dev = [ "build>=1.3.0", "hatch-vcs>=0.5.0", "mypy>=1.17.1", - "openapi-generator-cli>=7.15.0", + "openapi-generator-cli>=7.16.0", "pip-audit>=2.9.0", "pre-commit>=4.3.0", "pytest>=7.0.0", diff --git a/src/.openapi-generator/VERSION b/src/.openapi-generator/VERSION index 368fd8f..971ecb2 100644 --- a/src/.openapi-generator/VERSION +++ b/src/.openapi-generator/VERSION @@ -1 +1 @@ -7.15.0 +7.16.0 diff --git a/src/workato_platform/client/workato_api/__init__.py b/src/workato_platform/client/workato_api/__init__.py index 95e3a40..279a191 100644 --- a/src/workato_platform/client/workato_api/__init__.py +++ b/src/workato_platform/client/workato_api/__init__.py @@ -107,109 +107,7 @@ "ValidationErrorErrorsValue", ] -if __import__("typing").TYPE_CHECKING: - # import apis into sdk package - from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi as APIPlatformApi - from workato_platform.client.workato_api.api.connections_api import ConnectionsApi as ConnectionsApi - from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi as ConnectorsApi - from workato_platform.client.workato_api.api.data_tables_api import DataTablesApi as DataTablesApi - from workato_platform.client.workato_api.api.export_api import ExportApi as ExportApi - from workato_platform.client.workato_api.api.folders_api import FoldersApi as FoldersApi - from workato_platform.client.workato_api.api.packages_api import PackagesApi as PackagesApi - from workato_platform.client.workato_api.api.projects_api import ProjectsApi as ProjectsApi - from workato_platform.client.workato_api.api.properties_api import PropertiesApi as PropertiesApi - from workato_platform.client.workato_api.api.recipes_api import RecipesApi as RecipesApi - from workato_platform.client.workato_api.api.users_api import UsersApi as UsersApi - - # import ApiClient - from workato_platform.client.workato_api.api_response import ApiResponse as ApiResponse - from workato_platform.client.workato_api.api_client import ApiClient as ApiClient - from workato_platform.client.workato_api.configuration import Configuration as Configuration - from workato_platform.client.workato_api.exceptions import OpenApiException as OpenApiException - from workato_platform.client.workato_api.exceptions import ApiTypeError as ApiTypeError - from workato_platform.client.workato_api.exceptions import ApiValueError as ApiValueError - from workato_platform.client.workato_api.exceptions import ApiKeyError as ApiKeyError - from workato_platform.client.workato_api.exceptions import ApiAttributeError as ApiAttributeError - from workato_platform.client.workato_api.exceptions import ApiException as ApiException - - # import models into sdk package - from workato_platform.client.workato_api.models.api_client import ApiClient as ApiClient - from workato_platform.client.workato_api.models.api_client_api_collections_inner import ApiClientApiCollectionsInner as ApiClientApiCollectionsInner - from workato_platform.client.workato_api.models.api_client_api_policies_inner import ApiClientApiPoliciesInner as ApiClientApiPoliciesInner - from workato_platform.client.workato_api.models.api_client_create_request import ApiClientCreateRequest as ApiClientCreateRequest - from workato_platform.client.workato_api.models.api_client_list_response import ApiClientListResponse as ApiClientListResponse - from workato_platform.client.workato_api.models.api_client_response import ApiClientResponse as ApiClientResponse - from workato_platform.client.workato_api.models.api_collection import ApiCollection as ApiCollection - from workato_platform.client.workato_api.models.api_collection_create_request import ApiCollectionCreateRequest as ApiCollectionCreateRequest - from workato_platform.client.workato_api.models.api_endpoint import ApiEndpoint as ApiEndpoint - from workato_platform.client.workato_api.models.api_key import ApiKey as ApiKey - from workato_platform.client.workato_api.models.api_key_create_request import ApiKeyCreateRequest as ApiKeyCreateRequest - from workato_platform.client.workato_api.models.api_key_list_response import ApiKeyListResponse as ApiKeyListResponse - from workato_platform.client.workato_api.models.api_key_response import ApiKeyResponse as ApiKeyResponse - from workato_platform.client.workato_api.models.asset import Asset as Asset - from workato_platform.client.workato_api.models.asset_reference import AssetReference as AssetReference - from workato_platform.client.workato_api.models.connection import Connection as Connection - from workato_platform.client.workato_api.models.connection_create_request import ConnectionCreateRequest as ConnectionCreateRequest - from workato_platform.client.workato_api.models.connection_update_request import ConnectionUpdateRequest as ConnectionUpdateRequest - from workato_platform.client.workato_api.models.connector_action import ConnectorAction as ConnectorAction - from workato_platform.client.workato_api.models.connector_version import ConnectorVersion as ConnectorVersion - from workato_platform.client.workato_api.models.create_export_manifest_request import CreateExportManifestRequest as CreateExportManifestRequest - from workato_platform.client.workato_api.models.create_folder_request import CreateFolderRequest as CreateFolderRequest - from workato_platform.client.workato_api.models.custom_connector import CustomConnector as CustomConnector - from workato_platform.client.workato_api.models.custom_connector_code_response import CustomConnectorCodeResponse as CustomConnectorCodeResponse - from workato_platform.client.workato_api.models.custom_connector_code_response_data import CustomConnectorCodeResponseData as CustomConnectorCodeResponseData - from workato_platform.client.workato_api.models.custom_connector_list_response import CustomConnectorListResponse as CustomConnectorListResponse - from workato_platform.client.workato_api.models.data_table import DataTable as DataTable - from workato_platform.client.workato_api.models.data_table_column import DataTableColumn as DataTableColumn - from workato_platform.client.workato_api.models.data_table_column_request import DataTableColumnRequest as DataTableColumnRequest - from workato_platform.client.workato_api.models.data_table_create_request import DataTableCreateRequest as DataTableCreateRequest - from workato_platform.client.workato_api.models.data_table_create_response import DataTableCreateResponse as DataTableCreateResponse - from workato_platform.client.workato_api.models.data_table_list_response import DataTableListResponse as DataTableListResponse - from workato_platform.client.workato_api.models.data_table_relation import DataTableRelation as DataTableRelation - from workato_platform.client.workato_api.models.delete_project403_response import DeleteProject403Response as DeleteProject403Response - from workato_platform.client.workato_api.models.error import Error as Error - from workato_platform.client.workato_api.models.export_manifest_request import ExportManifestRequest as ExportManifestRequest - from workato_platform.client.workato_api.models.export_manifest_response import ExportManifestResponse as ExportManifestResponse - from workato_platform.client.workato_api.models.export_manifest_response_result import ExportManifestResponseResult as ExportManifestResponseResult - from workato_platform.client.workato_api.models.folder import Folder as Folder - from workato_platform.client.workato_api.models.folder_assets_response import FolderAssetsResponse as FolderAssetsResponse - from workato_platform.client.workato_api.models.folder_assets_response_result import FolderAssetsResponseResult as FolderAssetsResponseResult - from workato_platform.client.workato_api.models.folder_creation_response import FolderCreationResponse as FolderCreationResponse - from workato_platform.client.workato_api.models.import_results import ImportResults as ImportResults - from workato_platform.client.workato_api.models.o_auth_url_response import OAuthUrlResponse as OAuthUrlResponse - from workato_platform.client.workato_api.models.o_auth_url_response_data import OAuthUrlResponseData as OAuthUrlResponseData - from workato_platform.client.workato_api.models.open_api_spec import OpenApiSpec as OpenApiSpec - from workato_platform.client.workato_api.models.package_details_response import PackageDetailsResponse as PackageDetailsResponse - from workato_platform.client.workato_api.models.package_details_response_recipe_status_inner import PackageDetailsResponseRecipeStatusInner as PackageDetailsResponseRecipeStatusInner - from workato_platform.client.workato_api.models.package_response import PackageResponse as PackageResponse - from workato_platform.client.workato_api.models.picklist_request import PicklistRequest as PicklistRequest - from workato_platform.client.workato_api.models.picklist_response import PicklistResponse as PicklistResponse - from workato_platform.client.workato_api.models.platform_connector import PlatformConnector as PlatformConnector - from workato_platform.client.workato_api.models.platform_connector_list_response import PlatformConnectorListResponse as PlatformConnectorListResponse - from workato_platform.client.workato_api.models.project import Project as Project - from workato_platform.client.workato_api.models.recipe import Recipe as Recipe - from workato_platform.client.workato_api.models.recipe_config_inner import RecipeConfigInner as RecipeConfigInner - from workato_platform.client.workato_api.models.recipe_connection_update_request import RecipeConnectionUpdateRequest as RecipeConnectionUpdateRequest - from workato_platform.client.workato_api.models.recipe_list_response import RecipeListResponse as RecipeListResponse - from workato_platform.client.workato_api.models.recipe_start_response import RecipeStartResponse as RecipeStartResponse - from workato_platform.client.workato_api.models.runtime_user_connection_create_request import RuntimeUserConnectionCreateRequest as RuntimeUserConnectionCreateRequest - from workato_platform.client.workato_api.models.runtime_user_connection_response import RuntimeUserConnectionResponse as RuntimeUserConnectionResponse - from workato_platform.client.workato_api.models.runtime_user_connection_response_data import RuntimeUserConnectionResponseData as RuntimeUserConnectionResponseData - from workato_platform.client.workato_api.models.success_response import SuccessResponse as SuccessResponse - from workato_platform.client.workato_api.models.upsert_project_properties_request import UpsertProjectPropertiesRequest as UpsertProjectPropertiesRequest - from workato_platform.client.workato_api.models.user import User as User - from workato_platform.client.workato_api.models.validation_error import ValidationError as ValidationError - from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue as ValidationErrorErrorsValue - -else: - from lazy_imports import LazyModule, as_package, load - - load( - LazyModule( - *as_package(__file__), - ("__version__", __version__), - ("__all__", __all__), - """# import apis into sdk package +# import apis into sdk package from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi as APIPlatformApi from workato_platform.client.workato_api.api.connections_api import ConnectionsApi as ConnectionsApi from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi as ConnectorsApi @@ -302,8 +200,3 @@ from workato_platform.client.workato_api.models.validation_error import ValidationError as ValidationError from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue as ValidationErrorErrorsValue -""", - name=__name__, - doc=__doc__, - ) - ) diff --git a/src/workato_platform/client/workato_api/api/__init__.py b/src/workato_platform/client/workato_api/api/__init__.py index 4e41a38..a0e5380 100644 --- a/src/workato_platform/client/workato_api/api/__init__.py +++ b/src/workato_platform/client/workato_api/api/__init__.py @@ -1,26 +1,6 @@ # flake8: noqa -if __import__("typing").TYPE_CHECKING: - # import apis into api package - from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi - from workato_platform.client.workato_api.api.connections_api import ConnectionsApi - from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi - from workato_platform.client.workato_api.api.data_tables_api import DataTablesApi - from workato_platform.client.workato_api.api.export_api import ExportApi - from workato_platform.client.workato_api.api.folders_api import FoldersApi - from workato_platform.client.workato_api.api.packages_api import PackagesApi - from workato_platform.client.workato_api.api.projects_api import ProjectsApi - from workato_platform.client.workato_api.api.properties_api import PropertiesApi - from workato_platform.client.workato_api.api.recipes_api import RecipesApi - from workato_platform.client.workato_api.api.users_api import UsersApi - -else: - from lazy_imports import LazyModule, as_package, load - - load( - LazyModule( - *as_package(__file__), - """# import apis into api package +# import apis into api package from workato_platform.client.workato_api.api.api_platform_api import APIPlatformApi from workato_platform.client.workato_api.api.connections_api import ConnectionsApi from workato_platform.client.workato_api.api.connectors_api import ConnectorsApi @@ -33,8 +13,3 @@ from workato_platform.client.workato_api.api.recipes_api import RecipesApi from workato_platform.client.workato_api.api.users_api import UsersApi -""", - name=__name__, - doc=__doc__, - ) - ) diff --git a/src/workato_platform/client/workato_api/api_client.py b/src/workato_platform/client/workato_api/api_client.py index 3c8bd2b..ea849af 100644 --- a/src/workato_platform/client/workato_api/api_client.py +++ b/src/workato_platform/client/workato_api/api_client.py @@ -463,13 +463,13 @@ def __deserialize(self, data, klass): if klass in self.PRIMITIVE_TYPES: return self.__deserialize_primitive(data, klass) - elif klass == object: + elif klass is object: return self.__deserialize_object(data) - elif klass == datetime.date: + elif klass is datetime.date: return self.__deserialize_date(data) - elif klass == datetime.datetime: + elif klass is datetime.datetime: return self.__deserialize_datetime(data) - elif klass == decimal.Decimal: + elif klass is decimal.Decimal: return decimal.Decimal(data) elif issubclass(klass, Enum): return self.__deserialize_enum(data, klass) diff --git a/src/workato_platform/client/workato_api/models/__init__.py b/src/workato_platform/client/workato_api/models/__init__.py index 7d4a8e8..28c8fe0 100644 --- a/src/workato_platform/client/workato_api/models/__init__.py +++ b/src/workato_platform/client/workato_api/models/__init__.py @@ -12,84 +12,7 @@ Do not edit the class manually. """ # noqa: E501 - -if __import__("typing").TYPE_CHECKING: - # import models into model package - from workato_platform.client.workato_api.models.api_client import ApiClient - from workato_platform.client.workato_api.models.api_client_api_collections_inner import ApiClientApiCollectionsInner - from workato_platform.client.workato_api.models.api_client_api_policies_inner import ApiClientApiPoliciesInner - from workato_platform.client.workato_api.models.api_client_create_request import ApiClientCreateRequest - from workato_platform.client.workato_api.models.api_client_list_response import ApiClientListResponse - from workato_platform.client.workato_api.models.api_client_response import ApiClientResponse - from workato_platform.client.workato_api.models.api_collection import ApiCollection - from workato_platform.client.workato_api.models.api_collection_create_request import ApiCollectionCreateRequest - from workato_platform.client.workato_api.models.api_endpoint import ApiEndpoint - from workato_platform.client.workato_api.models.api_key import ApiKey - from workato_platform.client.workato_api.models.api_key_create_request import ApiKeyCreateRequest - from workato_platform.client.workato_api.models.api_key_list_response import ApiKeyListResponse - from workato_platform.client.workato_api.models.api_key_response import ApiKeyResponse - from workato_platform.client.workato_api.models.asset import Asset - from workato_platform.client.workato_api.models.asset_reference import AssetReference - from workato_platform.client.workato_api.models.connection import Connection - from workato_platform.client.workato_api.models.connection_create_request import ConnectionCreateRequest - from workato_platform.client.workato_api.models.connection_update_request import ConnectionUpdateRequest - from workato_platform.client.workato_api.models.connector_action import ConnectorAction - from workato_platform.client.workato_api.models.connector_version import ConnectorVersion - from workato_platform.client.workato_api.models.create_export_manifest_request import CreateExportManifestRequest - from workato_platform.client.workato_api.models.create_folder_request import CreateFolderRequest - from workato_platform.client.workato_api.models.custom_connector import CustomConnector - from workato_platform.client.workato_api.models.custom_connector_code_response import CustomConnectorCodeResponse - from workato_platform.client.workato_api.models.custom_connector_code_response_data import CustomConnectorCodeResponseData - from workato_platform.client.workato_api.models.custom_connector_list_response import CustomConnectorListResponse - from workato_platform.client.workato_api.models.data_table import DataTable - from workato_platform.client.workato_api.models.data_table_column import DataTableColumn - from workato_platform.client.workato_api.models.data_table_column_request import DataTableColumnRequest - from workato_platform.client.workato_api.models.data_table_create_request import DataTableCreateRequest - from workato_platform.client.workato_api.models.data_table_create_response import DataTableCreateResponse - from workato_platform.client.workato_api.models.data_table_list_response import DataTableListResponse - from workato_platform.client.workato_api.models.data_table_relation import DataTableRelation - from workato_platform.client.workato_api.models.delete_project403_response import DeleteProject403Response - from workato_platform.client.workato_api.models.error import Error - from workato_platform.client.workato_api.models.export_manifest_request import ExportManifestRequest - from workato_platform.client.workato_api.models.export_manifest_response import ExportManifestResponse - from workato_platform.client.workato_api.models.export_manifest_response_result import ExportManifestResponseResult - from workato_platform.client.workato_api.models.folder import Folder - from workato_platform.client.workato_api.models.folder_assets_response import FolderAssetsResponse - from workato_platform.client.workato_api.models.folder_assets_response_result import FolderAssetsResponseResult - from workato_platform.client.workato_api.models.folder_creation_response import FolderCreationResponse - from workato_platform.client.workato_api.models.import_results import ImportResults - from workato_platform.client.workato_api.models.o_auth_url_response import OAuthUrlResponse - from workato_platform.client.workato_api.models.o_auth_url_response_data import OAuthUrlResponseData - from workato_platform.client.workato_api.models.open_api_spec import OpenApiSpec - from workato_platform.client.workato_api.models.package_details_response import PackageDetailsResponse - from workato_platform.client.workato_api.models.package_details_response_recipe_status_inner import PackageDetailsResponseRecipeStatusInner - from workato_platform.client.workato_api.models.package_response import PackageResponse - from workato_platform.client.workato_api.models.picklist_request import PicklistRequest - from workato_platform.client.workato_api.models.picklist_response import PicklistResponse - from workato_platform.client.workato_api.models.platform_connector import PlatformConnector - from workato_platform.client.workato_api.models.platform_connector_list_response import PlatformConnectorListResponse - from workato_platform.client.workato_api.models.project import Project - from workato_platform.client.workato_api.models.recipe import Recipe - from workato_platform.client.workato_api.models.recipe_config_inner import RecipeConfigInner - from workato_platform.client.workato_api.models.recipe_connection_update_request import RecipeConnectionUpdateRequest - from workato_platform.client.workato_api.models.recipe_list_response import RecipeListResponse - from workato_platform.client.workato_api.models.recipe_start_response import RecipeStartResponse - from workato_platform.client.workato_api.models.runtime_user_connection_create_request import RuntimeUserConnectionCreateRequest - from workato_platform.client.workato_api.models.runtime_user_connection_response import RuntimeUserConnectionResponse - from workato_platform.client.workato_api.models.runtime_user_connection_response_data import RuntimeUserConnectionResponseData - from workato_platform.client.workato_api.models.success_response import SuccessResponse - from workato_platform.client.workato_api.models.upsert_project_properties_request import UpsertProjectPropertiesRequest - from workato_platform.client.workato_api.models.user import User - from workato_platform.client.workato_api.models.validation_error import ValidationError - from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue - -else: - from lazy_imports import LazyModule, as_package, load - - load( - LazyModule( - *as_package(__file__), - """# import models into model package +# import models into model package from workato_platform.client.workato_api.models.api_client import ApiClient from workato_platform.client.workato_api.models.api_client_api_collections_inner import ApiClientApiCollectionsInner from workato_platform.client.workato_api.models.api_client_api_policies_inner import ApiClientApiPoliciesInner @@ -158,8 +81,3 @@ from workato_platform.client.workato_api.models.validation_error import ValidationError from workato_platform.client.workato_api.models.validation_error_errors_value import ValidationErrorErrorsValue -""", - name=__name__, - doc=__doc__, - ) - ) diff --git a/src/workato_platform/client/workato_api_README.md b/src/workato_platform/client/workato_api_README.md index 6c460a8..da7d2f2 100644 --- a/src/workato_platform/client/workato_api_README.md +++ b/src/workato_platform/client/workato_api_README.md @@ -5,7 +5,7 @@ The `workato_platform.client.workato_api` package is automatically generated by - API version: 1.0.0 - Package version: 1.0.0 -- Generator version: 7.15.0 +- Generator version: 7.16.0 - Build package: org.openapitools.codegen.languages.PythonClientCodegen For more information, please visit [https://docs.workato.com](https://docs.workato.com) diff --git a/uv.lock b/uv.lock index a71d65d..a09bce5 100644 --- a/uv.lock +++ b/uv.lock @@ -807,15 +807,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085, upload-time = "2024-12-25T15:26:44.377Z" }, ] -[[package]] -name = "lazy-imports" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/1c/6675601691fd6007021e8e95cfcb83e6d11067de3d7ecde0d0de970324c8/lazy_imports-1.0.1.tar.gz", hash = "sha256:7d3e4b1547cb574ec7ef3c47a074673e2612330b2b50bf7eec939f2c393fc261", size = 24484, upload-time = "2025-08-09T07:15:55.353Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/37/c84d7fec58dec38564574dec8f94bb1db788598fe397f116a9d6a86d3055/lazy_imports-1.0.1-py3-none-any.whl", hash = "sha256:eb5accc33bf9987e5197e79476bbeb960b74a2c16619bdf41281b3240f730846", size = 18896, upload-time = "2025-08-09T07:15:53.7Z" }, -] - [[package]] name = "license-expression" version = "30.4.4" @@ -1035,11 +1026,11 @@ wheels = [ [[package]] name = "openapi-generator-cli" -version = "7.15.0" +version = "7.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a4/e7/f62514b564a2ef5ccae3c2270193bf667dfc3d8fcc3b8a443189e31eb313/openapi_generator_cli-7.15.0.tar.gz", hash = "sha256:93b3c1ac6d9d13d1309e95bedcbc0af839dcfe3047c840531cef662b61368fc1", size = 27444822, upload-time = "2025-08-23T01:27:36.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/75/477c36fa8a6d1279c48c4be16155ca9985c6dbc8dd75d3bc1466d81469e9/openapi_generator_cli-7.16.0.tar.gz", hash = "sha256:a056ea34c12b989363c94025a5290ec24b714d80bac2e275bb9366c6bfda130b", size = 27710447, upload-time = "2025-09-29T01:27:50.66Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/ec/5ac2715079da83cbec2f7a1211e46c516e29a1f4a701103ea0010d7c7383/openapi_generator_cli-7.15.0-py3-none-any.whl", hash = "sha256:ff95305ce9a8ad1250fb16d6b0a20e6f5d3041fcb515f4b1a471719dbb1d56ef", size = 27459322, upload-time = "2025-08-23T01:27:33.4Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ee/c274afa6b0817d6a80704f6ecc5cb98a655e64f5992c14d0813f1288a761/openapi_generator_cli-7.16.0-py3-none-any.whl", hash = "sha256:b4ac990a9c6d3cd7e38a1b914c089449943183fca6fff169cbd219d06123fd7d", size = 27724625, upload-time = "2025-09-29T01:27:47.333Z" }, ] [[package]] @@ -1727,7 +1718,6 @@ dependencies = [ { name = "dependency-injector" }, { name = "inquirer" }, { name = "keyring" }, - { name = "lazy-imports" }, { name = "packaging" }, { name = "pydantic" }, { name = "python-dateutil" }, @@ -1783,7 +1773,6 @@ requires-dist = [ { name = "dependency-injector", specifier = ">=4.41.0" }, { name = "inquirer", specifier = ">=3.1.0" }, { name = "keyring", specifier = ">=25.6.0" }, - { name = "lazy-imports", specifier = ">=0.3.1" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.0.0" }, { name = "packaging", specifier = ">=21.0" }, { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.0.0" }, @@ -1808,7 +1797,7 @@ dev = [ { name = "build", specifier = ">=1.3.0" }, { name = "hatch-vcs", specifier = ">=0.5.0" }, { name = "mypy", specifier = ">=1.17.1" }, - { name = "openapi-generator-cli", specifier = ">=7.15.0" }, + { name = "openapi-generator-cli", specifier = ">=7.16.0" }, { name = "pip-audit", specifier = ">=2.9.0" }, { name = "pre-commit", specifier = ">=4.3.0" }, { name = "pytest", specifier = ">=7.0.0" },