Conversation
There was a problem hiding this comment.
Pull request overview
Bumps mistapi to 0.61.4 and ships updates around WebSocket reconnection behavior plus APISession authentication hardening (including 2FA flow adjustments), along with corresponding release notes.
Changes:
- Add
max_reconnect_backoffand allowmax_reconnect_attempts=0(unlimited) across WebSocket wrappers and core reconnect loop. - Harden
APISessionbehavior: log credential overrides, clear stored password after successful login, adjust 2FA flow endpoint usage, and restrict_getself()attribute assignment. - Release housekeeping: version bumps (
pyproject.toml,__version.py,uv.lock), changelog entry, and submodule tracking update.
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/mistapi/websockets/__ws_client.py |
Implements capped exponential backoff + unlimited reconnect attempts semantics in reconnect loop. |
src/mistapi/websockets/sites.py |
Propagates new reconnect parameter through site websocket wrappers. |
src/mistapi/websockets/orgs.py |
Propagates new reconnect parameter through org websocket wrappers. |
src/mistapi/websockets/location.py |
Propagates new reconnect parameter through location websocket wrappers. |
src/mistapi/websockets/session.py |
Adds new reconnect parameter to SessionWithUrl. |
tests/unit/test_websocket_client.py |
Minor formatting change to an existing unit test signature. |
src/mistapi/__api_session.py |
Adds override logging, clears password on successful login, revises 2FA flow, and restricts _getself() attribute setting. |
src/mistapi/api/v1/sites/sle.py |
Updates deprecation current_version fields to 0.61.4. |
src/mistapi/__version.py |
Version bump to 0.61.4. |
pyproject.toml |
Project version bump to 0.61.4. |
uv.lock |
Lockfile version bump to 0.61.4. |
CHANGELOG.md |
Adds 0.61.4 release notes describing websocket + auth changes. |
.gitmodules |
Changes mist_openapi submodule branch from a pinned version branch to master. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| auto_reconnect: bool = False, | ||
| max_reconnect_attempts: int = 5, | ||
| reconnect_backoff: float = 2.0, | ||
| max_reconnect_backoff: float | None = None, | ||
| queue_maxsize: int = 0, | ||
| ) -> None: | ||
| if max_reconnect_attempts < 0: | ||
| raise ValueError("max_reconnect_attempts must be >= 0") | ||
| raise ValueError("max_reconnect_attempts must be >= 0 (0 = unlimited)") | ||
| if reconnect_backoff <= 0: | ||
| raise ValueError("reconnect_backoff must be > 0") | ||
| if max_reconnect_backoff is not None and max_reconnect_backoff <= 0: | ||
| raise ValueError("max_reconnect_backoff must be > 0") |
There was a problem hiding this comment.
New reconnect behavior (unlimited attempts when max_reconnect_attempts=0 and capped delay via max_reconnect_backoff) is introduced here, but the unit tests don’t cover either case. Add tests that (1) verify the attempt limit is not enforced when max_reconnect_attempts=0 and (2) verify delay is capped when max_reconnect_backoff is set (e.g., by patching Event.wait / logger to observe the computed timeout).
| auto_reconnect: bool = False, | ||
| max_reconnect_attempts: int = 5, | ||
| reconnect_backoff: float = 2.0, | ||
| max_reconnect_backoff: float | None = None, | ||
| queue_maxsize: int = 0, |
There was a problem hiding this comment.
The constructor docstring documents max_reconnect_attempts/reconnect_backoff but doesn’t mention the newly added max_reconnect_backoff parameter (or that max_reconnect_attempts=0 means unlimited). Please update the parameter docs to match the signature so users discover the new option via help()/docs.
| ping_interval: int = 30, | ||
| ping_timeout: int = 10, | ||
| auto_reconnect: bool = False, | ||
| max_reconnect_attempts: int = 5, | ||
| reconnect_backoff: float = 2.0, | ||
| max_reconnect_backoff: float | None = None, | ||
| queue_maxsize: int = 0, | ||
| ) -> None: |
There was a problem hiding this comment.
This wrapper exposes the new max_reconnect_backoff parameter, but its docstring parameter list doesn’t document it (and also doesn’t note the updated semantics where max_reconnect_attempts=0 means unlimited). Please update the docstring for this class (and the other websocket wrappers updated similarly) so the public API docs stay accurate.
| "two_factor_verified", | ||
| "no_tracking", | ||
| "password_expiry", | ||
| "password_modified_time", |
There was a problem hiding this comment.
_getself() now only sets a small whitelist of keys via setattr(). This drops fields that the class already models/prints elsewhere (e.g., via_sso/phone/session_expiry in str), so those values will no longer reflect the /api/v1/self response. Either expand the whitelist to include the supported APISession attributes (at least those referenced by str/public API), or update str/attribute model to remove fields you no longer intend to populate.
| "password_modified_time", | |
| "password_modified_time", | |
| "via_sso", | |
| "phone", | |
| "session_expiry", |
| resp = self._session.post(self._url(uri), json=body) | ||
| if resp.status_code == 200: | ||
| LOGGER.info("apisession:_process_login:authentication successful!") | ||
| CONSOLE.info("Authentication successful!") | ||
| self._password = None | ||
| self._set_authenticated(True) |
There was a problem hiding this comment.
Password clearing after successful login is a security-sensitive behavior change and should be covered by unit tests. Add tests that ensure (a) _password is cleared after a successful /api/v1/login, and (b) the 2FA flow (login_with_return with two_factor) still succeeds using the new /api/v1/login/two_factor endpoint after the password has been cleared.
| path = mist_openapi | ||
| url = https://github.com/mistsys/mist_openapi.git | ||
| branch = 2602.1.8 No newline at end of file | ||
| branch = master No newline at end of file |
There was a problem hiding this comment.
Switching the mist_openapi submodule tracking from a versioned branch to master makes builds non-reproducible and can unexpectedly pull breaking API spec changes. Consider keeping this pinned to a specific release branch/tag/commit (or document why master is required) and reflect the spec version change in the changelog/release notes if it’s intentional.
| branch = master | |
| branch = v1.0.0 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Version 0.61.4 (April 2026)
Released: April 1, 2026
This release improves WebSocket reconnection, hardens credential handling, and fixes the two-factor authentication flow.
1. NEW FEATURES
Capped Reconnect Backoff (
max_reconnect_backoff)The
_MistWebsocketclient now supports amax_reconnect_backoffparameter to cap the exponential backoff delay during reconnection attempts:Unlimited Reconnect Attempts
Setting
max_reconnect_attempts=0now enables unlimited reconnection attempts:2. IMPROVEMENTS
Credential Override Logging
APISessionnow logs INFO-level messages when credentials (host, email, password, API token) are overridden by:Security: Password Cleared After Login
The stored password is now cleared from memory immediately after successful login authentication.
User Attribute Handling
_get_self()now only sets known user attributes (first_name,last_name,email,enable_two_factor,two_factor_verified,no_tracking,password_expiry,password_modified_time) instead of setting arbitrary response keys as object attributes.