Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors device_utils to make WebSocket-based device utility functions non-blocking by running WebSocket connections in background threads. It also removes old duplicate module files that have been superseded by the __tools internal modules, and converts several incorrectly-marked async functions to synchronous.
Changes:
- Refactored
WebSocketWrapper.start()to run WebSocket connections in the background (run_in_background=True), withUtilResponsegainingreceive(),wait(),done,disconnect(), context manager, and__await__support for flexible consumption patterns. - Removed 9 old top-level
device_utilsmodule files (tools.py,sessions.py,service_path.py,port.py,policy.py,ospf.py,dot1x.py,dhcp.py,bpdu.py,bgp.py) that duplicated functionality now in__tools. - Converted
asyncfunctions (clear_error,clear_sessions,clear_hit_count) to synchronous, and added input validation formonitor_traffic.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Core refactor: non-blocking WS, new UtilResponse API (receive, wait, done, disconnect, context manager, await) |
src/mistapi/device_utils/__tools/miscellaneous.py |
Added isinstance check for monitor_traffic URL response |
src/mistapi/device_utils/__tools/bpdu.py |
async → sync |
src/mistapi/device_utils/__tools/dot1x.py |
async → sync |
src/mistapi/device_utils/__tools/policy.py |
async → sync |
src/mistapi/device_utils/__tools/mac.py |
Comment change (adds await to commented code) |
src/mistapi/device_utils/__tools/dns.py |
Comment change (adds await to commented code) |
src/mistapi/device_utils/ap.py |
Removed TracerouteProtocol re-export |
src/mistapi/device_utils/tools.py |
Deleted (old duplicate) |
src/mistapi/device_utils/sessions.py |
Deleted (old duplicate) |
src/mistapi/device_utils/service_path.py |
Deleted (old duplicate) |
src/mistapi/device_utils/port.py |
Deleted (old duplicate) |
src/mistapi/device_utils/policy.py |
Deleted (old duplicate) |
src/mistapi/device_utils/ospf.py |
Deleted (old duplicate) |
src/mistapi/device_utils/dot1x.py |
Deleted (old duplicate) |
src/mistapi/device_utils/dhcp.py |
Deleted (old duplicate) |
src/mistapi/device_utils/bpdu.py |
Deleted (old duplicate) |
src/mistapi/device_utils/bgp.py |
Deleted (old duplicate) |
README.md |
Updated documentation for new non-blocking API patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
…onous operations - Updated clear_sessions, clear_mac_table, and clear_learned_mac functions to utilize WebSocketWrapper for handling API calls and WebSocket events. - Enhanced logging for debugging purposes in various functions including ping, traceroute, and OSPF commands. - Removed synchronous trigger handling and replaced it with asynchronous WebSocket handling across multiple device utility functions. - Updated version number in uv.lock to 0.61.1.
- Fix SessionWithUrl to connect directly to the custom URL instead of subscribing to it as a channel on the standard stream endpoint - Extract shared Node enum into __common.py to eliminate duplication across 7 device utility modules - Add await timeout safety net to UtilResponse (bounded by max_duration) - Reduce receive() poll interval from 1s to 0.1s for lower tail latency - Remove redundant _closed.clear() in WebSocketWrapper.start() - Unify tcpdump_expression guard to use `is not None` in remote_capture - Fix CHANGELOG: correct channel class names, fix port_id keyword, remove duplicate version entries, reorder sections - Improve README async example comments to clarify concurrency model - Sanitize API token logging with _apitoken_sanitizer helper - Fix test mocks to match current APIResponse.raw_data (uses .text) - Update test for SessionWithUrl channel behavior
There was a problem hiding this comment.
Pull request overview
This PR (v0.61.1) refactors the device_utils module to make all device utility functions non-blocking, adds async support via mistapi.arun(), fixes several bugs (swapped API calls in dot1x/mac, file handle leaks, thread-safety for token rotation), improves API token log sanitization, and consolidates duplicate Node enums into a shared __common module.
Changes:
- Device utility functions now return
UtilResponseimmediately with background WebSocket streaming, supporting callbacks, generators, context managers, polling, and asyncawait - New
mistapi.arun()helper for running sync API calls in async contexts viaasyncio.to_thread() - Consolidation of duplicate code: shared
Nodeenum, centralized_apitoken_sanitizer, removal of legacy per-function modules in favor of__toolssubpackage
Reviewed changes
Copilot reviewed 43 out of 44 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/__api_session.py |
Extract _apitoken_sanitizer helper, replace inline token masking |
src/mistapi/__api_request.py |
Add thread lock for token rotation, fix file handle leak in mist_post_file |
src/mistapi/__api_response.py |
Use response.text instead of str(response.content) for raw_data |
src/mistapi/__init__.py |
Add arun() async helper |
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Major refactor: non-blocking UtilResponse with queue, start_with_trigger, background threading |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/*.py |
Refactor to use start_with_trigger, shared Node, improved logging |
src/mistapi/device_utils/{ap,ex,srx,ssr}.py |
Update re-exports, rename OSPF functions, add sessions |
src/mistapi/device_utils/{bgp,bpdu,...}.py (top-level) |
Deleted legacy modules |
src/mistapi/websockets/session.py |
Fix SessionWithUrl to use _build_ws_url() override |
README.md, CHANGELOG.md |
Document new async/non-blocking features |
| Version files | Bump to 0.61.1 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
This PR bumps the version to 0.61.1 and introduces several improvements: non-blocking device utilities with a new start_with_trigger pattern, an arun() async helper, consolidated Node enum, API token log sanitization, thread-safety for token rotation, and file handle leak fixes.
Changes:
- Device utility functions are now non-blocking — trigger + WebSocket runs in background threads, returning a
UtilResponseimmediately withreceive(),wait(),done,disconnect(), andawaitsupport - New
mistapi.arun()async helper wraps sync API calls inasyncio.to_thread(), plus_apitoken_sanitizerfor consistent token masking and file handle leak fix inmist_post_file - Consolidation of duplicated
Nodeenum into__common.py, renaming of OSPF exports (e.g.showDatabase→retrieveOspfDatabase), addition of sessions/OSPF summary to SSR/SRX modules, and removal of legacy per-function module files
Reviewed changes
Copilot reviewed 43 out of 44 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/__api_request.py |
Add _apitoken_sanitizer, _token_lock for thread-safe rotation, fix file handle leak |
src/mistapi/__api_session.py |
Use _apitoken_sanitizer throughout token logging |
src/mistapi/__api_response.py |
Use response.text instead of str(response.content) for raw_data |
src/mistapi/__init__.py |
Add arun() async helper |
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Non-blocking UtilResponse with queue/events, start_with_trigger method |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/*.py |
Refactor to use start_with_trigger, import shared Node, rename apissession → apisession |
src/mistapi/device_utils/{ssr,srx}.py |
Add sessions/OSPF summary exports, rename OSPF aliases |
src/mistapi/device_utils/{bgp,bpdu,dhcp,...}.py |
Remove legacy per-function modules (moved to __tools/) |
src/mistapi/websockets/session.py |
Fix SessionWithUrl to use _build_ws_url() instead of passing URL as channel |
README.md, CHANGELOG.md |
Document new features, fix class name references |
pyproject.toml, uv.lock, __version.py, sle.py |
Version bump to 0.61.1 |
tests/unit/test_*.py |
Update tests for raw_data and SessionWithUrl changes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| self._count: int = 0 | ||
| self._apitoken: list[str] = [] | ||
| self._apitoken_index: int = -1 | ||
| self._token_lock: threading.Lock = threading.Lock() |
- Add _VT100Screen class and ANSI escape stripping in WebSocketWrapper for rendering screen-based output (top, monitor interface) - Uncomment and refactor top_command() to use start_with_trigger pattern - Export topCommand from device_utils.ex and device_utils.srx - Handle binary WebSocket frames in _MistWebsocket._handle_message (null byte stripping, bytes→str decode, TypeError catch) - Fix first_message_timeout stop to check timer is active before stopping - Update README with new functions and print flush examples - Add unit tests for VT100 screen, ANSI stripping, and binary frames
There was a problem hiding this comment.
Pull request overview
This PR bumps mistapi from 0.61.0 to 0.61.1, introducing non-blocking device utilities, async support via mistapi.arun(), VT100 terminal emulation for screen-based command output, binary WebSocket frame handling, and various refactors including consolidating Node enums, renaming OSPF exports, token sanitization improvements, and file handle leak fixes.
Changes:
- Device utility functions now run trigger + WebSocket in background threads, returning
UtilResponseimmediately withreceive(),wait(),await, and context manager support - New
mistapi.arun()async helper, VT100 screen buffer for terminal output, binary frame decoding in WebSocket client, and thread-safe API token rotation - Consolidation of duplicate
Nodeenums into__common.py, deletion of legacy per-function modules, and renaming of OSPF public exports
Reviewed changes
Copilot reviewed 46 out of 48 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/__init__.py |
Adds arun() async helper |
src/mistapi/__api_request.py |
Adds _apitoken_sanitizer, thread-safe token rotation, file handle leak fix |
src/mistapi/__api_session.py |
Uses _apitoken_sanitizer for log masking |
src/mistapi/__api_response.py |
Uses response.text instead of str(response.content) |
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Adds _VT100Screen, ANSI stripping, non-blocking start()/start_with_trigger(), enhanced UtilResponse |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/*.py |
Refactored to use start_with_trigger() pattern |
src/mistapi/device_utils/{srx,ssr,ex}.py |
Updated exports, renamed OSPF functions, added topCommand/sessions |
src/mistapi/device_utils/{tools,sessions,port,...}.py |
Deleted legacy per-function public modules |
src/mistapi/websockets/__ws_client.py |
Handles binary WebSocket frames |
src/mistapi/websockets/session.py |
SessionWithUrl uses _build_ws_url() instead of channels |
tests/unit/test_ws_wrapper.py |
New tests for VT100 screen and ANSI stripping |
tests/unit/test_websocket_client.py |
Tests for binary frame handling |
README.md, CHANGELOG.md |
Documentation updates |
| Version files | Bump to 0.61.1 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
This PR (v0.61.1) is a significant refactor of the device_utils module, making all device utility functions non-blocking, adding async support via mistapi.arun(), introducing interactive shell sessions, and consolidating the Node enum into a shared __common module.
Changes:
- All device utility functions now use
start_with_trigger()to run API calls and WebSocket streams in background threads, returningUtilResponseimmediately with support for generators,await, and context managers - New
ShellSessionclass andinteractive_shell()for SSH-over-WebSocket access to EX/SRX devices, plus newmistapi.arun()async helper - Refactoring: consolidated duplicate
Nodeenums into__common.py, renamed OSPF exports (e.g.,showDatabase→retrieveOspfDatabase), removed legacy top-level modules (e.g.,device_utils/tools.py), added VT100 screen emulator, fixed file handle leaks, added thread-safety to token rotation
Reviewed changes
Copilot reviewed 48 out of 50 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/__init__.py |
Added arun() async helper |
src/mistapi/__api_request.py |
Token sanitizer, thread-safe rotation, file handle leak fix |
src/mistapi/__api_session.py |
Use _apitoken_sanitizer throughout |
src/mistapi/__api_response.py |
Use response.text instead of str(response.content) |
src/mistapi/__version.py, pyproject.toml, uv.lock |
Version bump to 0.61.1, add sshkeyboard dep |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/__ws_wrapper.py |
VT100 screen emulator, non-blocking start()/start_with_trigger(), enhanced UtilResponse |
src/mistapi/device_utils/__tools/shell.py |
New ShellSession and interactive_shell() |
src/mistapi/device_utils/__tools/*.py |
Refactored to use start_with_trigger() pattern |
src/mistapi/device_utils/{ap,ex,srx,ssr}.py |
Updated exports, renamed OSPF functions, added shell/sessions |
src/mistapi/device_utils/*.py (deleted) |
Removed legacy top-level modules |
src/mistapi/websockets/session.py |
SessionWithUrl stores URL separately, overrides _build_ws_url() |
src/mistapi/websockets/__ws_client.py |
Handle binary WebSocket frames |
tests/unit/*.py |
New tests for shell, ws_wrapper; updated existing tests |
README.md, CHANGELOG.md |
Comprehensive documentation updates |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| return WebSocketWrapper(apisession, util_response).start_with_trigger( | ||
| trigger_fn=lambda: devices.clearSiteDevicePolicyHitCount( | ||
| apisession, | ||
| site_id=site_id, | ||
| device_id=device_id, | ||
| body={"policy_name": policy_name}, | ||
| ), | ||
| ) |
| def _ws_factory(trigger): | ||
| if isinstance(trigger.data, dict) and "url" in trigger.data: | ||
| return SessionWithUrl(apisession, url=trigger.data.get("url", "")) | ||
| LOGGER.error("Top command command did not return a valid URL: %s", trigger.data) |
| elif key == "up": | ||
| k = "\x00\x1b[A" | ||
| elif key == "right": | ||
| k = "\x00\x1b[C" | ||
| elif key == "down": | ||
| k = "\x00\x1b[B" | ||
| elif key == "left": | ||
| k = "\x00\x1b[D" | ||
| elif key == "backspace": | ||
| k = "\x00\x7f" | ||
| else: | ||
| k = key | ||
| data = f"\x00{k}" | ||
| data_bytes = bytearray() | ||
| data_bytes.extend(map(ord, data)) | ||
| session.send(bytes(data_bytes)) |
There was a problem hiding this comment.
Pull request overview
This PR bumps the version to 0.61.1 and introduces several significant changes: non-blocking device utilities with UtilResponse supporting generators/await/callbacks, a new interactive SSH shell feature, arun() async helper, refactored internal modules (consolidating Node enum, renaming OSPF functions), token sanitization improvements, thread-safety for token rotation, file handle leak fix, VT100 screen buffer for terminal output, and binary WebSocket frame handling.
Changes:
- Device utilities are now non-blocking: trigger + WebSocket run in background threads,
UtilResponsesupportsreceive(),wait(),await, and context manager patterns - New
ShellSessionandinteractive_shell()for SSH-over-WebSocket access to EX/SRX devices, plusarun()async helper - Refactored internals: consolidated
Nodeenum to__common.py, renamed OSPF exports, fixed file handle leaks, added thread-safe token rotation, improved log sanitization
Reviewed changes
Copilot reviewed 48 out of 50 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/__init__.py |
Added arun() async helper |
src/mistapi/__api_request.py |
Added _apitoken_sanitizer, thread-safe token rotation, file handle leak fix |
src/mistapi/__api_session.py |
Use _apitoken_sanitizer for log masking |
src/mistapi/__api_response.py |
Use response.text instead of str(response.content) for raw_data |
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Major rewrite: VT100 screen, ANSI stripping, non-blocking start(), start_with_trigger(), enhanced UtilResponse |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/shell.py |
New ShellSession, create_shell_session, interactive_shell |
src/mistapi/device_utils/__tools/*.py |
Refactored to use start_with_trigger() pattern, consolidated Node import |
src/mistapi/device_utils/{ex,srx,ssr}.py |
Updated exports: renamed OSPF functions, added shell/sessions/topCommand |
src/mistapi/device_utils/*.py (deleted) |
Removed legacy function-based modules (bgp, bpdu, dhcp, etc.) |
src/mistapi/websockets/session.py |
SessionWithUrl stores URL separately, overrides _build_ws_url() |
src/mistapi/websockets/__ws_client.py |
Handle binary WebSocket frames |
tests/unit/* |
New tests for shell, VT100 screen, binary frames; updated API response tests |
pyproject.toml, uv.lock |
Version bump, added sshkeyboard dependency |
README.md, CHANGELOG.md |
Documentation updates |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| listen_keyboard( | ||
| on_release=_on_key_release, | ||
| delay_second_char=0, | ||
| delay_other_chars=0, | ||
| lower=False, | ||
| ) |
| data = bytearray() | ||
| data.extend(map(ord, f"\x00{text}")) | ||
| self.send(bytes(data)) | ||
|
|
There was a problem hiding this comment.
Pull request overview
This PR (v0.61.1) is a significant refactor of the mistapi device utilities module. It makes all device utility functions non-blocking by running triggers and WebSocket streams in background threads, adds VT100 terminal emulation for screen-based commands, introduces interactive SSH shell support for EX/SRX devices, adds an arun() async helper, and consolidates duplicate Node enums into a shared __common.py module. Several legacy wrapper modules are deleted in favor of the __tools implementations.
Changes:
- Device utility functions refactored to be non-blocking with new
start_with_trigger()pattern,UtilResponseenhanced withreceive(),wait(),disconnect(), and__await__support - New
ShellSessionandinteractive_shell()for SSH-over-WebSocket, new_VT100Screenfor terminal emulation, newarun()async helper - Various fixes: binary WebSocket frame handling, file handle leak in
mist_post_file, thread-safe token rotation,raw_datausingresponse.textinstead ofstr(response.content)
Reviewed changes
Copilot reviewed 48 out of 50 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Core refactor: added _VT100Screen, ANSI stripping, UtilResponse enhancements, start_with_trigger() |
src/mistapi/device_utils/__tools/shell.py |
New ShellSession and interactive_shell() for SSH-over-WebSocket |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/*.py |
Refactored to use start_with_trigger(), consolidated Node import |
src/mistapi/device_utils/{ex,srx,ssr}.py |
Updated exports, added shell/topCommand/OSPF renames |
src/mistapi/__init__.py |
Added arun() async helper |
src/mistapi/__api_request.py |
Token sanitizer, thread-safe rotation, file handle leak fix |
src/mistapi/__api_response.py |
raw_data changed from str(content) to response.text |
src/mistapi/__api_session.py |
Use _apitoken_sanitizer throughout |
src/mistapi/websockets/__ws_client.py |
Binary frame handling |
src/mistapi/websockets/session.py |
SessionWithUrl fix: store URL separately, override _build_ws_url |
src/mistapi/device_utils/{bgp,bpdu,dhcp,dot1x,ospf,policy,port,sessions,service_path,tools}.py |
Deleted legacy wrapper modules |
tests/unit/test_ws_wrapper.py |
New tests for VT100 screen and ANSI stripping |
tests/unit/test_shell.py |
New tests for ShellSession |
tests/unit/test_websocket_client.py |
Tests for binary frame handling, SessionWithUrl fix |
tests/unit/test_api_response.py |
Updated for raw_data change |
README.md, CHANGELOG.md |
Documentation updates |
pyproject.toml, uv.lock |
Version bump, sshkeyboard dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| mode changes are silently ignored. | ||
| """ | ||
|
|
||
| def __init__(self, rows: int = 80, cols: int = 200) -> None: |
There was a problem hiding this comment.
Pull request overview
This PR (v0.61.1) is a substantial refactoring of the device_utils module, making all device utility functions non-blocking by running API triggers and WebSocket streams in background threads. It also adds VT100 terminal emulation, interactive SSH shell support, async helpers, binary WebSocket frame handling, token sanitization improvements, and a file handle leak fix.
Changes:
- All device utility functions now return
UtilResponseimmediately (non-blocking), with a newstart_with_triggerpattern replacing the old synchronous trigger-then-stream approach. DuplicateNodeenums consolidated into__common.py. OSPF functions renamed (showDatabase→retrieveOspfDatabase, etc.). Legacy function-based modules deleted. - New features:
ShellSession/interactiveShell()for SSH-over-WebSocket,_VT100Screenfor screen-based command rendering,mistapi.arun()async helper, binary frame support in_handle_message,_apitoken_sanitizerfor log safety, thread-safe token rotation, file handle leak fix inmist_post_file. UtilResponseenhanced withreceive()generator,wait(),doneproperty,disconnect(), context manager, and__await__support.
Reviewed changes
Copilot reviewed 48 out of 50 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/device_utils/__tools/__ws_wrapper.py |
Core refactoring: added _VT100Screen, ANSI stripping, UtilResponse with async/generator/context manager support, start_with_trigger method |
src/mistapi/device_utils/__tools/shell.py |
New ShellSession class and interactive_shell() for SSH-over-WebSocket |
src/mistapi/device_utils/__tools/__common.py |
New shared Node enum |
src/mistapi/device_utils/__tools/*.py |
Refactored to use start_with_trigger, consolidated Node, renamed apissession → apisession |
src/mistapi/device_utils/{ex,srx,ssr}.py |
Updated exports: renamed OSPF functions, added shell/sessions/topCommand |
src/mistapi/device_utils/*.py (deleted) |
Removed legacy function-based modules (bgp, ospf, port, dhcp, etc.) |
src/mistapi/__init__.py |
Added arun() async helper |
src/mistapi/__api_request.py |
Added _apitoken_sanitizer, thread-safe token rotation, file handle leak fix |
src/mistapi/__api_session.py |
Uses _apitoken_sanitizer for log messages |
src/mistapi/__api_response.py |
raw_data now uses response.text instead of str(response.content) |
src/mistapi/websockets/__ws_client.py |
Binary frame handling in _handle_message |
src/mistapi/websockets/session.py |
SessionWithUrl stores URL separately, overrides _build_ws_url |
tests/unit/test_ws_wrapper.py |
New tests for ANSI stripping and VT100 screen rendering |
tests/unit/test_shell.py |
New tests for ShellSession and create_shell_session |
tests/unit/test_websocket_client.py |
Tests for binary frame handling |
tests/unit/test_api_response.py |
Updated for raw_data change |
pyproject.toml, uv.lock |
Version bump, added sshkeyboard dependency |
README.md, CHANGELOG.md |
Documentation updates |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Code reviewFound 1 issue:
mistapi_python/src/mistapi/device_utils/__tools/shell.py Lines 156 to 170 in 7f17b1b 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
No description provided.