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,847 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import asyncclick as click
|
|
7
|
+
|
|
8
|
+
from dependency_injector.wiring import Provide, inject
|
|
9
|
+
|
|
10
|
+
from workato_platform_cli import Workato
|
|
11
|
+
from workato_platform_cli.cli.commands.recipes.validator import RecipeValidator
|
|
12
|
+
from workato_platform_cli.cli.containers import Container
|
|
13
|
+
from workato_platform_cli.cli.utils import Spinner
|
|
14
|
+
from workato_platform_cli.cli.utils.config import ConfigManager
|
|
15
|
+
from workato_platform_cli.cli.utils.exception_handler import (
|
|
16
|
+
handle_api_exceptions,
|
|
17
|
+
handle_cli_exceptions,
|
|
18
|
+
)
|
|
19
|
+
from workato_platform_cli.client.workato_api.models.asset import Asset
|
|
20
|
+
from workato_platform_cli.client.workato_api.models.recipe import Recipe
|
|
21
|
+
from workato_platform_cli.client.workato_api.models.recipe_connection_update_request import ( # noqa: E501
|
|
22
|
+
RecipeConnectionUpdateRequest,
|
|
23
|
+
)
|
|
24
|
+
from workato_platform_cli.client.workato_api.models.recipe_start_response import (
|
|
25
|
+
RecipeStartResponse,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@click.group()
|
|
30
|
+
def recipes() -> None:
|
|
31
|
+
"""Manage recipes"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@recipes.command(name="list")
|
|
36
|
+
@click.option(
|
|
37
|
+
"--adapter-names-all", help="Comma-separated adapter names (recipes must use ALL)"
|
|
38
|
+
)
|
|
39
|
+
@click.option(
|
|
40
|
+
"--adapter-names-any", help="Comma-separated adapter names (recipes must use ANY)"
|
|
41
|
+
)
|
|
42
|
+
@click.option("--folder-id", type=int, help="Return recipes in specified folder")
|
|
43
|
+
@click.option(
|
|
44
|
+
"--order", type=click.Choice(["activity", "default"]), help="Ordering method"
|
|
45
|
+
)
|
|
46
|
+
@click.option("--running", is_flag=True, help="Return only running recipes")
|
|
47
|
+
@click.option(
|
|
48
|
+
"--since-id", type=int, help="Return recipes with IDs lower than this value"
|
|
49
|
+
)
|
|
50
|
+
@click.option(
|
|
51
|
+
"--stopped-after", help="Exclude recipes stopped after this date (ISO 8601 format)"
|
|
52
|
+
)
|
|
53
|
+
@click.option(
|
|
54
|
+
"--stop-cause",
|
|
55
|
+
type=click.Choice(
|
|
56
|
+
[
|
|
57
|
+
"trigger_errors_limit",
|
|
58
|
+
"action_quota_limit",
|
|
59
|
+
"trial_expired",
|
|
60
|
+
"txn_quota_limit",
|
|
61
|
+
]
|
|
62
|
+
),
|
|
63
|
+
help="Filter by stop reason",
|
|
64
|
+
)
|
|
65
|
+
@click.option(
|
|
66
|
+
"--updated-after", help="Include recipes updated after this date (ISO 8601 format)"
|
|
67
|
+
)
|
|
68
|
+
@click.option("--include-tags", help="Filter by recipe tags (comma-separated)")
|
|
69
|
+
@click.option(
|
|
70
|
+
"--exclude-code", is_flag=True, help="Exclude recipe code from response (faster)"
|
|
71
|
+
)
|
|
72
|
+
@click.option(
|
|
73
|
+
"--recursive", is_flag=True, help="Recursively list recipes in subfolders"
|
|
74
|
+
)
|
|
75
|
+
@handle_cli_exceptions
|
|
76
|
+
@inject
|
|
77
|
+
@handle_api_exceptions
|
|
78
|
+
async def list_recipes(
|
|
79
|
+
adapter_names_all: str | None = None,
|
|
80
|
+
adapter_names_any: str | None = None,
|
|
81
|
+
folder_id: int | None = None,
|
|
82
|
+
order: str | None = None,
|
|
83
|
+
running: bool | None = None,
|
|
84
|
+
since_id: int | None = None,
|
|
85
|
+
stopped_after: str | None = None,
|
|
86
|
+
stop_cause: str | None = None,
|
|
87
|
+
updated_after: str | None = None,
|
|
88
|
+
include_tags: str | None = None,
|
|
89
|
+
exclude_code: bool | None = None,
|
|
90
|
+
recursive: bool | None = None,
|
|
91
|
+
config_manager: ConfigManager = Provide[Container.config_manager],
|
|
92
|
+
) -> None:
|
|
93
|
+
"""List recipes with optional filtering"""
|
|
94
|
+
|
|
95
|
+
folder_id = folder_id or config_manager.load_config().folder_id
|
|
96
|
+
|
|
97
|
+
if not folder_id:
|
|
98
|
+
click.echo("β No folder ID provided and no project configured.")
|
|
99
|
+
click.echo("π‘ Use --folder-id <ID> or run 'workato init' first.")
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
# Handle recursive mode
|
|
103
|
+
if recursive:
|
|
104
|
+
# Recursive mode - ignore some filters
|
|
105
|
+
if any(
|
|
106
|
+
[
|
|
107
|
+
adapter_names_all,
|
|
108
|
+
adapter_names_any,
|
|
109
|
+
order,
|
|
110
|
+
since_id,
|
|
111
|
+
stopped_after,
|
|
112
|
+
stop_cause,
|
|
113
|
+
updated_after,
|
|
114
|
+
include_tags,
|
|
115
|
+
]
|
|
116
|
+
):
|
|
117
|
+
click.echo("β οΈ Recursive mode ignores most filters except --running")
|
|
118
|
+
|
|
119
|
+
click.echo(f"π Recursively searching for recipes in folder {folder_id}...")
|
|
120
|
+
click.echo()
|
|
121
|
+
|
|
122
|
+
# Get all recipes recursively
|
|
123
|
+
recipes = await get_recipes_recursive(folder_id)
|
|
124
|
+
|
|
125
|
+
# Apply running filter if specified
|
|
126
|
+
if running:
|
|
127
|
+
recipes = [recipe for recipe in recipes if recipe.running]
|
|
128
|
+
|
|
129
|
+
click.echo()
|
|
130
|
+
click.echo(f"π Total: {len(recipes)} recipe(s) found across all folders")
|
|
131
|
+
|
|
132
|
+
if not recipes:
|
|
133
|
+
click.echo(" βΉοΈ No recipes found")
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
click.echo()
|
|
137
|
+
|
|
138
|
+
# Display all recipes
|
|
139
|
+
for recipe in recipes:
|
|
140
|
+
display_recipe_summary(recipe=recipe)
|
|
141
|
+
click.echo()
|
|
142
|
+
|
|
143
|
+
click.echo("π‘ Commands:")
|
|
144
|
+
click.echo(" β’ Start recipe: workato recipes start --id <ID>")
|
|
145
|
+
click.echo(" β’ View running only: workato recipes list --running --recursive")
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
# Non-recursive mode - get ALL recipes with pagination
|
|
149
|
+
# Build filter description for user feedback
|
|
150
|
+
filter_parts = []
|
|
151
|
+
if folder_id:
|
|
152
|
+
filter_parts.append(f"folder {folder_id}")
|
|
153
|
+
if running:
|
|
154
|
+
filter_parts.append("running recipes only")
|
|
155
|
+
if adapter_names_all:
|
|
156
|
+
filter_parts.append(f"using ALL adapters: {adapter_names_all}")
|
|
157
|
+
if adapter_names_any:
|
|
158
|
+
filter_parts.append(f"using ANY adapters: {adapter_names_any}")
|
|
159
|
+
if stop_cause:
|
|
160
|
+
filter_parts.append(f"stopped due to: {stop_cause}")
|
|
161
|
+
|
|
162
|
+
filter_desc = f" ({', '.join(filter_parts)})" if filter_parts else ""
|
|
163
|
+
|
|
164
|
+
spinner = Spinner(f"Fetching all recipes{filter_desc}")
|
|
165
|
+
spinner.start()
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
recipes = await get_all_recipes_paginated(
|
|
169
|
+
folder_id=folder_id,
|
|
170
|
+
adapter_names_all=adapter_names_all,
|
|
171
|
+
adapter_names_any=adapter_names_any,
|
|
172
|
+
order=order,
|
|
173
|
+
running=running,
|
|
174
|
+
since_id=since_id,
|
|
175
|
+
stopped_after=stopped_after,
|
|
176
|
+
stop_cause=stop_cause,
|
|
177
|
+
updated_after=updated_after,
|
|
178
|
+
include_tags=include_tags,
|
|
179
|
+
exclude_code=exclude_code,
|
|
180
|
+
)
|
|
181
|
+
finally:
|
|
182
|
+
elapsed = spinner.stop()
|
|
183
|
+
|
|
184
|
+
click.echo(f"π Recipes ({len(recipes)} found) - ({elapsed:.1f}s)")
|
|
185
|
+
if filter_parts:
|
|
186
|
+
click.echo(f" π Filters: {', '.join(filter_parts)}")
|
|
187
|
+
|
|
188
|
+
if not recipes:
|
|
189
|
+
click.echo(" βΉοΈ No recipes found")
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
click.echo()
|
|
193
|
+
|
|
194
|
+
# Display recipes
|
|
195
|
+
for recipe in recipes:
|
|
196
|
+
display_recipe_summary(recipe=recipe)
|
|
197
|
+
click.echo()
|
|
198
|
+
|
|
199
|
+
click.echo("π‘ Commands:")
|
|
200
|
+
click.echo(" β’ Start recipe: workato recipes start --id <ID>")
|
|
201
|
+
click.echo(" β’ View running only: workato recipes list --running")
|
|
202
|
+
click.echo(" β’ Recursive search: workato recipes list --recursive")
|
|
203
|
+
click.echo(" β’ Filter by folder: workato recipes list --folder-id <ID>")
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@recipes.command()
|
|
207
|
+
@click.option("--path", required=True, help="Path to the recipe JSON file")
|
|
208
|
+
@handle_cli_exceptions
|
|
209
|
+
@inject
|
|
210
|
+
@handle_api_exceptions
|
|
211
|
+
async def validate(
|
|
212
|
+
path: str,
|
|
213
|
+
recipe_validator: RecipeValidator = Provide[Container.recipe_validator],
|
|
214
|
+
) -> None:
|
|
215
|
+
"""Validate a recipe file"""
|
|
216
|
+
|
|
217
|
+
recipe_path = Path(path)
|
|
218
|
+
|
|
219
|
+
# Check if file exists
|
|
220
|
+
if not recipe_path.exists():
|
|
221
|
+
click.echo(f"β File not found: {path}")
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
# Check if it's a JSON file
|
|
225
|
+
if recipe_path.suffix.lower() != ".json":
|
|
226
|
+
click.echo(f"β File must be a JSON file: {path}")
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
# Read and parse the recipe file
|
|
231
|
+
with open(recipe_path) as f:
|
|
232
|
+
recipe_data = json.load(f)
|
|
233
|
+
|
|
234
|
+
# Validate the recipe
|
|
235
|
+
spinner = Spinner(f"Validating recipe: {recipe_path.name}")
|
|
236
|
+
spinner.start()
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
result = await recipe_validator.validate_recipe(recipe_data)
|
|
240
|
+
finally:
|
|
241
|
+
elapsed = spinner.stop()
|
|
242
|
+
|
|
243
|
+
# Display results
|
|
244
|
+
if result.is_valid:
|
|
245
|
+
click.echo(f"β
Recipe validation passed ({elapsed:.1f}s)")
|
|
246
|
+
click.echo(f" π File: {recipe_path.name}")
|
|
247
|
+
else:
|
|
248
|
+
click.echo(f"β Recipe validation failed ({elapsed:.1f}s)")
|
|
249
|
+
click.echo(f" π File: {recipe_path.name}")
|
|
250
|
+
click.echo(f" β {len(result.errors)} error(s) found")
|
|
251
|
+
|
|
252
|
+
for i, error in enumerate(result.errors, 1):
|
|
253
|
+
click.echo(f"\n Error {i}:")
|
|
254
|
+
if error.line_number:
|
|
255
|
+
click.echo(f" Line: {error.line_number}")
|
|
256
|
+
if error.field_label:
|
|
257
|
+
click.echo(f" Field: {error.field_label}")
|
|
258
|
+
if error.field_path:
|
|
259
|
+
click.echo(f" Path: {' -> '.join(error.field_path)}")
|
|
260
|
+
click.echo(f" Message: {error.message}")
|
|
261
|
+
if error.error_type:
|
|
262
|
+
click.echo(f" Type: {error.error_type.value}")
|
|
263
|
+
|
|
264
|
+
# Display warnings if any
|
|
265
|
+
if result.warnings:
|
|
266
|
+
click.echo(f"\nβ οΈ {len(result.warnings)} warning(s):")
|
|
267
|
+
for warning in result.warnings:
|
|
268
|
+
click.echo(f" β’ {warning.message}")
|
|
269
|
+
|
|
270
|
+
except json.JSONDecodeError as e:
|
|
271
|
+
click.echo(f"β Invalid JSON file: {str(e)}")
|
|
272
|
+
except (FileNotFoundError, PermissionError) as e:
|
|
273
|
+
click.echo(f"β File access error: {str(e)}")
|
|
274
|
+
except ValueError as e:
|
|
275
|
+
click.echo(f"β Validation failed: {str(e)}")
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@recipes.command()
|
|
279
|
+
@click.option("--id", "recipe_id", type=int, help="Recipe ID to start")
|
|
280
|
+
@click.option(
|
|
281
|
+
"--all", "start_all", is_flag=True, help="Start all recipes in current project"
|
|
282
|
+
)
|
|
283
|
+
@click.option("--folder-id", type=int, help="Start all recipes in specified folder")
|
|
284
|
+
@handle_cli_exceptions
|
|
285
|
+
@handle_api_exceptions
|
|
286
|
+
async def start(
|
|
287
|
+
recipe_id: int,
|
|
288
|
+
start_all: bool,
|
|
289
|
+
folder_id: int,
|
|
290
|
+
) -> None:
|
|
291
|
+
"""Start recipes (individual, all in project, or all in folder)"""
|
|
292
|
+
|
|
293
|
+
# Validate that exactly one option is provided
|
|
294
|
+
options_count = sum([bool(recipe_id), start_all, bool(folder_id)])
|
|
295
|
+
if options_count == 0:
|
|
296
|
+
click.echo("β Please specify one of: --id, --all, or --folder-id")
|
|
297
|
+
click.echo("π‘ Examples:")
|
|
298
|
+
click.echo(" workato recipes start --id 12345")
|
|
299
|
+
click.echo(" workato recipes start --all")
|
|
300
|
+
click.echo(" workato recipes start --folder-id 67890")
|
|
301
|
+
return
|
|
302
|
+
elif options_count > 1:
|
|
303
|
+
click.echo("β Please specify only one option: --id, --all, or --folder-id")
|
|
304
|
+
return
|
|
305
|
+
|
|
306
|
+
if recipe_id:
|
|
307
|
+
# Start single recipe
|
|
308
|
+
await start_single_recipe(recipe_id)
|
|
309
|
+
elif start_all:
|
|
310
|
+
# Start all recipes in current project
|
|
311
|
+
await start_project_recipes()
|
|
312
|
+
elif folder_id:
|
|
313
|
+
# Start all recipes in specified folder
|
|
314
|
+
await start_folder_recipes(folder_id)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
@recipes.command()
|
|
318
|
+
@click.option("--id", "recipe_id", type=int, help="Recipe ID to stop")
|
|
319
|
+
@click.option(
|
|
320
|
+
"--all", "stop_all", is_flag=True, help="Stop all recipes in current project"
|
|
321
|
+
)
|
|
322
|
+
@click.option("--folder-id", type=int, help="Stop all recipes in specified folder")
|
|
323
|
+
async def stop(
|
|
324
|
+
recipe_id: int,
|
|
325
|
+
stop_all: bool,
|
|
326
|
+
folder_id: int,
|
|
327
|
+
) -> None:
|
|
328
|
+
"""Stop recipes (individual, all in project, or all in folder)"""
|
|
329
|
+
|
|
330
|
+
# Validate that exactly one option is provided
|
|
331
|
+
options_count = sum([bool(recipe_id), stop_all, bool(folder_id)])
|
|
332
|
+
if options_count == 0:
|
|
333
|
+
click.echo("β Please specify one of: --id, --all, or --folder-id")
|
|
334
|
+
click.echo("π‘ Examples:")
|
|
335
|
+
click.echo(" workato recipes stop --id 12345")
|
|
336
|
+
click.echo(" workato recipes stop --all")
|
|
337
|
+
click.echo(" workato recipes stop --folder-id 67890")
|
|
338
|
+
return
|
|
339
|
+
elif options_count > 1:
|
|
340
|
+
click.echo("β Please specify only one option: --id, --all, or --folder-id")
|
|
341
|
+
return
|
|
342
|
+
|
|
343
|
+
if recipe_id:
|
|
344
|
+
# Stop single recipe
|
|
345
|
+
await stop_single_recipe(recipe_id)
|
|
346
|
+
elif stop_all:
|
|
347
|
+
# Stop all recipes in current project
|
|
348
|
+
await stop_project_recipes()
|
|
349
|
+
elif folder_id:
|
|
350
|
+
# Stop all recipes in specified folder
|
|
351
|
+
await stop_folder_recipes(folder_id)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def _display_recipe_errors(
|
|
355
|
+
recipe_start_response: RecipeStartResponse,
|
|
356
|
+
indent: str = " ",
|
|
357
|
+
) -> None:
|
|
358
|
+
"""Display detailed recipe error information in a readable format"""
|
|
359
|
+
# Handle code_errors (validation errors in recipe steps)
|
|
360
|
+
code_errors = recipe_start_response.code_errors
|
|
361
|
+
if code_errors:
|
|
362
|
+
click.echo(f"{indent}π Recipe Validation Errors:")
|
|
363
|
+
|
|
364
|
+
for step_error in code_errors:
|
|
365
|
+
if len(step_error) >= 2:
|
|
366
|
+
step_number = step_error[0]
|
|
367
|
+
error_details = step_error[1]
|
|
368
|
+
|
|
369
|
+
click.echo(f"{indent} πΈ Step {step_number}:")
|
|
370
|
+
|
|
371
|
+
for error in error_details:
|
|
372
|
+
field_label = error[0]
|
|
373
|
+
account_id = error[1] # Connection ID (account_id)
|
|
374
|
+
error_message = error[2]
|
|
375
|
+
field_path = error[3]
|
|
376
|
+
|
|
377
|
+
click.echo(f"{indent} β’ {field_label}: {error_message}")
|
|
378
|
+
if account_id is not None:
|
|
379
|
+
click.echo(f"{indent} Connection ID: {account_id}")
|
|
380
|
+
if field_path:
|
|
381
|
+
click.echo(f"{indent} Field: {field_path}")
|
|
382
|
+
|
|
383
|
+
# Handle config_errors (configuration-level errors)
|
|
384
|
+
config_errors = recipe_start_response.config_errors
|
|
385
|
+
if config_errors:
|
|
386
|
+
click.echo(f"{indent}βοΈ Configuration Errors:")
|
|
387
|
+
|
|
388
|
+
for config_error in config_errors:
|
|
389
|
+
if isinstance(config_error, list) and len(config_error) >= 2:
|
|
390
|
+
step_number = config_error[0]
|
|
391
|
+
error_details = config_error[1]
|
|
392
|
+
|
|
393
|
+
click.echo(f"{indent} πΈ Step {step_number}:")
|
|
394
|
+
|
|
395
|
+
for error in error_details:
|
|
396
|
+
if len(error) >= 3:
|
|
397
|
+
field_name = error[0]
|
|
398
|
+
account_id = error[1] # Connection ID (account_id)
|
|
399
|
+
error_message = error[2]
|
|
400
|
+
|
|
401
|
+
click.echo(f"{indent} β’ {field_name}: {error_message}")
|
|
402
|
+
if account_id is not None:
|
|
403
|
+
click.echo(f"{indent} Connection ID: {account_id}")
|
|
404
|
+
else:
|
|
405
|
+
click.echo(f"{indent} β’ {config_error}")
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
@inject
|
|
409
|
+
async def start_single_recipe(
|
|
410
|
+
recipe_id: int,
|
|
411
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
412
|
+
) -> None:
|
|
413
|
+
"""Start a single recipe by ID"""
|
|
414
|
+
spinner = Spinner(f"Starting recipe {recipe_id}")
|
|
415
|
+
spinner.start()
|
|
416
|
+
|
|
417
|
+
try:
|
|
418
|
+
recipe_start_response = await workato_api_client.recipes_api.start_recipe(
|
|
419
|
+
recipe_id
|
|
420
|
+
)
|
|
421
|
+
finally:
|
|
422
|
+
elapsed = spinner.stop()
|
|
423
|
+
|
|
424
|
+
# Check if the API response indicates success
|
|
425
|
+
if recipe_start_response.success:
|
|
426
|
+
click.echo(f"β
Recipe {recipe_id} started successfully ({elapsed:.1f}s)")
|
|
427
|
+
else:
|
|
428
|
+
# API returned success: false - extract error message
|
|
429
|
+
click.echo(f"β Recipe {recipe_id} failed to start ({elapsed:.1f}s)")
|
|
430
|
+
|
|
431
|
+
# Handle detailed error information
|
|
432
|
+
_display_recipe_errors(recipe_start_response=recipe_start_response)
|
|
433
|
+
return
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
@inject
|
|
437
|
+
async def start_project_recipes(
|
|
438
|
+
config_manager: ConfigManager = Provide[Container.config_manager],
|
|
439
|
+
) -> None:
|
|
440
|
+
"""Start all recipes in the current project"""
|
|
441
|
+
# Get project folder ID from meta file
|
|
442
|
+
meta_data = config_manager.load_config()
|
|
443
|
+
folder_id = meta_data.folder_id
|
|
444
|
+
|
|
445
|
+
if not folder_id:
|
|
446
|
+
click.echo("β No project configured. Please run 'workato init' first.")
|
|
447
|
+
return
|
|
448
|
+
|
|
449
|
+
click.echo(f"π Starting all recipes in current project (folder {folder_id})")
|
|
450
|
+
await start_folder_recipes(folder_id)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@inject
|
|
454
|
+
async def start_folder_recipes(
|
|
455
|
+
folder_id: int,
|
|
456
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
457
|
+
) -> None:
|
|
458
|
+
"""Start all recipes in a specific folder"""
|
|
459
|
+
# First, get all recipes in the folder using the assets API
|
|
460
|
+
recipe_assets = await get_folder_recipe_assets(folder_id)
|
|
461
|
+
|
|
462
|
+
if not recipe_assets:
|
|
463
|
+
click.echo(f"βΉοΈ No recipes found in folder {folder_id}")
|
|
464
|
+
return
|
|
465
|
+
|
|
466
|
+
click.echo(f"π Found {len(recipe_assets)} recipe(s) to start")
|
|
467
|
+
click.echo()
|
|
468
|
+
|
|
469
|
+
# Track results
|
|
470
|
+
started_count = 0
|
|
471
|
+
failed_count = 0
|
|
472
|
+
failed_recipes: list[Asset] = []
|
|
473
|
+
|
|
474
|
+
# Start each recipe
|
|
475
|
+
for recipe in recipe_assets:
|
|
476
|
+
recipe_id = recipe.id
|
|
477
|
+
recipe_name = recipe.name
|
|
478
|
+
|
|
479
|
+
response = await workato_api_client.recipes_api.start_recipe(recipe_id)
|
|
480
|
+
|
|
481
|
+
if response.success:
|
|
482
|
+
click.echo(f" β
{recipe_name} (ID: {recipe_id})")
|
|
483
|
+
started_count += 1
|
|
484
|
+
else:
|
|
485
|
+
# success is false or missing - show detailed error
|
|
486
|
+
click.echo(f" β {recipe_name} (ID: {recipe_id})")
|
|
487
|
+
_display_recipe_errors(response, indent=" ")
|
|
488
|
+
failed_count += 1
|
|
489
|
+
failed_recipes.append(recipe)
|
|
490
|
+
|
|
491
|
+
# Summary
|
|
492
|
+
click.echo()
|
|
493
|
+
click.echo(f"π Results: {started_count} started, {failed_count} failed")
|
|
494
|
+
|
|
495
|
+
if failed_recipes:
|
|
496
|
+
click.echo()
|
|
497
|
+
click.echo("β Failed recipes (you can retry individually):")
|
|
498
|
+
for recipe in failed_recipes:
|
|
499
|
+
click.echo(f" β’ {recipe.name} (ID: {recipe.id})")
|
|
500
|
+
click.echo(f" Retry: workato recipes start --id {recipe.id}")
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
@inject
|
|
504
|
+
async def stop_single_recipe(
|
|
505
|
+
recipe_id: int,
|
|
506
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
507
|
+
) -> None:
|
|
508
|
+
"""Stop a single recipe by ID"""
|
|
509
|
+
spinner = Spinner(f"Stopping recipe {recipe_id}")
|
|
510
|
+
spinner.start()
|
|
511
|
+
|
|
512
|
+
try:
|
|
513
|
+
await workato_api_client.recipes_api.stop_recipe(recipe_id)
|
|
514
|
+
finally:
|
|
515
|
+
elapsed = spinner.stop()
|
|
516
|
+
|
|
517
|
+
click.echo(f"β
Recipe {recipe_id} stopped successfully ({elapsed:.1f}s)")
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@inject
|
|
521
|
+
async def stop_project_recipes(
|
|
522
|
+
config_manager: ConfigManager = Provide[Container.config_manager],
|
|
523
|
+
) -> None:
|
|
524
|
+
"""Stop all recipes in the current project"""
|
|
525
|
+
# Get project folder ID from meta file
|
|
526
|
+
meta_data = config_manager.load_config()
|
|
527
|
+
folder_id = meta_data.folder_id
|
|
528
|
+
|
|
529
|
+
if not folder_id:
|
|
530
|
+
click.echo("β No project configured. Please run 'workato init' first.")
|
|
531
|
+
return
|
|
532
|
+
|
|
533
|
+
click.echo(f"π Stopping all recipes in current project (folder {folder_id})")
|
|
534
|
+
await stop_folder_recipes(folder_id)
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
@inject
|
|
538
|
+
async def stop_folder_recipes(
|
|
539
|
+
folder_id: int,
|
|
540
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
541
|
+
) -> None:
|
|
542
|
+
"""Stop all recipes in a specific folder"""
|
|
543
|
+
# First, get all recipes in the folder using the assets API
|
|
544
|
+
recipes = await get_folder_recipe_assets(folder_id)
|
|
545
|
+
|
|
546
|
+
if not recipes:
|
|
547
|
+
click.echo(f"βΉοΈ No recipes found in folder {folder_id}")
|
|
548
|
+
return
|
|
549
|
+
|
|
550
|
+
click.echo(f"π Found {len(recipes)} recipe(s) to stop")
|
|
551
|
+
click.echo()
|
|
552
|
+
|
|
553
|
+
# Track results
|
|
554
|
+
stopped_count = 0
|
|
555
|
+
|
|
556
|
+
# Stop each recipe
|
|
557
|
+
for recipe in recipes:
|
|
558
|
+
recipe_id = recipe.id
|
|
559
|
+
recipe_name = recipe.name
|
|
560
|
+
|
|
561
|
+
await workato_api_client.recipes_api.stop_recipe(recipe_id)
|
|
562
|
+
|
|
563
|
+
click.echo(f" β
{recipe_name} (ID: {recipe_id})")
|
|
564
|
+
stopped_count += 1
|
|
565
|
+
|
|
566
|
+
# Summary
|
|
567
|
+
click.echo()
|
|
568
|
+
click.echo(f"π Results: {stopped_count} stopped")
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
@inject
|
|
572
|
+
async def get_folder_recipe_assets(
|
|
573
|
+
folder_id: int,
|
|
574
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
575
|
+
) -> list[Asset]:
|
|
576
|
+
"""Get all recipes in a folder using the assets API"""
|
|
577
|
+
spinner = Spinner(f"Fetching recipes in folder {folder_id}")
|
|
578
|
+
spinner.start()
|
|
579
|
+
|
|
580
|
+
try:
|
|
581
|
+
# Use existing utility function
|
|
582
|
+
assets_response = await workato_api_client.export_api.list_assets_in_folder(
|
|
583
|
+
folder_id=folder_id,
|
|
584
|
+
)
|
|
585
|
+
finally:
|
|
586
|
+
elapsed = spinner.stop()
|
|
587
|
+
|
|
588
|
+
# Filter for recipe assets
|
|
589
|
+
recipes = [
|
|
590
|
+
asset for asset in assets_response.result.assets if asset.type == "recipe"
|
|
591
|
+
]
|
|
592
|
+
|
|
593
|
+
click.echo(
|
|
594
|
+
f"π Found {len(recipes)} recipe(s) in folder {folder_id} ({elapsed:.1f}s)"
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
return recipes
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
@inject
|
|
601
|
+
async def get_all_recipes_paginated(
|
|
602
|
+
folder_id: int,
|
|
603
|
+
adapter_names_all: str | None = None,
|
|
604
|
+
adapter_names_any: str | None = None,
|
|
605
|
+
order: str | None = None,
|
|
606
|
+
running: bool | None = None,
|
|
607
|
+
since_id: int | None = None,
|
|
608
|
+
stopped_after: str | None = None,
|
|
609
|
+
stop_cause: str | None = None,
|
|
610
|
+
updated_after: str | None = None,
|
|
611
|
+
include_tags: str | None = None,
|
|
612
|
+
exclude_code: bool | None = None,
|
|
613
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
614
|
+
) -> list[Recipe]:
|
|
615
|
+
"""Get all recipes in a folder with automatic pagination"""
|
|
616
|
+
all_recipes = []
|
|
617
|
+
page = 1
|
|
618
|
+
while True:
|
|
619
|
+
response = await workato_api_client.recipes_api.list_recipes(
|
|
620
|
+
adapter_names_all=adapter_names_all,
|
|
621
|
+
adapter_names_any=adapter_names_any,
|
|
622
|
+
folder_id=folder_id,
|
|
623
|
+
order=order,
|
|
624
|
+
page=page,
|
|
625
|
+
per_page=100,
|
|
626
|
+
running=running,
|
|
627
|
+
since_id=since_id,
|
|
628
|
+
stopped_after=datetime.fromisoformat(stopped_after)
|
|
629
|
+
if stopped_after
|
|
630
|
+
else None,
|
|
631
|
+
stop_cause=stop_cause,
|
|
632
|
+
updated_after=datetime.fromisoformat(updated_after)
|
|
633
|
+
if updated_after
|
|
634
|
+
else None,
|
|
635
|
+
includes=[tag.strip() for tag in include_tags.split(",")]
|
|
636
|
+
if include_tags
|
|
637
|
+
else None,
|
|
638
|
+
exclude_code=exclude_code if exclude_code else None,
|
|
639
|
+
)
|
|
640
|
+
|
|
641
|
+
all_recipes.extend(response.items)
|
|
642
|
+
|
|
643
|
+
# If we got less than 100 results, we're on the last page
|
|
644
|
+
if len(response.items) < 100:
|
|
645
|
+
break
|
|
646
|
+
|
|
647
|
+
page += 1
|
|
648
|
+
|
|
649
|
+
return all_recipes
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
@inject
|
|
653
|
+
async def get_recipes_recursive(
|
|
654
|
+
folder_id: int,
|
|
655
|
+
visited_folders: set | None = None,
|
|
656
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
657
|
+
) -> list[Recipe]:
|
|
658
|
+
"""Recursively get all recipes in a folder and its subfolders"""
|
|
659
|
+
if visited_folders is None:
|
|
660
|
+
visited_folders = set()
|
|
661
|
+
|
|
662
|
+
# Prevent infinite loops in case of circular folder references
|
|
663
|
+
if folder_id in visited_folders:
|
|
664
|
+
return []
|
|
665
|
+
|
|
666
|
+
visited_folders.add(folder_id)
|
|
667
|
+
|
|
668
|
+
all_recipes = []
|
|
669
|
+
|
|
670
|
+
# Get ALL recipes in current folder with pagination
|
|
671
|
+
spinner = Spinner(f"Fetching recipes in folder {folder_id}")
|
|
672
|
+
spinner.start()
|
|
673
|
+
|
|
674
|
+
try:
|
|
675
|
+
folder_recipes = await get_all_recipes_paginated(
|
|
676
|
+
folder_id=folder_id,
|
|
677
|
+
exclude_code=True,
|
|
678
|
+
)
|
|
679
|
+
all_recipes.extend(folder_recipes)
|
|
680
|
+
|
|
681
|
+
finally:
|
|
682
|
+
elapsed = spinner.stop()
|
|
683
|
+
|
|
684
|
+
click.echo(
|
|
685
|
+
f"π Found {len(folder_recipes)} recipe(s) in folder {folder_id} "
|
|
686
|
+
f"({elapsed:.1f}s)"
|
|
687
|
+
)
|
|
688
|
+
|
|
689
|
+
# Get ALL subfolders and recursively process them with pagination
|
|
690
|
+
spinner = Spinner(f"Fetching subfolders in folder {folder_id}")
|
|
691
|
+
spinner.start()
|
|
692
|
+
|
|
693
|
+
try:
|
|
694
|
+
folders = []
|
|
695
|
+
page = 1
|
|
696
|
+
while True:
|
|
697
|
+
folder_response = await workato_api_client.folders_api.list_folders(
|
|
698
|
+
parent_id=folder_id,
|
|
699
|
+
page=page,
|
|
700
|
+
per_page=100,
|
|
701
|
+
)
|
|
702
|
+
|
|
703
|
+
folders.extend(folder_response)
|
|
704
|
+
|
|
705
|
+
# If we got less than 100 results, we're on the last page
|
|
706
|
+
if len(folder_response) < 100:
|
|
707
|
+
break
|
|
708
|
+
|
|
709
|
+
page += 1
|
|
710
|
+
|
|
711
|
+
finally:
|
|
712
|
+
elapsed = spinner.stop()
|
|
713
|
+
|
|
714
|
+
folder_count = len(folders)
|
|
715
|
+
click.echo(
|
|
716
|
+
f"π Found {folder_count} subfolder(s) in folder {folder_id} ({elapsed:.1f}s)"
|
|
717
|
+
)
|
|
718
|
+
|
|
719
|
+
# Recursively get recipes from each subfolder
|
|
720
|
+
for folder in folders:
|
|
721
|
+
subfolder_recipes = await get_recipes_recursive(
|
|
722
|
+
folder.id, visited_folders, workato_api_client
|
|
723
|
+
)
|
|
724
|
+
all_recipes.extend(subfolder_recipes)
|
|
725
|
+
|
|
726
|
+
return all_recipes
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
def display_recipe_summary(recipe: Recipe) -> None:
|
|
730
|
+
"""Display a summary of a recipe"""
|
|
731
|
+
name = recipe.name
|
|
732
|
+
recipe_id = recipe.id
|
|
733
|
+
running = recipe.running
|
|
734
|
+
|
|
735
|
+
status_icon = "βΆοΈ" if running else "βΈοΈ"
|
|
736
|
+
status_text = "Running" if running else "Stopped"
|
|
737
|
+
|
|
738
|
+
click.echo(f" {status_icon} {name}")
|
|
739
|
+
click.echo(f" π ID: {recipe_id}")
|
|
740
|
+
click.echo(f" π Status: {status_text}")
|
|
741
|
+
click.echo(f" π± Trigger App: {recipe.trigger_application}")
|
|
742
|
+
|
|
743
|
+
# Show action applications if available
|
|
744
|
+
if recipe.action_applications:
|
|
745
|
+
apps_display = ", ".join(recipe.action_applications)
|
|
746
|
+
click.echo(f" π§ Action Apps: {apps_display}")
|
|
747
|
+
|
|
748
|
+
# Show config information (applications/connections configured)
|
|
749
|
+
if recipe.config:
|
|
750
|
+
config_apps = []
|
|
751
|
+
for config_item in recipe.config:
|
|
752
|
+
if config_item.keyword == "application":
|
|
753
|
+
name = config_item.name or ""
|
|
754
|
+
|
|
755
|
+
# Show account_id if present and not null
|
|
756
|
+
account_info = ""
|
|
757
|
+
if config_item.account_id:
|
|
758
|
+
account_info = f" (Account: {config_item.account_id})"
|
|
759
|
+
|
|
760
|
+
config_apps.append(f"{name}{account_info}")
|
|
761
|
+
|
|
762
|
+
if config_apps:
|
|
763
|
+
config_display = ", ".join(config_apps)
|
|
764
|
+
click.echo(f" βοΈ Config Apps: {config_display}")
|
|
765
|
+
|
|
766
|
+
click.echo(f" π Folder ID: {recipe.folder_id}")
|
|
767
|
+
|
|
768
|
+
# Show job statistics if available
|
|
769
|
+
succeeded = recipe.job_succeeded_count
|
|
770
|
+
failed = recipe.job_failed_count
|
|
771
|
+
if succeeded > 0 or failed > 0:
|
|
772
|
+
click.echo(f" π Jobs: {succeeded} succeeded, {failed} failed")
|
|
773
|
+
|
|
774
|
+
# Show last run information if available
|
|
775
|
+
if recipe.last_run_at:
|
|
776
|
+
click.echo(f" π Last Run: {recipe.last_run_at.isoformat()}")
|
|
777
|
+
|
|
778
|
+
# Show stopped time if recipe is stopped
|
|
779
|
+
if not running and recipe.stopped_at:
|
|
780
|
+
click.echo(f" βΉοΈ Stopped: {recipe.stopped_at.isoformat()}")
|
|
781
|
+
|
|
782
|
+
# Show stop cause if recipe is stopped and has a cause
|
|
783
|
+
if not running and recipe.stop_cause:
|
|
784
|
+
stop_cause = recipe.stop_cause.replace("_", " ").title()
|
|
785
|
+
click.echo(f" β οΈ Stop Cause: {stop_cause}")
|
|
786
|
+
|
|
787
|
+
# Show creation date if available
|
|
788
|
+
if recipe.created_at:
|
|
789
|
+
click.echo(f" π
Created: {recipe.created_at.isoformat()}")
|
|
790
|
+
|
|
791
|
+
# Show author information if available
|
|
792
|
+
if recipe.author_name:
|
|
793
|
+
click.echo(f" π€ Author: {recipe.author_name}")
|
|
794
|
+
|
|
795
|
+
if recipe.tags:
|
|
796
|
+
tags_display = ", ".join(recipe.tags)
|
|
797
|
+
click.echo(f" π·οΈ Tags: {tags_display}")
|
|
798
|
+
|
|
799
|
+
# Show description if available (truncated)
|
|
800
|
+
if recipe.description:
|
|
801
|
+
description = recipe.description
|
|
802
|
+
if len(description) > 80:
|
|
803
|
+
description = description[:77] + "..."
|
|
804
|
+
click.echo(f" π Description: {description}")
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
@recipes.command()
|
|
808
|
+
@click.argument("recipe_id", type=int)
|
|
809
|
+
@click.option(
|
|
810
|
+
"--adapter-name",
|
|
811
|
+
required=True,
|
|
812
|
+
help="The internal name of the connector (e.g., box, salesforce)",
|
|
813
|
+
)
|
|
814
|
+
@click.option(
|
|
815
|
+
"--connection-id", required=True, type=int, help="The ID of the connection to use"
|
|
816
|
+
)
|
|
817
|
+
@handle_cli_exceptions
|
|
818
|
+
@inject
|
|
819
|
+
@handle_api_exceptions
|
|
820
|
+
async def update_connection(
|
|
821
|
+
recipe_id: int,
|
|
822
|
+
adapter_name: str,
|
|
823
|
+
connection_id: int,
|
|
824
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
825
|
+
) -> None:
|
|
826
|
+
"""Update a connection for a specific connector in a recipe"""
|
|
827
|
+
|
|
828
|
+
spinner = Spinner("Updating recipe connection...")
|
|
829
|
+
spinner.start()
|
|
830
|
+
|
|
831
|
+
try:
|
|
832
|
+
await workato_api_client.recipes_api.update_recipe_connection(
|
|
833
|
+
recipe_id=recipe_id,
|
|
834
|
+
recipe_connection_update_request=RecipeConnectionUpdateRequest(
|
|
835
|
+
adapter_name=adapter_name,
|
|
836
|
+
connection_id=connection_id,
|
|
837
|
+
),
|
|
838
|
+
)
|
|
839
|
+
|
|
840
|
+
finally:
|
|
841
|
+
elapsed = spinner.stop()
|
|
842
|
+
|
|
843
|
+
click.echo(
|
|
844
|
+
f"β
Successfully updated connection for recipe {recipe_id} ({elapsed:.1f}s)"
|
|
845
|
+
)
|
|
846
|
+
click.echo(f" π Connector: {adapter_name}")
|
|
847
|
+
click.echo(f" π Connection ID: {connection_id}")
|