feat: replace garth with garminconnect for Garmin Connect uploads#79
Merged
Conversation
Garmin's Cloudflare TLS fingerprinting blocks garth's mobile user-agent, breaking OAuth token creation and all uploads. Replace with python-garminconnect v0.3.3+, which uses curl_cffi TLS impersonation and automatic fallback login strategies to bypass rate limiting. - Swap garth>=0.5.21 dependency for garminconnect>=0.3.3 - Rename get_garth_dir() to get_token_dir(); move token storage from user_cache_path to user_data_path so tokens survive cache wipes - Token directory prefix changes from .garth_<name> to .garmin_<name> - Rewrite upload() to use Garmin.login(tokenstore=) + upload_activity(); raise ValueError immediately for missing credentials instead of prompting interactively - Update --show-dirs output to show data directory and .garmin_* dirs - Remove garth-specific oauth1_auth logger suppression - Update tests: replace mock_garth_* fixtures with mock_garmin_client; update show-dirs tests for new directory names and locations
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #79 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 6 6
Lines 1238 1226 -12
=========================================
- Hits 1238 1226 -12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
docs: restore changelog.md (auto-generated on release, not committed manually)
de29fef to
1b9839c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Garmin changed their authentication flow to use Cloudflare TLS fingerprinting, which blocks
garth's mobile user-agent (GCM-iOS-5.7.2.1). This prevents OAuth tokens from being created, breaking all uploads. Also, as of now, thegarthproject is effectively archived and so we should no longer rely on it.This PR swaps out garth with
python-garminconnectfor authentication and uploading files.Closes #75.
Changes
garth>=0.5.21→garminconnect>=0.3.3get_garth_dir()→get_token_dir(): Token storage moved fromuser_cache_pathtouser_data_pathso tokens survive routine cache wipes; directory prefix changes from.garth_<name>to.garmin_<name>upload()rewritten: UsesGarmin(email, password).login(tokenstore=...)+upload_activity(); raisesValueErrorimmediately for missing credentials instead of prompting interactively--show-dirs: Now shows the data directory and lists.garmin_*token directoriesoauth1_authlogger suppression (garth-specific)mock_garth_*fixtures withmock_garmin_client; updated show-dirs tests for new directory names and locationsUpgrade behavior for users
.garth_*directories are left behind as orphaned dirs; they cause no harm but can be manually deletedgarminconnectautomatically falls back through multiple login strategies if rate-limited (429), so auth is resilientTest plan
ruff checkandruff formatpassfit-file-faker -u -d tests/files/mywhoosh_20260111.fitauthenticated successfully viawidget+cffifallback strategyfit-file-faker -u tests/files/mywhoosh_20260111.fituploaded successfully to Garmin Connect~/Library/Application Support/FitFileFaker/.garmin_<profile>/garmin_tokens.json