Context
garminconnect/__init__.py has grown to 2,957 lines containing the entire Garmin class with 132 public methods. Navigating it is rough — finding a specific method means scrolling or grepping, and code review on PRs that touch multiple domains is harder than it needs to be.
I'd like to propose splitting the file along domain boundaries, while keeping the single Garmin class as the public API so this is 100% backward compatible.
Proposal
Move method groups into separate module files, then have Garmin compose them via inheritance (mixin pattern):
garminconnect/
├── __init__.py # Garmin class (inherits mixins), exports (~300 lines)
├── client.py # (unchanged — auth/transport)
├── exceptions.py # (unchanged)
├── workout.py # (unchanged)
├── fit.py # (unchanged)
├── _validation.py # (new) _validate_date_format, constants, helpers
└── _mixins/ # (new)
├── __init__.py
├── health.py # HrV, stress, readiness, sleep, respiration, spo2, intensity
├── activity.py # activities, steps, heart rates, training status/load
├── body.py # body composition, weigh-ins, hydration, blood pressure
├── nutrition.py # food, meals, nutrition settings
├── workouts.py # workout CRUD, scheduling
├── devices.py # devices, device settings, gear
├── badges.py # earned/available/in_progress badges, challenges
├── social.py # connections, personal records
└── admin.py # login, logout, connectapi wrappers, download
__init__.py would become:
from ._mixins.health import HealthMixin
from ._mixins.activity import ActivityMixin
# ... etc
class Garmin(
AdminMixin,
HealthMixin,
ActivityMixin,
BodyMixin,
NutritionMixin,
WorkoutMixin,
DeviceMixin,
BadgeMixin,
SocialMixin,
):
\"\"\"Main client, composed of domain mixins.\"\"\"
Each mixin file is ~200-400 lines and covers one area. Much easier to navigate, grep, and review.
What it doesn't change
- Public API is identical.
from garminconnect import Garmin still works, every method name and signature is preserved.
- No behavior changes. This is pure mechanical refactoring —
git log --follow still works because we're moving code, not rewriting it.
- Tests don't change — they import
garminconnect.Garmin and call methods. Same behavior.
Risks
- Diff size is large (~3000 lines moved across ~10 files). Hard to review for correctness.
- Git blame noise — tracing history of a specific method requires
--follow.
- Potential ordering bugs if mixins accidentally override each other. Method names are all unique today, so this should be safe, but I'd add a test that enumerates all methods and asserts uniqueness.
- Imports get more complex —
_mixins/__init__.py needs to export everything cleanly.
Alternative: leave it alone
Honestly, 2957 lines is large but not unmanageable. If you prefer the monolithic style for grep-ability / context-retention, that's a totally valid choice and I'll drop it. I mostly wanted to raise it as an option since I've been touching the file a lot recently for other PRs (#351, #352, #353) and kept getting lost.
What I'm asking
Not asking for an immediate yes/no — just whether you're open to the idea in principle. If yes, I'd draft a single large refactor PR that you can review as one atomic change. If no, I'll leave it alone and focus on other contributions.
Thanks again for all the work on this library.
Context
garminconnect/__init__.pyhas grown to 2,957 lines containing the entireGarminclass with 132 public methods. Navigating it is rough — finding a specific method means scrolling or grepping, and code review on PRs that touch multiple domains is harder than it needs to be.I'd like to propose splitting the file along domain boundaries, while keeping the single
Garminclass as the public API so this is 100% backward compatible.Proposal
Move method groups into separate module files, then have
Garmincompose them via inheritance (mixin pattern):__init__.pywould become:Each mixin file is ~200-400 lines and covers one area. Much easier to navigate, grep, and review.
What it doesn't change
from garminconnect import Garminstill works, every method name and signature is preserved.git log --followstill works because we're moving code, not rewriting it.garminconnect.Garminand call methods. Same behavior.Risks
--follow._mixins/__init__.pyneeds to export everything cleanly.Alternative: leave it alone
Honestly, 2957 lines is large but not unmanageable. If you prefer the monolithic style for grep-ability / context-retention, that's a totally valid choice and I'll drop it. I mostly wanted to raise it as an option since I've been touching the file a lot recently for other PRs (#351, #352, #353) and kept getting lost.
What I'm asking
Not asking for an immediate yes/no — just whether you're open to the idea in principle. If yes, I'd draft a single large refactor PR that you can review as one atomic change. If no, I'll leave it alone and focus on other contributions.
Thanks again for all the work on this library.