pe-st / garmin-connect-export

Download a copy of your Garmin Connect data, including stats and GPX tracks.
MIT License
374 stars 77 forks source link

garmin-connect-export script

:exclamation: This script now requires Python 3.8 or newer
:exclamation: There is a report of a deactivated user account that might by caused by using this script. The exact reasons are not known, and my account has never been deactivated. But be aware that I can give no guarantee that Garmin tolerates requests made from this script. I believe though that this script is fair use (it doesn't do anything other than automating stuff that you do in the browser). But be careful if you plan to run the script as periodical task (with cron etc)

Download a copy of your Garmin Connect data, including stats and GPX tracks.

Note that Garmin introduced a while ago (around May 2018, for GDPR compatibility) a possibility to download all of your Garmin Connect data in one zip file. Depending on your needs this might be enough, but the script here offers additional features like getting GPX tracks instead of the original upload format or limiting the export to just a couple of activities.

Forks and Branches

Before going into the details of this script itself, some meta information.

There exist many forks of this script repository:

For the branches in pe-st's repo see BRANCH.md

Description

This script will backup your personal Garmin Connect data. All downloaded data will go into a directory called YYYY-MM-DD_garmin_connect_export/ in the current working directory. Activity records and details will go into a CSV file called activities.csv. GPX files (or whatever format you specify) containing track data, activity title, and activity descriptions are saved as well, using the Activity ID.

If there is no GPS track data (e.g., due to an indoor treadmill workout), a data file is still saved. If the GPX format is used, activity title and description data are saved. If the original format is used, Garmin may not provide a file at all and an empty file will be created. For activities where a GPX file was uploaded, Garmin may not have a TCX file available for download, so an empty file will be created. Since GPX is the only format Garmin should have for every activity, it is the default and preferred download format.

If you have many activities, you may find that this script crashes with an "Operation timed out" message. Just run the script again and it will pick up where it left off.

Installation

Usage

You will need a little experience running things from the command line to use this script. That said, here are the usage details from the --help flag:

usage: gcexport.py [-h] [--version] [-v] [--username USERNAME] [--password PASSWORD]
                   [-c COUNT] [-sd START_DATE] [-ed END_DATE] [-e EXTERNAL] [-a ARGS]
                   [-f {gpx,tcx,original,json}] [-d DIRECTORY] [-s SUBDIR] [-lp LOGPATH]
                   [-u] [-ot] [--desc [DESC]] [-t TEMPLATE] [-fp] [-sa START_ACTIVITY_NO]
                   [-ex FILE] [-tf TYPE_FILTER] [-ss DIRECTORY]

Garmin Connect Exporter

optional arguments:
  -h, --help            show this help message and exit
  --version             print version and exit
  -v, --verbosity       increase output and log verbosity, save more intermediate files
  --username USERNAME   your Garmin Connect username or email address (otherwise, you will be prompted)
  --password PASSWORD   your Garmin Connect password (otherwise, you will be prompted)
  -c COUNT, --count COUNT
                        number of recent activities to download, or 'all' (default: 1)
  -sd START_DATE, --start_date START_DATE
                        the start date to get activities from (inclusive). Format example: 2023-07-31
  -ed END_DATE, --end_date END_DATE
                        the end date to get activities to (inclusive). Format example: 2023-07-31
  -e EXTERNAL, --external EXTERNAL
                        path to external program to pass CSV file too
  -a ARGS, --args ARGS  additional arguments to pass to external program
  -f {gpx,tcx,original,json}, --format {gpx,tcx,original,json}
                        export format; can be 'gpx', 'tcx', 'original' or 'json' (default: 'gpx')
  -d DIRECTORY, --directory DIRECTORY
                        the directory to export to (default: './YYYY-MM-DD_garmin_connect_export')
  -s SUBDIR, --subdir SUBDIR
                        the subdirectory for activity files (tcx, gpx etc.), supported placeholders are {YYYY} and {MM}
                        (default: export directory)
  -lp LOGPATH, --logpath LOGPATH
                        the directory to store logfiles (default: same as for --directory)
  -u, --unzip           if downloading ZIP files (format: 'original'), unzip the file and remove the ZIP file
  -ot, --originaltime   will set downloaded (and possibly unzipped) file time to the activity start time
  --desc [DESC]         append the activity's description to the file name of the download; limit size if number is given
  -t TEMPLATE, --template TEMPLATE
                        template file with desired columns for CSV output
  -fp, --fileprefix     set the local time as activity file name prefix
  -sa START_ACTIVITY_NO, --start_activity_no START_ACTIVITY_NO
                        give index for first activity to import, i.e. skipping the newest activities
  -ex FILE, --exclude FILE
                        JSON file with array of activity IDs to exclude from download.
                        Format example: {"ids": ["6176888711"]}
  -tf TYPE_FILTER, --type_filter TYPE_FILTER
                        comma-separated list of activity type IDs to allow. Format example: 3,9
  -ss DIRECTORY, --session DIRECTORY
                        enable loading and storing SSO information from/to given directory

Authentication

You have to authenticate with username and password, and possibly an MFA code, at least for an initial login.

The script is then using OAuth tokens (thanks to the garth library). You can persist the OAuth token by giving a session directory, removing the need to provide username/password/MFA for every script run.

But keep the persistent tokens safe; if somebody gets hold of your tokens, they might be able to read all your data in Garmin Connect (e.g. your health data), maybe even change or delete it.

Examples

Alternatively, you may run it with ./gcexport.py if you set the file as executable (i.e., chmod u+x gcexport.py).

Notes on the Usage

Python

Of course, you must have Python installed to run this, any recent 3.x version should work (see also Python 3.x Versions).

Most Mac and Linux users should already have Python. Note that if you run into the TLSV1 ALERT problem or the HTTP 403 Authentication Error, your Python installation might not be recent enough. In this case you can install a more recent Python on your Mac using Homebrew and/or pyenv.

Also, as stated above, you should have some basic command line experience.

Data

This tool is not guaranteed to get all of your data, or even download it correctly. I have only tested it with my account and it works fine, but different account settings or different data types could potentially cause problems. Also, because this is not an official feature of Garmin Connect, Garmin may very well make changes that break this utility (and they certainly have since I created this project).

If you want to see all the raw data that Garmin hands to this script, just choose the JSON export format (-f json); in this case only metadata is exported, no track data.

The format of the CSV export file can be customized with template files (in Properties format, see the --template option); three examples are included:

You can easily create a template file for your needs, just copy one of the examples and change the appearing columns, their order and/or their title.

Some important columns explained:

Garmin Connect API

This script is for personal use only. It simulates a standard user session (i.e., in the browser), logging in using cookies and an authorization ticket. This makes the script pretty brittle. If you're looking for a more reliable option, particularly if you wish to use this for some production service, Garmin does offer a paid API service.

More information about the API endpoints used in the script is available in CONTRIBUTING.md

History

The original project was written in PHP (formerly in the old directory, now deleted), based on "Garmin Connect export to Dailymile" code at http://www.ciscomonkey.net/gc-to-dm-export/ (link has been down for a while). It no longer works due to the way Garmin handles logins. It could be updated, but I (kjkjava) decided to rewrite everything in Python for the latest version.

After 2015, when the original repo stopped being maintained, several forks from kjkjava started appearing (see Forks and Branches section above).

In 2021 this fork was detached from the original repo; in what concerns Github, the repo isn't a fork anymore, but a new "original". For the history of this fork see the CHANGELOG

Contributions

Contributions are welcome, see CONTRIBUTING.md

Contributors as of 2024-07 (Hope I didn't forget anyone, see also Contributors):

License

MIT © 2015 Kyle Krafka and contributors

Thank You

Thanks for using this script and I hope you find it as useful as I do! :smile: