Skip to content

Add Token Restoration Support for Session Persistence#29

Merged
eman merged 4 commits intomainfrom
feature/token-restoration
Oct 27, 2025
Merged

Add Token Restoration Support for Session Persistence#29
eman merged 4 commits intomainfrom
feature/token-restoration

Conversation

@eman
Copy link
Copy Markdown
Owner

@eman eman commented Oct 27, 2025

Overview

This PR adds token restoration support to enable session persistence across application restarts. This reduces API load, improves startup time, and prevents rate limiting for frequently restarting applications (e.g., Home Assistant integrations).

Changes

Core Features

  • Token Restoration: Added stored_tokens parameter to NavienAuthClient.__init__() for restoring previously saved tokens
  • Token Serialization: Added AuthTokens.to_dict() method for serializing tokens (includes issued_at timestamp)
  • Enhanced Deserialization: Enhanced AuthTokens.from_dict() to support both API responses (camelCase) and stored data (snake_case)
  • Smart Authentication: Modified NavienAuthClient.__aenter__() to skip authentication when valid stored tokens are provided
  • Auto-Refresh: Automatically refreshes expired JWT tokens or re-authenticates if AWS credentials expired

Testing

  • Added 7 comprehensive tests covering:
    • Token serialization and deserialization
    • Stored tokens initialization
    • Context manager with valid stored tokens
    • JWT token refresh on expiry
    • Full re-authentication on AWS credential expiry

Documentation & Examples

  • Added examples/token_restoration_example.py demonstrating complete save/restore workflow
  • Updated authentication documentation in docs/python_api/auth_client.rst with token restoration guide
  • Added comprehensive CHANGELOG entry

Benefits

  • Reduced API Load: Skip unnecessary authentication requests
  • Faster Startup: Applications start immediately with cached tokens
  • Rate Limit Prevention: Avoid hitting API rate limits from frequent restarts
  • Better UX: Seamless session continuity for end users

Testing Performed

  • All existing tests pass
  • 7 new tests specifically for token restoration
  • Manual testing with example script

Breaking Changes

None - this is a backward-compatible addition. Existing code continues to work without modifications.

Related Issues

Addresses session persistence requirements for long-running applications and Home Assistant integrations.

eman added 2 commits October 27, 2025 14:18
- Add stored_tokens parameter to NavienAuthClient for restoring saved tokens
- Add AuthTokens.to_dict() for serializing tokens with issued_at timestamp
- Enhance AuthTokens.from_dict() to support both API and stored data formats
- Skip authentication when valid stored tokens provided
- Auto-refresh expired JWT tokens or re-authenticate if AWS creds expired
- Add 7 new tests covering token serialization and restoration flows
- Add examples/token_restoration_example.py demonstrating workflow
- Update authentication documentation with token restoration guide

Benefits:
- Reduces API load and improves startup time
- Prevents rate limiting for frequently restarting applications
- Enables session persistence across application restarts
- Replace manual token reconstruction with stored_tokens parameter
- Use AuthTokens.to_dict() and from_dict() for serialization
- Simplify token storage code by leveraging built-in methods
- Remove unnecessary manual validation logic
- Properly manage context manager lifecycle for auth client

Benefits:
- Cleaner, more maintainable code
- Automatic token refresh and AWS credential re-authentication
- Consistent with new token restoration pattern
@eman eman requested a review from Copilot October 27, 2025 22:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds token restoration support to enable session persistence across application restarts, reducing API load and preventing rate limiting for frequently restarting applications.

Key Changes

  • Added stored_tokens parameter to NavienAuthClient for restoring previously saved sessions
  • Implemented AuthTokens.to_dict() and enhanced from_dict() for token serialization/deserialization
  • Modified NavienAuthClient.__aenter__() to intelligently handle stored tokens with automatic refresh/re-authentication

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/nwp500/auth.py Implements core token restoration logic with serialization methods and smart authentication handling
tests/test_auth.py Adds 7 comprehensive tests covering token serialization, restoration, and expiration scenarios
src/nwp500/cli/token_storage.py Refactors CLI token storage to use new built-in serialization methods
src/nwp500/cli/__main__.py Updates CLI authentication flow to leverage stored tokens parameter
examples/token_restoration_example.py Provides complete example demonstrating token save/restore workflow
docs/python_api/auth_client.rst Documents token restoration feature with examples
CHANGELOG.rst Documents the new feature for version 4.8.0

auth_client = NavienAuthClient(email, password, stored_tokens=tokens)

# Enter the context manager to authenticate/restore session
await auth_client.__aenter__()
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually calling __aenter__() breaks the context manager pattern and can lead to resource leaks if an exception occurs before __aexit__() is called. Use the context manager properly with async with instead of manual enter/exit calls. If you need the client outside the context manager scope, refactor to use async with and return the client for use within that scope.

Copilot uses AI. Check for mistakes.
# Auth client close will close the underlying aiohttp session
await auth_client.close()
# Also call __aexit__ to properly clean up context manager
await auth_client.__aexit__(None, None, None)
Copy link

Copilot AI Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manually calling __aexit__() is error-prone and violates the context manager pattern. If __aenter__() was never called or failed, this will cause issues. Use async with to ensure proper resource management, or use a try/finally block with the manual calls to guarantee cleanup.

Copilot uses AI. Check for mistakes.
eman added 2 commits October 27, 2025 15:45
- Replace 'or' operator with explicit None/empty string checks
- Add helper function get_value() to correctly check both camelCase and snake_case
- Prevent empty strings in camelCase keys from blocking snake_case fallback
- Add test for empty string and None value handling

This fixes the issue where empty strings would be treated as truthy,
preventing the fallback to snake_case alternatives.
- Replace manual __aenter__/__aexit__ calls with async with context manager
- Eliminate error-prone manual context manager lifecycle management
- Move authentication logic directly into async_main()
- Remove now-unused get_authenticated_client() helper function
- Remove unused Optional import

Benefits:
- Guaranteed proper cleanup even on exceptions
- More Pythonic and follows best practices
- Simpler control flow with single entry point
- Eliminates potential resource leaks from failed __aenter__ calls
@eman eman merged commit 1b99bc7 into main Oct 27, 2025
10 checks passed
@eman eman deleted the feature/token-restoration branch October 27, 2025 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants