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,627 @@
1
+ import re
2
+
3
+ import asyncclick as click
4
+
5
+ from dependency_injector.wiring import Provide, inject
6
+
7
+ from workato_platform_cli import Workato
8
+ from workato_platform_cli.cli.containers import Container
9
+ from workato_platform_cli.cli.utils.exception_handler import (
10
+ handle_api_exceptions,
11
+ handle_cli_exceptions,
12
+ )
13
+ from workato_platform_cli.cli.utils.spinner import Spinner
14
+ from workato_platform_cli.client.workato_api.models.api_client import ApiClient
15
+ from workato_platform_cli.client.workato_api.models.api_client_create_request import (
16
+ ApiClientCreateRequest,
17
+ )
18
+ from workato_platform_cli.client.workato_api.models.api_key import ApiKey
19
+ from workato_platform_cli.client.workato_api.models.api_key_create_request import (
20
+ ApiKeyCreateRequest,
21
+ )
22
+
23
+
24
+ @click.group(name="api-clients")
25
+ def api_clients() -> None:
26
+ """Manage API clients"""
27
+ pass
28
+
29
+
30
+ @api_clients.command()
31
+ @click.option("--name", required=True, help="Name of the client")
32
+ @click.option("--description", help="Description of the client")
33
+ @click.option(
34
+ "--project-id", type=int, help="ID of the project to create the client in"
35
+ )
36
+ @click.option(
37
+ "--api-portal-id", type=int, help="ID of the API portal to assign the client"
38
+ )
39
+ @click.option(
40
+ "--email", help="Email address for the client (required if api-portal-id provided)"
41
+ )
42
+ @click.option(
43
+ "--api-collection-ids",
44
+ required=True,
45
+ help="Comma-separated list of API collection IDs to assign",
46
+ )
47
+ @click.option("--api-policy-id", type=int, help="ID of the API policy to apply")
48
+ @click.option(
49
+ "--auth-type",
50
+ required=True,
51
+ type=click.Choice(["token", "jwt", "oauth2", "oidc"]),
52
+ help="Authentication method (token, jwt, oauth2, oidc)",
53
+ )
54
+ @click.option(
55
+ "--jwt-method",
56
+ type=click.Choice(["hmac", "rsa"]),
57
+ help="JWT signing method (hmac or rsa) - required when auth-type is jwt",
58
+ )
59
+ @click.option(
60
+ "--jwt-secret",
61
+ help="HMAC shared secret or RSA public key - required when auth-type is jwt",
62
+ )
63
+ @click.option("--oidc-issuer", help="Discovery URL for OIDC identity provider")
64
+ @click.option("--oidc-jwks-uri", help="JWKS URL for OIDC identity provider")
65
+ @click.option(
66
+ "--access-profile-claim", help="JWT claim key for access profile identification"
67
+ )
68
+ @click.option("--required-claims", help="Comma-separated list of claims to enforce")
69
+ @click.option("--allowed-issuers", help="Comma-separated list of allowed issuers")
70
+ @click.option("--mtls-enabled", is_flag=True, help="Enable mutual TLS for this client")
71
+ @click.option("--validation-formula", help="Formula to validate client certificates")
72
+ @click.option(
73
+ "--cert-bundle-ids", help="Comma-separated list of certificate bundle IDs for mTLS"
74
+ )
75
+ @handle_cli_exceptions
76
+ @inject
77
+ @handle_api_exceptions
78
+ async def create(
79
+ name: str,
80
+ auth_type: str,
81
+ description: str | None = None,
82
+ project_id: int | None = None,
83
+ api_portal_id: int | None = None,
84
+ email: str | None = None,
85
+ api_collection_ids: str | None = None,
86
+ api_policy_id: int | None = None,
87
+ jwt_method: str | None = None,
88
+ jwt_secret: str | None = None,
89
+ oidc_issuer: str | None = None,
90
+ oidc_jwks_uri: str | None = None,
91
+ access_profile_claim: str | None = None,
92
+ required_claims: str | None = None,
93
+ allowed_issuers: str | None = None,
94
+ mtls_enabled: bool | None = None,
95
+ validation_formula: str | None = None,
96
+ cert_bundle_ids: str | None = None,
97
+ workato_api_client: Workato = Provide[Container.workato_api_client],
98
+ ) -> None:
99
+ """Create a new API client"""
100
+
101
+ # Validate conditional parameters
102
+ validation_errors = validate_create_parameters(
103
+ auth_type,
104
+ jwt_method,
105
+ jwt_secret,
106
+ oidc_issuer,
107
+ oidc_jwks_uri,
108
+ api_portal_id,
109
+ email,
110
+ )
111
+
112
+ if validation_errors:
113
+ click.echo("❌ Parameter validation failed:")
114
+ for error in validation_errors:
115
+ click.echo(f" â€ĸ {error}")
116
+ return
117
+
118
+ # Parse comma-separated lists
119
+ try:
120
+ collection_ids = (
121
+ [int(id.strip()) for id in api_collection_ids.split(",")]
122
+ if api_collection_ids
123
+ else []
124
+ )
125
+ except ValueError:
126
+ click.echo(
127
+ "❌ Invalid API collection IDs. Please provide comma-separated integers."
128
+ )
129
+ return
130
+
131
+ api_client_create_request = ApiClientCreateRequest(
132
+ name=name,
133
+ description=description,
134
+ project_id=project_id,
135
+ api_portal_id=api_portal_id,
136
+ email=email,
137
+ api_policy_id=api_policy_id,
138
+ api_collection_ids=collection_ids,
139
+ auth_type=auth_type,
140
+ jwt_method=jwt_method,
141
+ jwt_secret=jwt_secret,
142
+ oidc_issuer=oidc_issuer,
143
+ oidc_jwks_uri=oidc_jwks_uri,
144
+ access_profile_claim=access_profile_claim,
145
+ required_claims=[claim.strip() for claim in required_claims.split(",")]
146
+ if required_claims
147
+ else None,
148
+ allowed_issuers=[issuer.strip() for issuer in allowed_issuers.split(",")]
149
+ if allowed_issuers
150
+ else None,
151
+ mtls_enabled=mtls_enabled,
152
+ validation_formula=validation_formula,
153
+ cert_bundle_ids=[int(id.strip()) for id in cert_bundle_ids.split(",")]
154
+ if cert_bundle_ids
155
+ else None,
156
+ )
157
+
158
+ # Create the API client
159
+ spinner = Spinner(f"Creating API client '{name}'")
160
+ spinner.start()
161
+
162
+ try:
163
+ response = await workato_api_client.api_platform_api.create_api_client(
164
+ api_client_create_request=api_client_create_request
165
+ )
166
+ finally:
167
+ elapsed = spinner.stop()
168
+
169
+ click.echo(f"✅ API client created successfully ({elapsed:.1f}s)")
170
+
171
+ # Display client details
172
+ client_data = response.data
173
+ if client_data:
174
+ click.echo(f" 📄 Name: {client_data.name}")
175
+ click.echo(f" 🆔 ID: {client_data.id}")
176
+ click.echo(f" 🔐 Auth Type: {client_data.auth_type}")
177
+
178
+ # Show API token if it's token-based auth
179
+ if client_data.auth_type == "token" and client_data.api_token:
180
+ click.echo(f" 🔑 API Token: {client_data.api_token}")
181
+
182
+ # Show assigned collections
183
+ if client_data.api_collections:
184
+ collection_names = [
185
+ col.name or f"ID: {col.id}" for col in client_data.api_collections
186
+ ]
187
+ click.echo(f" 📚 Collections: {', '.join(collection_names)}")
188
+
189
+ click.echo()
190
+ click.echo("💡 Next steps:")
191
+ click.echo(" â€ĸ Configure your application to use the API client")
192
+ if client_data.auth_type == "token":
193
+ click.echo(" â€ĸ Save the API token securely")
194
+ click.echo(" â€ĸ Test API access with the assigned collections")
195
+
196
+
197
+ def validate_create_parameters(
198
+ auth_type: str | None = None,
199
+ jwt_method: str | None = None,
200
+ jwt_secret: str | None = None,
201
+ oidc_issuer: str | None = None,
202
+ oidc_jwks_uri: str | None = None,
203
+ api_portal_id: int | None = None,
204
+ email: str | None = None,
205
+ ) -> list[str]:
206
+ """Validate conditional parameters based on auth_type and other conditions"""
207
+ errors = []
208
+
209
+ # JWT validation
210
+ if auth_type == "jwt":
211
+ if not jwt_method:
212
+ errors.append("--jwt-method is required when --auth-type is 'jwt'")
213
+ if not jwt_secret:
214
+ errors.append("--jwt-secret is required when --auth-type is 'jwt'")
215
+
216
+ # OIDC validation
217
+ if auth_type in ["jwt", "oidc"] and not oidc_issuer and not oidc_jwks_uri:
218
+ errors.append(
219
+ f"Either --oidc-issuer or --oidc-jwks-uri is required when "
220
+ f"--auth-type is '{auth_type}'"
221
+ )
222
+
223
+ # API portal validation
224
+ if api_portal_id and not email:
225
+ errors.append("--email is required when --api-portal-id is provided")
226
+ if email and not api_portal_id:
227
+ errors.append("--api-portal-id is required when --email is provided")
228
+
229
+ return errors
230
+
231
+
232
+ @api_clients.command(name="create-key")
233
+ @click.option(
234
+ "--api-client-id",
235
+ required=True,
236
+ type=int,
237
+ help="ID of the API client to create key for",
238
+ )
239
+ @click.option("--name", required=True, help="Name of the API key")
240
+ @click.option(
241
+ "--active/--inactive",
242
+ default=True,
243
+ help="Whether the API key is enabled (default: active)",
244
+ )
245
+ @click.option(
246
+ "--ip-allow-list", help="Comma-separated list of IP addresses to allowlist"
247
+ )
248
+ @click.option("--ip-deny-list", help="Comma-separated list of IP addresses to deny")
249
+ @handle_cli_exceptions
250
+ @inject
251
+ @handle_api_exceptions
252
+ async def create_key(
253
+ api_client_id: int,
254
+ name: str,
255
+ active: bool = True,
256
+ ip_allow_list: str | None = None,
257
+ ip_deny_list: str | None = None,
258
+ workato_api_client: Workato = Provide[Container.workato_api_client],
259
+ ) -> None:
260
+ """Create a new API key for an existing API client"""
261
+
262
+ # Validate IP address lists if provided
263
+ parsed_allow_list: list[str] | None = None
264
+ parsed_deny_list: list[str] | None = None
265
+
266
+ if ip_allow_list:
267
+ parsed_allow_list = parse_ip_list(ip_allow_list, "allow")
268
+ if parsed_allow_list is None:
269
+ return
270
+
271
+ if ip_deny_list:
272
+ parsed_deny_list = parse_ip_list(ip_deny_list, "deny")
273
+ if parsed_deny_list is None:
274
+ return
275
+
276
+ spinner = Spinner(f"Creating API key '{name}' for client {api_client_id}")
277
+ spinner.start()
278
+
279
+ try:
280
+ response = await workato_api_client.api_platform_api.create_api_key(
281
+ api_client_id=api_client_id,
282
+ api_key_create_request=ApiKeyCreateRequest(
283
+ name=name,
284
+ active=active,
285
+ ip_allow_list=parsed_allow_list,
286
+ ip_deny_list=parsed_deny_list,
287
+ ),
288
+ )
289
+ finally:
290
+ elapsed = spinner.stop()
291
+
292
+ click.echo(f"✅ API key created successfully ({elapsed:.1f}s)")
293
+ click.echo(f" 📄 Name: {response.data.name}")
294
+ click.echo(f" 🆔 Key ID: {response.data.id}")
295
+
296
+ # Try different possible field names for the API key
297
+ api_key_value = response.data.auth_token
298
+
299
+ if api_key_value:
300
+ click.echo(f" 🔑 API Key: {api_key_value}")
301
+ else:
302
+ click.echo(" 🔑 API Key: Not provided in response")
303
+
304
+ click.echo(f" ✅ Status: {'Active' if response.data.active else 'Inactive'}")
305
+
306
+ # Show IP restrictions if configured
307
+ if response.data.ip_allow_list:
308
+ allow_list = ", ".join(response.data.ip_allow_list)
309
+ click.echo(f" đŸŸĸ IP Allow List: {allow_list}")
310
+
311
+ if response.data.ip_deny_list:
312
+ deny_list = ", ".join(response.data.ip_deny_list)
313
+ click.echo(f" 🔴 IP Deny List: {deny_list}")
314
+
315
+ click.echo()
316
+ click.echo("💡 Next steps:")
317
+ click.echo(" â€ĸ Save the API key securely")
318
+ click.echo(" â€ĸ Configure your application to use this key")
319
+ click.echo(" â€ĸ Test API access from allowed IP addresses")
320
+
321
+ if response.data.ip_allow_list or response.data.ip_deny_list:
322
+ click.echo(" â€ĸ Verify IP restrictions are working as expected")
323
+
324
+
325
+ def parse_ip_list(ip_list_str: str, list_type: str) -> list[str] | None:
326
+ """Parse and validate IP address list"""
327
+ ip_addresses = [ip.strip() for ip in ip_list_str.split(",")]
328
+
329
+ # Basic IP address validation
330
+ for ip in ip_addresses:
331
+ if not ip:
332
+ continue
333
+
334
+ # Simple validation - could be enhanced with proper IP validation
335
+ if not validate_ip_address(ip):
336
+ click.echo(f"❌ Invalid IP address in {list_type} list: {ip}")
337
+ click.echo(
338
+ "💡 Please provide valid IP addresses (IPv4 or IPv6) or CIDR blocks"
339
+ )
340
+ return None
341
+
342
+ return [ip for ip in ip_addresses if ip]
343
+
344
+
345
+ def validate_ip_address(ip: str) -> bool:
346
+ """Basic IP address validation"""
347
+ # IPv4 pattern (including CIDR)
348
+ ipv4_pattern = r"^(\d{1,3}\.){3}\d{1,3}(\/\d{1,2})?$"
349
+
350
+ # IPv6 pattern (basic - could be more comprehensive)
351
+ ipv6_pattern = r"^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::1$|^::$"
352
+
353
+ # Check if it matches IPv4 or IPv6 patterns
354
+ if re.match(ipv4_pattern, ip):
355
+ # Validate IPv4 octets
356
+ parts = ip.split("/")
357
+ octets = parts[0].split(".")
358
+ for octet in octets:
359
+ if not (0 <= int(octet) <= 255):
360
+ return False
361
+
362
+ # Validate CIDR if present
363
+ if len(parts) == 2:
364
+ cidr = int(parts[1])
365
+ if not (0 <= cidr <= 32):
366
+ return False
367
+
368
+ return True
369
+
370
+ elif re.match(ipv6_pattern, ip):
371
+ return True
372
+
373
+ return False
374
+
375
+
376
+ @api_clients.command(name="refresh-secret")
377
+ @click.option("--api-client-id", required=True, type=int, help="ID of the API client")
378
+ @click.option(
379
+ "--api-key-id", required=True, type=int, help="ID of the API key to refresh"
380
+ )
381
+ @click.option("--force", is_flag=True, help="Skip confirmation prompt")
382
+ @handle_cli_exceptions
383
+ @handle_api_exceptions
384
+ async def refresh_secret(
385
+ api_client_id: int,
386
+ api_key_id: int,
387
+ force: bool | None = None,
388
+ ) -> None:
389
+ """Refresh the secret for an existing API key"""
390
+
391
+ # Show warning and confirmation unless --force is used
392
+ if force is False:
393
+ click.echo("âš ī¸ Warning: Refreshing the API key secret will:")
394
+ click.echo(" â€ĸ Generate a new API key")
395
+ click.echo(" â€ĸ Invalidate the current API key immediately")
396
+ click.echo(" â€ĸ Require updating all applications using this key")
397
+ click.echo()
398
+
399
+ if not click.confirm("Do you want to continue?"):
400
+ click.echo("Cancelled")
401
+ return
402
+
403
+ # Refresh the API key secret
404
+ await refresh_api_key_secret(api_client_id, api_key_id)
405
+
406
+
407
+ @inject
408
+ async def refresh_api_key_secret(
409
+ api_client_id: int,
410
+ api_key_id: int,
411
+ workato_api_client: Workato = Provide[Container.workato_api_client],
412
+ ) -> None:
413
+ """Refresh the API key secret using the Workato API"""
414
+ spinner = Spinner(f"Refreshing secret for API key {api_key_id}")
415
+ spinner.start()
416
+
417
+ try:
418
+ response = await workato_api_client.api_platform_api.refresh_api_key_secret(
419
+ api_client_id=api_client_id,
420
+ api_key_id=api_key_id,
421
+ )
422
+ finally:
423
+ elapsed = spinner.stop()
424
+
425
+ click.echo(f"✅ API key secret refreshed successfully ({elapsed:.1f}s)")
426
+
427
+ # Display updated key details - check for 'data' field first (new format)
428
+ key_data = response.data
429
+ click.echo(f" 📄 Name: {key_data.name}")
430
+ click.echo(f" 🆔 Key ID: {key_data.id}")
431
+ click.echo(f" 🔐 Auth Type: {key_data.auth_type}")
432
+
433
+ # Get the new API key/token
434
+ api_key_value = key_data.auth_token
435
+ click.echo(f" 🔑 New API Key: {api_key_value}")
436
+ click.echo(f" ✅ Status: {'Active' if key_data.active else 'Inactive'}")
437
+
438
+ # Show activation time if available
439
+ if key_data.active_since:
440
+ click.echo(f" 🕐 Active Since: {key_data.active_since.isoformat()}")
441
+
442
+ # Show IP restrictions if configured
443
+ if key_data.ip_allow_list:
444
+ allow_list = ", ".join(key_data.ip_allow_list)
445
+ click.echo(f" đŸŸĸ IP Allow List: {allow_list}")
446
+
447
+ if key_data.ip_deny_list:
448
+ deny_list = ", ".join(key_data.ip_deny_list)
449
+ click.echo(f" 🔴 IP Deny List: {deny_list}")
450
+
451
+ click.echo()
452
+ click.echo("🚨 Important:")
453
+ click.echo(" â€ĸ The old API key is now invalid")
454
+ click.echo(" â€ĸ Update all applications with the new API key")
455
+ click.echo(" â€ĸ Test connectivity with the new key")
456
+ click.echo(" â€ĸ Store the new key securely")
457
+
458
+
459
+ @api_clients.command(name="list")
460
+ @click.option("--project-id", type=int, help="Filter API clients by project ID")
461
+ @handle_cli_exceptions
462
+ @inject
463
+ @handle_api_exceptions
464
+ async def list_api_clients(
465
+ project_id: int | None = None,
466
+ workato_api_client: Workato = Provide[Container.workato_api_client],
467
+ ) -> None:
468
+ """List API clients, optionally filtered by project"""
469
+ filter_text = f" for project {project_id}" if project_id else ""
470
+ spinner = Spinner(f"Fetching API clients{filter_text}")
471
+ spinner.start()
472
+
473
+ try:
474
+ response = await workato_api_client.api_platform_api.list_api_clients(
475
+ project_id=project_id,
476
+ )
477
+ finally:
478
+ elapsed = spinner.stop()
479
+
480
+ clients = response.data
481
+
482
+ if project_id:
483
+ click.echo(
484
+ f"📋 API Clients for Project {project_id} ({len(clients)} found) "
485
+ f"- ({elapsed:.1f}s)"
486
+ )
487
+ else:
488
+ click.echo(f"📋 All API Clients ({len(clients)} found) - ({elapsed:.1f}s)")
489
+
490
+ if not clients:
491
+ click.echo(" â„šī¸ No API clients found")
492
+ if project_id:
493
+ click.echo(" 💡 Try without --project-id to see all clients")
494
+ return
495
+
496
+ click.echo()
497
+
498
+ # Display clients
499
+ for client in clients:
500
+ display_client_summary(client)
501
+ click.echo()
502
+
503
+ click.echo("💡 Commands:")
504
+ click.echo(
505
+ " â€ĸ Create API key: workato api-clients create-key --api-client-id <ID>"
506
+ )
507
+ click.echo(
508
+ " â€ĸ List client keys: workato api-clients list-keys --api-client-id <ID>"
509
+ )
510
+
511
+
512
+ @api_clients.command(name="list-keys")
513
+ @click.option(
514
+ "--api-client-id",
515
+ required=True,
516
+ type=int,
517
+ help="ID of the API client to list keys for",
518
+ )
519
+ @handle_cli_exceptions
520
+ @inject
521
+ @handle_api_exceptions
522
+ async def list_api_keys(
523
+ api_client_id: int,
524
+ workato_api_client: Workato = Provide[Container.workato_api_client],
525
+ ) -> None:
526
+ """List API keys for a specific API client"""
527
+
528
+ spinner = Spinner(f"Fetching API keys for client {api_client_id}")
529
+ spinner.start()
530
+
531
+ try:
532
+ response = await workato_api_client.api_platform_api.list_api_keys(
533
+ api_client_id=api_client_id,
534
+ )
535
+ finally:
536
+ elapsed = spinner.stop()
537
+
538
+ # Parse the response
539
+ keys = response.data
540
+
541
+ click.echo(
542
+ f"🔑 API Keys for Client {api_client_id} ({len(keys)} found) - ({elapsed:.1f}s)"
543
+ )
544
+
545
+ if not keys:
546
+ click.echo(" â„šī¸ No API keys found for this client")
547
+ click.echo(
548
+ " 💡 Create one: workato api-clients create-key "
549
+ "--api-client-id {api_client_id}"
550
+ )
551
+ return
552
+
553
+ click.echo()
554
+
555
+ # Display keys
556
+ for key in keys:
557
+ display_key_summary(key)
558
+ click.echo()
559
+
560
+ click.echo("💡 Commands:")
561
+ click.echo(
562
+ f" â€ĸ Create new key: workato api-clients create-key "
563
+ f"--api-client-id {api_client_id}"
564
+ )
565
+ click.echo(
566
+ f" â€ĸ Refresh key: workato api-clients refresh-secret "
567
+ f"--api-client-id {api_client_id} --api-key-id <KEY_ID>"
568
+ )
569
+
570
+
571
+ def display_client_summary(client: ApiClient) -> None:
572
+ """Display a summary of an API client"""
573
+
574
+ click.echo(f" {client.name}")
575
+ click.echo(f" 🆔 ID: {client.id}")
576
+ click.echo(f" 🔐 Auth Type: {client.auth_type}")
577
+
578
+ # Show API collections if available
579
+ for collection in client.api_collections:
580
+ click.echo(f" 📚 {collection.name} (ID: {collection.id})")
581
+
582
+ # Show email if available (API portal integration)
583
+ if client.email:
584
+ click.echo(f" 📧 Email: {client.email}")
585
+
586
+ click.echo(f" 🕐 Created: {client.created_at.isoformat()[:10]}")
587
+
588
+
589
+ def display_key_summary(key: ApiKey) -> None:
590
+ """Display a summary of an API key"""
591
+ name = key.name
592
+ key_id = key.id
593
+ active = key.active
594
+
595
+ status_icon = "✅" if active else "❌"
596
+ status_text = "Active" if active else "Inactive"
597
+
598
+ click.echo(f" {status_icon} {name}")
599
+ click.echo(f" 🆔 Key ID: {key_id}")
600
+ click.echo(f" 📊 Status: {status_text}")
601
+
602
+ # Show partial API key if available (first 8 + last 4 characters)
603
+ api_key = key.auth_token
604
+ if api_key:
605
+ masked_key = api_key[:8] + "..." + api_key[-4:] if len(api_key) > 12 else "***"
606
+ click.echo(f" 🔑 Key: {masked_key}")
607
+
608
+ # Show IP restrictions if configured
609
+ if key.ip_allow_list:
610
+ allow_count = len(key.ip_allow_list)
611
+ if allow_count <= 2:
612
+ allow_list = ", ".join(key.ip_allow_list)
613
+ click.echo(f" đŸŸĸ Allow List: {allow_list}")
614
+ else:
615
+ click.echo(f" đŸŸĸ Allow List: {allow_count} IP addresses")
616
+
617
+ if key.ip_deny_list:
618
+ deny_count = len(key.ip_deny_list)
619
+ if deny_count <= 2:
620
+ deny_list = ", ".join(key.ip_deny_list)
621
+ click.echo(f" 🔴 Deny List: {deny_list}")
622
+ else:
623
+ click.echo(f" 🔴 Deny List: {deny_count} IP addresses")
624
+
625
+ click.echo(
626
+ f" 🕐 Created: {key.active_since.isoformat()[:10]}"
627
+ ) # Just the date part