diff --git a/pyecobee/__init__.py b/pyecobee/__init__.py index a99f155..0837bc2 100644 --- a/pyecobee/__init__.py +++ b/pyecobee/__init__.py @@ -93,9 +93,9 @@ def _generate_pkce_pair() -> tuple[str, str]: class MfaChallenge: """Opaque resumption state for an in-progress MFA-gated login. - Returned (via :class:`EcobeeAuthMfaRequiredError`) when ecobee Auth0 - interrupts the login flow with an MFA challenge. Pass this back into - :meth:`Ecobee.submit_mfa_code` along with the user-entered code to + Returned via :attr:`EcobeeAuthMfaRequiredError.challenge` when ecobee + Auth0 interrupts the login flow with an MFA challenge. Pass this back + into :meth:`Ecobee.submit_mfa_code` along with the user-entered code to complete the login and obtain tokens. """ diff --git a/pyecobee/errors.py b/pyecobee/errors.py index 0abcae2..1bc4899 100644 --- a/pyecobee/errors.py +++ b/pyecobee/errors.py @@ -26,11 +26,18 @@ class EcobeeAuthUnknownError(EcobeeError): class EcobeeAuthMfaRequiredError(EcobeeError): """Raised when ecobee Auth0 redirects to an MFA challenge during login. - Carries an :class:`~pyecobee.MfaChallenge` payload (in ``args[0]``) that - must be passed back into :meth:`Ecobee.submit_mfa_code` along with the - user-entered OTP code to resume the login flow. + Carries an :class:`~pyecobee.MfaChallenge` payload that must be passed + back into :meth:`Ecobee.submit_mfa_code` along with the user-entered OTP + code to resume the login flow. + + Prefer :attr:`challenge` over indexing ``args[0]``. """ + @property + def challenge(self): + """Return the :class:`~pyecobee.MfaChallenge` carried by this error.""" + return self.args[0] + # Sensor errors class InvalidSensorError(EcobeeError): diff --git a/setup.py b/setup.py index de7f9a4..4e9617e 100755 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ setup( name="python-ecobee-api", - version="0.4.1", + version="0.4.2", description="Python API for talking to Ecobee thermostats", url="https://github.com/nkgilley/python-ecobee-api", author="Nolan Gilley", diff --git a/tests/test_auth.py b/tests/test_auth.py index 4403ecd..7e1fb10 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -209,7 +209,8 @@ def test_request_tokens_web_mfa_required_raises_with_challenge( ecobee = _make_ecobee() with pytest.raises(EcobeeAuthMfaRequiredError) as exc_info: ecobee.request_tokens_web() - challenge = exc_info.value.args[0] + challenge = exc_info.value.challenge + assert challenge is exc_info.value.args[0] assert isinstance(challenge, MfaChallenge) assert challenge.mfa_type == "otp" assert challenge.state == "MFA_STATE_9" @@ -237,7 +238,8 @@ def test_request_tokens_web_sms_mfa_required_raises_with_challenge( ecobee = _make_ecobee() with pytest.raises(EcobeeAuthMfaRequiredError) as exc_info: ecobee.request_tokens_web() - challenge = exc_info.value.args[0] + challenge = exc_info.value.challenge + assert challenge is exc_info.value.args[0] assert isinstance(challenge, MfaChallenge) assert challenge.mfa_type == "sms" assert challenge.state == "SMS_STATE_7"