Fix garth token serialization using TypeAdapter for Pydantic dataclasses
Garth's OAuth1Token and OAuth2Token are Pydantic dataclasses, not BaseModel subclasses, so they require TypeAdapter for serialization instead of model_dump(). Also adds user-friendly error handling for authentication failures. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,11 +10,15 @@ Usage:
|
|||||||
python3 garmin_auth.py
|
python3 garmin_auth.py
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import garth
|
import garth
|
||||||
|
from garth.auth_tokens import OAuth1Token, OAuth2Token
|
||||||
|
from garth.exc import GarthHTTPError
|
||||||
|
from pydantic import TypeAdapter
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("Error: garth library not installed.")
|
print("Error: garth library not installed.")
|
||||||
print("Please install it with: pip install garth")
|
print("Please install it with: pip install garth")
|
||||||
@@ -24,11 +28,25 @@ email = input("Garmin email: ")
|
|||||||
password = getpass("Garmin password: ")
|
password = getpass("Garmin password: ")
|
||||||
|
|
||||||
# MFA handled automatically - prompts if needed
|
# MFA handled automatically - prompts if needed
|
||||||
garth.login(email, password)
|
try:
|
||||||
|
garth.login(email, password)
|
||||||
|
except GarthHTTPError as e:
|
||||||
|
if "401" in str(e):
|
||||||
|
print("\nError: Invalid email or password.", file=sys.stderr)
|
||||||
|
else:
|
||||||
|
print(f"\nError: Authentication failed - {e}", file=sys.stderr)
|
||||||
|
exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\nError: {e}", file=sys.stderr)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# Serialize Pydantic dataclasses using TypeAdapter
|
||||||
|
oauth1_adapter = TypeAdapter(OAuth1Token)
|
||||||
|
oauth2_adapter = TypeAdapter(OAuth2Token)
|
||||||
|
|
||||||
tokens = {
|
tokens = {
|
||||||
"oauth1": garth.client.oauth1_token.model_dump(),
|
"oauth1": oauth1_adapter.dump_python(garth.client.oauth1_token, mode='json'),
|
||||||
"oauth2": garth.client.oauth2_token.model_dump(),
|
"oauth2": oauth2_adapter.dump_python(garth.client.oauth2_token, mode='json'),
|
||||||
"expires_at": garth.client.oauth2_token.expires_at
|
"expires_at": garth.client.oauth2_token.expires_at
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user