After updating VSCode to May 2025 (v1.101) on Windows, I found that any WSL terminals failed to open. Somehow VSCode was now trying to use “C:\WINDOWS\System32\bash.exe” to run the WSL terminals which was resulting in the following errors:
The terminal process "C:\WINDOWS\System32\bash.exe '-d', 'Debian'" terminated with exit code: 2.
The terminal process "C:\WINDOWS\System32\bash.exe '-d', 'Ubuntu'" terminated with exit code: 2.
The solution is to update the VSCode settings to use the correct WSL executable. The settings are located in the `settings.json` file at C:\Users\<YourUsername>\AppData\Roaming\Code\User\settings.json.
Look for “terminal.integrated.profiles.windows” and if it doesn’t exist, you can add it. If it does exist, ensure that the WSL profile is set to use `wsl.exe` instead of `bash.exe`. Here is the code snippet you need to add or modify in your `settings.json` file:
The current Strava API does not allow for users to request activities in the form of a gpx file. The strava2gpx package for Python uses the Strava API to pull data streams which it then compiles into GPX files, effectively allowing users to get GPX files from the Strava API. This tutorial will cover usage of the strava2gpx package in Python.
Before beginning, it is important to note that gpx files deal with gps data, so Strava activities that do not have gps data, currently will not work with the strava2gpx package. (eg. Yoga, Weightlifting, Pool Swimming, etc.)
Why not use strava.com/activities/id/export_gpx?
The /export_gpx endpoint is useful for some, but is more complicated because accessing private activities requires extra code for authenticating a user and getting the resulting cookies for authentication. This way is much simpler and through the official Strava API.
Will this get heartrate data?
Yes, the strava2gpx package will grab all heartrate, position, power (watts), temperature, and cadence data and encode them into the resulting gpx file using the commonly used Garmin GpxExtensions format.
Installing strava2gpx
The strava2gpx Python package is available through PyPi and can be downloaded easily by running the following command in your development environment:
pip install strava2gpx
strava2gpx installation in terminal
Getting Strava API Access
If you already have your credentials for Strava API access you can skip this section. Go to https://www.strava.com/settings/api and if you have not already, go through the steps to create an app there. Eventually, you should get to a screen that looks like this:
The information that we are interested in is the Client ID, Client Secret, and the Refresh Token. Copy those down in a safe spot and don’t share them.
Next go to the following url and replace YOUR_CLIENT_ID with the Client ID that we just copied down.
We are interested in the code part of the url that it redirected to, which in this example is the part that says “9ds8fg340vss0f98sd3fdefwfs.” Copy that down as well. That will be YOUR_AUTH_CODE that we use later.
Now run the following curl command in the terminal, being sure to replace the YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, and YOUR_AUTHORIZATION_CODE with the values we have previously retrieved:
Copy down this new refresh_token for the next section.
Getting the GPX File in Python
Copy the code below into your code editor and replace client_id, client_secret, and refresh_token with their respective values you copied in the previous section from the Strava API. The client_id and client_secret come from the Strava API page and the refresh_token comes from the various web requests we made.
fromstrava2gpximportstrava2gpximportasyncioasync def main():
'''
put in your Strava Api client_id, refresh_token, and client_secret
'''client_id = '123456'
refresh_token = 'adfh750a7s5df8a00dh7asdf98a9s8df6s9asdf8'
client_secret = 'ahgdyt5672i3y8d345hgd2345c23hjgd1234yd23'
# create an instance of strava2gpx s2g = strava2gpx(client_id, client_secret, refresh_token)
# connect to the Strava APIawaits2g.connect()
# write activity to output.gpx by activity idawaits2g.write_to_gpx(11893637629, "output")
if __name__ == '__main__':
asyncio.run(main())
On the line
# write activity to output.gpx by activity idawaits2g.write_to_gpx(11893637629, "output")
you can replace the number (11893637629) with one of your own Strava activity IDs which can be found in the url when looking at them in Strava. (Ex: strava.com/activities/11893637629) This will pull the data from that activity and then compile it into a file called output.gpx. You can change the name of the file by editing the second argument where it currently reads “output”.
Save the python file as strava2gpx.py and run it in the terminal with the following command
python3 strava2gpx.py
When the program has run to completion, you will have an “output.gpx” file in the same directory. This file can be uploaded to other services like Garmin Connect and similar and contains all data like heartrate, power, etc.
Advanced Usage
The package provides an additional function called get_activities_list() which will get a list of all the user’s data and store it in a list of lists where each element is in the following format:
This gives room for bulk processing of activities using custom actions like using date-time to choose what activities are processed or naming them by id and whatnot. Below is an example of calling the function.
fromstrava2gpximportstrava2gpximportasyncioasync def main():
'''
put in your Strava Api client_id, refresh_token, and client_secret
'''client_id = '123456'
refresh_token = 'adfh750a7s5df8a00dh7asdf98a9s8df6s9asdf8'
client_secret = 'ahgdyt5672i3y8d345hgd2345c23hjgd1234yd23'
# create an instance of strava2gpx s2g = strava2gpx(client_id, client_secret, refresh_token)
# connect to the Strava API
awaits2g.connect()
# get a list of all user's Strava activities
activities_list = awaits2g.get_activities_list()print(activities_list[0:5])
if __name__ == '__main__':
asyncio.run(main())
The above code would generate the following output:
[
['Legs may be sore', 11910466229, '2024-07-17T11:57:21Z', 'Ride'],
['Tall Grass, Hidden Dirt', 11906994862, '2024-07-17T00:10:57Z', 'Ride'],
['A little thunder there, a little MTB here', 11898361818, '2024-07-16T01:16:13Z', 'Ride'],
['Morning Run', 11893637629, '2024-07-15T11:50:49Z', 'Run'],
['Afternoon Yoga', 11880523323, '2024-07-13T19:09:04Z', 'Yoga']
]