GithubHelp home page GithubHelp logo

pe-st / garmin-connect-export Goto Github PK

View Code? Open in Web Editor NEW
358.0 358.0 72.0 561 KB

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

License: MIT License

Python 80.24% HTML 19.76%

garmin-connect-export's People

Contributors

bxsx avatar cdstrachan avatar chs8691 avatar cmccarty avatar cristian5th avatar embear avatar jedie avatar jkall avatar joetimmerman avatar jowiho avatar julienr avatar kjkjava avatar moderation avatar pe-st avatar reto avatar retoborm avatar ryeguard avatar sclub avatar simonbaars avatar telemaxx avatar tobiaslj avatar ulf-lindback avatar yohcop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

garmin-connect-export's Issues

Bug: existing activities are reloaded again and again

seems so, that garmin is using are sligtliy different fitfilename
1234567890_ACTIVITY.fit

instead of:
1234567890.fit

so when using:

-f original

with:

--unzip

it did not detect existing fitfiles

inside:
def export_data_file
i changed one line from:
fit_filename = directory + sep + prefix + 'activity_' + activity_id + append_desc + '.fit'
to:
fit_filename = directory + sep + prefix + 'activity_' + activity_id + '_ACTIVITY' + append_desc + '.fit'
and add directly behind that line for testing:
logging.debug('fitfilename: %s', fit_filename)

Cannot get clean data with gpx, tcx or original

Hi @pe-st and thanks for making this tool.

I'm trying to forward my data to TrainingPeaks, and am facing issues.

Initially, I had downloaded all data in the original (.fit) format, and it seemed to look ok, until I realized that all of the Indoor cycling activities' distances were missing.
Since Indoor cycling cannot record the distance, I'm always modifying my garmin activity afterwards to record the distance measured by my bike's odometer.

I then tried to download using other formats, without success.

Fit data

not attaching the result since it's a compressed format, but the uploaded data appears like this in TrainingPeaks:

Gpx data

<?xml version="1.0" encoding="UTF-8"?>
<gpx creator="Garmin Connect" version="1.1"
  xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/11.xsd"
  xmlns:ns3="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
  xmlns="http://www.topografix.com/GPX/1/1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
  <metadata>
    <link href="connect.garmin.com">
      <text>Garmin Connect</text>
    </link>
    <time>2020-10-08T11:50:05.000Z</time>
  </metadata>
  <trk>
    <name>Indoor Cycling</name>
    <type>indoor_cycling</type>
    <trkseg/>
  </trk>
</gpx>

The result is quite unexpected:

Even the date is wrong, appearing in yesterday's calendar instead of last week.

Tcx data

example
<?xml version="1.0" encoding="UTF-8"?>
<TrainingCenterDatabase
  xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"
  xmlns:ns5="http://www.garmin.com/xmlschemas/ActivityGoals/v1"
  xmlns:ns3="http://www.garmin.com/xmlschemas/ActivityExtension/v2"
  xmlns:ns2="http://www.garmin.com/xmlschemas/UserProfile/v2"
  xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns4="http://www.garmin.com/xmlschemas/ProfileExtension/v1">
  <Activities>
    <Activity Sport="Biking">
      <Id>2020-10-08T11:50:05.000Z</Id>
      <Lap StartTime="2020-10-08T11:50:05.000Z">
        <TotalTimeSeconds>5336.0</TotalTimeSeconds>
        <DistanceMeters>0.0</DistanceMeters>
        <Calories>779</Calories>
        <AverageHeartRateBpm>
          <Value>131</Value>
        </AverageHeartRateBpm>
        <MaximumHeartRateBpm>
          <Value>158</Value>
        </MaximumHeartRateBpm>
        <Intensity>Active</Intensity>
        <TriggerMethod>Manual</TriggerMethod>
        <Track>
          <Trackpoint>
            <Time>2020-10-08T11:50:05.000Z</Time>
            <DistanceMeters>0.0</DistanceMeters>
            <HeartRateBpm>
              <Value>73</Value>
            </HeartRateBpm>
            <Extensions>
              <ns3:TPX/>
            </Extensions>
          </Trackpoint>
...
          <Trackpoint>
            <Time>2020-10-08T13:19:01.000Z</Time>
            <DistanceMeters>0.0</DistanceMeters>
            <HeartRateBpm>
              <Value>130</Value>
            </HeartRateBpm>
            <Extensions>
              <ns3:TPX/>
            </Extensions>
          </Trackpoint>
        </Track>

As you can see:

  • The distance stays 0 all the time
  • The activity name has changed from "Indoor Cycling" to "Cycling"

What's the proper way to download the final data (including updates) as visible from garmin?

What is strange is that the downloader shows the correct information every time:

$ for ft in gpx tcx original; do python gcexport.py --username my@email -u -ot -c 10 -f $ft; done
...
Garmin Connect activity (10/10) [5648870175] Indoor Cycling
        2020-10-08T20:50:05+09:00, 01:28:56, 40.000km
...
Garmin Connect activity (10/10) [5648870175] Indoor Cycling
        2020-10-08T20:50:05+09:00, 01:28:56, 40.000km
...
Garmin Connect activity (10/10) [5648870175] Indoor Cycling
        2020-10-08T20:50:05+09:00, 01:28:56, 40.000km
...

and the accompanying activities.csv file also shows the right data:

"2020-10-08T20:50:05+09:00","2020-10-08T22:19:01+09:00","5648870175","Indoor Cycling","","","Asia/Tokyo","+09:00","01:28:56","01:28:56","","Cycling","Indoor Cycling","Uncategorized","ForeAthlete 935 19.10.0.0","Trek Emonda S5","subscribers","fit","40.00000","27.882781971118338","27.0","","","","","","","","","false","","","","","158","131","779","","3.0","1.1","","","","","","","","37.0","37.0","37.0"

TrainingPeaks allows many file formats to upload data:

But they recommend only .tcx and .fit

For most activity types you may also use the .tcx file. For swimming workouts we recommend the original file.

I'm trying to upload years of data, with hundreds of indoor cycling, so manual update would take too much time. I really just want to see the .fit data with my distance.
Do you have a solution?

Please use git tags

Due to the fact I'm using this wonderful software to backup automatic my metrics I hope it is possible to start using Git tags. This is so the software can be pinned to a version and upgraded later if needed.

Why two different filenames for fit files?

Hello.

This is not really an issue. It Is more a doubt I'm having. But I don't know where to ask for this other than here.

When args.format=original, the name used to check if the fit file was already existing is created and stored into a variable like this:
fit_filename = os.path.join(directory, prefix + 'activity_' + activity_id + append_desc + '.fit')

But when the file is physically written into the disk, a new name is created for the fit file, like this:
new_name = os.path.join(directory, prefix + 'activity_' + name_base + append_desc + name_ext)

My doubt is that name_base and activity_id are not necessary the same thing. Actually, you had to recently add a workaround because in 2020 Garmin added '_ACTIVITY' to the name in the ZIP.

Why not use activity_id when writing the file into the disk? Is there any particular reason that I'm missing?

Thank you. Regards.

relative path for csv_header_properties

Hi there,

On windows, if you run the script from another working directory you get the following error:

IOError: [Errno 2] No such file or directory: 'csv_header_default.properties

This works however if you run the script from the script directory but this might deserve improvement.

Doesn't skip existing .fit files

The script failed when repeating a download, not ignoring the existing files correctly,
I added this at line 908 which solved the problem for me, though it's not elegant.
elif isfile(args.directory + '/activity_' + str(actvty['activityId']) + '.fit'):
pass
# Display which entry we're skipping.
print('//#!JFS!# Skipping Garmin Connect activity (exists)')

csv file is populated with already downloaded activities

Hello all.

When executing the script on already downloaded activities, the file will not be re-downloaded again, but the activity data will be appended to the csv file, creating doubles and worst.

I find solution to be pretty simple but I don't know how to propose it via GitHub. This has always been a big mystery to me. Do you know to point me to some instructions for dummies?

I'm just adding a return TRUE or FALSE to the function export_data_file. FALSE is returned when the file already exists; TRUE is returned at any other case.

In the main program, I also invert the functions to write the file and write the csv data with an if clause, like this:

# Save the file and inform if it already existed. If the file already existed, do not append the record to the csv
if export_data_file(str(actvty['activityId']), activity_details, args, start_time_seconds, append_desc, actvty['startTimeLocal']):
    # Write stats to CSV.
    csv_write_record(csv_filter, extract, actvty, details, activity_type_name, event_type_name)

Thank you for all your work on this splendid script.

Best regards.

Feature request - new parameter: --workflowdirectory

currently i still use: repro from rsjrny
The advantage is/was Pathon3 support, but hopefully youre repro is soon also p3 compatible...
For this repro i have implemented a new parameter -w --workflowdirectory
https://github.com/rsjrny/Garmin-Connect-Export/pull/4/files

i use that function for postprocessing my activities with "mytourbook"
mytourbook imports the file from that directory and removes that file after that.
but it stays in the -d --directory folder and will not be downloaded again.

what do you think about that function? should i implement it also for youre repro?

the disadvantage of rsjrny is the broken github history. seem so that the author has not started with a fork.

HTTP 404 error when activity does not exist

The activity is in the list of activities but when you select the activity you get a 404 error (page not found error). I have two instances of this and will leave my Garmin activities as they are so I can reproduce the error when testing the resolution.

I would like to display a warning message and return to processing.

Garmin Connect activity (1332/1500) [2646199078] 4 x 2:30 intervals
2018-04-23T10:26:38+20:00, 00:51:12, 6.453km
FIT data file already exists; skipping...
Garmin Connect activity (1333/1500) [2646171725] Zwift Run - Richmond
[ERROR] Failed to reach url https://connect.garmin.com/modern/proxy/activity-service/activity/2646171725, error: HTTP Error 404: Not Found
Traceback (most recent call last):
File "C:/Users/russl/Dropbox/PYCharmProjects/garmin-connect-export-1/gcexport.py", line 1105, in
main(sys.argv)
File "C:/Users/russl/Dropbox/PYCharmProjects/garmin-connect-export-1/gcexport.py", line 1013, in main
activity_details = http_req_as_string(URL_GC_ACTIVITY + str(actvty['activityId']))
File "C:/Users/russl/Dropbox/PYCharmProjects/garmin-connect-export-1/gcexport.py", line 273, in http_req_as_string
return http_req(url, post, headers).decode()
File "C:/Users/russl/Dropbox/PYCharmProjects/garmin-connect-export-1/gcexport.py", line 249, in http_req
response = OPENER.open(request, data=post)
File "C:\Program Files (x86)\Python37\lib\urllib\request.py", line 531, in open
response = meth(req, response)
File "C:\Program Files (x86)\Python37\lib\urllib\request.py", line 641, in http_response
'http', request, response, code, msg, hdrs)
File "C:\Program Files (x86)\Python37\lib\urllib\request.py", line 569, in error
return self._call_chain(*args)
File "C:\Program Files (x86)\Python37\lib\urllib\request.py", line 503, in _call_chain
result = func(*args)
File "C:\Program Files (x86)\Python37\lib\urllib\request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found

Process finished with exit code 1

issue on packages import

hi, I find some of the packages or methods unable to be imported.

I tried to fix myself, but I'm a python beginner and even not familiar with the basic syntax.

the python version is 3.6.2

below shows the issues:

image

Looking forward to your reply.

which branch to use? UTF issue still alive

Hi all

Which branch to use ;) ? Is develop most up to date? Will all changes merged to master someday?

In both develop and master I have still UTF issue

Garmin Connect activity: [2806957153] Maszyna eliptyczna
	Wt, 26 cze 2018 17:38, 	Downloading file... Traceback (most recent call last):
  File "/Users/tomek/Garmin/garmin-connect-export//gcexport3.py", line 371, in <module>
    write_to_file(data_filename, data.decode(), file_mode)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdc in position 12: invalid continuation byte

Downloading GPX files with HR

Great code thank you! I was wondering if you had any arguments / way to download the GPX files with heart rate - on the garmin connect the activites has this feature.

Then can visualise the heart rate variabliity over the course of an activity!

Thanks,

Sol

activity-search-service-1.2 doesn't work anymore

Just recently (maybe two weeks ago) this still worked. Now it doesn't:

Making result summary request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
https://connect.garmin.com/proxy/activity-search-service-1.2/json/activities?start=0&limit=1
Traceback (most recent call last):
  File "./gcexport.py", line 710, in <module>
    main(sys.argv)
  File "./gcexport.py", line 577, in main
    result = http_req(URL_GC_SEARCH)
  File "./gcexport.py", line 158, in http_req
    response = OPENER.open(request, data=post)  # This line may throw a urllib2.HTTPError.
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 437, in open
    response = meth(req, response)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 550, in http_response
    'http', request, response, code, msg, hdrs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 475, in error
    return self._call_chain(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 558, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: Bad Request

Maybe Garmin changed the endpoints?

Download summary data

Hi was using Garpy but it no longer lets me connect .
They have a nice feature to download the summary which includes a laps.csv which I find most useful.
Could this option be included ?

[ERROR] Failed to reach url http://connect.garmin.com/proxy/download-service/files/activity/5321283197, error: HTTP Error 400: Bad Request

I started using the gcexport.py script again last week (after the Garmin ransomware problem) following ~3 months not using it. Now it seems the gcexport.py keeps throwing an error 400 when downloading the tcx.

pierre@pierre-thinkpad:~$ python ~/Workspace/garmin-connect-export/gcexport.py -d ~/GarminConnect -c 10 -f original -u --username [email protected] --password mypassword --originaltime --desc && rm ~/GarminConnect/*.json
Welcome to Garmin Connect Exporter!
[WARNING] Output directory /home/pierre/GarminConnect already exists. Will skip already-downloaded files and append to the CSV file.
Connecting to Garmin Connect... Done.
Requesting Login ticket... Done. Ticket=ST-02141344-WEqXaqbVlyOKmWWPqgm4-cas
Authenticating... Done.
Querying list of activities 1..10... Done.
Garmin Connect activity (1/10) [5321283197] San Francisco Running
	2020-08-01T17:56:37+17:00, 01:23:02, 16.428km
[ERROR] Failed to reach url http://connect.garmin.com/proxy/download-service/files/activity/5321283197, error: HTTP Error 400: Bad Request
Traceback (most recent call last):
  File "/home/pierre/Workspace/garmin-connect-export/gcexport.py", line 1007, in <module>
    main(sys.argv)
  File "/home/pierre/Workspace/garmin-connect-export/gcexport.py", line 988, in main
    actvty['startTimeLocal'])
  File "/home/pierre/Workspace/garmin-connect-export/gcexport.py", line 720, in export_data_file
    raise Exception('Failed. Got an HTTP error ' + str(ex.code) + ' for ' + download_url)
Exception: Failed. Got an HTTP error 400 for http://connect.garmin.com/proxy/download-service/files/activity/5321283197

Was wondering if someone has encountered this issue? Wondering if the API changed or if it's related to the ransomware problem where Garmin might have changed something?

I'm on ubuntu 18.04.

Payment Required?

Greetings.

Is anyone else encountering the Payment Required message/error after authentication?

[ERROR] Failed to reach url https://connect.garmin.com/modern/proxy/activitylist-service/activities/search/activities?start=0&limit=1, error: HTTP Error 402: Payment Required

Everything was fine as of last night.

My best,
Gowtham

file prefix (-fp) wont work with "-f original"

fit_filename is not really used.
fit_filename = directory + '/' + prefix + 'activity_' + activity_id + append_desc + '.fit'
with -f gpx it is ok.
i will fix that with the next PR for workflow mode

Certificate verify failed

When trying to use the script i get the following error:

Welcome to Garmin Connect Exporter!
[ERROR] Failed to reach url https://sso.garmin.com/sso/signin?service...(url shortened)
<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1108)>

When I try to open the URL in a browser I get to a login page.

Traceback

Connecting to Garmin Connect...Traceback (most recent call last):
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\urllib\request.py", line 1350, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1240, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1286, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1235, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1006, in _send_output
    self.send(msg)
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 946, in send
    self.connect()
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\http\client.py", line 1409, in connect
    self.sock = self._context.wrap_socket(self.sock,
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Users\marti\AppData\Local\Programs\Python\Python38-32\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1108)

Time spent in HR zones

Greetings.

I am wondering if there's a way to extract the time spent in various heart rate zones (e.g, Z1, Z2, Z3, Z4 and Z5) in hh:mm:ss format for a given activity using this garmin-connect-export python workflow?

My best,
Gowtham

HTTPError: Unauthorized

Hi,
I am trying to use this script but im facing this error message after writing my username (email adress) for Garmin Connect:

Connecting to Garmin Connect... Done.
Requesting Login ticket...[ERROR] Server couldn't fulfill the request, url https://sso.garmin.com/sso/signin?service=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&webhost=https%3A%2F%2Fconnect.garmin.com&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&locale=en_US&id=gauth-widget&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=true&generateTwoExtraServiceTickets=false&generateNoServiceTicket=false&globalOptInShown=true&globalOptInChecked=false&mobile=false&connectLegalTerms=true&locationPromptShown=true&showPassword=true#, code 401, error: HTTP Error 401: Unauthorized
[ERROR] Server couldn't fulfill the request, url https://sso.garmin.com/sso/signin?service=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&webhost=https%3A%2F%2Fconnect.garmin.com&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&locale=en_US&id=gauth-widget&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=true&generateTwoExtraServiceTickets=false&generateNoServiceTicket=false&globalOptInShown=true&globalOptInChecked=false&mobile=false&connectLegalTerms=true&locationPromptShown=true&showPassword=true#, code 401, error: HTTP Error 401: Unauthorized

HTTPError: Unauthorized

I triple verified that the email adress I used is correct (also checked on garmin account page), is there something that I'm doing wrong?
Many thanks,
Yonatan

Detaching from the upstream repository

It's been a long history for forking garmin-connect-export. We can see it at here: https://github.com/pe-st/garmin-connect-export/network/members

Unfortunately, it seems like @kjkjava (owner of the upstream) is not interested in the project anymore. Since 2018, we have been expecting at least a comment on the PR42@upstream kjkjava/garmin-connect-export#42
No luck. As for now, we are 271 commits ahead.

As this is the most active repository of the project, I'm suggesting to detach from the upstream.

Pros:

  • GitHub will count activity in the repository (such as commits)
  • Users will stop to be confused about multiple forks and which project is actually active
  • Contributors will know where to send PRs instead of randomly sending them around forks
    Cons:
  • Breaking a great history of forking the project ;)

Here are some docs regarding the issue:

Only able to download 1 activity

I used version 3.0.3 until it stopped working. Now using version 3.3.0 but I can only download 1 activity instead of all (over 2000 activities). What goes wrong, I'm quite new to Python and I'm trying to understand but can't understand. The result that I get is:

Connecting to Garmin Connect... Done.
Requesting Login ticket... Done. Ticket=ST-04883869-IcK67OckuWlLoiqyNrqE-cas
Authenticating... Done.
Getting display name... Done. displayName=############
Fetching user stats... Done.
Querying list of activities 1..1... Done.
Downloading: Garmin Connect activity (1/1) [#########] Zutphen Wandelen
2022-01-02T12:04:50+01:00, 00:30:49, 2.462km
Data file already exists; skipping...
Done!

Do I have to change some lines to pass this problem?

issue on username and password

Hi, thank you very much for your work!

the username in your readme file is not an email, however, an email address is required in my garmin login page.

Besides, I don‘t know why but I can't type my password in the command window

Looking forward to your reply.

is anyone else having an issue downloading files?

I am getting to the User Stats Done then hanging. I just did a fresh pull of this repo to see if it helps but no luck. The authenticating URL step seems to be taking a long delay.

If I copy the URL and paste it into my browser I am sent to my activities without issue

Connecting to Garmin Connect... Done.
[INFO] Requesting Login ticket
Requesting Login ticket... Done. Ticket=ST-0774660-2WO9JpRWhWmiyHIwnO6r-cas
[INFO] Authentication URL https://connect.garmin.com/modern/activities?ticket=ST-0774660-2WO9JpRWhWmiyHIwnO6r-cas

subdir quit working after update

Subdir no longer works after I updated to gcexport.py 3.0.0.
I tried with Python 2.7.12 and Python 3.7.7.
Running:
python3 gcexport.py -d ~/Activities/GarminConnect -c 10 -f original --desc --username xxxx --subdir activities
Results in the following error:
Traceback (most recent call last): File "/home/john/Documents/Git/garmin-connect-export/gcexport.py", line 1057, in <module> main(sys.argv) File "/home/john/Documents/Git/garmin-connect-export/gcexport.py", line 1038, in main actvty['startTimeLocal']) File "/home/john/Documents/Git/garmin-connect-export/gcexport.py", line 710, in export_data_file directory = resolve_path(args.directory, args.subdir, start_time_locale) File "/home/john/Documents/Git/garmin-connect-export/gcexport.py", line 163, in resolve_path ret = join(directory, subdir) NameError: name 'join' is not defined
The --directory and --subdir folders both exist and this worked before the update.
If I remove --subdir activities from the command it works.

Downloading wellness-reports

Hi,
This is not so much an issue, but wanted to connect and say thank you. This is absolutely golden and what I was looking for.
I've been trying to download my steps data from connect but without much luck. Do you know the endpoint to automate the download of my daily steps data?

Display name error, using Python 3

Tried: python gcexport.py --count all --username user_email_address

Got the following error related to "display name". Using Python 3.8.6.

Authenticating... Done.
Getting display name...Traceback (most recent call last):
File "gcexport.py", line 1255, in
main(sys.argv)
File "gcexport.py", line 1132, in main
userstats_json = fetch_userstats(args.directory)
File "gcexport.py", line 913, in fetch_userstats
raise Exception('Did not find the display name in the profile page.')
Exception: Did not find the display name in the profile page.

AttributeError: module 'urllib.request' has no attribute 'HTTPSHandler'

Hello here, for a couple of months now I'm getting the error in the title when running gcexport.py, I just downloaded the most recent version of the package and still have the same error. The problem is this line of code:

OPENER = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(COOKIE_JAR), urllib.request.HTTPSHandler(debuglevel=0))

I investigated and it can seem like a python 2 vs python 3 error but I checked and I use python 3.9 so it should work. Can anyone help ? Thanks a lot

HTTP 403 Authentication Error

Raising the presence of a new round of authentication errors.

Connecting to Garmin Connect... Done.
[ERROR] Failed to reach url https://sso.garmin.com/sso/signin?service=https%3A%2F%2Fconnect.garmin.com%2Flegacy%2Fsession&webhost=https%3A%2F%2Fconnect.garmin.com&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Flegacy%2Fsession&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Flegacy%2Fsession&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&locale=en_US&id=gauth-widget&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=true&generateTwoExtraServiceTickets=false&generateNoServiceTicket=false&globalOptInShown=true&globalOptInChecked=false&mobile=false&connectLegalTerms=true&locationPromptShown=true&showPassword=true#, error: HTTP Error 403: Forbidden
Requesting Login ticket...Traceback (most recent call last):
  File "C:\Users\ryand\git\garmin-connect-export\gcexport.py", line 1063, in <module>
    main(sys.argv)
  File "C:\Users\ryand\git\garmin-connect-export\gcexport.py", line 865, in main
    login_to_garmin_connect(args)
  File "C:\Users\ryand\git\garmin-connect-export\gcexport.py", line 516, in login_to_garmin_connect
    login_response = http_req_as_string(URL_GC_LOGIN + '#', post_data, headers)
  File "C:\Users\ryand\git\garmin-connect-export\gcexport.py", line 273, in http_req_as_string
    return http_req(url, post, headers).decode()
  File "C:\Users\ryand\git\garmin-connect-export\gcexport.py", line 249, in http_req
    response = OPENER.open(request, data=post)
  File "C:\Users\ryand\miniconda3\envs\gc_36\lib\urllib\request.py", line 532, in open
    response = meth(req, response)
  File "C:\Users\ryand\miniconda3\envs\gc_36\lib\urllib\request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Users\ryand\miniconda3\envs\gc_36\lib\urllib\request.py", line 570, in error
    return self._call_chain(*args)
  File "C:\Users\ryand\miniconda3\envs\gc_36\lib\urllib\request.py", line 504, in _call_chain
    result = func(*args)
  File "C:\Users\ryand\miniconda3\envs\gc_36\lib\urllib\request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

Will need to confirm if this call is running into the same cloudflare error that other repos such as garmin-uploader have reported. The workaround currently in place there is to make the calls more cloudflare friendly by replaceing the requests with cloudscraper (see here).

I'll do some tests tonight to confirm the proplem and check the viability of this fix for us as well.

UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 16: ordinal not in range(128)

I get this error when the script is run by cron. Works fine when running manually in shell.

Welcome to Garmin Connect Exporter!
Connecting to Garmin Connect... Done.
Requesting Login ticket... Done. Ticket=###
Authenticating... Done.
Querying list of activities 1..3... Done.
Garmin Connect activity (1/3) [4984080154] Traceback (most recent call last):
  File "gcexport.py", line 1005, in <module>
    main(sys.argv)
  File "gcexport.py", line 913, in main
    print(actvty['activityName'])
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 16: ordinal not in range(128)

CERTIFICATE_VERIFY_FAILED

Hello all.

I'm finding an SSL certificate issue only when executing the script with Python 3. If I execute it with Python 2, then there is no problem at all.

This is the complete error message I'm getting:

[ERROR] Failed to reach url https://sso.garmin.com/sso/signin?service=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&webhost=https%3A%2F%2Fconnect.garmin.com&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&locale=en_US&id=gauth-widget&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=true&generateTwoExtraServiceTickets=false&generateNoServiceTicket=false&globalOptInShown=true&globalOptInChecked=false&mobile=false&connectLegalTerms=true&locationPromptShown=true&showPassword=true, error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>
Connecting to Garmin Connect...Traceback (most recent call last):
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 1317, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1229, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1275, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1224, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1016, in _send_output
self.send(msg)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 956, in send
self.connect()
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1392, in connect
server_hostname=server_hostname)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/ssl.py", line 412, in wrap_socket
session=session
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/ssl.py", line 853, in _create
self.do_handshake()
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/ssl.py", line 1117, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "/Users/cralvarez/Downloads/garmin-connect-export-master/gcexport.py", line 1057, in
main(sys.argv)
File "/Users/cralvarez/Downloads/garmin-connect-export-master/gcexport.py", line 859, in main
login_to_garmin_connect(args)
File "/Users/cralvarez/Downloads/garmin-connect-export-master/gcexport.py", line 494, in login_to_garmin_connect
connect_response = http_req_as_string(URL_GC_LOGIN)
File "/Users/cralvarez/Downloads/garmin-connect-export-master/gcexport.py", line 271, in http_req_as_string
return http_req(url, post, headers).decode()
File "/Users/cralvarez/Downloads/garmin-connect-export-master/gcexport.py", line 247, in http_req
response = OPENER.open(request, data=post)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 525, in open
response = self._open(req, data)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 543, in _open
'_open', req)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 503, in _call_chain
result = func(*args)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 1360, in https_open
context=self._context, check_hostname=self._check_hostname)
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 1319, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>

I wonder if the issue could be because of some module dependency that I'm missing in Python 3.

Somebody has any idea about how to proceed?

Thank you. Best regards.

urllib.error.HTTPError: HTTP Error 403: Forbidden

Having problems with the logging in process, errors as follows:

Connecting to Garmin Connect... Done.
[ERROR] Server couldn't fulfill the request, url https://sso.garmin.com/sso/signin?service=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&webhost=https%3A%2F%2Fconnect.garmin.com&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&locale=en_US&id=gauth-widget&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=true&generateTwoExtraServiceTickets=false&generateNoServiceTicket=false&globalOptInShown=true&globalOptInChecked=false&mobile=false&connectLegalTerms=true&locationPromptShown=true&showPassword=true#, code 403, error: HTTP Error 403: Forbidden
Requesting Login ticket...Traceback (most recent call last):
File "./gcexport.py", line 1342, in
main(sys.argv)
File "./gcexport.py", line 1292, in main
login_to_garmin_connect(args)
File "./gcexport.py", line 536, in login_to_garmin_connect
login_response = http_req_as_string(f'{URL_GC_LOGIN}#', post_data, headers)
File "./gcexport.py", line 266, in http_req_as_string
return http_req(url, post, headers).decode()
File "./gcexport.py", line 238, in http_req
response = OPENER.open(request, data=post)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 531, in open
response = meth(req, response)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 641, in http_response
'http', request, response, code, msg, hdrs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 503, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidden

Exported files wont load into GoldenCheetah

After running python gcexport.py -d ~/Garmin -c 10 -f original -u --username foo --password bar all the files retrieved are named like activity_542056943.gpx but wont be loaded into GoldenCheetah because of a date issue. Looking at the GC code it looks like the filename of the fit file has to contains the activity date?
Am I using the CLI properly?
image
image

SSL: TLSV1_ALERT_PROTOCOL_VERSION

Two or three weeks ago the login still worked, but today the request to

https://connect.garmin.com/modern/activities?ticket=XXXX

fails with

[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590)

Complete traceback:

Authenticating...Traceback (most recent call last):
  File "./gcexport.py", line 890, in <module>
    main(sys.argv)
  File "./gcexport.py", line 708, in main
    login_to_garmin_connect(args)
  File "./gcexport.py", line 436, in login_to_garmin_connect
    http_req(URL_GC_POST_AUTH + 'ticket=' + login_ticket)
  File "./gcexport.py", line 180, in http_req
    response = OPENER.open(request, data=post)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
    response = self._open(req, data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
    '_open', req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
    context=self._context)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590)>

500 error with -c all

With -c all to download all my history once I am downloading activities all the way back to 2013 I get:

Traceback (most recent call last):
  File "gcexport.py", line 710, in <module>
    main(sys.argv)
  File "gcexport.py", line 694, in main
    export_data_file(str(a['activityId']), activity_details, args)
  File "gcexport.py", line 499, in export_data_file
    raise Exception('Failed. Got an unexpected HTTP error (' + str(e.code) + download_url + ').')
Exception: Failed. Got an unexpected HTTP error (500http://connect.garmin.com/proxy/download-service/files/activity/320606384).

I guess I can't download activities that old maybe. Or maybe not so many in a single call. Is there a way to --retry it?

how to obtain the URL_GC_SEARCH

I find the url links end with .com in the scrips are not applicable to Chinese users. Our website is end with cn

I have replaced all the urls and log in successfully, however, issue occurs when making request.

Finished authentication
Making activity request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
https://connect.garmin.cn/proxy/activity-search-service-1.2/json/activities?start=0&limit=1
Traceback (most recent call last):
File "gcexport3.py", line 283, in
RESULT = http_req(URL_GC_SEARCH + urllib.parse.urlencode(SEARCH_PARAMS))
File "gcexport3.py", line 101, in http_req
response = OPENER.open((request), data=post)
File "D:\InstallFolder\Anaconda\lib\urllib\request.py", line 532, in open
response = meth(req, response)
File "D:\InstallFolder\Anaconda\lib\urllib\request.py", line 642, in http_response
'http', request, response, code, msg, hdrs)
File "D:\InstallFolder\Anaconda\lib\urllib\request.py", line 570, in error
return self._call_chain(*args)
File "D:\InstallFolder\Anaconda\lib\urllib\request.py", line 504, in _call_chain
result = func(*args)
File "D:\InstallFolder\Anaconda\lib\urllib\request.py", line 650, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found

It seems the URL_GC_SEARCH is not applicable. Do you know how to get the right link for this issue.

Thanks

Feature request - export body metrics

Hi,
thanks for the export tool, works perfectly.
Would it be possible to add the export of body metrics to the script?
Today the export is done manually:
https://connect.garmin.com/modern/proxy/userprofile-service/userprofile/personal-information/weightWithOutbound/ with optional filter "filterByDay?from=1483228800&until=1527807599999"
than paste it in https://json-csv.com/ to make it readable/editable in Excel. Source: https://www.alunr.com/exporting-weight-data-from-garmin-connect/

Target should be a csv file with the following format, wich can be used with GoldenCheetah for example:
https://github.com/GoldenCheetah/GoldenCheetah/blob/master/test/bodymeasures/bodymeasures-format-example-ts.csv

Thanks
Mark

Download Fit file instead of GPX

Hello everyone,
I am a researcher @university and I'm currently using this package to obtain gpx data. Is there a possibility to obtain also the .fit file so that I can also gather info the overall activity?

Thanks,

n

Feature request - export golf scorecards

Hi Peter, thanks for keeping this export scripts alive!
Wonder if there is a possibility to include also golf scorecards exporting feature or maybe just outline what URLs are behind the raw data Garmin Connect uses?
scorecard_list
scorecard
Thanks! Appreciate your work.
Pavel

Garmin account deactivated probably due to gcexport

I've been in rather stressful contact with Garmin over the last 2 weeks because my account got deactivated - twice. I used to use this script to auto-sync my activities once every hour.

After lengthy discussions with the user support they concluded that I should disable the program because it makes calls to their SSO service (??? of course it does). I can't quote here, because it's prohibited to disclose information from that communication ( 🙄 ). Apparently they also implemented a new service a couple of weeks back and my guess is that it erroneously auto-detects the syncer as a malicious program and locks the account.

I primarily opened this issue for people in the same situation. If you are greeted with this (incorrect) message:

Welcome back! We hadn’t seen you in a while, so your account was
temporarily deactivated. To reactivate your account, follow the
instructions in the email we just sent to the email address below.

chances are you are also locked out. Don't wait for that e-mail, because it never arrives. Don't try to reset your password, it won't work. You have to open a ticket and they have to manually reset your account with a password.

gcexport.py - No such file or directory

Hi,

I have this problem:

/Library/Frameworks/Python.framework/Versions/3.7/Resources/Python.app/Contents/MacOS/Python: can't open file 'gcexport.py': [Errno 2] No such file or directory

that I have to do?

Thanks

HTTP Error 400: Bad Request when using "--count all"

Hi pe-st!
I've tryed to download with the "--count all" parameter and got an error; in my case it was an Error 400: Bad Request. This will happens only in conjunction with the "all" parm. Every other eg. "--count 10" or whatever else is working fine. Except when I set "--count 1732" the limit will be set to 1000 (1732 are my count of activities in GC).
See the error message output:

python gcexport.py --username telefunker --password xxx --count all -f tcx -d ../garmin

Welcome to Garmin Connect Exporter!
Warning: Output directory already exists. Will skip already-downloaded files and append to the CSV file.
openCreateAccount=false&createAccountShown=true&consumeServiceTicket=false&embedWidget=false&service=https%3A%2F%2Fconnect.garmin.com%2Fpost-auth%2Flogin&webhost=https%3A%2F%2Fconnect.garmin.com&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Fpost-auth%2Flogin&rememberMeShown=true&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&usernameShown=false&clientId=GarminConnect&id=gauth-widget&source=http%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&initialFocus=true&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&rememberMeChecked=false&locale=en_US&displayNameShown=false&generateExtraServiceTicket=false&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Fpost-auth%2Flogin
Request login page
Finish login page
Post login data
Finish login post
login ticket=ST-0375575-xxxxxxxxxxxx-cas
Request authentication URL: https://connect.garmin.com/modern/activities?ticket=ST-xxxxxxxxxxxx-cas
Finished authentication
Making result summary request ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
https://connect.garmin.com/proxy/activity-search-service-1.2/json/activities?start=0&limit=1
Traceback (most recent call last):
File "gcexport.py", line 710, in
main(sys.argv)
File "gcexport.py", line 577, in main
result = http_req(URL_GC_SEARCH)
File "gcexport.py", line 158, in http_req
response = OPENER.open(request, data=post) # This line may throw a urllib2.HTTPError.
File "/usr/lib/python2.7/urllib2.py", line 435, in open
response = meth(req, response)
File "/usr/lib/python2.7/urllib2.py", line 548, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.7/urllib2.py", line 473, in error
return self._call_chain(*args)
File "/usr/lib/python2.7/urllib2.py", line 407, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 556, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: Bad Request

Any idea about this?
Btw. great work and many thanks for that script.
Greets

SSL Certificate verify fails

Apologies if this is just a short-term glitch on Garmin's side, but in case there is something that needs fixing, here's my report.

I use the exporter almost daily, and it has never failed in over two months. Today it seems to have a problem with SSL verification. Things I tried:

  • Account login from a browser still works.
  • This happens on my wife's Garmin account as well.
  • Fetched the latest version (mine was from March). No change.

A clip from the console window is below:

[ERROR] Failed to reach url https://sso.garmin.com/sso/signin?webhost=https%3A%2
F%2Fconnect.garmin.com&locale=en_US&rememberMeShown=true&generateNoServiceTicket
=false&id=gauth-widget&service=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&conn
ectLegalTerms=true&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.
com%2Fmodern%2F&displayNameShown=false&redirectAfterAccountLoginUrl=https%3A%2F%
2Fconnect.garmin.com%2Fmodern%2F&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US
%2Fsignin&rememberMeChecked=false&generateExtraServiceTicket=true&openCreateAcco
unt=false&showPassword=true&createAccountShown=true&embedWidget=false&initialFoc
us=true&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&globalOptInChecked=false&cs
sUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-
custom-v1.2-min.css&locationPromptShown=true&globalOptInShown=true&mobile=false&
clientId=GarminConnect&generateTwoExtraServiceTickets=false&consumeServiceTicket
=false, error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verif
y failed (_ssl.c:590)>
Traceback (most recent call last):
File "D:\GitHub\garmin-connect-export\gcexport.py", line 1057, in
main(sys.argv)
File "D:\GitHub\garmin-connect-export\gcexport.py", line 859, in main
login_to_garmin_connect(args)
File "D:\GitHub\garmin-connect-export\gcexport.py", line 494, in login_to_garm
in_connect
connect_response = http_req_as_string(URL_GC_LOGIN)
File "D:\GitHub\garmin-connect-export\gcexport.py", line 273, in http_req_as_s
tring
return http_req(url, post, headers)
File "D:\GitHub\garmin-connect-export\gcexport.py", line 247, in http_req
response = OPENER.open(request, data=post)
File "C:\Python27\lib\urllib2.py", line 431, in open
response = self._open(req, data)
File "C:\Python27\lib\urllib2.py", line 449, in _open
'_open', req)
File "C:\Python27\lib\urllib2.py", line 409, in _call_chain
result = func(*args)
File "C:\Python27\lib\urllib2.py", line 1240, in https_open
context=self._context)
File "C:\Python27\lib\urllib2.py", line 1197, in do_open
raise URLError(err)
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate ve
rify failed (_ssl.c:590)>

HTTP Error 401: Unauthorized

python version 3.6.9 on linux

console report:

Welcome to Garmin Connect Exporter!
Connecting to Garmin Connect... Done.
[ERROR] Failed to reach url https://sso.garmin.com/sso/signin?service=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&webhost=https%3A%2F%2Fconnect.garmin.com&source=https%3A%2F%2Fconnect.garmin.com%2Fen-US%2Fsignin&redirectAfterAccountLoginUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&redirectAfterAccountCreationUrl=https%3A%2F%2Fconnect.garmin.com%2Fmodern%2F&gauthHost=https%3A%2F%2Fsso.garmin.com%2Fsso&locale=en_US&id=gauth-widget&cssUrl=https%3A%2F%2Fstatic.garmincdn.com%2Fcom.garmin.connect%2Fui%2Fcss%2Fgauth-custom-v1.2-min.css&clientId=GarminConnect&rememberMeShown=true&rememberMeChecked=false&createAccountShown=true&openCreateAccount=false&displayNameShown=false&consumeServiceTicket=false&initialFocus=true&embedWidget=false&generateExtraServiceTicket=true&generateTwoExtraServiceTickets=false&generateNoServiceTicket=false&globalOptInShown=true&globalOptInChecked=false&mobile=false&connectLegalTerms=true&locationPromptShown=true&showPassword=true#, error: HTTP Error 401: Unauthorized
Requesting Login ticket...Traceback (most recent call last):
File "gcexport.py", line 1061, in
main(sys.argv)
File "gcexport.py", line 863, in main
login_to_garmin_connect(args)
File "gcexport.py", line 514, in login_to_garmin_connect
login_response = http_req_as_string(URL_GC_LOGIN + '#', post_data, headers)
File "gcexport.py", line 271, in http_req_as_string
return http_req(url, post, headers).decode()
File "gcexport.py", line 247, in http_req
response = OPENER.open(request, data=post)
File "/usr/lib/python3.6/urllib/request.py", line 532, in open
response = meth(req, response)
File "/usr/lib/python3.6/urllib/request.py", line 642, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.6/urllib/request.py", line 570, in error
return self._call_chain(*args)
File "/usr/lib/python3.6/urllib/request.py", line 504, in _call_chain
result = func(*args)
File "/usr/lib/python3.6/urllib/request.py", line 650, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized

Login refused with Python 2.7

When trying to understand #60 I noticed that the exact same login request works with Python 3.x (3.9 in my case) and fails with Python 2.7.18

With Python 2.7.18 the request for a login ticket fails with HTTP status 403 (forbidden).

Somewhere between 2021-05-09 (of when I have a log of a successful request) and 2021-05-27 (issue #60 created) something must have changed on Garmin's servers.

I'm not an expert and haven't found so far what exactly is different between HTTP requests from Python 2.7 and Python 3.x

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.