Files
go-garth-cli/portingplan.md
2025-09-21 11:03:52 -07:00

7.3 KiB

Garth Python to Go Port Plan

Overview

Port the Python garth library to Go with feature parity. The existing Go code provides basic authentication and activity retrieval. This plan outlines the systematic porting of all Python modules.

Current State Analysis

Existing Go code has:

  • Basic SSO authentication flow (main.go)
  • OAuth1/OAuth2 token handling
  • Activity retrieval
  • Session persistence

Missing (needs porting):

  • All data models and retrieval methods
  • Stats modules
  • User profile/settings
  • Structured error handling
  • Client configuration options

Implementation Plan

1. Project Structure Setup

garth/
├── main.go                 (keep existing)
├── client/
│   ├── client.go          (refactor from main.go)
│   ├── auth.go            (OAuth flows)
│   └── sso.go             (SSO authentication)
├── data/
│   ├── base.go
│   ├── body_battery.go
│   ├── hrv.go
│   ├── sleep.go
│   └── weight.go
├── stats/
│   ├── base.go
│   ├── hrv.go
│   ├── steps.go
│   ├── stress.go
│   └── [other stats].go
├── users/
│   ├── profile.go
│   └── settings.go
├── utils/
│   └── utils.go
└── types/
    └── tokens.go

2. Core Client Refactoring (Priority 1)

File: client/client.go

  • Extract client logic from main.go
  • Port src/garth/http.py Client class
  • Key methods to implement:
    type Client struct {
        Domain string
        HTTPClient *http.Client
        OAuth1Token *OAuth1Token
        OAuth2Token *OAuth2Token
        // ... other fields from Python Client
    }
    
    func (c *Client) Configure(opts ...ConfigOption) error
    func (c *Client) ConnectAPI(path, method string, data interface{}) (interface{}, error)
    func (c *Client) Download(path string) ([]byte, error)
    func (c *Client) Upload(filePath, uploadPath string) (map[string]interface{}, error)
    

Reference: src/garth/http.py lines 23-280

3. Authentication Module (Priority 1)

File: client/auth.go

  • Port src/garth/auth_tokens.py token structures
  • Implement token expiration checking
  • Add MFA support placeholder

File: client/sso.go

  • Port SSO functions from src/garth/sso.py
  • Extract login logic from current main.go
  • Implement ResumeLogin() for MFA completion

Reference: src/garth/sso.py and src/garth/auth_tokens.py

4. Data Models Base (Priority 2)

File: data/base.go

  • Port src/garth/data/_base.py Data interface and base functionality
  • Implement concurrent data fetching pattern:
    type Data interface {
        Get(day time.Time, client *Client) (interface{}, error)
        List(end time.Time, days int, client *Client, maxWorkers int) ([]interface{}, error)
    }
    

Reference: src/garth/data/_base.py lines 8-40

5. Body Battery Data (Priority 2)

File: data/body_battery.go

  • Port all structs from src/garth/data/body_battery/ directory
  • Key structures to implement:
    type DailyBodyBatteryStress struct {
        UserProfilePK int `json:"userProfilePk"`
        CalendarDate time.Time `json:"calendarDate"`
        // ... all fields from Python class
    }
    
    type BodyBatteryData struct {
        Event *BodyBatteryEvent `json:"event"`
        // ... other fields
    }
    

Reference:

  • src/garth/data/body_battery/daily_stress.py
  • src/garth/data/body_battery/events.py
  • src/garth/data/body_battery/readings.py

6. Other Data Models (Priority 2)

Files: data/hrv.go, data/sleep.go, data/weight.go

For each file, port the corresponding Python module:

HRV Data (data/hrv.go):

type HRVData struct {
    UserProfilePK int `json:"userProfilePk"`
    HRVSummary HRVSummary `json:"hrvSummary"`
    HRVReadings []HRVReading `json:"hrvReadings"`
    // ... rest of fields
}

Reference: src/garth/data/hrv.py

Sleep Data (data/sleep.go):

  • Port DailySleepDTO, SleepScores, SleepMovement structs
  • Implement property methods as getter functions Reference: src/garth/data/sleep.py

Weight Data (data/weight.go):

  • Port WeightData struct with field validation
  • Implement date range fetching logic Reference: src/garth/data/weight.py

7. Stats Modules (Priority 3)

File: stats/base.go

  • Port src/garth/stats/_base.py Stats base class
  • Implement pagination logic for large date ranges

Individual Stats Files: Create separate files for each stat type, porting from corresponding Python files:

  • stats/hrv.gosrc/garth/stats/hrv.py
  • stats/steps.gosrc/garth/stats/steps.py
  • stats/stress.gosrc/garth/stats/stress.py
  • stats/sleep.gosrc/garth/stats/sleep.py
  • stats/hydration.gosrc/garth/stats/hydration.py
  • stats/intensity_minutes.gosrc/garth/stats/intensity_minutes.py

Reference: All files in src/garth/stats/

8. User Profile and Settings (Priority 3)

File: users/profile.go

type UserProfile struct {
    ID int `json:"id"`
    ProfileID int `json:"profileId"`
    DisplayName string `json:"displayName"`
    // ... all other fields from Python UserProfile
}

func (up *UserProfile) Get(client *Client) error

File: users/settings.go

  • Port all nested structs: PowerFormat, FirstDayOfWeek, WeatherLocation, etc.
  • Implement UserSettings.Get() method

Reference: src/garth/users/profile.py and src/garth/users/settings.py

9. Utilities (Priority 3)

File: utils/utils.go

func CamelToSnake(s string) string
func CamelToSnakeDict(m map[string]interface{}) map[string]interface{}
func FormatEndDate(end interface{}) time.Time
func DateRange(end time.Time, days int) []time.Time
func GetLocalizedDateTime(gmtTimestamp, localTimestamp int64) time.Time

Reference: src/garth/utils.py

10. Error Handling (Priority 4)

File: errors/errors.go

type GarthError struct {
    Message string
    Cause error
}

type GarthHTTPError struct {
    GarthError
    StatusCode int
    Response string
}

Reference: src/garth/exc.py

11. CLI Tool (Priority 4)

File: cmd/garth/main.go

  • Port src/garth/cli.py functionality
  • Support login and token output

12. Testing Strategy

For each module:

  1. Create *_test.go files with unit tests
  2. Mock HTTP responses using Python examples as expected data
  3. Test error handling paths
  4. Add integration tests with real API calls (optional)

13. Key Implementation Notes

  1. JSON Handling: Use struct tags for proper JSON marshaling/unmarshaling
  2. Time Handling: Convert Python datetime objects to Go time.Time
  3. Error Handling: Wrap errors with context using fmt.Errorf
  4. Concurrency: Use goroutines and channels for the concurrent data fetching in List() methods
  5. HTTP Client: Reuse the existing HTTP client setup with proper timeout and retry logic

14. Development Order

  1. Start with client refactoring and authentication
  2. Implement base data structures and one data model (body battery)
  3. Add remaining data models
  4. Implement stats modules
  5. Add user profile/settings
  6. Complete utilities and error handling
  7. Add CLI tool and tests

This plan provides a systematic approach to achieving feature parity with the Python library while maintaining Go idioms and best practices.