workato-platform-cli 1.0.0rc5.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- workato_platform_cli/__init__.py +135 -0
- workato_platform_cli/_version.py +34 -0
- workato_platform_cli/cli/__init__.py +126 -0
- workato_platform_cli/cli/commands/__init__.py +0 -0
- workato_platform_cli/cli/commands/api_clients.py +627 -0
- workato_platform_cli/cli/commands/api_collections.py +497 -0
- workato_platform_cli/cli/commands/assets.py +82 -0
- workato_platform_cli/cli/commands/connections.py +1205 -0
- workato_platform_cli/cli/commands/connectors/__init__.py +0 -0
- workato_platform_cli/cli/commands/connectors/command.py +178 -0
- workato_platform_cli/cli/commands/connectors/connector_manager.py +351 -0
- workato_platform_cli/cli/commands/data_tables.py +345 -0
- workato_platform_cli/cli/commands/guide.py +315 -0
- workato_platform_cli/cli/commands/init.py +229 -0
- workato_platform_cli/cli/commands/profiles.py +364 -0
- workato_platform_cli/cli/commands/projects/__init__.py +0 -0
- workato_platform_cli/cli/commands/projects/command.py +513 -0
- workato_platform_cli/cli/commands/projects/project_manager.py +338 -0
- workato_platform_cli/cli/commands/properties.py +174 -0
- workato_platform_cli/cli/commands/pull.py +327 -0
- workato_platform_cli/cli/commands/push/__init__.py +0 -0
- workato_platform_cli/cli/commands/push/command.py +320 -0
- workato_platform_cli/cli/commands/recipes/__init__.py +0 -0
- workato_platform_cli/cli/commands/recipes/command.py +847 -0
- workato_platform_cli/cli/commands/recipes/validator.py +1740 -0
- workato_platform_cli/cli/commands/workspace.py +73 -0
- workato_platform_cli/cli/containers.py +80 -0
- workato_platform_cli/cli/resources/data/connection-data.json +7364 -0
- workato_platform_cli/cli/resources/data/picklist-data.json +3706 -0
- workato_platform_cli/cli/resources/docs/README.md +178 -0
- workato_platform_cli/cli/resources/docs/actions.md +452 -0
- workato_platform_cli/cli/resources/docs/block-structure.md +424 -0
- workato_platform_cli/cli/resources/docs/connections-parameters.md +11946 -0
- workato_platform_cli/cli/resources/docs/data-mapping.md +779 -0
- workato_platform_cli/cli/resources/docs/formulas/array-list-formulas.md +1276 -0
- workato_platform_cli/cli/resources/docs/formulas/conditions.md +102 -0
- workato_platform_cli/cli/resources/docs/formulas/date-formulas.md +798 -0
- workato_platform_cli/cli/resources/docs/formulas/number-formulas.md +507 -0
- workato_platform_cli/cli/resources/docs/formulas/other-formulas.md +419 -0
- workato_platform_cli/cli/resources/docs/formulas/string-formulas.md +1353 -0
- workato_platform_cli/cli/resources/docs/formulas.md +214 -0
- workato_platform_cli/cli/resources/docs/naming-conventions.md +163 -0
- workato_platform_cli/cli/resources/docs/recipe-deployment-workflow.md +352 -0
- workato_platform_cli/cli/resources/docs/recipe-fundamentals.md +179 -0
- workato_platform_cli/cli/resources/docs/triggers.md +360 -0
- workato_platform_cli/cli/utils/__init__.py +10 -0
- workato_platform_cli/cli/utils/config/__init__.py +33 -0
- workato_platform_cli/cli/utils/config/manager.py +1001 -0
- workato_platform_cli/cli/utils/config/models.py +89 -0
- workato_platform_cli/cli/utils/config/profiles.py +491 -0
- workato_platform_cli/cli/utils/config/workspace.py +113 -0
- workato_platform_cli/cli/utils/exception_handler.py +531 -0
- workato_platform_cli/cli/utils/gitignore.py +32 -0
- workato_platform_cli/cli/utils/ignore_patterns.py +44 -0
- workato_platform_cli/cli/utils/spinner.py +63 -0
- workato_platform_cli/cli/utils/version_checker.py +237 -0
- workato_platform_cli/client/__init__.py +0 -0
- workato_platform_cli/client/workato_api/__init__.py +202 -0
- workato_platform_cli/client/workato_api/api/__init__.py +15 -0
- workato_platform_cli/client/workato_api/api/api_platform_api.py +2875 -0
- workato_platform_cli/client/workato_api/api/connections_api.py +1807 -0
- workato_platform_cli/client/workato_api/api/connectors_api.py +840 -0
- workato_platform_cli/client/workato_api/api/data_tables_api.py +604 -0
- workato_platform_cli/client/workato_api/api/export_api.py +621 -0
- workato_platform_cli/client/workato_api/api/folders_api.py +621 -0
- workato_platform_cli/client/workato_api/api/packages_api.py +1197 -0
- workato_platform_cli/client/workato_api/api/projects_api.py +590 -0
- workato_platform_cli/client/workato_api/api/properties_api.py +620 -0
- workato_platform_cli/client/workato_api/api/recipes_api.py +1379 -0
- workato_platform_cli/client/workato_api/api/users_api.py +285 -0
- workato_platform_cli/client/workato_api/api_client.py +807 -0
- workato_platform_cli/client/workato_api/api_response.py +21 -0
- workato_platform_cli/client/workato_api/configuration.py +601 -0
- workato_platform_cli/client/workato_api/docs/APIPlatformApi.md +844 -0
- workato_platform_cli/client/workato_api/docs/ApiClient.md +46 -0
- workato_platform_cli/client/workato_api/docs/ApiClientApiCollectionsInner.md +30 -0
- workato_platform_cli/client/workato_api/docs/ApiClientApiPoliciesInner.md +30 -0
- workato_platform_cli/client/workato_api/docs/ApiClientCreateRequest.md +46 -0
- workato_platform_cli/client/workato_api/docs/ApiClientListResponse.md +32 -0
- workato_platform_cli/client/workato_api/docs/ApiClientResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/ApiCollection.md +38 -0
- workato_platform_cli/client/workato_api/docs/ApiCollectionCreateRequest.md +32 -0
- workato_platform_cli/client/workato_api/docs/ApiEndpoint.md +41 -0
- workato_platform_cli/client/workato_api/docs/ApiKey.md +36 -0
- workato_platform_cli/client/workato_api/docs/ApiKeyCreateRequest.md +32 -0
- workato_platform_cli/client/workato_api/docs/ApiKeyListResponse.md +32 -0
- workato_platform_cli/client/workato_api/docs/ApiKeyResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/Asset.md +39 -0
- workato_platform_cli/client/workato_api/docs/AssetReference.md +37 -0
- workato_platform_cli/client/workato_api/docs/Connection.md +44 -0
- workato_platform_cli/client/workato_api/docs/ConnectionCreateRequest.md +35 -0
- workato_platform_cli/client/workato_api/docs/ConnectionUpdateRequest.md +34 -0
- workato_platform_cli/client/workato_api/docs/ConnectionsApi.md +526 -0
- workato_platform_cli/client/workato_api/docs/ConnectorAction.md +33 -0
- workato_platform_cli/client/workato_api/docs/ConnectorVersion.md +32 -0
- workato_platform_cli/client/workato_api/docs/ConnectorsApi.md +249 -0
- workato_platform_cli/client/workato_api/docs/CreateExportManifestRequest.md +29 -0
- workato_platform_cli/client/workato_api/docs/CreateFolderRequest.md +30 -0
- workato_platform_cli/client/workato_api/docs/CustomConnector.md +35 -0
- workato_platform_cli/client/workato_api/docs/CustomConnectorCodeResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/CustomConnectorCodeResponseData.md +29 -0
- workato_platform_cli/client/workato_api/docs/CustomConnectorListResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/DataTable.md +34 -0
- workato_platform_cli/client/workato_api/docs/DataTableColumn.md +37 -0
- workato_platform_cli/client/workato_api/docs/DataTableColumnRequest.md +37 -0
- workato_platform_cli/client/workato_api/docs/DataTableCreateRequest.md +31 -0
- workato_platform_cli/client/workato_api/docs/DataTableCreateResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/DataTableListResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/DataTableRelation.md +30 -0
- workato_platform_cli/client/workato_api/docs/DataTablesApi.md +172 -0
- workato_platform_cli/client/workato_api/docs/DeleteProject403Response.md +29 -0
- workato_platform_cli/client/workato_api/docs/Error.md +29 -0
- workato_platform_cli/client/workato_api/docs/ExportApi.md +175 -0
- workato_platform_cli/client/workato_api/docs/ExportManifestRequest.md +35 -0
- workato_platform_cli/client/workato_api/docs/ExportManifestResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/ExportManifestResponseResult.md +36 -0
- workato_platform_cli/client/workato_api/docs/Folder.md +35 -0
- workato_platform_cli/client/workato_api/docs/FolderAssetsResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/FolderAssetsResponseResult.md +29 -0
- workato_platform_cli/client/workato_api/docs/FolderCreationResponse.md +35 -0
- workato_platform_cli/client/workato_api/docs/FoldersApi.md +176 -0
- workato_platform_cli/client/workato_api/docs/ImportResults.md +32 -0
- workato_platform_cli/client/workato_api/docs/OAuthUrlResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/OAuthUrlResponseData.md +29 -0
- workato_platform_cli/client/workato_api/docs/OpenApiSpec.md +30 -0
- workato_platform_cli/client/workato_api/docs/PackageDetailsResponse.md +35 -0
- workato_platform_cli/client/workato_api/docs/PackageDetailsResponseRecipeStatusInner.md +30 -0
- workato_platform_cli/client/workato_api/docs/PackageResponse.md +33 -0
- workato_platform_cli/client/workato_api/docs/PackagesApi.md +364 -0
- workato_platform_cli/client/workato_api/docs/PicklistRequest.md +30 -0
- workato_platform_cli/client/workato_api/docs/PicklistResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/PlatformConnector.md +36 -0
- workato_platform_cli/client/workato_api/docs/PlatformConnectorListResponse.md +32 -0
- workato_platform_cli/client/workato_api/docs/Project.md +32 -0
- workato_platform_cli/client/workato_api/docs/ProjectsApi.md +173 -0
- workato_platform_cli/client/workato_api/docs/PropertiesApi.md +186 -0
- workato_platform_cli/client/workato_api/docs/Recipe.md +58 -0
- workato_platform_cli/client/workato_api/docs/RecipeConfigInner.md +33 -0
- workato_platform_cli/client/workato_api/docs/RecipeConnectionUpdateRequest.md +30 -0
- workato_platform_cli/client/workato_api/docs/RecipeListResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/RecipeStartResponse.md +31 -0
- workato_platform_cli/client/workato_api/docs/RecipesApi.md +367 -0
- workato_platform_cli/client/workato_api/docs/RuntimeUserConnectionCreateRequest.md +34 -0
- workato_platform_cli/client/workato_api/docs/RuntimeUserConnectionResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/RuntimeUserConnectionResponseData.md +30 -0
- workato_platform_cli/client/workato_api/docs/SuccessResponse.md +29 -0
- workato_platform_cli/client/workato_api/docs/UpsertProjectPropertiesRequest.md +29 -0
- workato_platform_cli/client/workato_api/docs/User.md +48 -0
- workato_platform_cli/client/workato_api/docs/UsersApi.md +84 -0
- workato_platform_cli/client/workato_api/docs/ValidationError.md +30 -0
- workato_platform_cli/client/workato_api/docs/ValidationErrorErrorsValue.md +28 -0
- workato_platform_cli/client/workato_api/exceptions.py +216 -0
- workato_platform_cli/client/workato_api/models/__init__.py +83 -0
- workato_platform_cli/client/workato_api/models/api_client.py +185 -0
- workato_platform_cli/client/workato_api/models/api_client_api_collections_inner.py +89 -0
- workato_platform_cli/client/workato_api/models/api_client_api_policies_inner.py +89 -0
- workato_platform_cli/client/workato_api/models/api_client_create_request.py +138 -0
- workato_platform_cli/client/workato_api/models/api_client_list_response.py +101 -0
- workato_platform_cli/client/workato_api/models/api_client_response.py +91 -0
- workato_platform_cli/client/workato_api/models/api_collection.py +110 -0
- workato_platform_cli/client/workato_api/models/api_collection_create_request.py +97 -0
- workato_platform_cli/client/workato_api/models/api_endpoint.py +117 -0
- workato_platform_cli/client/workato_api/models/api_key.py +102 -0
- workato_platform_cli/client/workato_api/models/api_key_create_request.py +93 -0
- workato_platform_cli/client/workato_api/models/api_key_list_response.py +101 -0
- workato_platform_cli/client/workato_api/models/api_key_response.py +91 -0
- workato_platform_cli/client/workato_api/models/asset.py +124 -0
- workato_platform_cli/client/workato_api/models/asset_reference.py +110 -0
- workato_platform_cli/client/workato_api/models/connection.py +173 -0
- workato_platform_cli/client/workato_api/models/connection_create_request.py +99 -0
- workato_platform_cli/client/workato_api/models/connection_update_request.py +97 -0
- workato_platform_cli/client/workato_api/models/connector_action.py +100 -0
- workato_platform_cli/client/workato_api/models/connector_version.py +99 -0
- workato_platform_cli/client/workato_api/models/create_export_manifest_request.py +91 -0
- workato_platform_cli/client/workato_api/models/create_folder_request.py +89 -0
- workato_platform_cli/client/workato_api/models/custom_connector.py +117 -0
- workato_platform_cli/client/workato_api/models/custom_connector_code_response.py +91 -0
- workato_platform_cli/client/workato_api/models/custom_connector_code_response_data.py +87 -0
- workato_platform_cli/client/workato_api/models/custom_connector_list_response.py +95 -0
- workato_platform_cli/client/workato_api/models/data_table.py +107 -0
- workato_platform_cli/client/workato_api/models/data_table_column.py +125 -0
- workato_platform_cli/client/workato_api/models/data_table_column_request.py +130 -0
- workato_platform_cli/client/workato_api/models/data_table_create_request.py +99 -0
- workato_platform_cli/client/workato_api/models/data_table_create_response.py +91 -0
- workato_platform_cli/client/workato_api/models/data_table_list_response.py +95 -0
- workato_platform_cli/client/workato_api/models/data_table_relation.py +90 -0
- workato_platform_cli/client/workato_api/models/delete_project403_response.py +87 -0
- workato_platform_cli/client/workato_api/models/error.py +87 -0
- workato_platform_cli/client/workato_api/models/export_manifest_request.py +107 -0
- workato_platform_cli/client/workato_api/models/export_manifest_response.py +91 -0
- workato_platform_cli/client/workato_api/models/export_manifest_response_result.py +112 -0
- workato_platform_cli/client/workato_api/models/folder.py +110 -0
- workato_platform_cli/client/workato_api/models/folder_assets_response.py +91 -0
- workato_platform_cli/client/workato_api/models/folder_assets_response_result.py +95 -0
- workato_platform_cli/client/workato_api/models/folder_creation_response.py +110 -0
- workato_platform_cli/client/workato_api/models/import_results.py +93 -0
- workato_platform_cli/client/workato_api/models/o_auth_url_response.py +91 -0
- workato_platform_cli/client/workato_api/models/o_auth_url_response_data.py +87 -0
- workato_platform_cli/client/workato_api/models/open_api_spec.py +96 -0
- workato_platform_cli/client/workato_api/models/package_details_response.py +126 -0
- workato_platform_cli/client/workato_api/models/package_details_response_recipe_status_inner.py +99 -0
- workato_platform_cli/client/workato_api/models/package_response.py +109 -0
- workato_platform_cli/client/workato_api/models/picklist_request.py +89 -0
- workato_platform_cli/client/workato_api/models/picklist_response.py +88 -0
- workato_platform_cli/client/workato_api/models/platform_connector.py +116 -0
- workato_platform_cli/client/workato_api/models/platform_connector_list_response.py +101 -0
- workato_platform_cli/client/workato_api/models/project.py +93 -0
- workato_platform_cli/client/workato_api/models/recipe.py +174 -0
- workato_platform_cli/client/workato_api/models/recipe_config_inner.py +100 -0
- workato_platform_cli/client/workato_api/models/recipe_connection_update_request.py +89 -0
- workato_platform_cli/client/workato_api/models/recipe_list_response.py +95 -0
- workato_platform_cli/client/workato_api/models/recipe_start_response.py +91 -0
- workato_platform_cli/client/workato_api/models/runtime_user_connection_create_request.py +97 -0
- workato_platform_cli/client/workato_api/models/runtime_user_connection_response.py +91 -0
- workato_platform_cli/client/workato_api/models/runtime_user_connection_response_data.py +89 -0
- workato_platform_cli/client/workato_api/models/success_response.py +87 -0
- workato_platform_cli/client/workato_api/models/upsert_project_properties_request.py +88 -0
- workato_platform_cli/client/workato_api/models/user.py +151 -0
- workato_platform_cli/client/workato_api/models/validation_error.py +102 -0
- workato_platform_cli/client/workato_api/models/validation_error_errors_value.py +143 -0
- workato_platform_cli/client/workato_api/rest.py +213 -0
- workato_platform_cli/client/workato_api/test/__init__.py +0 -0
- workato_platform_cli/client/workato_api/test/test_api_client.py +94 -0
- workato_platform_cli/client/workato_api/test/test_api_client_api_collections_inner.py +52 -0
- workato_platform_cli/client/workato_api/test/test_api_client_api_policies_inner.py +52 -0
- workato_platform_cli/client/workato_api/test/test_api_client_create_request.py +75 -0
- workato_platform_cli/client/workato_api/test/test_api_client_list_response.py +114 -0
- workato_platform_cli/client/workato_api/test/test_api_client_response.py +104 -0
- workato_platform_cli/client/workato_api/test/test_api_collection.py +72 -0
- workato_platform_cli/client/workato_api/test/test_api_collection_create_request.py +57 -0
- workato_platform_cli/client/workato_api/test/test_api_endpoint.py +75 -0
- workato_platform_cli/client/workato_api/test/test_api_key.py +64 -0
- workato_platform_cli/client/workato_api/test/test_api_key_create_request.py +56 -0
- workato_platform_cli/client/workato_api/test/test_api_key_list_response.py +78 -0
- workato_platform_cli/client/workato_api/test/test_api_key_response.py +68 -0
- workato_platform_cli/client/workato_api/test/test_api_platform_api.py +101 -0
- workato_platform_cli/client/workato_api/test/test_asset.py +67 -0
- workato_platform_cli/client/workato_api/test/test_asset_reference.py +62 -0
- workato_platform_cli/client/workato_api/test/test_connection.py +81 -0
- workato_platform_cli/client/workato_api/test/test_connection_create_request.py +59 -0
- workato_platform_cli/client/workato_api/test/test_connection_update_request.py +56 -0
- workato_platform_cli/client/workato_api/test/test_connections_api.py +73 -0
- workato_platform_cli/client/workato_api/test/test_connector_action.py +59 -0
- workato_platform_cli/client/workato_api/test/test_connector_version.py +58 -0
- workato_platform_cli/client/workato_api/test/test_connectors_api.py +52 -0
- workato_platform_cli/client/workato_api/test/test_create_export_manifest_request.py +88 -0
- workato_platform_cli/client/workato_api/test/test_create_folder_request.py +53 -0
- workato_platform_cli/client/workato_api/test/test_custom_connector.py +76 -0
- workato_platform_cli/client/workato_api/test/test_custom_connector_code_response.py +54 -0
- workato_platform_cli/client/workato_api/test/test_custom_connector_code_response_data.py +52 -0
- workato_platform_cli/client/workato_api/test/test_custom_connector_list_response.py +82 -0
- workato_platform_cli/client/workato_api/test/test_data_table.py +88 -0
- workato_platform_cli/client/workato_api/test/test_data_table_column.py +72 -0
- workato_platform_cli/client/workato_api/test/test_data_table_column_request.py +64 -0
- workato_platform_cli/client/workato_api/test/test_data_table_create_request.py +82 -0
- workato_platform_cli/client/workato_api/test/test_data_table_create_response.py +90 -0
- workato_platform_cli/client/workato_api/test/test_data_table_list_response.py +94 -0
- workato_platform_cli/client/workato_api/test/test_data_table_relation.py +54 -0
- workato_platform_cli/client/workato_api/test/test_data_tables_api.py +45 -0
- workato_platform_cli/client/workato_api/test/test_delete_project403_response.py +51 -0
- workato_platform_cli/client/workato_api/test/test_error.py +52 -0
- workato_platform_cli/client/workato_api/test/test_export_api.py +45 -0
- workato_platform_cli/client/workato_api/test/test_export_manifest_request.py +69 -0
- workato_platform_cli/client/workato_api/test/test_export_manifest_response.py +68 -0
- workato_platform_cli/client/workato_api/test/test_export_manifest_response_result.py +66 -0
- workato_platform_cli/client/workato_api/test/test_folder.py +64 -0
- workato_platform_cli/client/workato_api/test/test_folder_assets_response.py +80 -0
- workato_platform_cli/client/workato_api/test/test_folder_assets_response_result.py +78 -0
- workato_platform_cli/client/workato_api/test/test_folder_creation_response.py +64 -0
- workato_platform_cli/client/workato_api/test/test_folders_api.py +45 -0
- workato_platform_cli/client/workato_api/test/test_import_results.py +58 -0
- workato_platform_cli/client/workato_api/test/test_o_auth_url_response.py +54 -0
- workato_platform_cli/client/workato_api/test/test_o_auth_url_response_data.py +52 -0
- workato_platform_cli/client/workato_api/test/test_open_api_spec.py +54 -0
- workato_platform_cli/client/workato_api/test/test_package_details_response.py +64 -0
- workato_platform_cli/client/workato_api/test/test_package_details_response_recipe_status_inner.py +52 -0
- workato_platform_cli/client/workato_api/test/test_package_response.py +58 -0
- workato_platform_cli/client/workato_api/test/test_packages_api.py +59 -0
- workato_platform_cli/client/workato_api/test/test_picklist_request.py +53 -0
- workato_platform_cli/client/workato_api/test/test_picklist_response.py +52 -0
- workato_platform_cli/client/workato_api/test/test_platform_connector.py +94 -0
- workato_platform_cli/client/workato_api/test/test_platform_connector_list_response.py +106 -0
- workato_platform_cli/client/workato_api/test/test_project.py +57 -0
- workato_platform_cli/client/workato_api/test/test_projects_api.py +45 -0
- workato_platform_cli/client/workato_api/test/test_properties_api.py +45 -0
- workato_platform_cli/client/workato_api/test/test_recipe.py +124 -0
- workato_platform_cli/client/workato_api/test/test_recipe_config_inner.py +55 -0
- workato_platform_cli/client/workato_api/test/test_recipe_connection_update_request.py +54 -0
- workato_platform_cli/client/workato_api/test/test_recipe_list_response.py +134 -0
- workato_platform_cli/client/workato_api/test/test_recipe_start_response.py +54 -0
- workato_platform_cli/client/workato_api/test/test_recipes_api.py +59 -0
- workato_platform_cli/client/workato_api/test/test_runtime_user_connection_create_request.py +59 -0
- workato_platform_cli/client/workato_api/test/test_runtime_user_connection_response.py +56 -0
- workato_platform_cli/client/workato_api/test/test_runtime_user_connection_response_data.py +54 -0
- workato_platform_cli/client/workato_api/test/test_success_response.py +52 -0
- workato_platform_cli/client/workato_api/test/test_upsert_project_properties_request.py +52 -0
- workato_platform_cli/client/workato_api/test/test_user.py +85 -0
- workato_platform_cli/client/workato_api/test/test_users_api.py +38 -0
- workato_platform_cli/client/workato_api/test/test_validation_error.py +52 -0
- workato_platform_cli/client/workato_api/test/test_validation_error_errors_value.py +50 -0
- workato_platform_cli/client/workato_api_README.md +205 -0
- workato_platform_cli-1.0.0rc5.dev5.dist-info/METADATA +185 -0
- workato_platform_cli-1.0.0rc5.dev5.dist-info/RECORD +306 -0
- workato_platform_cli-1.0.0rc5.dev5.dist-info/WHEEL +4 -0
- workato_platform_cli-1.0.0rc5.dev5.dist-info/entry_points.txt +2 -0
- workato_platform_cli-1.0.0rc5.dev5.dist-info/licenses/LICENSE +7 -0
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
"""Exception handler decorator for user-friendly error messages."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import functools
|
|
5
|
+
import json
|
|
6
|
+
import ssl
|
|
7
|
+
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
from json import JSONDecodeError
|
|
10
|
+
from typing import Any, TypeVar, cast
|
|
11
|
+
|
|
12
|
+
import aiohttp
|
|
13
|
+
import asyncclick as click
|
|
14
|
+
|
|
15
|
+
from workato_platform_cli.client.workato_api.exceptions import (
|
|
16
|
+
ApiException,
|
|
17
|
+
BadRequestException,
|
|
18
|
+
ConflictException,
|
|
19
|
+
ForbiddenException,
|
|
20
|
+
NotFoundException,
|
|
21
|
+
ServiceException,
|
|
22
|
+
UnauthorizedException,
|
|
23
|
+
UnprocessableEntityException,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def handle_api_exceptions(func: F) -> F:
|
|
31
|
+
"""Decorator to handle workato_api exceptions with user-friendly messages.
|
|
32
|
+
|
|
33
|
+
This decorator catches HTTP exceptions from the Workato API client and
|
|
34
|
+
displays user-friendly error messages instead of raw stack traces.
|
|
35
|
+
|
|
36
|
+
Supports both sync and async functions.
|
|
37
|
+
|
|
38
|
+
Usage:
|
|
39
|
+
@handle_api_exceptions
|
|
40
|
+
async def my_command():
|
|
41
|
+
# Your command logic here
|
|
42
|
+
pass
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
if asyncio.iscoroutinefunction(func):
|
|
46
|
+
|
|
47
|
+
@functools.wraps(func)
|
|
48
|
+
async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
49
|
+
try:
|
|
50
|
+
return await func(*args, **kwargs)
|
|
51
|
+
except (BadRequestException, UnprocessableEntityException) as e:
|
|
52
|
+
_handle_client_error(e)
|
|
53
|
+
raise SystemExit(1) from None
|
|
54
|
+
except UnauthorizedException as e:
|
|
55
|
+
_handle_auth_error(e)
|
|
56
|
+
raise SystemExit(1) from None
|
|
57
|
+
except ForbiddenException as e:
|
|
58
|
+
_handle_forbidden_error(e)
|
|
59
|
+
raise SystemExit(1) from None
|
|
60
|
+
except NotFoundException as e:
|
|
61
|
+
_handle_not_found_error(e)
|
|
62
|
+
raise SystemExit(1) from None
|
|
63
|
+
except ConflictException as e:
|
|
64
|
+
_handle_conflict_error(e)
|
|
65
|
+
raise SystemExit(1) from None
|
|
66
|
+
except ServiceException as e:
|
|
67
|
+
_handle_server_error(e)
|
|
68
|
+
raise SystemExit(1) from None
|
|
69
|
+
except ApiException as e:
|
|
70
|
+
_handle_generic_api_error(e)
|
|
71
|
+
raise SystemExit(1) from None
|
|
72
|
+
|
|
73
|
+
return cast(F, async_wrapper)
|
|
74
|
+
else:
|
|
75
|
+
|
|
76
|
+
@functools.wraps(func)
|
|
77
|
+
def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
78
|
+
try:
|
|
79
|
+
return func(*args, **kwargs)
|
|
80
|
+
except (BadRequestException, UnprocessableEntityException) as e:
|
|
81
|
+
_handle_client_error(e)
|
|
82
|
+
raise SystemExit(1) from None
|
|
83
|
+
except UnauthorizedException as e:
|
|
84
|
+
_handle_auth_error(e)
|
|
85
|
+
raise SystemExit(1) from None
|
|
86
|
+
except ForbiddenException as e:
|
|
87
|
+
_handle_forbidden_error(e)
|
|
88
|
+
raise SystemExit(1) from None
|
|
89
|
+
except NotFoundException as e:
|
|
90
|
+
_handle_not_found_error(e)
|
|
91
|
+
raise SystemExit(1) from None
|
|
92
|
+
except ConflictException as e:
|
|
93
|
+
_handle_conflict_error(e)
|
|
94
|
+
raise SystemExit(1) from None
|
|
95
|
+
except ServiceException as e:
|
|
96
|
+
_handle_server_error(e)
|
|
97
|
+
raise SystemExit(1) from None
|
|
98
|
+
except ApiException as e:
|
|
99
|
+
_handle_generic_api_error(e)
|
|
100
|
+
raise SystemExit(1) from None
|
|
101
|
+
|
|
102
|
+
return cast(F, sync_wrapper)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def handle_cli_exceptions(func: F) -> F:
|
|
106
|
+
"""Handle CLI initialization and network errors with friendly messages.
|
|
107
|
+
|
|
108
|
+
This decorator catches errors that occur during dependency injection and CLI
|
|
109
|
+
initialization, such as missing credentials, network failures, and configuration
|
|
110
|
+
errors. It should be placed above @inject in the decorator stack.
|
|
111
|
+
|
|
112
|
+
Supports both sync and async functions.
|
|
113
|
+
|
|
114
|
+
Usage:
|
|
115
|
+
@click.command()
|
|
116
|
+
@handle_cli_exceptions
|
|
117
|
+
@inject
|
|
118
|
+
@handle_api_exceptions
|
|
119
|
+
async def my_command():
|
|
120
|
+
# Your command logic here
|
|
121
|
+
pass
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
if asyncio.iscoroutinefunction(func):
|
|
125
|
+
|
|
126
|
+
@functools.wraps(func)
|
|
127
|
+
async def async_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
128
|
+
try:
|
|
129
|
+
return await func(*args, **kwargs)
|
|
130
|
+
except (
|
|
131
|
+
aiohttp.ClientConnectorError,
|
|
132
|
+
aiohttp.ClientConnectionError,
|
|
133
|
+
) as e:
|
|
134
|
+
_handle_network_error(e)
|
|
135
|
+
raise SystemExit(1) from None
|
|
136
|
+
except TimeoutError as e:
|
|
137
|
+
_handle_timeout_error(e)
|
|
138
|
+
raise SystemExit(1) from None
|
|
139
|
+
except aiohttp.ServerDisconnectedError as e:
|
|
140
|
+
_handle_server_disconnect_error(e)
|
|
141
|
+
raise SystemExit(1) from None
|
|
142
|
+
except (aiohttp.ClientSSLError, ssl.SSLError) as e:
|
|
143
|
+
_handle_ssl_error(e)
|
|
144
|
+
raise SystemExit(1) from None
|
|
145
|
+
except click.Abort:
|
|
146
|
+
# Let Click handle Abort - don't catch it
|
|
147
|
+
raise
|
|
148
|
+
except Exception as e:
|
|
149
|
+
# Catch-all for any exceptions during initialization
|
|
150
|
+
_handle_generic_cli_error(e)
|
|
151
|
+
raise SystemExit(1) from None
|
|
152
|
+
|
|
153
|
+
return cast(F, async_wrapper)
|
|
154
|
+
else:
|
|
155
|
+
|
|
156
|
+
@functools.wraps(func)
|
|
157
|
+
def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
158
|
+
try:
|
|
159
|
+
return func(*args, **kwargs)
|
|
160
|
+
except (
|
|
161
|
+
aiohttp.ClientConnectorError,
|
|
162
|
+
aiohttp.ClientConnectionError,
|
|
163
|
+
) as e:
|
|
164
|
+
_handle_network_error(e)
|
|
165
|
+
raise SystemExit(1) from None
|
|
166
|
+
except TimeoutError as e:
|
|
167
|
+
_handle_timeout_error(e)
|
|
168
|
+
raise SystemExit(1) from None
|
|
169
|
+
except aiohttp.ServerDisconnectedError as e:
|
|
170
|
+
_handle_server_disconnect_error(e)
|
|
171
|
+
raise SystemExit(1) from None
|
|
172
|
+
except (aiohttp.ClientSSLError, ssl.SSLError) as e:
|
|
173
|
+
_handle_ssl_error(e)
|
|
174
|
+
raise SystemExit(1) from None
|
|
175
|
+
except click.Abort:
|
|
176
|
+
# Let Click handle Abort - don't catch it
|
|
177
|
+
raise
|
|
178
|
+
except Exception as e:
|
|
179
|
+
# Catch-all for any exceptions during initialization
|
|
180
|
+
_handle_generic_cli_error(e)
|
|
181
|
+
raise SystemExit(1) from None
|
|
182
|
+
|
|
183
|
+
return cast(F, sync_wrapper)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _get_output_mode() -> str:
|
|
187
|
+
"""Get the output mode from Click context."""
|
|
188
|
+
ctx = click.get_current_context(silent=True)
|
|
189
|
+
if ctx and hasattr(ctx, "params"):
|
|
190
|
+
output_mode: str = ctx.params.get("output_mode", "table")
|
|
191
|
+
return output_mode
|
|
192
|
+
return "table"
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _handle_client_error(
|
|
196
|
+
e: BadRequestException | UnprocessableEntityException,
|
|
197
|
+
) -> None:
|
|
198
|
+
"""Handle 400 Bad Request and 422 Unprocessable Entity errors."""
|
|
199
|
+
output_mode = _get_output_mode()
|
|
200
|
+
|
|
201
|
+
if output_mode == "json":
|
|
202
|
+
error_details = _extract_error_details(e)
|
|
203
|
+
error_data = {
|
|
204
|
+
"status": "error",
|
|
205
|
+
"error": error_details
|
|
206
|
+
or e.reason
|
|
207
|
+
or "Bad request - check your input parameters",
|
|
208
|
+
"error_code": "BAD_REQUEST"
|
|
209
|
+
if isinstance(e, BadRequestException)
|
|
210
|
+
else "UNPROCESSABLE_ENTITY",
|
|
211
|
+
}
|
|
212
|
+
click.echo(json.dumps(error_data))
|
|
213
|
+
return
|
|
214
|
+
|
|
215
|
+
click.echo("❌ Invalid request")
|
|
216
|
+
|
|
217
|
+
# Try to extract error details from response body
|
|
218
|
+
error_details = _extract_error_details(e)
|
|
219
|
+
if error_details:
|
|
220
|
+
click.echo(f" {error_details}")
|
|
221
|
+
else:
|
|
222
|
+
click.echo(f" {e.reason or 'Bad request - check your input parameters'}")
|
|
223
|
+
|
|
224
|
+
click.echo("💡 Please check your input and try again")
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def _handle_auth_error(e: UnauthorizedException) -> None:
|
|
228
|
+
"""Handle 401 Unauthorized errors."""
|
|
229
|
+
output_mode = _get_output_mode()
|
|
230
|
+
|
|
231
|
+
if output_mode == "json":
|
|
232
|
+
error_data = {
|
|
233
|
+
"status": "error",
|
|
234
|
+
"error": "Authentication failed - invalid or missing API token",
|
|
235
|
+
"error_code": "UNAUTHORIZED",
|
|
236
|
+
}
|
|
237
|
+
click.echo(json.dumps(error_data))
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
click.echo("❌ Authentication failed")
|
|
241
|
+
click.echo(" Your API token may be invalid")
|
|
242
|
+
click.echo("💡 Please check your authentication:")
|
|
243
|
+
click.echo(" • Verify your API token is correct")
|
|
244
|
+
click.echo(" • Run 'workato profiles list' to check your profile")
|
|
245
|
+
click.echo(" • Run 'workato profiles use' to update your credentials")
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def _handle_forbidden_error(e: ForbiddenException) -> None:
|
|
249
|
+
"""Handle 403 Forbidden errors."""
|
|
250
|
+
output_mode = _get_output_mode()
|
|
251
|
+
|
|
252
|
+
if output_mode == "json":
|
|
253
|
+
error_details = _extract_error_details(e)
|
|
254
|
+
error_data = {
|
|
255
|
+
"status": "error",
|
|
256
|
+
"error": error_details or "Access forbidden - insufficient permissions",
|
|
257
|
+
"error_code": "FORBIDDEN",
|
|
258
|
+
}
|
|
259
|
+
click.echo(json.dumps(error_data))
|
|
260
|
+
return
|
|
261
|
+
|
|
262
|
+
click.echo("❌ Access forbidden")
|
|
263
|
+
click.echo(" You don't have permission to perform this action")
|
|
264
|
+
|
|
265
|
+
error_details = _extract_error_details(e)
|
|
266
|
+
if error_details:
|
|
267
|
+
click.echo(f" {error_details}")
|
|
268
|
+
|
|
269
|
+
click.echo("💡 Please check:")
|
|
270
|
+
click.echo(" • Your account has the required permissions")
|
|
271
|
+
click.echo(" • You're working in the correct workspace/folder")
|
|
272
|
+
click.echo(" • The resource exists and is accessible to you")
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _handle_not_found_error(e: NotFoundException) -> None:
|
|
276
|
+
"""Handle 404 Not Found errors."""
|
|
277
|
+
output_mode = _get_output_mode()
|
|
278
|
+
|
|
279
|
+
if output_mode == "json":
|
|
280
|
+
error_details = _extract_error_details(e)
|
|
281
|
+
error_data = {
|
|
282
|
+
"status": "error",
|
|
283
|
+
"error": error_details or "Resource not found",
|
|
284
|
+
"error_code": "NOT_FOUND",
|
|
285
|
+
}
|
|
286
|
+
click.echo(json.dumps(error_data))
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
click.echo("❌ Resource not found")
|
|
290
|
+
click.echo(" The requested resource could not be found")
|
|
291
|
+
|
|
292
|
+
error_details = _extract_error_details(e)
|
|
293
|
+
if error_details:
|
|
294
|
+
click.echo(f" {error_details}")
|
|
295
|
+
|
|
296
|
+
click.echo("💡 Please check:")
|
|
297
|
+
click.echo(" • The ID or name is correct")
|
|
298
|
+
click.echo(" • The resource exists in your workspace")
|
|
299
|
+
click.echo(" • You have permission to access the resource")
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def _handle_conflict_error(e: ConflictException) -> None:
|
|
303
|
+
"""Handle 409 Conflict errors."""
|
|
304
|
+
output_mode = _get_output_mode()
|
|
305
|
+
|
|
306
|
+
if output_mode == "json":
|
|
307
|
+
error_details = _extract_error_details(e)
|
|
308
|
+
error_data = {
|
|
309
|
+
"status": "error",
|
|
310
|
+
"error": error_details or "Request conflicts with current state",
|
|
311
|
+
"error_code": "CONFLICT",
|
|
312
|
+
}
|
|
313
|
+
click.echo(json.dumps(error_data))
|
|
314
|
+
return
|
|
315
|
+
|
|
316
|
+
click.echo("❌ Conflict detected")
|
|
317
|
+
click.echo(" The request conflicts with the current state")
|
|
318
|
+
|
|
319
|
+
error_details = _extract_error_details(e)
|
|
320
|
+
if error_details:
|
|
321
|
+
click.echo(f" {error_details}")
|
|
322
|
+
|
|
323
|
+
click.echo("💡 This usually means:")
|
|
324
|
+
click.echo(" • A resource with the same name already exists")
|
|
325
|
+
click.echo(" • The resource is being used by another process")
|
|
326
|
+
click.echo(" • There's a version conflict")
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def _handle_server_error(e: ServiceException) -> None:
|
|
330
|
+
"""Handle 5xx Server errors."""
|
|
331
|
+
output_mode = _get_output_mode()
|
|
332
|
+
|
|
333
|
+
if output_mode == "json":
|
|
334
|
+
error_data = {
|
|
335
|
+
"status": "error",
|
|
336
|
+
"error": "Server error - Workato API is experiencing issues",
|
|
337
|
+
"error_code": "SERVER_ERROR",
|
|
338
|
+
"http_status": e.status,
|
|
339
|
+
}
|
|
340
|
+
click.echo(json.dumps(error_data))
|
|
341
|
+
return
|
|
342
|
+
|
|
343
|
+
click.echo("❌ Server error")
|
|
344
|
+
click.echo(" The Workato API is experiencing issues")
|
|
345
|
+
click.echo(f" Status: {e.status}")
|
|
346
|
+
|
|
347
|
+
click.echo("💡 Please try:")
|
|
348
|
+
click.echo(" • Wait a few moments and retry")
|
|
349
|
+
click.echo(" • Check Workato status page for outages")
|
|
350
|
+
click.echo(" • Contact support if the issue persists")
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _handle_generic_api_error(e: ApiException) -> None:
|
|
354
|
+
"""Handle other API errors."""
|
|
355
|
+
output_mode = _get_output_mode()
|
|
356
|
+
|
|
357
|
+
if output_mode == "json":
|
|
358
|
+
error_details = _extract_error_details(e)
|
|
359
|
+
error_data = {
|
|
360
|
+
"status": "error",
|
|
361
|
+
"error": error_details or e.reason or "API error occurred",
|
|
362
|
+
"error_code": "API_ERROR",
|
|
363
|
+
}
|
|
364
|
+
if e.status:
|
|
365
|
+
error_data["http_status"] = e.status
|
|
366
|
+
click.echo(json.dumps(error_data))
|
|
367
|
+
return
|
|
368
|
+
|
|
369
|
+
click.echo("❌ API error occurred")
|
|
370
|
+
|
|
371
|
+
if e.status:
|
|
372
|
+
click.echo(f" Status: {e.status}")
|
|
373
|
+
if e.reason:
|
|
374
|
+
click.echo(f" Reason: {e.reason}")
|
|
375
|
+
|
|
376
|
+
error_details = _extract_error_details(e)
|
|
377
|
+
if error_details:
|
|
378
|
+
click.echo(f" Details: {error_details}")
|
|
379
|
+
|
|
380
|
+
click.echo("💡 Please check your request and try again")
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def _extract_error_details(e: ApiException) -> str:
|
|
384
|
+
"""Extract meaningful error details from API exception response."""
|
|
385
|
+
if not (e.body or e.data):
|
|
386
|
+
return ""
|
|
387
|
+
|
|
388
|
+
try:
|
|
389
|
+
# Try to parse JSON error response
|
|
390
|
+
import json
|
|
391
|
+
|
|
392
|
+
error_data = json.loads(e.body) if e.body else e.data
|
|
393
|
+
|
|
394
|
+
# Common error message patterns
|
|
395
|
+
if isinstance(error_data, dict):
|
|
396
|
+
# Look for common error message fields
|
|
397
|
+
for field in ["message", "error", "detail", "description"]:
|
|
398
|
+
if field in error_data:
|
|
399
|
+
return str(error_data[field])
|
|
400
|
+
|
|
401
|
+
# Look for validation errors
|
|
402
|
+
if "errors" in error_data:
|
|
403
|
+
errors = error_data["errors"]
|
|
404
|
+
if isinstance(errors, list) and errors:
|
|
405
|
+
return f"Validation error: {errors[0]}"
|
|
406
|
+
elif isinstance(errors, dict):
|
|
407
|
+
# Format field-specific errors
|
|
408
|
+
error_msgs = []
|
|
409
|
+
for field, msgs in errors.items():
|
|
410
|
+
if isinstance(msgs, list):
|
|
411
|
+
error_msgs.append(f"{field}: {', '.join(msgs)}")
|
|
412
|
+
else:
|
|
413
|
+
error_msgs.append(f"{field}: {msgs}")
|
|
414
|
+
return "; ".join(error_msgs)
|
|
415
|
+
|
|
416
|
+
except JSONDecodeError:
|
|
417
|
+
# If we can't parse the error, fall back to raw response
|
|
418
|
+
pass
|
|
419
|
+
|
|
420
|
+
# Return first 200 chars of raw response as fallback
|
|
421
|
+
raw_response = str(e.body or e.data)
|
|
422
|
+
return raw_response[:200] + ("..." if len(raw_response) > 200 else "")
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def _handle_network_error(
|
|
426
|
+
e: aiohttp.ClientConnectorError | aiohttp.ClientConnectionError,
|
|
427
|
+
) -> None:
|
|
428
|
+
"""Handle network connection errors."""
|
|
429
|
+
output_mode = _get_output_mode()
|
|
430
|
+
|
|
431
|
+
if output_mode == "json":
|
|
432
|
+
error_data = {
|
|
433
|
+
"status": "error",
|
|
434
|
+
"error": "Cannot connect to Workato API",
|
|
435
|
+
"error_code": "NETWORK_ERROR",
|
|
436
|
+
"details": str(e),
|
|
437
|
+
}
|
|
438
|
+
click.echo(json.dumps(error_data))
|
|
439
|
+
return
|
|
440
|
+
|
|
441
|
+
click.echo("❌ Cannot connect to Workato API")
|
|
442
|
+
click.echo(f" {str(e)}")
|
|
443
|
+
click.echo("💡 Please check:")
|
|
444
|
+
click.echo(" • Your internet connection is working")
|
|
445
|
+
click.echo(" • The Workato API is accessible")
|
|
446
|
+
click.echo(" • Your firewall/proxy settings allow the connection")
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def _handle_timeout_error(e: TimeoutError) -> None:
|
|
450
|
+
"""Handle timeout errors."""
|
|
451
|
+
output_mode = _get_output_mode()
|
|
452
|
+
|
|
453
|
+
if output_mode == "json":
|
|
454
|
+
error_data = {
|
|
455
|
+
"status": "error",
|
|
456
|
+
"error": "Request timed out",
|
|
457
|
+
"error_code": "TIMEOUT_ERROR",
|
|
458
|
+
}
|
|
459
|
+
click.echo(json.dumps(error_data))
|
|
460
|
+
return
|
|
461
|
+
|
|
462
|
+
click.echo("❌ Request timed out")
|
|
463
|
+
click.echo(" The request took too long to complete")
|
|
464
|
+
click.echo("💡 Please try:")
|
|
465
|
+
click.echo(" • Retry the operation")
|
|
466
|
+
click.echo(" • Check your network connection")
|
|
467
|
+
click.echo(" • The Workato API may be experiencing high load")
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def _handle_server_disconnect_error(e: aiohttp.ServerDisconnectedError) -> None:
|
|
471
|
+
"""Handle server disconnection errors."""
|
|
472
|
+
output_mode = _get_output_mode()
|
|
473
|
+
|
|
474
|
+
if output_mode == "json":
|
|
475
|
+
error_data = {
|
|
476
|
+
"status": "error",
|
|
477
|
+
"error": "Server disconnected unexpectedly",
|
|
478
|
+
"error_code": "SERVER_DISCONNECT",
|
|
479
|
+
}
|
|
480
|
+
click.echo(json.dumps(error_data))
|
|
481
|
+
return
|
|
482
|
+
|
|
483
|
+
click.echo("❌ Server disconnected")
|
|
484
|
+
click.echo(" The connection to Workato API was lost")
|
|
485
|
+
click.echo("💡 Please try:")
|
|
486
|
+
click.echo(" • Retry the operation")
|
|
487
|
+
click.echo(" • Check Workato status page for outages")
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def _handle_ssl_error(e: aiohttp.ClientSSLError | ssl.SSLError) -> None:
|
|
491
|
+
"""Handle SSL/certificate errors."""
|
|
492
|
+
output_mode = _get_output_mode()
|
|
493
|
+
|
|
494
|
+
if output_mode == "json":
|
|
495
|
+
error_data = {
|
|
496
|
+
"status": "error",
|
|
497
|
+
"error": "SSL certificate verification failed",
|
|
498
|
+
"error_code": "SSL_ERROR",
|
|
499
|
+
"details": str(e),
|
|
500
|
+
}
|
|
501
|
+
click.echo(json.dumps(error_data))
|
|
502
|
+
return
|
|
503
|
+
|
|
504
|
+
click.echo("❌ SSL certificate error")
|
|
505
|
+
click.echo(" Could not verify the SSL certificate")
|
|
506
|
+
click.echo(f" {str(e)}")
|
|
507
|
+
click.echo("💡 Please check:")
|
|
508
|
+
click.echo(" • Your system clock is set correctly")
|
|
509
|
+
click.echo(" • You have the latest CA certificates installed")
|
|
510
|
+
click.echo(" • Your network is not intercepting HTTPS connections")
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def _handle_generic_cli_error(e: Exception) -> None:
|
|
514
|
+
"""Handle any other unexpected CLI errors with a generic message."""
|
|
515
|
+
output_mode = _get_output_mode()
|
|
516
|
+
|
|
517
|
+
error_type = type(e).__name__
|
|
518
|
+
error_msg = str(e)
|
|
519
|
+
|
|
520
|
+
if output_mode == "json":
|
|
521
|
+
error_data = {
|
|
522
|
+
"status": "error",
|
|
523
|
+
"error": error_msg,
|
|
524
|
+
"error_code": "CLI_ERROR",
|
|
525
|
+
"error_type": error_type,
|
|
526
|
+
}
|
|
527
|
+
click.echo(json.dumps(error_data))
|
|
528
|
+
return
|
|
529
|
+
|
|
530
|
+
click.echo(f"❌ {error_type}")
|
|
531
|
+
click.echo(f" {error_msg}")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Utilities for managing .gitignore files."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def ensure_gitignore_entry(workspace_root: Path, entry: str) -> None:
|
|
7
|
+
"""Ensure an entry is added to .gitignore in the workspace root.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
workspace_root: Path to the workspace root directory
|
|
11
|
+
entry: Gitignore entry to add (e.g., "projects/*/workato/")
|
|
12
|
+
"""
|
|
13
|
+
gitignore_file = workspace_root / ".gitignore"
|
|
14
|
+
|
|
15
|
+
# Read existing .gitignore if it exists
|
|
16
|
+
existing_lines = []
|
|
17
|
+
if gitignore_file.exists():
|
|
18
|
+
with open(gitignore_file) as f:
|
|
19
|
+
existing_lines = [line.rstrip("\n") for line in f.readlines()]
|
|
20
|
+
|
|
21
|
+
# Check if entry is already in .gitignore
|
|
22
|
+
if entry not in existing_lines:
|
|
23
|
+
# Add entry to .gitignore
|
|
24
|
+
with open(gitignore_file, "a") as f:
|
|
25
|
+
if existing_lines and existing_lines[-1] != "":
|
|
26
|
+
f.write("\n") # Add newline if file doesn't end with one
|
|
27
|
+
f.write(f"{entry}\n")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def ensure_stubs_in_gitignore(workspace_root: Path) -> None:
|
|
31
|
+
"""Ensure workato/ generated packages are added to .gitignore in workspace root."""
|
|
32
|
+
ensure_gitignore_entry(workspace_root, "projects/*/workato/")
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Utility functions for handling .workato-ignore patterns"""
|
|
2
|
+
|
|
3
|
+
import fnmatch
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def load_ignore_patterns(workspace_root: Path) -> set[str]:
|
|
9
|
+
"""Load patterns from .workato-ignore file"""
|
|
10
|
+
ignore_file = workspace_root / ".workato-ignore"
|
|
11
|
+
patterns = {".workatoenv"} # Always protect config file
|
|
12
|
+
|
|
13
|
+
if not ignore_file.exists():
|
|
14
|
+
return patterns
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
with open(ignore_file, encoding="utf-8") as f:
|
|
18
|
+
for line in f:
|
|
19
|
+
line = line.strip()
|
|
20
|
+
if line and not line.startswith("#"):
|
|
21
|
+
patterns.add(line)
|
|
22
|
+
except (OSError, UnicodeDecodeError):
|
|
23
|
+
# If we can't read the ignore file, just use defaults
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
return patterns
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def should_skip_file(file_path: Path, ignore_patterns: set[str]) -> bool:
|
|
30
|
+
"""Check if file should be skipped using .workato-ignore patterns"""
|
|
31
|
+
path_str = str(file_path)
|
|
32
|
+
file_name = file_path.name
|
|
33
|
+
|
|
34
|
+
for pattern in ignore_patterns:
|
|
35
|
+
# Check exact matches, glob patterns, and filename patterns
|
|
36
|
+
if (
|
|
37
|
+
fnmatch.fnmatch(path_str, pattern)
|
|
38
|
+
or fnmatch.fnmatch(file_name, pattern)
|
|
39
|
+
or path_str.startswith(pattern + "/")
|
|
40
|
+
or path_str.startswith(pattern + "\\")
|
|
41
|
+
):
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
return False
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Spinner:
|
|
7
|
+
"""Simple spinner animation with elapsed time counter for CLI"""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message: str = "Loading") -> None:
|
|
10
|
+
self.message = message
|
|
11
|
+
self.spinner_chars = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
|
|
12
|
+
self.running = False
|
|
13
|
+
self.thread: threading.Thread | None = None
|
|
14
|
+
self.start_time = 0.0
|
|
15
|
+
self._message_lock = threading.Lock() # Thread safety for message updates
|
|
16
|
+
|
|
17
|
+
def start(self) -> None:
|
|
18
|
+
self.running = True
|
|
19
|
+
self.start_time = time.time()
|
|
20
|
+
self.thread = threading.Thread(target=self._spin)
|
|
21
|
+
self.thread.daemon = True
|
|
22
|
+
self.thread.start()
|
|
23
|
+
|
|
24
|
+
def stop(self) -> float:
|
|
25
|
+
self.running = False
|
|
26
|
+
if self.thread:
|
|
27
|
+
self.thread.join()
|
|
28
|
+
# Clear the line
|
|
29
|
+
max_line_length = (
|
|
30
|
+
len(self.message) + 20
|
|
31
|
+
) # Account for spinner, time, and padding
|
|
32
|
+
sys.stdout.write("\r" + " " * max_line_length + "\r")
|
|
33
|
+
sys.stdout.flush()
|
|
34
|
+
|
|
35
|
+
# Return elapsed time
|
|
36
|
+
if self.start_time:
|
|
37
|
+
return time.time() - self.start_time
|
|
38
|
+
return 0
|
|
39
|
+
|
|
40
|
+
def update_message(self, new_message: str) -> None:
|
|
41
|
+
"""Update the spinner message while it's running"""
|
|
42
|
+
with self._message_lock:
|
|
43
|
+
self.message = new_message
|
|
44
|
+
|
|
45
|
+
def _spin(self) -> None:
|
|
46
|
+
idx = 0
|
|
47
|
+
while self.running:
|
|
48
|
+
char = self.spinner_chars[idx % len(self.spinner_chars)]
|
|
49
|
+
elapsed = time.time() - self.start_time
|
|
50
|
+
elapsed_str = f"{elapsed:.1f}s"
|
|
51
|
+
|
|
52
|
+
# Format: spinner + message + elapsed time
|
|
53
|
+
# Use lock to safely read the message
|
|
54
|
+
with self._message_lock:
|
|
55
|
+
current_message = self.message
|
|
56
|
+
display_text = f"{char} {current_message}... ({elapsed_str})"
|
|
57
|
+
|
|
58
|
+
# Use carriage return to overwrite the line
|
|
59
|
+
# This is simpler and more reliable than trying to clear with spaces
|
|
60
|
+
sys.stdout.write(f"\r{display_text}")
|
|
61
|
+
sys.stdout.flush()
|
|
62
|
+
time.sleep(0.1)
|
|
63
|
+
idx += 1
|