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,327 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
import filecmp
|
|
3
|
+
import json
|
|
4
|
+
import shutil
|
|
5
|
+
import tempfile
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import asyncclick as click
|
|
10
|
+
|
|
11
|
+
from dependency_injector.wiring import Provide, inject
|
|
12
|
+
|
|
13
|
+
from workato_platform_cli.cli.commands.projects.project_manager import ProjectManager
|
|
14
|
+
from workato_platform_cli.cli.containers import Container
|
|
15
|
+
from workato_platform_cli.cli.utils.config import ConfigManager
|
|
16
|
+
from workato_platform_cli.cli.utils.exception_handler import (
|
|
17
|
+
handle_api_exceptions,
|
|
18
|
+
handle_cli_exceptions,
|
|
19
|
+
)
|
|
20
|
+
from workato_platform_cli.cli.utils.ignore_patterns import (
|
|
21
|
+
load_ignore_patterns,
|
|
22
|
+
should_skip_file,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def _pull_project(
|
|
27
|
+
config_manager: ConfigManager,
|
|
28
|
+
project_manager: ProjectManager,
|
|
29
|
+
non_interactive: bool = False,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""Internal pull logic that can be called from other commands"""
|
|
32
|
+
|
|
33
|
+
# Load API token
|
|
34
|
+
api_token = config_manager.api_token
|
|
35
|
+
if not api_token:
|
|
36
|
+
click.echo("❌ No API token found. Please run 'workato init' first.")
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
# Load project metadata
|
|
40
|
+
meta_data = config_manager.load_config()
|
|
41
|
+
if not meta_data.folder_id:
|
|
42
|
+
click.echo("❌ No project configured. Please run 'workato init' first.")
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
folder_id = meta_data.folder_id
|
|
46
|
+
project_name = meta_data.project_name or "project"
|
|
47
|
+
|
|
48
|
+
# Get project directory using the new relative path resolution
|
|
49
|
+
project_dir = config_manager.get_project_directory()
|
|
50
|
+
if not project_dir:
|
|
51
|
+
click.echo(
|
|
52
|
+
"❌ Could not determine project directory. Run 'workato init' first."
|
|
53
|
+
)
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
# Ensure project directory exists
|
|
57
|
+
project_dir.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
|
|
59
|
+
# Export the project to a temporary directory first
|
|
60
|
+
click.echo(f"Pulling latest changes for project: {project_name}")
|
|
61
|
+
|
|
62
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
63
|
+
temp_project_path = Path(temp_dir) / "remote_project"
|
|
64
|
+
|
|
65
|
+
# Download remote project to temp directory
|
|
66
|
+
result = await project_manager.export_project(
|
|
67
|
+
folder_id,
|
|
68
|
+
project_name,
|
|
69
|
+
target_dir=str(temp_project_path),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if not result:
|
|
73
|
+
click.echo("❌ Failed to pull project")
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
# If local project doesn't exist, just move the temp directory
|
|
77
|
+
if not project_dir.exists():
|
|
78
|
+
shutil.copytree(temp_project_path, project_dir)
|
|
79
|
+
click.echo("✅ Successfully pulled project to ./project")
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
# Get workspace root to load ignore patterns
|
|
83
|
+
workspace_root = config_manager.get_workspace_root()
|
|
84
|
+
ignore_patterns = load_ignore_patterns(workspace_root)
|
|
85
|
+
|
|
86
|
+
# Merge changes between remote and local
|
|
87
|
+
changes = merge_directories(
|
|
88
|
+
temp_project_path,
|
|
89
|
+
project_dir,
|
|
90
|
+
ignore_patterns,
|
|
91
|
+
non_interactive,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Show summary of changes
|
|
95
|
+
if changes["added"] or changes["modified"] or changes["removed"]:
|
|
96
|
+
click.echo("Changes applied:")
|
|
97
|
+
for change in changes["added"]:
|
|
98
|
+
file_path, stats = (
|
|
99
|
+
change if isinstance(change, tuple) else (change, None)
|
|
100
|
+
)
|
|
101
|
+
if stats:
|
|
102
|
+
click.echo(f" 📄 {file_path} (+{stats['lines']} lines)")
|
|
103
|
+
else:
|
|
104
|
+
click.echo(f" 📄 {file_path}")
|
|
105
|
+
for change in changes["modified"]:
|
|
106
|
+
file_path, stats = (
|
|
107
|
+
change if isinstance(change, tuple) else (change, None)
|
|
108
|
+
)
|
|
109
|
+
if stats:
|
|
110
|
+
added, removed = stats["added"], stats["removed"]
|
|
111
|
+
click.echo(f" 📝 {file_path} (+{added} -{removed})")
|
|
112
|
+
else:
|
|
113
|
+
click.echo(f" 📝 {file_path}")
|
|
114
|
+
for change in changes["removed"]:
|
|
115
|
+
file_path, stats = (
|
|
116
|
+
change if isinstance(change, tuple) else (change, None)
|
|
117
|
+
)
|
|
118
|
+
if stats:
|
|
119
|
+
click.echo(f" 🗑️ {file_path} (-{stats['lines']} lines)")
|
|
120
|
+
else:
|
|
121
|
+
click.echo(f" 🗑️ {file_path}")
|
|
122
|
+
|
|
123
|
+
# Show total stats
|
|
124
|
+
total_added = sum(
|
|
125
|
+
s[1]["lines"] if isinstance(s, tuple) and s[1] else 0
|
|
126
|
+
for s in changes["added"]
|
|
127
|
+
)
|
|
128
|
+
total_added += sum(
|
|
129
|
+
s[1]["added"] if isinstance(s, tuple) and s[1] else 0
|
|
130
|
+
for s in changes["modified"]
|
|
131
|
+
)
|
|
132
|
+
total_removed = sum(
|
|
133
|
+
s[1]["lines"] if isinstance(s, tuple) and s[1] else 0
|
|
134
|
+
for s in changes["removed"]
|
|
135
|
+
)
|
|
136
|
+
total_removed += sum(
|
|
137
|
+
s[1]["removed"] if isinstance(s, tuple) and s[1] else 0
|
|
138
|
+
for s in changes["modified"]
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
click.echo(
|
|
142
|
+
f"✅ Successfully pulled project changes (+{total_added} "
|
|
143
|
+
f"-{total_removed})"
|
|
144
|
+
)
|
|
145
|
+
else:
|
|
146
|
+
click.echo("✅ Project is already up to date")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def count_lines(file_path: Path) -> int:
|
|
150
|
+
"""Count lines in a file, handling different file types"""
|
|
151
|
+
try:
|
|
152
|
+
with open(file_path, encoding="utf-8") as f:
|
|
153
|
+
return len(f.readlines())
|
|
154
|
+
except (UnicodeDecodeError, OSError):
|
|
155
|
+
# For binary files, just return file size as rough estimate
|
|
156
|
+
try:
|
|
157
|
+
return file_path.stat().st_size // 50 # Rough estimate: 50 bytes per "line"
|
|
158
|
+
except OSError:
|
|
159
|
+
return 0
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def calculate_diff_stats(old_file: Path, new_file: Path) -> dict[str, int]:
|
|
163
|
+
"""Calculate diff statistics between two files"""
|
|
164
|
+
try:
|
|
165
|
+
# For JSON files, try to do more intelligent diffing
|
|
166
|
+
if old_file.suffix.lower() == ".json" and new_file.suffix.lower() == ".json":
|
|
167
|
+
return calculate_json_diff_stats(old_file, new_file)
|
|
168
|
+
|
|
169
|
+
# For text files, do line-based diffing
|
|
170
|
+
with open(old_file, encoding="utf-8") as f:
|
|
171
|
+
old_lines = f.readlines()
|
|
172
|
+
with open(new_file, encoding="utf-8") as f:
|
|
173
|
+
new_lines = f.readlines()
|
|
174
|
+
|
|
175
|
+
# Simple diff: count different lines
|
|
176
|
+
old_set = set(old_lines)
|
|
177
|
+
new_set = set(new_lines)
|
|
178
|
+
|
|
179
|
+
added = len(new_set - old_set)
|
|
180
|
+
removed = len(old_set - new_set)
|
|
181
|
+
|
|
182
|
+
return {"added": added, "removed": removed}
|
|
183
|
+
|
|
184
|
+
except (UnicodeDecodeError, OSError):
|
|
185
|
+
# For binary files, just show file size change
|
|
186
|
+
try:
|
|
187
|
+
old_size = old_file.stat().st_size
|
|
188
|
+
new_size = new_file.stat().st_size
|
|
189
|
+
if new_size > old_size:
|
|
190
|
+
return {"added": (new_size - old_size) // 50, "removed": 0}
|
|
191
|
+
else:
|
|
192
|
+
return {"added": 0, "removed": (old_size - new_size) // 50}
|
|
193
|
+
except OSError:
|
|
194
|
+
return {"added": 0, "removed": 0}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def calculate_json_diff_stats(old_file: Path, new_file: Path) -> dict[str, int]:
|
|
198
|
+
"""Calculate diff statistics for JSON files"""
|
|
199
|
+
try:
|
|
200
|
+
with open(old_file, encoding="utf-8") as f:
|
|
201
|
+
old_data = json.load(f)
|
|
202
|
+
with open(new_file, encoding="utf-8") as f:
|
|
203
|
+
new_data = json.load(f)
|
|
204
|
+
|
|
205
|
+
# Convert to JSON strings for comparison
|
|
206
|
+
old_str = json.dumps(old_data, sort_keys=True, indent=2)
|
|
207
|
+
new_str = json.dumps(new_data, sort_keys=True, indent=2)
|
|
208
|
+
|
|
209
|
+
old_lines = old_str.split("\n")
|
|
210
|
+
new_lines = new_str.split("\n")
|
|
211
|
+
|
|
212
|
+
old_set = set(old_lines)
|
|
213
|
+
new_set = set(new_lines)
|
|
214
|
+
|
|
215
|
+
added = len(new_set - old_set)
|
|
216
|
+
removed = len(old_set - new_set)
|
|
217
|
+
|
|
218
|
+
return {"added": added, "removed": removed}
|
|
219
|
+
|
|
220
|
+
except (json.JSONDecodeError, OSError):
|
|
221
|
+
# Fall back to regular diff
|
|
222
|
+
return calculate_diff_stats(old_file, new_file)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def merge_directories(
|
|
226
|
+
remote_dir: Path,
|
|
227
|
+
local_dir: Path,
|
|
228
|
+
ignore_patterns: set[str],
|
|
229
|
+
non_interactive: bool = False,
|
|
230
|
+
) -> dict[str, list[tuple[str, dict[str, int]]]]:
|
|
231
|
+
"""Merge remote directory into local directory, return summary of changes"""
|
|
232
|
+
remote_path = Path(remote_dir)
|
|
233
|
+
local_path = Path(local_dir)
|
|
234
|
+
|
|
235
|
+
changes: dict[str, list[tuple[str, dict[str, int]]]] = {
|
|
236
|
+
"added": [],
|
|
237
|
+
"modified": [],
|
|
238
|
+
"removed": [],
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
# Get all files in both directories
|
|
242
|
+
remote_files: set[Path] = set()
|
|
243
|
+
local_files = set()
|
|
244
|
+
|
|
245
|
+
# Collect remote files
|
|
246
|
+
if remote_path.exists():
|
|
247
|
+
for file_path in remote_path.rglob("*"):
|
|
248
|
+
if file_path.is_file():
|
|
249
|
+
rel_path = file_path.relative_to(remote_path)
|
|
250
|
+
remote_files.add(rel_path)
|
|
251
|
+
|
|
252
|
+
# Collect local files
|
|
253
|
+
for file_path in local_path.rglob("*"):
|
|
254
|
+
if file_path.is_file():
|
|
255
|
+
rel_path = file_path.relative_to(local_path)
|
|
256
|
+
local_files.add(rel_path)
|
|
257
|
+
|
|
258
|
+
# Handle additions and modifications
|
|
259
|
+
for rel_path in remote_files:
|
|
260
|
+
remote_file = remote_path / rel_path
|
|
261
|
+
local_file = local_path / rel_path
|
|
262
|
+
|
|
263
|
+
if not local_file.exists():
|
|
264
|
+
# New file - copy it and count lines
|
|
265
|
+
local_file.parent.mkdir(parents=True, exist_ok=True)
|
|
266
|
+
lines = count_lines(remote_file)
|
|
267
|
+
shutil.copy2(remote_file, local_file)
|
|
268
|
+
changes["added"].append((str(rel_path), {"lines": lines}))
|
|
269
|
+
else:
|
|
270
|
+
# Check if file is different
|
|
271
|
+
if not filecmp.cmp(remote_file, local_file, shallow=False):
|
|
272
|
+
# File modified - calculate diff stats before updating
|
|
273
|
+
diff_stats = calculate_diff_stats(local_file, remote_file)
|
|
274
|
+
shutil.copy2(remote_file, local_file)
|
|
275
|
+
changes["modified"].append((str(rel_path), diff_stats))
|
|
276
|
+
|
|
277
|
+
# Handle deletions (files that exist locally but not remotely)
|
|
278
|
+
files_to_delete = []
|
|
279
|
+
for rel_path in local_files - remote_files:
|
|
280
|
+
# Skip files matching ignore patterns
|
|
281
|
+
if should_skip_file(rel_path, ignore_patterns):
|
|
282
|
+
continue
|
|
283
|
+
files_to_delete.append(rel_path)
|
|
284
|
+
|
|
285
|
+
# If there are files to delete, ask for confirmation (unless non-interactive)
|
|
286
|
+
if files_to_delete and not non_interactive:
|
|
287
|
+
click.echo(
|
|
288
|
+
f"\n⚠️ The following {len(files_to_delete)} file(s) will be deleted:"
|
|
289
|
+
)
|
|
290
|
+
for rel_path in files_to_delete[:10]: # Show first 10
|
|
291
|
+
click.echo(f" 🗑️ {rel_path}")
|
|
292
|
+
|
|
293
|
+
if len(files_to_delete) > 10:
|
|
294
|
+
click.echo(f" ... and {len(files_to_delete) - 10} more files")
|
|
295
|
+
|
|
296
|
+
if not click.confirm("\nProceed with deletions?", default=False):
|
|
297
|
+
click.echo("❌ Pull cancelled - no files were deleted")
|
|
298
|
+
return changes
|
|
299
|
+
|
|
300
|
+
# Proceed with deletions
|
|
301
|
+
for rel_path in files_to_delete:
|
|
302
|
+
local_file = local_path / rel_path
|
|
303
|
+
lines = count_lines(local_file)
|
|
304
|
+
local_file.unlink()
|
|
305
|
+
changes["removed"].append((str(rel_path), {"lines": lines}))
|
|
306
|
+
|
|
307
|
+
# Remove empty directories (but not if they match ignore patterns)
|
|
308
|
+
parent_dir = local_file.parent
|
|
309
|
+
with contextlib.suppress(OSError):
|
|
310
|
+
if not should_skip_file(
|
|
311
|
+
parent_dir.relative_to(local_path), ignore_patterns
|
|
312
|
+
):
|
|
313
|
+
parent_dir.rmdir()
|
|
314
|
+
|
|
315
|
+
return changes
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
@click.command()
|
|
319
|
+
@handle_cli_exceptions
|
|
320
|
+
@inject
|
|
321
|
+
@handle_api_exceptions
|
|
322
|
+
async def pull(
|
|
323
|
+
config_manager: ConfigManager = Provide[Container.config_manager],
|
|
324
|
+
project_manager: ProjectManager = Provide[Container.project_manager],
|
|
325
|
+
) -> None:
|
|
326
|
+
"""Pull latest changes from Workato remote"""
|
|
327
|
+
await _pull_project(config_manager, project_manager)
|
|
File without changes
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import zipfile
|
|
3
|
+
|
|
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.containers import Container
|
|
12
|
+
from workato_platform_cli.cli.utils.config import ConfigManager
|
|
13
|
+
from workato_platform_cli.cli.utils.exception_handler import (
|
|
14
|
+
handle_api_exceptions,
|
|
15
|
+
handle_cli_exceptions,
|
|
16
|
+
)
|
|
17
|
+
from workato_platform_cli.cli.utils.ignore_patterns import (
|
|
18
|
+
load_ignore_patterns,
|
|
19
|
+
should_skip_file,
|
|
20
|
+
)
|
|
21
|
+
from workato_platform_cli.cli.utils.spinner import Spinner
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
STATUS_INFO = {
|
|
25
|
+
"no_update_or_updated_without_restart": {
|
|
26
|
+
"name": "No restart needed",
|
|
27
|
+
"icon": "✅",
|
|
28
|
+
"success": True,
|
|
29
|
+
"description": "Updated successfully or no changes needed",
|
|
30
|
+
},
|
|
31
|
+
"restarted": {
|
|
32
|
+
"name": "Updated and restarted",
|
|
33
|
+
"icon": "✅",
|
|
34
|
+
"success": True,
|
|
35
|
+
"description": "Successfully updated and restarted",
|
|
36
|
+
},
|
|
37
|
+
"not_found": {
|
|
38
|
+
"name": "Recipe not found",
|
|
39
|
+
"icon": "❌",
|
|
40
|
+
"success": False,
|
|
41
|
+
"description": "Failed - recipe could not be found",
|
|
42
|
+
},
|
|
43
|
+
"stop_failed": {
|
|
44
|
+
"name": "Failed to stop recipe",
|
|
45
|
+
"icon": "❌",
|
|
46
|
+
"success": False,
|
|
47
|
+
"description": "Failed - could not stop running recipe",
|
|
48
|
+
},
|
|
49
|
+
"stopped": {
|
|
50
|
+
"name": "Updated but stopped",
|
|
51
|
+
"icon": "⚠️",
|
|
52
|
+
"success": False,
|
|
53
|
+
"description": "Updated but failed to restart due to errors",
|
|
54
|
+
},
|
|
55
|
+
"restart_failed": {
|
|
56
|
+
"name": "Failed to restart recipe",
|
|
57
|
+
"icon": "⚠️",
|
|
58
|
+
"success": False,
|
|
59
|
+
"description": "Updated but failed to restart",
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@click.command()
|
|
65
|
+
@click.option(
|
|
66
|
+
"--restart-recipes",
|
|
67
|
+
is_flag=True,
|
|
68
|
+
default=False,
|
|
69
|
+
help="Allow restarting of running recipes that are updated during import. "
|
|
70
|
+
"Stopped recipes will remain stopped.",
|
|
71
|
+
)
|
|
72
|
+
@click.option(
|
|
73
|
+
"--include-tags", is_flag=True, default=True, help="Include tags in import"
|
|
74
|
+
)
|
|
75
|
+
@handle_cli_exceptions
|
|
76
|
+
@inject
|
|
77
|
+
@handle_api_exceptions
|
|
78
|
+
async def push(
|
|
79
|
+
restart_recipes: bool = False,
|
|
80
|
+
include_tags: bool = True,
|
|
81
|
+
config_manager: ConfigManager = Provide[Container.config_manager],
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Push local project changes to Workato"""
|
|
84
|
+
|
|
85
|
+
# Load API token
|
|
86
|
+
api_token = config_manager.api_token
|
|
87
|
+
if not api_token:
|
|
88
|
+
click.echo("❌ No API token found. Please run 'workato init' first.")
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
# Load project metadata
|
|
92
|
+
meta_data = config_manager.load_config()
|
|
93
|
+
if not meta_data.folder_id:
|
|
94
|
+
click.echo("❌ No project configured. Please run 'workato init' first.")
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
folder_id = meta_data.folder_id
|
|
98
|
+
project_name = meta_data.project_name
|
|
99
|
+
|
|
100
|
+
# Get project directory using simplified logic
|
|
101
|
+
project_dir = config_manager.get_project_directory()
|
|
102
|
+
if not project_dir:
|
|
103
|
+
click.echo(
|
|
104
|
+
"❌ Could not determine project directory. Please run 'workato init' first."
|
|
105
|
+
)
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
if not project_dir.exists():
|
|
109
|
+
click.echo(
|
|
110
|
+
"❌ Project directory does not exist. Please run 'workato pull' first."
|
|
111
|
+
)
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
# Get workspace root to load ignore patterns
|
|
115
|
+
workspace_root = config_manager.get_workspace_root()
|
|
116
|
+
ignore_patterns = load_ignore_patterns(workspace_root)
|
|
117
|
+
|
|
118
|
+
# Create zip file from project directory, excluding ignored files
|
|
119
|
+
zip_path = f"{project_name}.zip"
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
spinner = Spinner("Creating package from project directory")
|
|
123
|
+
spinner.start()
|
|
124
|
+
try:
|
|
125
|
+
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
|
|
126
|
+
for root, _dirs, files in os.walk(project_dir):
|
|
127
|
+
for file in files:
|
|
128
|
+
file_path = Path(root) / file
|
|
129
|
+
# Get relative path from project directory
|
|
130
|
+
arcname = file_path.relative_to(project_dir)
|
|
131
|
+
|
|
132
|
+
# Skip files matching ignore patterns
|
|
133
|
+
if should_skip_file(arcname, ignore_patterns):
|
|
134
|
+
continue
|
|
135
|
+
|
|
136
|
+
zipf.write(file_path, arcname)
|
|
137
|
+
finally:
|
|
138
|
+
elapsed = spinner.stop()
|
|
139
|
+
|
|
140
|
+
click.echo(f"✅ Package created: {zip_path} ({elapsed:.1f}s)")
|
|
141
|
+
|
|
142
|
+
# Upload the package
|
|
143
|
+
await upload_package(
|
|
144
|
+
folder_id=folder_id,
|
|
145
|
+
zip_path=zip_path,
|
|
146
|
+
restart_recipes=restart_recipes,
|
|
147
|
+
include_tags=include_tags,
|
|
148
|
+
)
|
|
149
|
+
finally:
|
|
150
|
+
# Clean up zip file
|
|
151
|
+
if os.path.exists(zip_path):
|
|
152
|
+
os.remove(zip_path)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@inject
|
|
156
|
+
async def upload_package(
|
|
157
|
+
folder_id: int,
|
|
158
|
+
zip_path: str,
|
|
159
|
+
restart_recipes: bool | None = None,
|
|
160
|
+
include_tags: bool | None = None,
|
|
161
|
+
workato_api_client: Workato = Provide[Container.workato_api_client],
|
|
162
|
+
) -> None:
|
|
163
|
+
"""Upload the package to Workato"""
|
|
164
|
+
spinner = Spinner("Uploading package to Workato")
|
|
165
|
+
spinner.start()
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
# Read and upload the zip file
|
|
169
|
+
with open(zip_path, "rb") as f:
|
|
170
|
+
response = await workato_api_client.packages_api.import_package(
|
|
171
|
+
id=folder_id,
|
|
172
|
+
body=f.read(),
|
|
173
|
+
restart_recipes=restart_recipes,
|
|
174
|
+
include_tags=include_tags,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
import_data = response
|
|
178
|
+
import_id = import_data.id
|
|
179
|
+
status = import_data.status
|
|
180
|
+
finally:
|
|
181
|
+
elapsed = spinner.stop()
|
|
182
|
+
|
|
183
|
+
click.echo(f"✅ Package uploaded successfully ({elapsed:.1f}s)")
|
|
184
|
+
click.echo(f" 📊 Import ID: {import_id}")
|
|
185
|
+
click.echo(f" 📈 Status: {status}")
|
|
186
|
+
|
|
187
|
+
if status == "completed":
|
|
188
|
+
click.echo("🎉 Import completed successfully")
|
|
189
|
+
else:
|
|
190
|
+
# Poll for completion
|
|
191
|
+
await poll_import_status(import_id)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@inject
|
|
195
|
+
async def poll_import_status(
|
|
196
|
+
import_id: int, workato_api_client: Workato = Provide[Container.workato_api_client]
|
|
197
|
+
) -> None:
|
|
198
|
+
"""Poll import status until completion or timeout"""
|
|
199
|
+
import time
|
|
200
|
+
|
|
201
|
+
max_wait_time = 300 # 5 minutes timeout
|
|
202
|
+
poll_interval = 3 # Check every 3 seconds
|
|
203
|
+
start_time = time.time()
|
|
204
|
+
|
|
205
|
+
# Start spinner for polling
|
|
206
|
+
spinner = Spinner("Processing import")
|
|
207
|
+
spinner.start()
|
|
208
|
+
|
|
209
|
+
# Give the import process a moment to initialize before first poll
|
|
210
|
+
time.sleep(2)
|
|
211
|
+
|
|
212
|
+
while time.time() - start_time < max_wait_time:
|
|
213
|
+
package_response = await workato_api_client.packages_api.get_package(import_id)
|
|
214
|
+
|
|
215
|
+
current_status = package_response.status
|
|
216
|
+
|
|
217
|
+
if current_status == "completed":
|
|
218
|
+
spinner.stop()
|
|
219
|
+
click.echo("🎉 Import completed successfully")
|
|
220
|
+
|
|
221
|
+
# Show recipe status information if available
|
|
222
|
+
if package_response.recipe_status:
|
|
223
|
+
recipe_statuses = package_response.recipe_status
|
|
224
|
+
click.echo("📋 Recipe Import Results:")
|
|
225
|
+
|
|
226
|
+
# Count different result types
|
|
227
|
+
result_counts: dict[str, int] = {}
|
|
228
|
+
for recipe in recipe_statuses:
|
|
229
|
+
if not recipe.import_result:
|
|
230
|
+
continue
|
|
231
|
+
result = recipe.import_result
|
|
232
|
+
result_counts[result] = result_counts.get(result, 0) + 1
|
|
233
|
+
|
|
234
|
+
# Display counts with friendly names and success/failure indicators
|
|
235
|
+
|
|
236
|
+
# Separate successful and failed imports
|
|
237
|
+
successful_results = []
|
|
238
|
+
failed_results = []
|
|
239
|
+
|
|
240
|
+
for result, count in result_counts.items():
|
|
241
|
+
info = STATUS_INFO.get(
|
|
242
|
+
result,
|
|
243
|
+
{
|
|
244
|
+
"name": result.replace("_", " ").title()
|
|
245
|
+
if result
|
|
246
|
+
else "Unknown",
|
|
247
|
+
"icon": "❓",
|
|
248
|
+
"success": False,
|
|
249
|
+
"description": "Unknown status",
|
|
250
|
+
},
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
result_line = f" {info['icon']} {count} recipe(s): {info['name']}"
|
|
254
|
+
|
|
255
|
+
if info["success"]:
|
|
256
|
+
successful_results.append(result_line)
|
|
257
|
+
else:
|
|
258
|
+
failed_results.append(result_line)
|
|
259
|
+
|
|
260
|
+
# Display successful imports first
|
|
261
|
+
for line in successful_results:
|
|
262
|
+
click.echo(line)
|
|
263
|
+
|
|
264
|
+
# Display failed imports
|
|
265
|
+
for line in failed_results:
|
|
266
|
+
click.echo(line)
|
|
267
|
+
|
|
268
|
+
# Show overall import summary
|
|
269
|
+
total_recipes = sum(result_counts.values())
|
|
270
|
+
successful_count = sum(
|
|
271
|
+
count
|
|
272
|
+
for result, count in result_counts.items()
|
|
273
|
+
if STATUS_INFO.get(result, {}).get("success", False)
|
|
274
|
+
)
|
|
275
|
+
failed_count = total_recipes - successful_count
|
|
276
|
+
|
|
277
|
+
if failed_count > 0:
|
|
278
|
+
click.echo(
|
|
279
|
+
f" 📊 Summary: {successful_count}/{total_recipes} "
|
|
280
|
+
"recipes imported successfully"
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
elif current_status == "failed":
|
|
286
|
+
spinner.stop()
|
|
287
|
+
click.echo("❌ Import failed")
|
|
288
|
+
|
|
289
|
+
# Show error details from the correct field
|
|
290
|
+
if package_response.error:
|
|
291
|
+
click.echo(f" 📄 Error: {package_response.error}")
|
|
292
|
+
if package_response.recipe_status:
|
|
293
|
+
click.echo(" 📋 Recipe Status:")
|
|
294
|
+
for (
|
|
295
|
+
recipe_name,
|
|
296
|
+
status_info,
|
|
297
|
+
) in package_response.recipe_status:
|
|
298
|
+
click.echo(f" 📄 {recipe_name}: {status_info}")
|
|
299
|
+
|
|
300
|
+
return
|
|
301
|
+
|
|
302
|
+
elif current_status in ["in_progress", "processing"]:
|
|
303
|
+
# Update spinner message with status (spinner handles elapsed time)
|
|
304
|
+
spinner.update_message(f"Processing import ({current_status})")
|
|
305
|
+
|
|
306
|
+
else:
|
|
307
|
+
# Update spinner with unknown status (spinner handles elapsed time)
|
|
308
|
+
spinner.update_message(f"Processing import ({current_status})")
|
|
309
|
+
|
|
310
|
+
# Sleep before next poll (for non-404 cases)
|
|
311
|
+
time.sleep(poll_interval)
|
|
312
|
+
|
|
313
|
+
# Timeout reached
|
|
314
|
+
spinner.stop()
|
|
315
|
+
click.echo(f"⏰ Import still in progress after {max_wait_time // 60} minutes")
|
|
316
|
+
click.echo(
|
|
317
|
+
f" 💡 Check status manually: workato packages import-status "
|
|
318
|
+
f"--import-id {import_id}"
|
|
319
|
+
)
|
|
320
|
+
click.echo(f" 📊 Import ID: {import_id}")
|
|
File without changes
|