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.
Files changed (306) hide show
  1. workato_platform_cli/__init__.py +135 -0
  2. workato_platform_cli/_version.py +34 -0
  3. workato_platform_cli/cli/__init__.py +126 -0
  4. workato_platform_cli/cli/commands/__init__.py +0 -0
  5. workato_platform_cli/cli/commands/api_clients.py +627 -0
  6. workato_platform_cli/cli/commands/api_collections.py +497 -0
  7. workato_platform_cli/cli/commands/assets.py +82 -0
  8. workato_platform_cli/cli/commands/connections.py +1205 -0
  9. workato_platform_cli/cli/commands/connectors/__init__.py +0 -0
  10. workato_platform_cli/cli/commands/connectors/command.py +178 -0
  11. workato_platform_cli/cli/commands/connectors/connector_manager.py +351 -0
  12. workato_platform_cli/cli/commands/data_tables.py +345 -0
  13. workato_platform_cli/cli/commands/guide.py +315 -0
  14. workato_platform_cli/cli/commands/init.py +229 -0
  15. workato_platform_cli/cli/commands/profiles.py +364 -0
  16. workato_platform_cli/cli/commands/projects/__init__.py +0 -0
  17. workato_platform_cli/cli/commands/projects/command.py +513 -0
  18. workato_platform_cli/cli/commands/projects/project_manager.py +338 -0
  19. workato_platform_cli/cli/commands/properties.py +174 -0
  20. workato_platform_cli/cli/commands/pull.py +327 -0
  21. workato_platform_cli/cli/commands/push/__init__.py +0 -0
  22. workato_platform_cli/cli/commands/push/command.py +320 -0
  23. workato_platform_cli/cli/commands/recipes/__init__.py +0 -0
  24. workato_platform_cli/cli/commands/recipes/command.py +847 -0
  25. workato_platform_cli/cli/commands/recipes/validator.py +1740 -0
  26. workato_platform_cli/cli/commands/workspace.py +73 -0
  27. workato_platform_cli/cli/containers.py +80 -0
  28. workato_platform_cli/cli/resources/data/connection-data.json +7364 -0
  29. workato_platform_cli/cli/resources/data/picklist-data.json +3706 -0
  30. workato_platform_cli/cli/resources/docs/README.md +178 -0
  31. workato_platform_cli/cli/resources/docs/actions.md +452 -0
  32. workato_platform_cli/cli/resources/docs/block-structure.md +424 -0
  33. workato_platform_cli/cli/resources/docs/connections-parameters.md +11946 -0
  34. workato_platform_cli/cli/resources/docs/data-mapping.md +779 -0
  35. workato_platform_cli/cli/resources/docs/formulas/array-list-formulas.md +1276 -0
  36. workato_platform_cli/cli/resources/docs/formulas/conditions.md +102 -0
  37. workato_platform_cli/cli/resources/docs/formulas/date-formulas.md +798 -0
  38. workato_platform_cli/cli/resources/docs/formulas/number-formulas.md +507 -0
  39. workato_platform_cli/cli/resources/docs/formulas/other-formulas.md +419 -0
  40. workato_platform_cli/cli/resources/docs/formulas/string-formulas.md +1353 -0
  41. workato_platform_cli/cli/resources/docs/formulas.md +214 -0
  42. workato_platform_cli/cli/resources/docs/naming-conventions.md +163 -0
  43. workato_platform_cli/cli/resources/docs/recipe-deployment-workflow.md +352 -0
  44. workato_platform_cli/cli/resources/docs/recipe-fundamentals.md +179 -0
  45. workato_platform_cli/cli/resources/docs/triggers.md +360 -0
  46. workato_platform_cli/cli/utils/__init__.py +10 -0
  47. workato_platform_cli/cli/utils/config/__init__.py +33 -0
  48. workato_platform_cli/cli/utils/config/manager.py +1001 -0
  49. workato_platform_cli/cli/utils/config/models.py +89 -0
  50. workato_platform_cli/cli/utils/config/profiles.py +491 -0
  51. workato_platform_cli/cli/utils/config/workspace.py +113 -0
  52. workato_platform_cli/cli/utils/exception_handler.py +531 -0
  53. workato_platform_cli/cli/utils/gitignore.py +32 -0
  54. workato_platform_cli/cli/utils/ignore_patterns.py +44 -0
  55. workato_platform_cli/cli/utils/spinner.py +63 -0
  56. workato_platform_cli/cli/utils/version_checker.py +237 -0
  57. workato_platform_cli/client/__init__.py +0 -0
  58. workato_platform_cli/client/workato_api/__init__.py +202 -0
  59. workato_platform_cli/client/workato_api/api/__init__.py +15 -0
  60. workato_platform_cli/client/workato_api/api/api_platform_api.py +2875 -0
  61. workato_platform_cli/client/workato_api/api/connections_api.py +1807 -0
  62. workato_platform_cli/client/workato_api/api/connectors_api.py +840 -0
  63. workato_platform_cli/client/workato_api/api/data_tables_api.py +604 -0
  64. workato_platform_cli/client/workato_api/api/export_api.py +621 -0
  65. workato_platform_cli/client/workato_api/api/folders_api.py +621 -0
  66. workato_platform_cli/client/workato_api/api/packages_api.py +1197 -0
  67. workato_platform_cli/client/workato_api/api/projects_api.py +590 -0
  68. workato_platform_cli/client/workato_api/api/properties_api.py +620 -0
  69. workato_platform_cli/client/workato_api/api/recipes_api.py +1379 -0
  70. workato_platform_cli/client/workato_api/api/users_api.py +285 -0
  71. workato_platform_cli/client/workato_api/api_client.py +807 -0
  72. workato_platform_cli/client/workato_api/api_response.py +21 -0
  73. workato_platform_cli/client/workato_api/configuration.py +601 -0
  74. workato_platform_cli/client/workato_api/docs/APIPlatformApi.md +844 -0
  75. workato_platform_cli/client/workato_api/docs/ApiClient.md +46 -0
  76. workato_platform_cli/client/workato_api/docs/ApiClientApiCollectionsInner.md +30 -0
  77. workato_platform_cli/client/workato_api/docs/ApiClientApiPoliciesInner.md +30 -0
  78. workato_platform_cli/client/workato_api/docs/ApiClientCreateRequest.md +46 -0
  79. workato_platform_cli/client/workato_api/docs/ApiClientListResponse.md +32 -0
  80. workato_platform_cli/client/workato_api/docs/ApiClientResponse.md +29 -0
  81. workato_platform_cli/client/workato_api/docs/ApiCollection.md +38 -0
  82. workato_platform_cli/client/workato_api/docs/ApiCollectionCreateRequest.md +32 -0
  83. workato_platform_cli/client/workato_api/docs/ApiEndpoint.md +41 -0
  84. workato_platform_cli/client/workato_api/docs/ApiKey.md +36 -0
  85. workato_platform_cli/client/workato_api/docs/ApiKeyCreateRequest.md +32 -0
  86. workato_platform_cli/client/workato_api/docs/ApiKeyListResponse.md +32 -0
  87. workato_platform_cli/client/workato_api/docs/ApiKeyResponse.md +29 -0
  88. workato_platform_cli/client/workato_api/docs/Asset.md +39 -0
  89. workato_platform_cli/client/workato_api/docs/AssetReference.md +37 -0
  90. workato_platform_cli/client/workato_api/docs/Connection.md +44 -0
  91. workato_platform_cli/client/workato_api/docs/ConnectionCreateRequest.md +35 -0
  92. workato_platform_cli/client/workato_api/docs/ConnectionUpdateRequest.md +34 -0
  93. workato_platform_cli/client/workato_api/docs/ConnectionsApi.md +526 -0
  94. workato_platform_cli/client/workato_api/docs/ConnectorAction.md +33 -0
  95. workato_platform_cli/client/workato_api/docs/ConnectorVersion.md +32 -0
  96. workato_platform_cli/client/workato_api/docs/ConnectorsApi.md +249 -0
  97. workato_platform_cli/client/workato_api/docs/CreateExportManifestRequest.md +29 -0
  98. workato_platform_cli/client/workato_api/docs/CreateFolderRequest.md +30 -0
  99. workato_platform_cli/client/workato_api/docs/CustomConnector.md +35 -0
  100. workato_platform_cli/client/workato_api/docs/CustomConnectorCodeResponse.md +29 -0
  101. workato_platform_cli/client/workato_api/docs/CustomConnectorCodeResponseData.md +29 -0
  102. workato_platform_cli/client/workato_api/docs/CustomConnectorListResponse.md +29 -0
  103. workato_platform_cli/client/workato_api/docs/DataTable.md +34 -0
  104. workato_platform_cli/client/workato_api/docs/DataTableColumn.md +37 -0
  105. workato_platform_cli/client/workato_api/docs/DataTableColumnRequest.md +37 -0
  106. workato_platform_cli/client/workato_api/docs/DataTableCreateRequest.md +31 -0
  107. workato_platform_cli/client/workato_api/docs/DataTableCreateResponse.md +29 -0
  108. workato_platform_cli/client/workato_api/docs/DataTableListResponse.md +29 -0
  109. workato_platform_cli/client/workato_api/docs/DataTableRelation.md +30 -0
  110. workato_platform_cli/client/workato_api/docs/DataTablesApi.md +172 -0
  111. workato_platform_cli/client/workato_api/docs/DeleteProject403Response.md +29 -0
  112. workato_platform_cli/client/workato_api/docs/Error.md +29 -0
  113. workato_platform_cli/client/workato_api/docs/ExportApi.md +175 -0
  114. workato_platform_cli/client/workato_api/docs/ExportManifestRequest.md +35 -0
  115. workato_platform_cli/client/workato_api/docs/ExportManifestResponse.md +29 -0
  116. workato_platform_cli/client/workato_api/docs/ExportManifestResponseResult.md +36 -0
  117. workato_platform_cli/client/workato_api/docs/Folder.md +35 -0
  118. workato_platform_cli/client/workato_api/docs/FolderAssetsResponse.md +29 -0
  119. workato_platform_cli/client/workato_api/docs/FolderAssetsResponseResult.md +29 -0
  120. workato_platform_cli/client/workato_api/docs/FolderCreationResponse.md +35 -0
  121. workato_platform_cli/client/workato_api/docs/FoldersApi.md +176 -0
  122. workato_platform_cli/client/workato_api/docs/ImportResults.md +32 -0
  123. workato_platform_cli/client/workato_api/docs/OAuthUrlResponse.md +29 -0
  124. workato_platform_cli/client/workato_api/docs/OAuthUrlResponseData.md +29 -0
  125. workato_platform_cli/client/workato_api/docs/OpenApiSpec.md +30 -0
  126. workato_platform_cli/client/workato_api/docs/PackageDetailsResponse.md +35 -0
  127. workato_platform_cli/client/workato_api/docs/PackageDetailsResponseRecipeStatusInner.md +30 -0
  128. workato_platform_cli/client/workato_api/docs/PackageResponse.md +33 -0
  129. workato_platform_cli/client/workato_api/docs/PackagesApi.md +364 -0
  130. workato_platform_cli/client/workato_api/docs/PicklistRequest.md +30 -0
  131. workato_platform_cli/client/workato_api/docs/PicklistResponse.md +29 -0
  132. workato_platform_cli/client/workato_api/docs/PlatformConnector.md +36 -0
  133. workato_platform_cli/client/workato_api/docs/PlatformConnectorListResponse.md +32 -0
  134. workato_platform_cli/client/workato_api/docs/Project.md +32 -0
  135. workato_platform_cli/client/workato_api/docs/ProjectsApi.md +173 -0
  136. workato_platform_cli/client/workato_api/docs/PropertiesApi.md +186 -0
  137. workato_platform_cli/client/workato_api/docs/Recipe.md +58 -0
  138. workato_platform_cli/client/workato_api/docs/RecipeConfigInner.md +33 -0
  139. workato_platform_cli/client/workato_api/docs/RecipeConnectionUpdateRequest.md +30 -0
  140. workato_platform_cli/client/workato_api/docs/RecipeListResponse.md +29 -0
  141. workato_platform_cli/client/workato_api/docs/RecipeStartResponse.md +31 -0
  142. workato_platform_cli/client/workato_api/docs/RecipesApi.md +367 -0
  143. workato_platform_cli/client/workato_api/docs/RuntimeUserConnectionCreateRequest.md +34 -0
  144. workato_platform_cli/client/workato_api/docs/RuntimeUserConnectionResponse.md +29 -0
  145. workato_platform_cli/client/workato_api/docs/RuntimeUserConnectionResponseData.md +30 -0
  146. workato_platform_cli/client/workato_api/docs/SuccessResponse.md +29 -0
  147. workato_platform_cli/client/workato_api/docs/UpsertProjectPropertiesRequest.md +29 -0
  148. workato_platform_cli/client/workato_api/docs/User.md +48 -0
  149. workato_platform_cli/client/workato_api/docs/UsersApi.md +84 -0
  150. workato_platform_cli/client/workato_api/docs/ValidationError.md +30 -0
  151. workato_platform_cli/client/workato_api/docs/ValidationErrorErrorsValue.md +28 -0
  152. workato_platform_cli/client/workato_api/exceptions.py +216 -0
  153. workato_platform_cli/client/workato_api/models/__init__.py +83 -0
  154. workato_platform_cli/client/workato_api/models/api_client.py +185 -0
  155. workato_platform_cli/client/workato_api/models/api_client_api_collections_inner.py +89 -0
  156. workato_platform_cli/client/workato_api/models/api_client_api_policies_inner.py +89 -0
  157. workato_platform_cli/client/workato_api/models/api_client_create_request.py +138 -0
  158. workato_platform_cli/client/workato_api/models/api_client_list_response.py +101 -0
  159. workato_platform_cli/client/workato_api/models/api_client_response.py +91 -0
  160. workato_platform_cli/client/workato_api/models/api_collection.py +110 -0
  161. workato_platform_cli/client/workato_api/models/api_collection_create_request.py +97 -0
  162. workato_platform_cli/client/workato_api/models/api_endpoint.py +117 -0
  163. workato_platform_cli/client/workato_api/models/api_key.py +102 -0
  164. workato_platform_cli/client/workato_api/models/api_key_create_request.py +93 -0
  165. workato_platform_cli/client/workato_api/models/api_key_list_response.py +101 -0
  166. workato_platform_cli/client/workato_api/models/api_key_response.py +91 -0
  167. workato_platform_cli/client/workato_api/models/asset.py +124 -0
  168. workato_platform_cli/client/workato_api/models/asset_reference.py +110 -0
  169. workato_platform_cli/client/workato_api/models/connection.py +173 -0
  170. workato_platform_cli/client/workato_api/models/connection_create_request.py +99 -0
  171. workato_platform_cli/client/workato_api/models/connection_update_request.py +97 -0
  172. workato_platform_cli/client/workato_api/models/connector_action.py +100 -0
  173. workato_platform_cli/client/workato_api/models/connector_version.py +99 -0
  174. workato_platform_cli/client/workato_api/models/create_export_manifest_request.py +91 -0
  175. workato_platform_cli/client/workato_api/models/create_folder_request.py +89 -0
  176. workato_platform_cli/client/workato_api/models/custom_connector.py +117 -0
  177. workato_platform_cli/client/workato_api/models/custom_connector_code_response.py +91 -0
  178. workato_platform_cli/client/workato_api/models/custom_connector_code_response_data.py +87 -0
  179. workato_platform_cli/client/workato_api/models/custom_connector_list_response.py +95 -0
  180. workato_platform_cli/client/workato_api/models/data_table.py +107 -0
  181. workato_platform_cli/client/workato_api/models/data_table_column.py +125 -0
  182. workato_platform_cli/client/workato_api/models/data_table_column_request.py +130 -0
  183. workato_platform_cli/client/workato_api/models/data_table_create_request.py +99 -0
  184. workato_platform_cli/client/workato_api/models/data_table_create_response.py +91 -0
  185. workato_platform_cli/client/workato_api/models/data_table_list_response.py +95 -0
  186. workato_platform_cli/client/workato_api/models/data_table_relation.py +90 -0
  187. workato_platform_cli/client/workato_api/models/delete_project403_response.py +87 -0
  188. workato_platform_cli/client/workato_api/models/error.py +87 -0
  189. workato_platform_cli/client/workato_api/models/export_manifest_request.py +107 -0
  190. workato_platform_cli/client/workato_api/models/export_manifest_response.py +91 -0
  191. workato_platform_cli/client/workato_api/models/export_manifest_response_result.py +112 -0
  192. workato_platform_cli/client/workato_api/models/folder.py +110 -0
  193. workato_platform_cli/client/workato_api/models/folder_assets_response.py +91 -0
  194. workato_platform_cli/client/workato_api/models/folder_assets_response_result.py +95 -0
  195. workato_platform_cli/client/workato_api/models/folder_creation_response.py +110 -0
  196. workato_platform_cli/client/workato_api/models/import_results.py +93 -0
  197. workato_platform_cli/client/workato_api/models/o_auth_url_response.py +91 -0
  198. workato_platform_cli/client/workato_api/models/o_auth_url_response_data.py +87 -0
  199. workato_platform_cli/client/workato_api/models/open_api_spec.py +96 -0
  200. workato_platform_cli/client/workato_api/models/package_details_response.py +126 -0
  201. workato_platform_cli/client/workato_api/models/package_details_response_recipe_status_inner.py +99 -0
  202. workato_platform_cli/client/workato_api/models/package_response.py +109 -0
  203. workato_platform_cli/client/workato_api/models/picklist_request.py +89 -0
  204. workato_platform_cli/client/workato_api/models/picklist_response.py +88 -0
  205. workato_platform_cli/client/workato_api/models/platform_connector.py +116 -0
  206. workato_platform_cli/client/workato_api/models/platform_connector_list_response.py +101 -0
  207. workato_platform_cli/client/workato_api/models/project.py +93 -0
  208. workato_platform_cli/client/workato_api/models/recipe.py +174 -0
  209. workato_platform_cli/client/workato_api/models/recipe_config_inner.py +100 -0
  210. workato_platform_cli/client/workato_api/models/recipe_connection_update_request.py +89 -0
  211. workato_platform_cli/client/workato_api/models/recipe_list_response.py +95 -0
  212. workato_platform_cli/client/workato_api/models/recipe_start_response.py +91 -0
  213. workato_platform_cli/client/workato_api/models/runtime_user_connection_create_request.py +97 -0
  214. workato_platform_cli/client/workato_api/models/runtime_user_connection_response.py +91 -0
  215. workato_platform_cli/client/workato_api/models/runtime_user_connection_response_data.py +89 -0
  216. workato_platform_cli/client/workato_api/models/success_response.py +87 -0
  217. workato_platform_cli/client/workato_api/models/upsert_project_properties_request.py +88 -0
  218. workato_platform_cli/client/workato_api/models/user.py +151 -0
  219. workato_platform_cli/client/workato_api/models/validation_error.py +102 -0
  220. workato_platform_cli/client/workato_api/models/validation_error_errors_value.py +143 -0
  221. workato_platform_cli/client/workato_api/rest.py +213 -0
  222. workato_platform_cli/client/workato_api/test/__init__.py +0 -0
  223. workato_platform_cli/client/workato_api/test/test_api_client.py +94 -0
  224. workato_platform_cli/client/workato_api/test/test_api_client_api_collections_inner.py +52 -0
  225. workato_platform_cli/client/workato_api/test/test_api_client_api_policies_inner.py +52 -0
  226. workato_platform_cli/client/workato_api/test/test_api_client_create_request.py +75 -0
  227. workato_platform_cli/client/workato_api/test/test_api_client_list_response.py +114 -0
  228. workato_platform_cli/client/workato_api/test/test_api_client_response.py +104 -0
  229. workato_platform_cli/client/workato_api/test/test_api_collection.py +72 -0
  230. workato_platform_cli/client/workato_api/test/test_api_collection_create_request.py +57 -0
  231. workato_platform_cli/client/workato_api/test/test_api_endpoint.py +75 -0
  232. workato_platform_cli/client/workato_api/test/test_api_key.py +64 -0
  233. workato_platform_cli/client/workato_api/test/test_api_key_create_request.py +56 -0
  234. workato_platform_cli/client/workato_api/test/test_api_key_list_response.py +78 -0
  235. workato_platform_cli/client/workato_api/test/test_api_key_response.py +68 -0
  236. workato_platform_cli/client/workato_api/test/test_api_platform_api.py +101 -0
  237. workato_platform_cli/client/workato_api/test/test_asset.py +67 -0
  238. workato_platform_cli/client/workato_api/test/test_asset_reference.py +62 -0
  239. workato_platform_cli/client/workato_api/test/test_connection.py +81 -0
  240. workato_platform_cli/client/workato_api/test/test_connection_create_request.py +59 -0
  241. workato_platform_cli/client/workato_api/test/test_connection_update_request.py +56 -0
  242. workato_platform_cli/client/workato_api/test/test_connections_api.py +73 -0
  243. workato_platform_cli/client/workato_api/test/test_connector_action.py +59 -0
  244. workato_platform_cli/client/workato_api/test/test_connector_version.py +58 -0
  245. workato_platform_cli/client/workato_api/test/test_connectors_api.py +52 -0
  246. workato_platform_cli/client/workato_api/test/test_create_export_manifest_request.py +88 -0
  247. workato_platform_cli/client/workato_api/test/test_create_folder_request.py +53 -0
  248. workato_platform_cli/client/workato_api/test/test_custom_connector.py +76 -0
  249. workato_platform_cli/client/workato_api/test/test_custom_connector_code_response.py +54 -0
  250. workato_platform_cli/client/workato_api/test/test_custom_connector_code_response_data.py +52 -0
  251. workato_platform_cli/client/workato_api/test/test_custom_connector_list_response.py +82 -0
  252. workato_platform_cli/client/workato_api/test/test_data_table.py +88 -0
  253. workato_platform_cli/client/workato_api/test/test_data_table_column.py +72 -0
  254. workato_platform_cli/client/workato_api/test/test_data_table_column_request.py +64 -0
  255. workato_platform_cli/client/workato_api/test/test_data_table_create_request.py +82 -0
  256. workato_platform_cli/client/workato_api/test/test_data_table_create_response.py +90 -0
  257. workato_platform_cli/client/workato_api/test/test_data_table_list_response.py +94 -0
  258. workato_platform_cli/client/workato_api/test/test_data_table_relation.py +54 -0
  259. workato_platform_cli/client/workato_api/test/test_data_tables_api.py +45 -0
  260. workato_platform_cli/client/workato_api/test/test_delete_project403_response.py +51 -0
  261. workato_platform_cli/client/workato_api/test/test_error.py +52 -0
  262. workato_platform_cli/client/workato_api/test/test_export_api.py +45 -0
  263. workato_platform_cli/client/workato_api/test/test_export_manifest_request.py +69 -0
  264. workato_platform_cli/client/workato_api/test/test_export_manifest_response.py +68 -0
  265. workato_platform_cli/client/workato_api/test/test_export_manifest_response_result.py +66 -0
  266. workato_platform_cli/client/workato_api/test/test_folder.py +64 -0
  267. workato_platform_cli/client/workato_api/test/test_folder_assets_response.py +80 -0
  268. workato_platform_cli/client/workato_api/test/test_folder_assets_response_result.py +78 -0
  269. workato_platform_cli/client/workato_api/test/test_folder_creation_response.py +64 -0
  270. workato_platform_cli/client/workato_api/test/test_folders_api.py +45 -0
  271. workato_platform_cli/client/workato_api/test/test_import_results.py +58 -0
  272. workato_platform_cli/client/workato_api/test/test_o_auth_url_response.py +54 -0
  273. workato_platform_cli/client/workato_api/test/test_o_auth_url_response_data.py +52 -0
  274. workato_platform_cli/client/workato_api/test/test_open_api_spec.py +54 -0
  275. workato_platform_cli/client/workato_api/test/test_package_details_response.py +64 -0
  276. workato_platform_cli/client/workato_api/test/test_package_details_response_recipe_status_inner.py +52 -0
  277. workato_platform_cli/client/workato_api/test/test_package_response.py +58 -0
  278. workato_platform_cli/client/workato_api/test/test_packages_api.py +59 -0
  279. workato_platform_cli/client/workato_api/test/test_picklist_request.py +53 -0
  280. workato_platform_cli/client/workato_api/test/test_picklist_response.py +52 -0
  281. workato_platform_cli/client/workato_api/test/test_platform_connector.py +94 -0
  282. workato_platform_cli/client/workato_api/test/test_platform_connector_list_response.py +106 -0
  283. workato_platform_cli/client/workato_api/test/test_project.py +57 -0
  284. workato_platform_cli/client/workato_api/test/test_projects_api.py +45 -0
  285. workato_platform_cli/client/workato_api/test/test_properties_api.py +45 -0
  286. workato_platform_cli/client/workato_api/test/test_recipe.py +124 -0
  287. workato_platform_cli/client/workato_api/test/test_recipe_config_inner.py +55 -0
  288. workato_platform_cli/client/workato_api/test/test_recipe_connection_update_request.py +54 -0
  289. workato_platform_cli/client/workato_api/test/test_recipe_list_response.py +134 -0
  290. workato_platform_cli/client/workato_api/test/test_recipe_start_response.py +54 -0
  291. workato_platform_cli/client/workato_api/test/test_recipes_api.py +59 -0
  292. workato_platform_cli/client/workato_api/test/test_runtime_user_connection_create_request.py +59 -0
  293. workato_platform_cli/client/workato_api/test/test_runtime_user_connection_response.py +56 -0
  294. workato_platform_cli/client/workato_api/test/test_runtime_user_connection_response_data.py +54 -0
  295. workato_platform_cli/client/workato_api/test/test_success_response.py +52 -0
  296. workato_platform_cli/client/workato_api/test/test_upsert_project_properties_request.py +52 -0
  297. workato_platform_cli/client/workato_api/test/test_user.py +85 -0
  298. workato_platform_cli/client/workato_api/test/test_users_api.py +38 -0
  299. workato_platform_cli/client/workato_api/test/test_validation_error.py +52 -0
  300. workato_platform_cli/client/workato_api/test/test_validation_error_errors_value.py +50 -0
  301. workato_platform_cli/client/workato_api_README.md +205 -0
  302. workato_platform_cli-1.0.0rc5.dev5.dist-info/METADATA +185 -0
  303. workato_platform_cli-1.0.0rc5.dev5.dist-info/RECORD +306 -0
  304. workato_platform_cli-1.0.0rc5.dev5.dist-info/WHEEL +4 -0
  305. workato_platform_cli-1.0.0rc5.dev5.dist-info/entry_points.txt +2 -0
  306. workato_platform_cli-1.0.0rc5.dev5.dist-info/licenses/LICENSE +7 -0
@@ -0,0 +1,1205 @@
1
+ import json
2
+ import time
3
+ import webbrowser
4
+
5
+ from pathlib import Path
6
+ from typing import Any
7
+ from urllib.parse import urlparse
8
+
9
+ import asyncclick as click
10
+
11
+ from dependency_injector.wiring import Provide, inject
12
+
13
+ from workato_platform_cli import Workato
14
+ from workato_platform_cli.cli.commands.connectors.connector_manager import (
15
+ ConnectorManager,
16
+ )
17
+ from workato_platform_cli.cli.commands.projects.project_manager import ProjectManager
18
+ from workato_platform_cli.cli.containers import Container
19
+ from workato_platform_cli.cli.utils import Spinner
20
+ from workato_platform_cli.cli.utils.config import ConfigManager
21
+ from workato_platform_cli.cli.utils.exception_handler import (
22
+ handle_api_exceptions,
23
+ handle_cli_exceptions,
24
+ )
25
+ from workato_platform_cli.client.workato_api.models.connection import Connection
26
+ from workato_platform_cli.client.workato_api.models.connection_create_request import (
27
+ ConnectionCreateRequest,
28
+ )
29
+ from workato_platform_cli.client.workato_api.models.connection_update_request import (
30
+ ConnectionUpdateRequest,
31
+ )
32
+ from workato_platform_cli.client.workato_api.models.picklist_request import (
33
+ PicklistRequest,
34
+ )
35
+ from workato_platform_cli.client.workato_api.models.runtime_user_connection_create_request import ( # noqa: E501
36
+ RuntimeUserConnectionCreateRequest,
37
+ )
38
+
39
+
40
+ OAUTH_TIMEOUT = 60
41
+
42
+
43
+ def _get_callback_url_from_api_host(api_host: str) -> str:
44
+ """Convert API host URL to web callback URL for OAuth
45
+
46
+ Args:
47
+ api_host: The API host URL (e.g., "https://www.workato.com")
48
+
49
+ Returns:
50
+ The corresponding web callback URL (e.g., "https://app.workato.com/")
51
+ """
52
+ if not api_host:
53
+ return "https://app.workato.com/"
54
+
55
+ try:
56
+ parsed = urlparse(api_host)
57
+ hostname = parsed.hostname
58
+
59
+ if not hostname:
60
+ return "https://app.workato.com/"
61
+
62
+ # Map regional hostnames to their web app URLs
63
+ hostname_mapping = {
64
+ "preview.workato.com": "https://app.preview.workato.com/",
65
+ "www.workato.com": "https://app.workato.com/",
66
+ "eu.workato.com": "https://app.eu.workato.com/",
67
+ "jp.workato.com": "https://app.jp.workato.com/",
68
+ "sg.workato.com": "https://app.sg.workato.com/",
69
+ "au.workato.com": "https://app.au.workato.com/",
70
+ "il.workato.com": "https://app.il.workato.com/",
71
+ }
72
+
73
+ # Check for exact hostname match
74
+ if hostname in hostname_mapping:
75
+ return hostname_mapping[hostname]
76
+
77
+ # If hostname ends with workato.com but isn't in our mapping, default to main
78
+ if hostname.endswith(".workato.com") or hostname == "workato.com":
79
+ return "https://app.workato.com/"
80
+
81
+ # For any other host, default to main app
82
+ return "https://app.workato.com/"
83
+
84
+ except Exception:
85
+ # If URL parsing fails, default to main app
86
+ return "https://app.workato.com/"
87
+
88
+
89
+ @click.group()
90
+ def connections() -> None:
91
+ """Manage connections"""
92
+ pass
93
+
94
+
95
+ @connections.command()
96
+ @click.option(
97
+ "--name",
98
+ required=True,
99
+ help='Name of the connection (e.g., "Prod JIRA connection")',
100
+ )
101
+ @click.option(
102
+ "--provider",
103
+ required=True,
104
+ help='The application type/provider (e.g., "jira", "salesforce")',
105
+ )
106
+ @click.option(
107
+ "--parent-id",
108
+ type=int,
109
+ help="ID of the parent connection (must be same provider type)",
110
+ )
111
+ @click.option(
112
+ "--folder-id",
113
+ type=int,
114
+ help="ID of the project/folder (uses current project if not specified)",
115
+ )
116
+ @click.option("--external-id", help="External ID assigned to the connection")
117
+ @click.option(
118
+ "--shell-connection", # noboost
119
+ is_flag=True,
120
+ help="Create as shell connection (no authentication test)", # noboost
121
+ )
122
+ @click.option("--input", "input_params", help="Connection parameters as JSON string")
123
+ @handle_cli_exceptions
124
+ @inject
125
+ @handle_api_exceptions
126
+ async def create(
127
+ name: str,
128
+ provider: str,
129
+ parent_id: int | None = None,
130
+ folder_id: int | None = None,
131
+ external_id: str | None = None,
132
+ shell_connection: bool | None = None,
133
+ input_params: str | None = None,
134
+ workato_api_client: Workato = Provide[Container.workato_api_client],
135
+ config_manager: ConfigManager = Provide[Container.config_manager],
136
+ connector_manager: ConnectorManager = Provide[Container.connector_manager],
137
+ ) -> None:
138
+ """Create a new connection
139
+
140
+ Connection input parameters vary by provider. Use 'workato connectors parameters'
141
+ to discover what parameters are required for each provider.
142
+
143
+ Examples:
144
+
145
+ # Find parameters for a provider
146
+ workato connectors parameters --provider salesforce
147
+
148
+ # Create connection with inline JSON
149
+ workato connections create --provider salesforce --name "My Salesforce"
150
+ --input '{"security_token": "token"}'
151
+
152
+ # Create shell connection (no authentication test)
153
+ workato connections create --provider jira --name "Dev JIRA" --shell-connection
154
+ """
155
+
156
+ if not provider or not name:
157
+ click.echo("❌ Provider and name are required")
158
+ click.echo("💡 Use 'workato connectors list' to see available providers")
159
+ return
160
+
161
+ # Get folder ID from parameter or meta file
162
+ if not folder_id:
163
+ meta_data = config_manager.load_config()
164
+
165
+ if not meta_data.folder_id:
166
+ click.echo("❌ No folder ID provided and no project configured.")
167
+ click.echo("💡 Either specify --folder-id or run 'workato init' first.")
168
+ return
169
+
170
+ folder_id = meta_data.folder_id
171
+
172
+ # Parse input parameters
173
+ connection_input = parse_connection_input(input_params)
174
+ if connection_input is None and input_params:
175
+ return # Error already displayed by parse function
176
+
177
+ # Check if this is an OAuth provider that needs special handling
178
+ oauth_required = await requires_oauth_flow(provider)
179
+
180
+ # Also check using connector manager data for OAuth providers
181
+ provider_data = connector_manager.get_provider_data(provider)
182
+ is_oauth_provider = provider_data.oauth if provider_data else False
183
+
184
+ # For OAuth providers, prompt for missing OAuth parameters
185
+ if (oauth_required or is_oauth_provider) and not shell_connection:
186
+ connection_input = await connector_manager.prompt_for_oauth_parameters(
187
+ provider, connection_input
188
+ )
189
+ # Update oauth_required if we detected OAuth via connector manager
190
+ oauth_required = oauth_required or is_oauth_provider
191
+
192
+ connection_create_request = ConnectionCreateRequest(
193
+ name=name,
194
+ provider=provider,
195
+ parent_id=parent_id,
196
+ folder_id=folder_id,
197
+ external_id=external_id,
198
+ shell_connection=shell_connection or oauth_required,
199
+ input=connection_input,
200
+ )
201
+
202
+ # Create the connection
203
+ connection_data = await workato_api_client.connections_api.create_connection(
204
+ connection_create_request=connection_create_request,
205
+ )
206
+ connection_id = connection_data.id
207
+
208
+ # Display creation success
209
+ click.echo("✅ Connection created successfully")
210
+ click.echo(f" 📄 Name: {connection_data.name}")
211
+ click.echo(f" 🆔 Connection ID: {connection_id}")
212
+ click.echo(f" 🔌 Provider: {connection_data.provider}")
213
+
214
+ if oauth_required:
215
+ # Try to get OAuth URL for OAuth providers
216
+ click.echo("🔐 OAuth provider detected - attempting to get OAuth URL...")
217
+ try:
218
+ await get_connection_oauth_url(
219
+ connection_id,
220
+ open_browser=True,
221
+ )
222
+ # Poll for OAuth completion
223
+ await poll_oauth_connection_status(connection_id)
224
+ except Exception:
225
+ # If OAuth URL fails, fall back to manual authorization
226
+ click.echo(
227
+ "⚠️ Automatic OAuth URL retrieval not available for this provider"
228
+ )
229
+ click.echo("🔗 Opening connection page for manual authorization...")
230
+
231
+ # Use the existing config_manager from DI
232
+ web_base_url = config_manager.api_host
233
+ connection_url = f"{web_base_url}/connections/{connection_id}"
234
+
235
+ click.echo(f"📋 Connection URL: {connection_url}")
236
+
237
+ # Open in browser
238
+ try:
239
+ webbrowser.open(connection_url)
240
+ click.echo("🌐 Opening connection page in browser...")
241
+ except OSError as e:
242
+ click.echo(f"⚠️ Could not open browser: {str(e)}")
243
+ click.echo(
244
+ "💡 Please copy and paste the connection URL into your browser"
245
+ )
246
+
247
+ click.echo()
248
+ click.echo("💡 Manual authorization steps:")
249
+ click.echo(" 1. Complete OAuth authorization in the opened browser page")
250
+ click.echo(" 2. Follow the on-screen prompts to authenticate")
251
+ click.echo(
252
+ f" 3. Use connection ID {connection_id} in recipes once authorized"
253
+ )
254
+
255
+ # Poll for OAuth completion in manual flow too
256
+ await poll_oauth_connection_status(connection_id)
257
+ return
258
+
259
+
260
+ @connections.command(name="create-oauth")
261
+ @click.option(
262
+ "--parent-id",
263
+ required=True,
264
+ help="ID of the parent OAuth connection (must be established/authorized)",
265
+ )
266
+ @click.option("--name", help="Name of the runtime user connection (optional)")
267
+ @click.option(
268
+ "--folder-id",
269
+ type=int,
270
+ help="ID of the project/folder (uses current project if not specified)",
271
+ )
272
+ @click.option("--external-id", help="End user string ID for identifying the connection")
273
+ @click.option(
274
+ "--callback-url",
275
+ help="URL called back after successful token acquisition (optional)",
276
+ )
277
+ @click.option(
278
+ "--redirect-url",
279
+ help="URL to redirect user after successful token acquisition (optional)",
280
+ )
281
+ @handle_cli_exceptions
282
+ @inject
283
+ @handle_api_exceptions
284
+ async def create_oauth(
285
+ parent_id: int,
286
+ external_id: str,
287
+ name: str | None = None,
288
+ folder_id: int | None = None,
289
+ callback_url: str | None = None,
290
+ redirect_url: str | None = None,
291
+ workato_api_client: Workato = Provide[Container.workato_api_client],
292
+ config_manager: ConfigManager = Provide[Container.config_manager],
293
+ ) -> None:
294
+ """Create an OAuth runtime user connection
295
+
296
+ This command creates a runtime user connection for OAuth-enabled providers.
297
+ The parent connection must be an established OAuth connection. This initiates
298
+ the OAuth flow and provides a URL for end user authorization.
299
+
300
+ Parameters:
301
+ - parent_id: ID of parent OAuth connector (connection must be established)
302
+ - name: Optional name for the runtime user connection
303
+ - folder_id: Folder to put connection (uses current project if not specified)
304
+ - external_id: End user string ID for identifying the connection
305
+ - callback_url: Optional URL called back after successful token acquisition
306
+ - redirect_url: Optional URL where user is redirected after successful authorization
307
+
308
+ Examples:
309
+
310
+ # Create OAuth connection with minimal parameters
311
+ workato connections create-oauth --parent-id 12345 --external-id "user@example.com"
312
+
313
+ # Create with custom name and URLs
314
+ workato connections create-oauth --parent-id 12345 --name "John's Google Drive"
315
+ --external-id "john.doe@company.com" --callback-url "https://myapp.com/oauth/callback"
316
+ --redirect-url "https://myapp.com/success"
317
+ """
318
+
319
+ # Get folder ID from parameter or meta file
320
+ if not folder_id:
321
+ meta_data = config_manager.load_config()
322
+ folder_id = meta_data.folder_id
323
+
324
+ if not folder_id:
325
+ click.echo("❌ No folder ID provided and no project configured.")
326
+ click.echo("💡 Either specify --folder-id or run 'workato init' first.")
327
+ return
328
+
329
+ # Set default callback URL if not provided
330
+ if not callback_url:
331
+ base_url = config_manager.api_host or ""
332
+ callback_url = _get_callback_url_from_api_host(base_url)
333
+
334
+ # Create the runtime user connection
335
+ response = await workato_api_client.connections_api.create_runtime_user_connection(
336
+ runtime_user_connection_create_request=RuntimeUserConnectionCreateRequest(
337
+ parent_id=parent_id,
338
+ name=name,
339
+ folder_id=folder_id,
340
+ external_id=external_id,
341
+ callback_url=callback_url,
342
+ redirect_url=redirect_url,
343
+ ),
344
+ )
345
+
346
+ # Display creation success
347
+ click.echo("✅ Runtime user connection created successfully")
348
+ click.echo(f" 🆔 Connection ID: {response.data.id}")
349
+ click.echo(f" 🔗 URL: {response.data.url}")
350
+
351
+ click.echo()
352
+
353
+ try:
354
+ webbrowser.open(response.data.url)
355
+ click.echo(" 🌐 Opening OAuth URL in browser...")
356
+ except OSError as e:
357
+ click.echo(f" ⚠️ Could not open browser: {str(e)}")
358
+ click.echo(
359
+ " 💡 Please copy and paste the OAuth URL into your browser manually"
360
+ )
361
+ click.echo()
362
+ click.echo("💡 Next steps:")
363
+ click.echo(" 1. Complete OAuth authorization in the opened browser page")
364
+ click.echo(" 2. Follow the on-screen prompts to authenticate")
365
+ click.echo(
366
+ f" 3. Use connection ID {response.data.id} in your recipes once authorized"
367
+ )
368
+ await poll_oauth_connection_status(response.data.id)
369
+
370
+
371
+ @connections.command()
372
+ @click.option(
373
+ "--connection-id", required=True, type=int, help="ID of the connection to update"
374
+ )
375
+ @click.option("--name", help="New name for the connection")
376
+ @click.option(
377
+ "--parent-id", help="ID of the parent connection (must be same provider type)"
378
+ )
379
+ @click.option(
380
+ "--folder-id", type=int, help="ID of the project/folder to move connection to"
381
+ )
382
+ @click.option("--external-id", help="External ID assigned to the connection")
383
+ @click.option(
384
+ "--shell-connection", type=bool, help="Set as shell connection (true/false)"
385
+ )
386
+ @click.option(
387
+ "--input", "input_params", help="Updated connection parameters as JSON string"
388
+ )
389
+ @click.option(
390
+ "--input-file", help="Path to JSON file containing updated connection parameters"
391
+ )
392
+ @handle_cli_exceptions
393
+ @handle_api_exceptions
394
+ async def update(
395
+ connection_id: int,
396
+ name: str | None = None,
397
+ parent_id: int | None = None,
398
+ folder_id: int | None = None,
399
+ external_id: str | None = None,
400
+ shell_connection: bool | None = None,
401
+ input_params: str | None = None,
402
+ ) -> None:
403
+ """Update an existing connection
404
+
405
+ Update connection properties like name, folder, parent, or authentication parameters.
406
+ Use 'workato connectors parameters' to discover what parameters are available.
407
+
408
+ Examples:
409
+
410
+ # Update connection name
411
+ workato connections update --connection-id 123 --name "Updated Salesforce"
412
+
413
+ # Move connection to different folder
414
+ workato connections update --connection-id 123 --folder-id 456
415
+
416
+ # Update authentication parameters
417
+ workato connections update --connection-id 123 --input '{"username": "new@example.com", "password": "newpass"}'
418
+
419
+ # Update from configuration file
420
+ workato connections update --connection-id 123 --input-file updated-config.json
421
+
422
+ # Convert to shell connection
423
+ workato connections update --connection-id 123 --shell-connection true
424
+ """ # noqa: E501
425
+
426
+ # Parse input parameters
427
+ connection_input = parse_connection_input(input_params)
428
+ if connection_input is None and input_params:
429
+ return # Error already displayed by parse function
430
+
431
+ # Build the request payload (only include fields that are being updated)
432
+ connection_update_request = ConnectionUpdateRequest(
433
+ name=name,
434
+ parent_id=parent_id,
435
+ folder_id=folder_id,
436
+ external_id=external_id,
437
+ shell_connection=shell_connection,
438
+ input=connection_input,
439
+ )
440
+
441
+ # Update the connection
442
+ await update_connection(connection_id, connection_update_request)
443
+
444
+
445
+ def parse_connection_input(input_params: str | None = None) -> dict[str, Any] | None:
446
+ """Parse connection input parameters from JSON string"""
447
+ if not input_params:
448
+ return None # No input provided, which is valid
449
+
450
+ try:
451
+ # Parse JSON string
452
+ connection_input = json.loads(input_params)
453
+
454
+ if not isinstance(connection_input, dict):
455
+ click.echo("❌ Connection input must be a JSON object")
456
+ return None
457
+
458
+ return connection_input
459
+
460
+ except json.JSONDecodeError as e:
461
+ click.echo(f"❌ Invalid JSON in connection input: {str(e)}")
462
+ return None
463
+
464
+
465
+ @inject
466
+ async def update_connection(
467
+ connection_id: int,
468
+ connection_update_request: ConnectionUpdateRequest,
469
+ workato_api_client: Workato = Provide[Container.workato_api_client],
470
+ project_manager: ProjectManager = Provide[Container.project_manager],
471
+ ) -> None:
472
+ """Update the connection using the Workato API"""
473
+ connection_name = connection_update_request.name
474
+ spinner = Spinner(f"Updating connection '{connection_name}'")
475
+ spinner.start()
476
+
477
+ try:
478
+ connection_data = await workato_api_client.connections_api.update_connection(
479
+ connection_id=connection_id,
480
+ connection_update_request=connection_update_request,
481
+ )
482
+ finally:
483
+ elapsed = spinner.stop()
484
+
485
+ click.echo(f"✅ Connection updated successfully ({elapsed:.1f}s)")
486
+
487
+ # Display updated connection details
488
+ click.echo(f" 📄 Name: {connection_data.name}")
489
+ click.echo(f" 🆔 ID: {connection_data.id}")
490
+ click.echo(f" 🔌 Provider: {connection_data.provider}")
491
+ click.echo(f" 📁 Folder ID: {connection_data.folder_id}")
492
+
493
+ # Show connection status
494
+ authorization_status = connection_data.authorization_status
495
+ if authorization_status == "success":
496
+ click.echo(" ✅ Status: Authorized")
497
+ else:
498
+ click.echo(" ⚠️ Status: Not authorized")
499
+
500
+ # Show parent connection if specified
501
+ if connection_data.parent_id:
502
+ click.echo(f" 🔗 Parent ID: {connection_data.parent_id}")
503
+
504
+ # Show external ID if specified
505
+ if connection_data.external_id:
506
+ click.echo(f" 🏷️ External ID: {connection_data.external_id}")
507
+
508
+ # Show what was updated
509
+ updated_fields = []
510
+ if connection_update_request.name:
511
+ updated_fields.append("name")
512
+ if connection_update_request.folder_id:
513
+ updated_fields.append("folder location")
514
+ if connection_update_request.input:
515
+ updated_fields.append("authentication parameters")
516
+ if connection_update_request.shell_connection:
517
+ updated_fields.append("connection type")
518
+ if connection_update_request.parent_id:
519
+ updated_fields.append("parent connection")
520
+ if connection_update_request.external_id:
521
+ updated_fields.append("external ID")
522
+
523
+ if updated_fields:
524
+ click.echo(f" 🔄 Updated: {', '.join(updated_fields)}")
525
+
526
+ click.echo()
527
+ click.echo("💡 Next steps:")
528
+ if connection_update_request.input:
529
+ click.echo(" • Test the connection with updated credentials")
530
+ if connection_update_request.shell_connection:
531
+ click.echo(" • Complete authentication setup for shell connection")
532
+ click.echo(" • Verify connection works in recipes")
533
+
534
+ # Handle post-update sync
535
+ await project_manager.handle_post_api_sync()
536
+
537
+
538
+ @connections.command(name="list")
539
+ @click.option("--folder-id", type=int, help="Filter by folder ID")
540
+ @click.option("--parent-id", type=int, help="Filter by parent connection ID")
541
+ @click.option("--external-id", help="Filter by external ID")
542
+ @click.option(
543
+ "--include-runtime", is_flag=True, help="Include runtime user connections"
544
+ )
545
+ @click.option("--tags", help="Filter by connection tags")
546
+ @click.option("--provider", help="Filter by provider type (e.g., salesforce, jira)")
547
+ @click.option("--unauthorized", is_flag=True, help="Show only authorized connections")
548
+ @handle_cli_exceptions
549
+ @inject
550
+ @handle_api_exceptions
551
+ async def list_connections(
552
+ folder_id: int | None = None,
553
+ parent_id: int | None = None,
554
+ external_id: str | None = None,
555
+ include_runtime: bool | None = None,
556
+ tags: str | None = None,
557
+ provider: str | None = None,
558
+ unauthorized: bool | None = None,
559
+ workato_api_client: Workato = Provide[Container.workato_api_client],
560
+ ) -> None:
561
+ """List connections with filtering options
562
+
563
+ Discover and manage connections in your workspace with detailed information
564
+ about authorization status, providers, and relationships.
565
+
566
+ Examples:
567
+
568
+ # List all connections
569
+ workato connections list
570
+
571
+ # Filter by provider
572
+ workato connections list --provider salesforce
573
+
574
+ # Show only unauthorized connections
575
+ workato connections list --unauthorized
576
+
577
+ # List connections in specific folder
578
+ workato connections list --folder-id 123
579
+
580
+ # Find child connections of a parent
581
+ workato connections list --parent-id 456
582
+
583
+ # Include tags and runtime connections
584
+ workato connections list --include-tags --include-runtime
585
+ """
586
+ # Build filter description for display
587
+ filter_parts = []
588
+ if folder_id:
589
+ filter_parts.append(f"folder {folder_id}")
590
+ if parent_id:
591
+ filter_parts.append(f"parent {parent_id}")
592
+ if external_id:
593
+ filter_parts.append(f"external ID '{external_id}'")
594
+ if provider:
595
+ filter_parts.append(f"provider '{provider}'")
596
+ if unauthorized:
597
+ filter_parts.append("unauthorized only")
598
+ if include_runtime:
599
+ filter_parts.append("including runtime connections")
600
+
601
+ filter_text = f" ({', '.join(filter_parts)})" if filter_parts else ""
602
+
603
+ spinner = Spinner(f"Fetching connections{filter_text}")
604
+ spinner.start()
605
+
606
+ try:
607
+ connections = await workato_api_client.connections_api.list_connections(
608
+ folder_id=folder_id,
609
+ parent_id=parent_id,
610
+ external_id=external_id,
611
+ include_runtime_connections=include_runtime,
612
+ includes=tags.split(",") if tags else None,
613
+ )
614
+ finally:
615
+ elapsed = spinner.stop()
616
+
617
+ # Apply client-side filters (for options not supported by API)
618
+ if provider:
619
+ connections = [
620
+ c
621
+ for c in connections
622
+ if c.application and c.application.lower() == provider.lower()
623
+ ]
624
+
625
+ if unauthorized:
626
+ connections = [c for c in connections if c.authorization_status != "success"]
627
+
628
+ click.echo(
629
+ f"🔗 Connections ({len(connections)} found{filter_text}) - ({elapsed:.1f}s)"
630
+ )
631
+
632
+ if not connections:
633
+ click.echo(" ℹ️ No connections found matching criteria")
634
+ if filter_parts:
635
+ click.echo(" 💡 Try removing some filters to see more connections")
636
+ else:
637
+ click.echo(
638
+ " 💡 Create one: workato connections create --provider <PROVIDER> "
639
+ "--name 'My Connection'"
640
+ )
641
+ return
642
+
643
+ click.echo()
644
+
645
+ # Group connections for better display
646
+ grouped = group_connections_by_provider(connections)
647
+
648
+ # Display connections by provider
649
+ for provider_name, provider_connections in grouped.items():
650
+ click.echo(
651
+ f"📦 {provider_name} ({len(provider_connections)} connection"
652
+ f"{'s' if len(provider_connections) != 1 else ''})"
653
+ )
654
+
655
+ for connection in provider_connections:
656
+ display_connection_summary(connection)
657
+
658
+ click.echo()
659
+
660
+ # Show summary statistics
661
+ show_connection_statistics(connections)
662
+
663
+ click.echo("💡 Commands:")
664
+ click.echo(
665
+ " • View parameters: workato connectors parameters --provider <PROVIDER>"
666
+ )
667
+ click.echo(" • Update connection: workato connections update --connection-id <ID>")
668
+ click.echo(
669
+ " • Create connection: workato connections create --provider <PROVIDER>"
670
+ )
671
+
672
+ # Add recipe integration guidance
673
+ click.echo()
674
+ click.echo("🔗 Recipe Integration:")
675
+ click.echo(" • To use connections in recipes, update recipe config or use:")
676
+ click.echo(
677
+ " workato recipes update-connection <RECIPE_ID> --adapter-name <PROVIDER> "
678
+ "--connection-id <CONNECTION_ID>"
679
+ )
680
+ click.echo(" • Ensure recipe config section includes the connector provider")
681
+
682
+
683
+ def group_connections_by_provider(
684
+ connections: list[Connection],
685
+ ) -> dict[str, list[Connection]]:
686
+ """Group connections by provider for organized display"""
687
+ grouped: dict[str, list[Connection]] = {}
688
+
689
+ for connection in connections:
690
+ application = connection.application
691
+ provider_display = application.replace("_", " ").title()
692
+
693
+ if provider_display not in grouped:
694
+ grouped[provider_display] = []
695
+
696
+ grouped[provider_display].append(connection)
697
+
698
+ # Sort each group by name
699
+ for provider_connections in grouped.values():
700
+ provider_connections.sort(key=lambda x: x.name.lower())
701
+
702
+ # Return sorted by provider name
703
+ return dict(sorted(grouped.items()))
704
+
705
+
706
+ def display_connection_summary(connection: Connection) -> None:
707
+ """Display a summary of a connection"""
708
+ name = connection.name
709
+ connection_id = connection.id
710
+
711
+ # Fix: Use authorization_status instead of authorized field
712
+ authorization_status = connection.authorization_status
713
+
714
+ # Status icons and text
715
+ if authorization_status == "success":
716
+ status_icon = "✅"
717
+ status_text = "Authorized"
718
+ else:
719
+ status_icon = "❌"
720
+ status_text = "Not authorized"
721
+
722
+ click.echo(f" {status_icon} {name}")
723
+ click.echo(f" 🆔 ID: {connection_id}")
724
+ click.echo(f" 📊 Status: {status_text}")
725
+
726
+ # Show folder information
727
+ if connection.folder_id:
728
+ click.echo(f" 📁 Folder ID: {connection.folder_id}")
729
+
730
+ # Show parent connection if available
731
+ if connection.parent_id:
732
+ click.echo(f" 🔗 Parent ID: {connection.parent_id}")
733
+
734
+ # Show external ID if available
735
+ if connection.external_id:
736
+ click.echo(f" 🏷️ External ID: {connection.external_id}")
737
+
738
+ # Show tags if requested and available
739
+ if connection.tags:
740
+ tag_list = (
741
+ ", ".join(connection.tags)
742
+ if len(connection.tags) <= 3
743
+ else f"{', '.join(connection.tags[:3])} +{len(connection.tags) - 3} more"
744
+ )
745
+ click.echo(f" 🏷️ Tags: {tag_list}")
746
+
747
+ # Show creation/update time if available
748
+ if connection.created_at:
749
+ click.echo(
750
+ f" 🕐 Created: {connection.created_at.strftime('%Y-%m-%d')}"
751
+ ) # Just the date part
752
+
753
+ click.echo()
754
+
755
+
756
+ @connections.command(name="get-oauth-url")
757
+ @click.option(
758
+ "--id",
759
+ "connection_id",
760
+ required=True,
761
+ help="OAuth connection ID",
762
+ )
763
+ @click.option(
764
+ "--open-browser",
765
+ is_flag=True,
766
+ default=True,
767
+ help="Automatically open OAuth URL in browser",
768
+ )
769
+ @handle_cli_exceptions
770
+ @handle_api_exceptions
771
+ async def get_oauth_url(
772
+ connection_id: int,
773
+ open_browser: bool | None = None,
774
+ ) -> None:
775
+ """Get OAuth authorization URL for a OAuth connection
776
+
777
+ This command retrieves the OAuth authorization URL for an existing OAuth connection.
778
+ Use this if you need to re-authorize or get a fresh OAuth URL.
779
+
780
+ Examples:
781
+
782
+ # Get OAuth URL and open in browser
783
+ workato connections get-oauth-url --id 73389
784
+
785
+ # Get OAuth URL without opening browser
786
+ workato connections get-oauth-url --id 73389 --no-open-browser
787
+ """
788
+
789
+ # Get the OAuth URL
790
+ await get_connection_oauth_url(connection_id, open_browser)
791
+
792
+
793
+ @inject
794
+ async def get_connection_oauth_url(
795
+ connection_id: int,
796
+ open_browser: bool | None = None,
797
+ workato_api_client: Workato = Provide[Container.workato_api_client],
798
+ ) -> None:
799
+ """Get OAuth authorization URL for a runtime user connection"""
800
+ spinner = Spinner(f"Getting OAuth URL for connection {connection_id}")
801
+ spinner.start()
802
+
803
+ try:
804
+ response = await workato_api_client.connections_api.get_connection_oauth_url(
805
+ connection_id=connection_id,
806
+ )
807
+ finally:
808
+ elapsed = spinner.stop()
809
+
810
+ click.echo(f"✅ OAuth URL retrieved successfully ({elapsed:.1f}s)")
811
+
812
+ # Display OAuth URL
813
+ oauth_url = response.data.url
814
+
815
+ click.echo(f" 🆔 Connection ID: {connection_id}")
816
+ click.echo()
817
+ click.echo("🔐 OAuth Authorization URL:")
818
+ click.echo(f" 📋 OAuth URL: {oauth_url}")
819
+
820
+ if open_browser and oauth_url:
821
+ try:
822
+ webbrowser.open(oauth_url)
823
+ click.echo(" 🌐 Opening OAuth URL in browser...")
824
+ except OSError as e:
825
+ click.echo(f" ⚠️ Could not open browser: {str(e)}")
826
+ click.echo(
827
+ " 💡 Please copy and paste the OAuth URL into your browser manually"
828
+ )
829
+ else:
830
+ click.echo(" 💡 Copy and paste the OAuth URL into your browser to authorize")
831
+
832
+ click.echo()
833
+ click.echo("💡 Next steps:")
834
+ click.echo(" 1. Complete OAuth authorization in your browser")
835
+ click.echo(" 2. The connection will be automatically authorized")
836
+ click.echo(f" 3. Use connection ID {connection_id} in your recipes")
837
+
838
+
839
+ def show_connection_statistics(connections: list[Connection]) -> None:
840
+ """Show summary statistics about the connections"""
841
+ total = len(connections)
842
+
843
+ # Count authorized connections using the correct field
844
+ authorized = 0
845
+ for c in connections:
846
+ if c.authorization_status == "success":
847
+ authorized += 1
848
+
849
+ unauthorized = total - authorized
850
+
851
+ # Provider breakdown
852
+ providers: dict[str, int] = {}
853
+ for connection in connections:
854
+ provider = connection.provider or connection.application
855
+ providers[provider] = providers.get(provider, 0) + 1
856
+
857
+ click.echo("📊 Summary:")
858
+ click.echo(f" ✅ Authorized: {authorized}")
859
+ if unauthorized > 0:
860
+ click.echo(f" ❌ Unauthorized: {unauthorized}")
861
+
862
+ if len(providers) > 1:
863
+ click.echo(f" 🔌 Providers: {len(providers)} different types")
864
+
865
+ click.echo()
866
+
867
+
868
+ @connections.command(name="pick-list")
869
+ @click.option("--id", required=True, type=int, help="Connection ID")
870
+ @click.option("--pick-list-name", required=True, help="Name of the pick list")
871
+ @click.option(
872
+ "--params",
873
+ help='Pick list params as JSON string (e.g. \'{"sobject_name": "Invoice__c"}\')',
874
+ )
875
+ @handle_cli_exceptions
876
+ @inject
877
+ @handle_api_exceptions
878
+ async def pick_list(
879
+ id: int,
880
+ pick_list_name: str,
881
+ params: str,
882
+ workato_api_client: Workato = Provide[Container.workato_api_client],
883
+ ) -> None:
884
+ """Get pick list values from a connection"""
885
+
886
+ # Parse params if provided
887
+ pick_list_params: dict[str, Any] = {}
888
+ if params:
889
+ try:
890
+ pick_list_params = json.loads(params)
891
+ except json.JSONDecodeError as e:
892
+ click.echo(f"❌ Invalid JSON in --params: {str(e)}")
893
+ click.echo(' Example: --params \'{"sobject_name": "Invoice__c"}\'')
894
+ return
895
+
896
+ spinner = Spinner(f"Fetching pick list '{pick_list_name}' from connection {id}")
897
+ spinner.start()
898
+
899
+ picklist_request = PicklistRequest(
900
+ pick_list_name=pick_list_name,
901
+ pick_list_params=pick_list_params,
902
+ )
903
+
904
+ try:
905
+ response = await workato_api_client.connections_api.get_connection_picklist(
906
+ connection_id=id,
907
+ picklist_request=picklist_request,
908
+ )
909
+ finally:
910
+ elapsed = spinner.stop()
911
+
912
+ click.echo(f"📋 Pick List Results ({elapsed:.1f}s)")
913
+ click.echo(f" 🔗 Connection ID: {id}")
914
+ click.echo(f" 📝 Pick List: {pick_list_name}")
915
+
916
+ if pick_list_params:
917
+ click.echo(
918
+ f" ⚙️ Parameters: {json.dumps(pick_list_params, separators=(',', ':'))}"
919
+ )
920
+
921
+ # Display the pick list results
922
+ if not response.data:
923
+ click.echo(" No results found")
924
+ return
925
+
926
+ click.echo(f"\n📄 Results ({len(response.data)} items):")
927
+ for i, item in enumerate(response.data, 1):
928
+ click.echo(f" {i:3d}. {item}")
929
+
930
+
931
+ @connections.command(name="pick-lists")
932
+ @click.option("--adapter", help="Show pick lists for a specific adapter/connector")
933
+ def pick_lists(adapter: str | None = None) -> None:
934
+ """List available pick lists by adapter"""
935
+
936
+ # Load the bundled picklist data
937
+ data_file = Path(__file__).parent.parent / "data" / "picklist-data.json"
938
+
939
+ if not data_file.exists():
940
+ click.echo(
941
+ "❌ Picklist data not found. Run 'python scripts/parse_picklist_docs.py' "
942
+ "to generate it."
943
+ )
944
+ return
945
+
946
+ try:
947
+ with open(data_file) as f:
948
+ picklist_data = json.load(f)
949
+ except (FileNotFoundError, json.JSONDecodeError, PermissionError) as e:
950
+ click.echo(f"❌ Failed to load picklist data: {str(e)}")
951
+ return
952
+
953
+ if adapter:
954
+ # Show pick lists for specific adapter
955
+ if adapter not in picklist_data:
956
+ click.echo(f"❌ Adapter '{adapter}' not found")
957
+ click.echo("💡 Use 'workato connectors list' to see all available adapters")
958
+ return
959
+
960
+ picklists = picklist_data[adapter]
961
+ click.echo(f"📋 Pick Lists for '{adapter}' ({len(picklists)} available)")
962
+ click.echo()
963
+
964
+ for i, picklist in enumerate(picklists, 1):
965
+ click.echo(f" {i:2d}. {picklist['name']}")
966
+ if picklist["parameters"]:
967
+ params_str = ", ".join(picklist["parameters"])
968
+ click.echo(f" 📝 Parameters: {params_str}")
969
+ else:
970
+ click.echo(" 📝 No parameters required")
971
+ click.echo()
972
+
973
+ click.echo("💡 Usage example:")
974
+ first_picklist = picklists[0]
975
+ if first_picklist["parameters"]:
976
+ params_example = (
977
+ "{"
978
+ + ", ".join(
979
+ [f'"{p}": "value"' for p in first_picklist["parameters"][:2]]
980
+ )
981
+ + "}"
982
+ )
983
+ click.echo(
984
+ " workato connections pick-list --id CONNECTION_ID --pick-list-name "
985
+ f"{first_picklist['name']} --params '{params_example}'"
986
+ )
987
+ else:
988
+ click.echo(
989
+ " workato connections pick-list --id CONNECTION_ID --pick-list-name "
990
+ f"{first_picklist['name']}"
991
+ )
992
+
993
+ else:
994
+ # Show all adapters
995
+ total_picklists = sum(len(picklists) for picklists in picklist_data.values())
996
+ click.echo(
997
+ f"📋 Available Adapters ({len(picklist_data)} adapters, {total_picklists} "
998
+ "total pick lists)"
999
+ )
1000
+ click.echo()
1001
+
1002
+ # Sort by picklist count
1003
+ adapter_counts = [
1004
+ (name, len(picklists)) for name, picklists in picklist_data.items()
1005
+ ]
1006
+ adapter_counts.sort(key=lambda x: x[1], reverse=True)
1007
+
1008
+ for adapter, count in adapter_counts:
1009
+ click.echo(f" 📦 {adapter:<30} ({count:2d} pick lists)")
1010
+
1011
+ click.echo()
1012
+ click.echo("💡 To see pick lists for a specific adapter:")
1013
+ click.echo(" workato connections pick-lists --adapter salesforce")
1014
+
1015
+
1016
+ async def requires_oauth_flow(provider: str) -> bool:
1017
+ """Determine if OAuth flow is required for this connection"""
1018
+ if not provider:
1019
+ return False
1020
+
1021
+ return await is_platform_oauth_provider(
1022
+ provider
1023
+ ) or await is_custom_connector_oauth(provider)
1024
+
1025
+
1026
+ @inject
1027
+ async def is_platform_oauth_provider(
1028
+ provider: str,
1029
+ connector_manager: ConnectorManager = Provide[Container.connector_manager],
1030
+ ) -> bool:
1031
+ """Check if a provider is a platform OAuth provider using the API"""
1032
+ all_connectors = await connector_manager.list_platform_connectors()
1033
+ return any(
1034
+ connector.name == provider and connector.oauth for connector in all_connectors
1035
+ )
1036
+
1037
+
1038
+ @inject
1039
+ async def is_custom_connector_oauth(
1040
+ provider: str,
1041
+ workato_api_client: Workato = Provide[Container.workato_api_client],
1042
+ ) -> bool:
1043
+ """Check if a custom connector requires OAuth by examining its code"""
1044
+ response = await workato_api_client.connectors_api.list_custom_connectors()
1045
+ connectors = response.result
1046
+
1047
+ # Find connector by name/provider
1048
+ target_connector = None
1049
+ for connector in connectors:
1050
+ if connector.name == provider:
1051
+ target_connector = connector
1052
+ break
1053
+
1054
+ if not target_connector:
1055
+ return False
1056
+
1057
+ # Get the connector code
1058
+ connector_id = target_connector.id
1059
+ if not connector_id:
1060
+ return False
1061
+
1062
+ code_response = await workato_api_client.connectors_api.get_custom_connector_code(
1063
+ id=connector_id,
1064
+ )
1065
+ code_data = code_response.data
1066
+
1067
+ # Look for OAuth indicators in the code
1068
+ oauth_indicators = [
1069
+ "oauth",
1070
+ "authorization_url",
1071
+ "acquire_access_token",
1072
+ "refresh_token",
1073
+ "client_id",
1074
+ "client_secret",
1075
+ "redirect_uri",
1076
+ ]
1077
+
1078
+ code_lower = code_data.code.lower()
1079
+
1080
+ return any(indicator in code_lower for indicator in oauth_indicators)
1081
+
1082
+
1083
+ @inject
1084
+ async def poll_oauth_connection_status(
1085
+ connection_id: int,
1086
+ external_id: str | None = None,
1087
+ workato_api_client: Workato = Provide[Container.workato_api_client],
1088
+ project_manager: ProjectManager = Provide[Container.project_manager],
1089
+ config_manager: ConfigManager = Provide[Container.config_manager],
1090
+ ) -> None:
1091
+ """Poll connection list to check if OAuth connection is authorized"""
1092
+ start_time = time.time()
1093
+ poll_interval = 5 # Check every 5 seconds
1094
+
1095
+ spinner = Spinner("Waiting for OAuth authorization")
1096
+ spinner.start()
1097
+
1098
+ try:
1099
+ while time.time() - start_time < OAUTH_TIMEOUT:
1100
+ elapsed_time = int(time.time() - start_time)
1101
+ remaining_time = OAUTH_TIMEOUT - elapsed_time
1102
+ spinner.update_message(
1103
+ f"Waiting for OAuth authorization ({remaining_time}s remaining)"
1104
+ )
1105
+
1106
+ # Get connections filtered by external_id
1107
+ connections = await workato_api_client.connections_api.list_connections(
1108
+ external_id=external_id,
1109
+ include_runtime_connections=True,
1110
+ )
1111
+
1112
+ # Find our connection
1113
+ our_connection = None
1114
+ for conn in connections:
1115
+ if conn.id == connection_id:
1116
+ our_connection = conn
1117
+ break
1118
+
1119
+ if not our_connection:
1120
+ click.echo(f"❌ Connection with ID {connection_id} not found")
1121
+ return
1122
+
1123
+ # Check authorization status using the correct field
1124
+ authorization_status = our_connection.authorization_status
1125
+ is_authorized = authorization_status == "success"
1126
+
1127
+ if is_authorized:
1128
+ # Connection is now authorized!
1129
+ elapsed = spinner.stop()
1130
+ click.echo(
1131
+ f"✅ OAuth authorization completed successfully! ({elapsed:.1f}s)"
1132
+ )
1133
+ click.echo()
1134
+
1135
+ # Display final connection details
1136
+ click.echo("🎉 OAuth Base Connection Ready:")
1137
+ click.echo(f" 📄 Name: {our_connection.name}")
1138
+ click.echo(f" 🆔 Connection ID: {our_connection.id}")
1139
+ click.echo(f" 🔌 Provider: {our_connection.provider}")
1140
+ click.echo(" ✅ Status: Authorized")
1141
+ click.echo(f" 📁 Folder ID: {our_connection.folder_id}")
1142
+
1143
+ click.echo()
1144
+ click.echo("💡 Next steps:")
1145
+ click.echo(
1146
+ " • Use this connection as a parent for runtime user connections"
1147
+ )
1148
+ click.echo(
1149
+ " • Create runtime connections: workato connections create-oauth "
1150
+ f"--parent-id {connection_id}"
1151
+ )
1152
+ click.echo(" • Test the connection in your recipes")
1153
+
1154
+ # Add recipe connection update guidance
1155
+ provider = our_connection.provider
1156
+ click.echo()
1157
+ click.echo("🔗 Recipe Integration:")
1158
+ click.echo(
1159
+ " • To use this connection in recipes, update recipe config with:"
1160
+ )
1161
+ click.echo(f" 'account_id': {connection_id}")
1162
+ click.echo(
1163
+ f" • Or use: workato recipes update-connection <RECIPE_ID> "
1164
+ f"--adapter-name {provider} --connection-id {connection_id}"
1165
+ )
1166
+ click.echo(
1167
+ " • Ensure recipe config section includes the connector provider"
1168
+ )
1169
+
1170
+ # Handle post-creation sync
1171
+ await project_manager.handle_post_api_sync()
1172
+ return
1173
+
1174
+ # Wait before next poll
1175
+ time.sleep(poll_interval)
1176
+
1177
+ # Timeout reached
1178
+ elapsed = spinner.stop()
1179
+ click.echo(f"⏰ Timeout reached after {OAUTH_TIMEOUT} seconds")
1180
+ click.echo()
1181
+ click.echo("❌ OAuth authorization was not completed within the timeout period")
1182
+ click.echo()
1183
+ click.echo("💡 What to do next:")
1184
+ click.echo(
1185
+ " • Check if the connection is authorized: workato connections list "
1186
+ f"--external-id {external_id}"
1187
+ )
1188
+ click.echo(
1189
+ " • Complete authorization manually: "
1190
+ f"{config_manager.api_host}/connections/{connection_id}"
1191
+ )
1192
+
1193
+ except KeyboardInterrupt:
1194
+ elapsed = spinner.stop()
1195
+ click.echo()
1196
+ click.echo("⚠️ Polling interrupted by user")
1197
+ click.echo()
1198
+ click.echo("💡 The shell connection has been created. You can:")
1199
+ click.echo(
1200
+ " • Complete authorization manually: "
1201
+ f"{config_manager.api_host}/connections/{connection_id}"
1202
+ )
1203
+ click.echo(
1204
+ f" • Check status: workato connections list --external-id {external_id}"
1205
+ )