mistapi 0.63.0__tar.gz → 0.63.1__tar.gz

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 (367) hide show
  1. {mistapi-0.63.0 → mistapi-0.63.1}/CHANGELOG.md +20 -0
  2. {mistapi-0.63.0 → mistapi-0.63.1}/PKG-INFO +1 -1
  3. {mistapi-0.63.0 → mistapi-0.63.1}/pyproject.toml +1 -1
  4. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__version.py +1 -1
  5. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/__ws_wrapper.py +31 -1
  6. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_ws_wrapper.py +74 -0
  7. {mistapi-0.63.0 → mistapi-0.63.1}/uv.lock +1 -1
  8. {mistapi-0.63.0 → mistapi-0.63.1}/.claude/settings.local.json +0 -0
  9. {mistapi-0.63.0 → mistapi-0.63.1}/.dccache +0 -0
  10. {mistapi-0.63.0 → mistapi-0.63.1}/.gitattributes +0 -0
  11. {mistapi-0.63.0 → mistapi-0.63.1}/.github/workflows/test.yml +0 -0
  12. {mistapi-0.63.0 → mistapi-0.63.1}/.gitignore +0 -0
  13. {mistapi-0.63.0 → mistapi-0.63.1}/.gitmodules +0 -0
  14. {mistapi-0.63.0 → mistapi-0.63.1}/.idea/.gitignore +0 -0
  15. {mistapi-0.63.0 → mistapi-0.63.1}/.idea/modules.xml +0 -0
  16. {mistapi-0.63.0 → mistapi-0.63.1}/.idea/python_package.iml +0 -0
  17. {mistapi-0.63.0 → mistapi-0.63.1}/.idea/vcs.xml +0 -0
  18. {mistapi-0.63.0 → mistapi-0.63.1}/.pre-commit-config.yaml +0 -0
  19. {mistapi-0.63.0 → mistapi-0.63.1}/.vscode/settings.json +0 -0
  20. {mistapi-0.63.0 → mistapi-0.63.1}/LICENSE +0 -0
  21. {mistapi-0.63.0 → mistapi-0.63.1}/Makefile +0 -0
  22. {mistapi-0.63.0 → mistapi-0.63.1}/README.md +0 -0
  23. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/._readme/img/get.png +0 -0
  24. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/._readme/img/main.png +0 -0
  25. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/._readme/img/post.png +0 -0
  26. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/._readme/img/thumbnail_get.jpg +0 -0
  27. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/._readme/img/thumbnail_main.jpg +0 -0
  28. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/._readme/img/thumbnail_post.jpg +0 -0
  29. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/.github/copilot-instructions.md +0 -0
  30. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/.gitignore +0 -0
  31. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/CHANGELOG.md +0 -0
  32. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/LICENSE +0 -0
  33. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/README.md +0 -0
  34. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/mist.openapi.json +0 -0
  35. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/mist.openapi.yaml +0 -0
  36. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/mist.postman.json +0 -0
  37. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/mist.postman.v2.json +0 -0
  38. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/mist.postman_env.json +0 -0
  39. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/tools/README.md +0 -0
  40. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/tools/api-doc-diff.sh +0 -0
  41. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/.apimaticvscodeignore +0 -0
  42. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/.idea/.gitignore +0 -0
  43. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/.idea/modules.xml +0 -0
  44. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/.idea/vcs.xml +0 -0
  45. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/.idea/workdir.iml +0 -0
  46. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/APIMATIC-META.json +0 -0
  47. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a1_process.py +0 -0
  48. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a2_postman_postprocess.py +0 -0
  49. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a3_doc_xtags.py +0 -0
  50. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a4_check_tag_description.py +0 -0
  51. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a5_check_tag_response.py +0 -0
  52. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a6_check_response_header.py +0 -0
  53. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/a7_additionalProperties.py +0 -0
  54. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/add_enum_desc.py +0 -0
  55. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/audit_description_coherence.py +0 -0
  56. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/check_descriptions.py +0 -0
  57. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/check_null.py +0 -0
  58. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/generate.sh +0 -0
  59. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/mist.postman_usage.json +0 -0
  60. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/openapi.yaml +0 -0
  61. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/spec_references.py +0 -0
  62. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/spec_references.yaml +0 -0
  63. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/test_query_param_commas.py +0 -0
  64. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/validate.sh +0 -0
  65. {mistapi-0.63.0 → mistapi-0.63.1}/mist_openapi/workdir/websocket_samples/show_route.md +0 -0
  66. {mistapi-0.63.0 → mistapi-0.63.1}/scripts/generate.sh +0 -0
  67. {mistapi-0.63.0 → mistapi-0.63.1}/scripts/generate_from_openapi.py +0 -0
  68. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__api_request.py +0 -0
  69. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__api_response.py +0 -0
  70. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__api_session.py +0 -0
  71. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__init__.py +0 -0
  72. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__logger.py +0 -0
  73. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__models/__init__.py +0 -0
  74. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__models/privilege.py +0 -0
  75. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/__pagination.py +0 -0
  76. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/__init__.py +0 -0
  77. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/__init__.py +0 -0
  78. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/__init__.py +0 -0
  79. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/alarm_defs.py +0 -0
  80. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/ap_channels.py +0 -0
  81. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/ap_esl_versions.py +0 -0
  82. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/ap_led_status.py +0 -0
  83. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/app_categories.py +0 -0
  84. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/app_subcategories.py +0 -0
  85. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/applications.py +0 -0
  86. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/client_events.py +0 -0
  87. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/countries.py +0 -0
  88. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/default_gateway_config.py +0 -0
  89. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/device_events.py +0 -0
  90. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/device_models.py +0 -0
  91. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/fingerprint_types.py +0 -0
  92. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/gateway_applications.py +0 -0
  93. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/insight_metrics.py +0 -0
  94. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/languages.py +0 -0
  95. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/license_types.py +0 -0
  96. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/marvisclient_versions.py +0 -0
  97. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/mxedge_events.py +0 -0
  98. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/mxedge_models.py +0 -0
  99. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/nac_events.py +0 -0
  100. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/otherdevice_events.py +0 -0
  101. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/otherdevice_models.py +0 -0
  102. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/states.py +0 -0
  103. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/system_events.py +0 -0
  104. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/traffic_types.py +0 -0
  105. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/const/webhook_topics.py +0 -0
  106. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/__init__.py +0 -0
  107. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/__init__.py +0 -0
  108. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/alarmtemplates.py +0 -0
  109. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/deviceprofiles.py +0 -0
  110. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/devices.py +0 -0
  111. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/rftemplates.py +0 -0
  112. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/sitegroups.py +0 -0
  113. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/orgs/sites.py +0 -0
  114. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/sites/__init__.py +0 -0
  115. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/installer/sites/optimize.py +0 -0
  116. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/invite/__init__.py +0 -0
  117. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/invite/verify.py +0 -0
  118. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/login/__init__.py +0 -0
  119. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/login/login.py +0 -0
  120. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/login/lookup.py +0 -0
  121. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/login/oauth.py +0 -0
  122. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/login/two_factor.py +0 -0
  123. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/logout/__init__.py +0 -0
  124. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/logout/logout.py +0 -0
  125. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/mobile/__init__.py +0 -0
  126. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/mobile/verify.py +0 -0
  127. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/__init__.py +0 -0
  128. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/admins.py +0 -0
  129. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/claim.py +0 -0
  130. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/insights.py +0 -0
  131. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/inventory.py +0 -0
  132. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/invites.py +0 -0
  133. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/licenses.py +0 -0
  134. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/logo.py +0 -0
  135. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/logs.py +0 -0
  136. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/msps.py +0 -0
  137. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/orggroups.py +0 -0
  138. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/orgs.py +0 -0
  139. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/search.py +0 -0
  140. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/ssoroles.py +0 -0
  141. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/ssos.py +0 -0
  142. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/stats.py +0 -0
  143. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/suggestion.py +0 -0
  144. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/msps/tickets.py +0 -0
  145. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/__init__.py +0 -0
  146. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/aamwprofiles.py +0 -0
  147. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/admins.py +0 -0
  148. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/alarms.py +0 -0
  149. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/alarmtemplates.py +0 -0
  150. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/aos.py +0 -0
  151. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/apitokens.py +0 -0
  152. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/aptemplates.py +0 -0
  153. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/assetfilters.py +0 -0
  154. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/assets.py +0 -0
  155. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/avprofiles.py +0 -0
  156. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/cert.py +0 -0
  157. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/claim.py +0 -0
  158. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/claims.py +0 -0
  159. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/clients.py +0 -0
  160. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/clone.py +0 -0
  161. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/crl.py +0 -0
  162. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/deviceprofiles.py +0 -0
  163. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/devices.py +0 -0
  164. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/events.py +0 -0
  165. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/evpn_topologies.py +0 -0
  166. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/exports.py +0 -0
  167. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/gatewaytemplates.py +0 -0
  168. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/guests.py +0 -0
  169. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/idpprofiles.py +0 -0
  170. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/insights.py +0 -0
  171. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/inventory.py +0 -0
  172. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/invites.py +0 -0
  173. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/jsi.py +0 -0
  174. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/licenses.py +0 -0
  175. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/logs.py +0 -0
  176. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/maps.py +0 -0
  177. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/marvisclients.py +0 -0
  178. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/marvisinvites.py +0 -0
  179. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/mist_nac.py +0 -0
  180. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/mxclusters.py +0 -0
  181. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/mxedges.py +0 -0
  182. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/mxtunnels.py +0 -0
  183. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/nac_clients.py +0 -0
  184. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/nacportals.py +0 -0
  185. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/nacrules.py +0 -0
  186. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/nactags.py +0 -0
  187. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/networks.py +0 -0
  188. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/networktemplates.py +0 -0
  189. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/ocdevices.py +0 -0
  190. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/orgs.py +0 -0
  191. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/otherdevices.py +0 -0
  192. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/pcaps.py +0 -0
  193. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/pma.py +0 -0
  194. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/pskportals.py +0 -0
  195. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/psks.py +0 -0
  196. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/rftemplates.py +0 -0
  197. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/sdkclients.py +0 -0
  198. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/sdkinvites.py +0 -0
  199. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/sdktemplates.py +0 -0
  200. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/secintelprofiles.py +0 -0
  201. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/secpolicies.py +0 -0
  202. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/servicepolicies.py +0 -0
  203. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/services.py +0 -0
  204. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/setting.py +0 -0
  205. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/sitegroups.py +0 -0
  206. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/sites.py +0 -0
  207. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/sitetemplates.py +0 -0
  208. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/ssl_proxy_cert.py +0 -0
  209. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/ssoroles.py +0 -0
  210. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/ssos.py +0 -0
  211. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/ssr.py +0 -0
  212. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/stats.py +0 -0
  213. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/subscriptions.py +0 -0
  214. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/templates.py +0 -0
  215. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/tickets.py +0 -0
  216. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/troubleshoot.py +0 -0
  217. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/uisettings.py +0 -0
  218. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/usermacs.py +0 -0
  219. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/vars.py +0 -0
  220. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/vpns.py +0 -0
  221. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wan_client.py +0 -0
  222. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wan_clients.py +0 -0
  223. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/webhooks.py +0 -0
  224. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wired_clients.py +0 -0
  225. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wlans.py +0 -0
  226. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wxrules.py +0 -0
  227. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wxtags.py +0 -0
  228. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/orgs/wxtunnels.py +0 -0
  229. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/recover/__init__.py +0 -0
  230. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/recover/recover.py +0 -0
  231. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/recover/verify.py +0 -0
  232. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/register/__init__.py +0 -0
  233. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/register/recaptcha.py +0 -0
  234. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/register/register.py +0 -0
  235. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/register/verify.py +0 -0
  236. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/__init__.py +0 -0
  237. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/apitokens.py +0 -0
  238. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/login_failures.py +0 -0
  239. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/logs.py +0 -0
  240. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/oauth.py +0 -0
  241. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/self.py +0 -0
  242. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/subscriptions.py +0 -0
  243. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/two_factor.py +0 -0
  244. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/update.py +0 -0
  245. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/self/usage.py +0 -0
  246. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/__init__.py +0 -0
  247. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/aamwprofiles.py +0 -0
  248. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/alarms.py +0 -0
  249. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/analyze_spectrum.py +0 -0
  250. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/anomaly.py +0 -0
  251. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/apply_auto_map_assignment.py +0 -0
  252. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/apps.py +0 -0
  253. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/aptemplates.py +0 -0
  254. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/assetfilters.py +0 -0
  255. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/assets.py +0 -0
  256. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/auto_map_assignment.py +0 -0
  257. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/avprofiles.py +0 -0
  258. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/beacons.py +0 -0
  259. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/clear_auto_map_assignment.py +0 -0
  260. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/clients.py +0 -0
  261. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/count.py +0 -0
  262. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/deviceprofiles.py +0 -0
  263. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/devices.py +0 -0
  264. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/events.py +0 -0
  265. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/evpn_topologies.py +0 -0
  266. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/gatewaytemplates.py +0 -0
  267. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/guests.py +0 -0
  268. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/idpprofiles.py +0 -0
  269. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/insights.py +0 -0
  270. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/iotendpoints.py +0 -0
  271. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/licenses.py +0 -0
  272. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/location.py +0 -0
  273. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/maps.py +0 -0
  274. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/mapstacks.py +0 -0
  275. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/marvis_configs.py +0 -0
  276. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/mxedges.py +0 -0
  277. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/mxtunnels.py +0 -0
  278. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/nac_clients.py +0 -0
  279. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/networks.py +0 -0
  280. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/networktemplates.py +0 -0
  281. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/otherdevices.py +0 -0
  282. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/pcaps.py +0 -0
  283. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/psks.py +0 -0
  284. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/rfdiags.py +0 -0
  285. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/rftemplates.py +0 -0
  286. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/rogues.py +0 -0
  287. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/rrm.py +0 -0
  288. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/rssizones.py +0 -0
  289. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/secintelprofiles.py +0 -0
  290. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/servicepolicies.py +0 -0
  291. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/services.py +0 -0
  292. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/setting.py +0 -0
  293. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/sites.py +0 -0
  294. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/sitetemplates.py +0 -0
  295. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/skyatp.py +0 -0
  296. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/sle.py +0 -0
  297. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/ssr.py +0 -0
  298. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/stats.py +0 -0
  299. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/subscriptions.py +0 -0
  300. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/synthetic_test.py +0 -0
  301. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/uisettings.py +0 -0
  302. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/vbeacons.py +0 -0
  303. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/visits.py +0 -0
  304. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/vpns.py +0 -0
  305. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wan_client.py +0 -0
  306. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wan_clients.py +0 -0
  307. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wan_usages.py +0 -0
  308. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/webhooks.py +0 -0
  309. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wired_clients.py +0 -0
  310. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wlans.py +0 -0
  311. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wxrules.py +0 -0
  312. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wxtags.py +0 -0
  313. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/wxtunnels.py +0 -0
  314. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/sites/zones.py +0 -0
  315. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/utils/__init__.py +0 -0
  316. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/utils/test_smsglobal.py +0 -0
  317. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/utils/test_telstra.py +0 -0
  318. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/api/v1/utils/test_twilio.py +0 -0
  319. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/cli.py +0 -0
  320. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__init__.py +0 -0
  321. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/__common.py +0 -0
  322. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/__init__.py +0 -0
  323. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/arp.py +0 -0
  324. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/bgp.py +0 -0
  325. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/bpdu.py +0 -0
  326. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/dhcp.py +0 -0
  327. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/dns.py +0 -0
  328. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/dot1x.py +0 -0
  329. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/mac.py +0 -0
  330. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/miscellaneous.py +0 -0
  331. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/ospf.py +0 -0
  332. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/policy.py +0 -0
  333. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/port.py +0 -0
  334. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/remote_capture.py +0 -0
  335. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/routes.py +0 -0
  336. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/service_path.py +0 -0
  337. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/sessions.py +0 -0
  338. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/__tools/shell.py +0 -0
  339. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/ap.py +0 -0
  340. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/ex.py +0 -0
  341. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/srx.py +0 -0
  342. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/device_utils/ssr.py +0 -0
  343. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/websockets/__init__.py +0 -0
  344. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/websockets/__ws_client.py +0 -0
  345. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/websockets/location.py +0 -0
  346. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/websockets/orgs.py +0 -0
  347. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/websockets/session.py +0 -0
  348. {mistapi-0.63.0 → mistapi-0.63.1}/src/mistapi/websockets/sites.py +0 -0
  349. {mistapi-0.63.0 → mistapi-0.63.1}/tests/__init__.py +0 -0
  350. {mistapi-0.63.0 → mistapi-0.63.1}/tests/conftest.py +0 -0
  351. {mistapi-0.63.0 → mistapi-0.63.1}/tests/fixtures/__init__.py +0 -0
  352. {mistapi-0.63.0 → mistapi-0.63.1}/tests/fixtures/mock_responses.py +0 -0
  353. {mistapi-0.63.0 → mistapi-0.63.1}/tests/fixtures/test_data.py +0 -0
  354. {mistapi-0.63.0 → mistapi-0.63.1}/tests/integration/__init__.py +0 -0
  355. {mistapi-0.63.0 → mistapi-0.63.1}/tests/integration/test_api_endpoints.py +0 -0
  356. {mistapi-0.63.0 → mistapi-0.63.1}/tests/integration/test_authentication_flow.py +0 -0
  357. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/__init__.py +0 -0
  358. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_api_request.py +0 -0
  359. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_api_response.py +0 -0
  360. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_api_session.py +0 -0
  361. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_cli.py +0 -0
  362. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_init.py +0 -0
  363. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_logger.py +0 -0
  364. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_models.py +0 -0
  365. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_pagination.py +0 -0
  366. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_shell.py +0 -0
  367. {mistapi-0.63.0 → mistapi-0.63.1}/tests/unit/test_websocket_client.py +0 -0
@@ -1,4 +1,24 @@
1
1
  # CHANGELOG
2
+ ## Version 0.63.1 (June 2026)
3
+
4
+ **Released**: June 14, 2026
5
+
6
+ This patch release lets callers of the device-utility helpers detect WebSocket failures that were previously only logged.
7
+
8
+ ---
9
+
10
+ ### 1. BUG FIXES
11
+
12
+ #### **Device Utilities: surface WebSocket errors on `UtilResponse`**
13
+ `UtilResponse` now exposes `ws_error` and `ws_close_code` so callers can distinguish a clean WebSocket completion from an errored, abnormally-closed, or never-started one. Previously a WebSocket transport error was only logged and discarded, and a WS-backed command whose WebSocket failed to start was indistinguishable from a healthy trigger-only command.
14
+ - `_on_error` records the first transport error (was a discard-only callback).
15
+ - `_on_close` records the close status code and flags a non-1000 abnormal close.
16
+ - `start_with_trigger` records `ws_error` when the WebSocket factory returns `None` or raises during setup.
17
+
18
+ Additive and backward-compatible: `ws_error` stays `None` on a clean completion or a trigger-only command. (#29)
19
+
20
+ ---
21
+
2
22
  ## Version 0.63.0 (June 2026)
3
23
 
4
24
  **Released**: June 12, 2026
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mistapi
3
- Version: 0.63.0
3
+ Version: 0.63.1
4
4
  Summary: Python package to simplify the Mist System APIs usage
5
5
  Project-URL: Source, https://github.com/tmunzer/mistapi_python
6
6
  Project-URL: Bug Tracker, https://github.com/tmunzer/mistapi_python/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mistapi"
7
- version = "0.63.0"
7
+ version = "0.63.1"
8
8
  authors = [{ name = "Thomas Munzer", email = "tmunzer@juniper.net" }]
9
9
  description = "Python package to simplify the Mist System APIs usage"
10
10
  keywords = ["Mist", "Juniper", "API"]
@@ -1,2 +1,2 @@
1
- __version__ = "0.63.0"
1
+ __version__ = "0.63.1"
2
2
  __author__ = "Thomas Munzer <tmunzer@juniper.net>"
@@ -219,6 +219,13 @@ class UtilResponse:
219
219
  self.ws_required: bool = False
220
220
  self.ws_data: list[str] = []
221
221
  self.ws_raw_events: list[str] = []
222
+ # Set when the WebSocket leg did NOT complete cleanly (transport error,
223
+ # abnormal close, or failure to start). Stays None on a clean completion or
224
+ # a trigger-only command, so `ws_error is not None` is a reliable
225
+ # "did not cleanly confirm" signal for consumers. ws_close_code records the
226
+ # WebSocket close status code when one was received.
227
+ self.ws_error: str | None = None
228
+ self.ws_close_code: int | None = None
222
229
  self._queue: queue.Queue[str | None] = queue.Queue()
223
230
  self._closed = threading.Event()
224
231
  self._await_timeout: float | None = None
@@ -349,8 +356,22 @@ class WebSocketWrapper:
349
356
  # Start the max duration timer
350
357
  self._timeout_handler(Timer.MAX_DURATION, TimerAction.START)
351
358
 
359
+ def _on_error(self, error):
360
+ LOGGER.error("Error: %s", error)
361
+ # Record the first WebSocket transport error so a consumer can tell an
362
+ # errored stream from a clean one (otherwise the error is only logged).
363
+ if self.util_response.ws_error is None:
364
+ self.util_response.ws_error = str(error)
365
+
352
366
  def _on_close(self, code, msg):
353
367
  LOGGER.info("WebSocket closed: %s - %s", code, msg)
368
+ self.util_response.ws_close_code = code
369
+ # An abnormal close (anything other than a normal 1000 / no-status close)
370
+ # is recorded as an error so a clean completion is distinguishable.
371
+ if code is not None and code != 1000 and self.util_response.ws_error is None:
372
+ self.util_response.ws_error = (
373
+ f"WebSocket closed abnormally (code {code}): {msg}"
374
+ )
354
375
  self._stop_all_timers()
355
376
  self.util_response._queue.put(None) # sentinel for receive()
356
377
  self.util_response._closed.set() # signal completion
@@ -507,7 +528,7 @@ class WebSocketWrapper:
507
528
  """
508
529
  self.ws = ws
509
530
  ws.on_message(self._handle_message)
510
- ws.on_error(lambda error: LOGGER.error("Error: %s", error))
531
+ ws.on_error(self._on_error)
511
532
  ws.on_close(self._on_close)
512
533
  ws.on_open(self._on_open)
513
534
 
@@ -564,6 +585,11 @@ class WebSocketWrapper:
564
585
  self.start(ws)
565
586
  return # start() / _on_close manages _closed
566
587
  LOGGER.error("WS factory returned None")
588
+ # The WebSocket leg was expected but never started; record it so
589
+ # consumers don't mistake this for a clean trigger-only completion.
590
+ # Guarded (first-write-wins) to match _on_error / _on_close.
591
+ if self.util_response.ws_error is None:
592
+ self.util_response.ws_error = "WebSocket factory returned None"
567
593
  else:
568
594
  LOGGER.error(
569
595
  "Failed to trigger command: %s - %s",
@@ -572,6 +598,10 @@ class WebSocketWrapper:
572
598
  )
573
599
  except Exception as e:
574
600
  LOGGER.error("Error during trigger: %s", e)
601
+ # This except also wraps trigger_fn(), so the message stays neutral
602
+ # rather than implying the failure was always in WebSocket setup.
603
+ if self.util_response.ws_error is None:
604
+ self.util_response.ws_error = f"trigger/WebSocket setup error: {e}"
575
605
  # Mark done (failure or WS factory returned None)
576
606
  self.util_response._queue.put(None)
577
607
  self.util_response._closed.set()
@@ -183,3 +183,77 @@ class TestVT100Screen:
183
183
  rendered = s.render()
184
184
  assert rendered == "A"
185
185
  assert not rendered.endswith(" ")
186
+
187
+
188
+ # ------------------------------------------------------------------
189
+ # ws_error / ws_close_code (issue #29): let consumers distinguish a clean
190
+ # WebSocket completion from an errored / abnormal / never-started one.
191
+ # ------------------------------------------------------------------
192
+ class TestUtilResponseWsErrorDefaults:
193
+ def test_defaults_are_none(self) -> None:
194
+ r = UtilResponse()
195
+ assert r.ws_error is None
196
+ assert r.ws_close_code is None
197
+
198
+
199
+ class TestOnError:
200
+ def test_records_first_error(self) -> None:
201
+ w = _make_wrapper()
202
+ w._on_error(Exception("boom"))
203
+ assert w.util_response.ws_error == "boom"
204
+
205
+ def test_does_not_overwrite_existing(self) -> None:
206
+ w = _make_wrapper()
207
+ w._on_error(Exception("first"))
208
+ w._on_error(Exception("second"))
209
+ assert w.util_response.ws_error == "first"
210
+
211
+
212
+ class TestOnClose:
213
+ def test_normal_close_is_clean(self) -> None:
214
+ w = _make_wrapper()
215
+ w._on_close(1000, "")
216
+ assert w.util_response.ws_close_code == 1000
217
+ assert w.util_response.ws_error is None
218
+
219
+ def test_abnormal_close_sets_error(self) -> None:
220
+ w = _make_wrapper()
221
+ w._on_close(1006, "abnormal closure")
222
+ assert w.util_response.ws_close_code == 1006
223
+ assert "1006" in (w.util_response.ws_error or "")
224
+
225
+ def test_no_status_close_is_not_flagged(self) -> None:
226
+ w = _make_wrapper()
227
+ w._on_close(None, "")
228
+ assert w.util_response.ws_close_code is None
229
+ assert w.util_response.ws_error is None
230
+
231
+
232
+ class TestStartWithTriggerWsError:
233
+ """A WS-backed command whose WebSocket never starts must record ws_error so it
234
+ is not mistaken for a clean trigger-only completion."""
235
+
236
+ @staticmethod
237
+ def _trigger(status: int = 200, data=None):
238
+ return Mock(status_code=status, data=data if data is not None else {})
239
+
240
+ def test_ws_factory_returning_none_sets_ws_error(self) -> None:
241
+ w = _make_wrapper()
242
+ w.start_with_trigger(
243
+ trigger_fn=lambda: self._trigger(),
244
+ ws_factory_fn=lambda trigger: None,
245
+ )
246
+ w.util_response.wait(timeout=5)
247
+ assert w.util_response.done
248
+ assert w.util_response.ws_required is False # WS never started
249
+ assert w.util_response.ws_error == "WebSocket factory returned None"
250
+
251
+ def test_ws_factory_raising_sets_ws_error(self) -> None:
252
+ def boom(trigger):
253
+ raise RuntimeError("factory kaboom")
254
+
255
+ w = _make_wrapper()
256
+ w.start_with_trigger(trigger_fn=lambda: self._trigger(), ws_factory_fn=boom)
257
+ w.util_response.wait(timeout=5)
258
+ assert w.util_response.done
259
+ assert "factory kaboom" in (w.util_response.ws_error or "")
@@ -567,7 +567,7 @@ wheels = [
567
567
 
568
568
  [[package]]
569
569
  name = "mistapi"
570
- version = "0.63.0"
570
+ version = "0.63.1"
571
571
  source = { editable = "." }
572
572
  dependencies = [
573
573
  { name = "deprecation" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes