Welcome guys to a new episode of the #getyourdata series with Python. Here we’ll learn how to interact with Strava API through RESTful requests to get your sports data. This could be an interesting chance to improve your Python skill and your ability to scrape and collect data.
The Swagger Client
In Strava’s API Getting Start Guide, developers suggest to use Swagger Playground to interact with Strava API submitting HTTP requests and processing the response. I tried, but I don’t like the approach. Too many complications to installing the Swagger Client that maybe we will use only this time in our entire developer’s life. Instead, we can proceed with an easy and elegant Python solution!
Before Starting
Before starting, you need to register an account on Strava. Don’t worry, it is not required a premium account to use API.
Create Strava App
First, we need to create an App to access Strava API. So, go on the Developers Strava Website and click on Create & Manage your App.

Name your App
Once you’ve clicked on Create & Manage your App, you’ll reach the App settings.

Strava asks us for some information about our new App.
- First, the name of the App. I’ve typed “MyExampleApp”.
- Second, the category. I’ve chosen “Performance Analysis”, but you can choose what you prefer.
- Third, the description, insert a little text that describes your App
- Finally, another required field is Authorization Callback Domain. Here you can insert your website (like in my case) or you can just insert http://localhost/.
Note: The club and website are not required fields.
Attention! Choose an Icon
Once you click on Create, you have to upload an AppIcon. This is a mandatory step, otherwise, the App will not be created.

For my app, I have taken the icon from IconArchive, a nice icons repository.
Congratulations! You’ve created your first App in Strava that allow you to use its RESTful API. But Keep calm! the work is not ended.
Client and Secret ID
Now, you should be redirected to your account settings, in the section My API Application, if not, you can reach the mentioned section at the following link: My API Application
You should see your App information and settings as shown in the following figures.


In particular, the most important fields are the Client ID and the Client Secret, also the Access Token is equally important, but we’ll see how to get it automatically.
Ok! Keep a note of your App’s info and, let’s get started with coding!
Get the Token
As you should know, most APIs require the Access Token, and Strava doesn’t make exceptions.
import json import os import requests import time # Initial Settings client_id = 'XXXXXXXXX' client_secret = 'XXXXXXXXXXXXXXX' redirect_uri = 'http://localhost/' # Authorization URL request_url = f'http://www.strava.com/oauth/authorize?client_id={client_id}' \ f'&response_type=code&redirect_uri={redirect_uri}' \ f'&approval_prompt=force' \ f'&scope=profile:read_all,activity:read_all' # User prompt showing the Authorization URL # and asks for the code print('Click here:', request_url) print('Please authorize the app and copy&paste below the generated code!') print('P.S: you can find the code in the URL') code = input('Insert the code from the url: ') # Get the access token token = requests.post(url='https://www.strava.com/api/v3/oauth/token', data={'client_id': client_id, 'client_secret': client_secret, 'code': code, 'grant_type': 'authorization_code'}) #Save json response as a variable strava_token = token.json() with open('strava_token.json', 'w') as outfile: json.dump(strava_tokens, outfile)

Run the code and click on the generated link and, as a result, you will see the Authorization page.

Authorize your App and, you will reach the redirection URL you have set, in this case, http://localhost/

Let’s have a look at your URL, you should see the keyword code followed by the authorization code you need, copy and paste it in the previous prompt.
Congratulations again! The majority of the work is gone, now let’s focus on collecting our data!
Get Athlete Data
First, let’s grab the Athlete information.
# Read the token from the saved file with open('strava_token.json', 'r') as token: data = json.load(token) # Get the access token access_token = data['access_token'] # Build the API url to get athlete info athlete_url = f"https://www.strava.com/api/v3/athlete?" \ f"access_token={access_token}" # Get the response in json format response = requests.get(athlete_url) athlete = response.json() # Print out the retrieved information print('RESTful API:', athlete_url) print('='* 5, 'ATHLETE INFO', '=' * 5) print('Name:', athlete['firstname'], '"' + athlete['username'] + '"', athlete['lastname']) print('Gender:', athlete['sex']) print('City:', athlete['city'], athlete['country']) print('Strava athlete from:', athlete['created_at'])

You can note how simple is to make a request to Strava API. Don’t forget, you can find other RESTful requests and examples of their use in the documentation.
Get your activities
It’s time to ask for your activities. Here is the code.
# Read the token from the saved file with open('strava_token.json', 'r') as token: data = json.load(token) # Build the API url to get activities data activities_url = f"https://www.strava.com/api/v3/athlete/activities?" \ f"access_token={access_token}" print('RESTful API:', activities_url) # Get the response in json format response = requests.get(activities_url) activity = response.json()[5] # Print out the retrieved information print('='*5, 'SINGLE ACTIVITY', '='*5) print('Athlete:', athlete['firstname'], athlete['lastname']) print('Name:', activity['name']) print('Date:', activity['start_date']) print('Disance:', activity['distance'], 'm') print('Average Speed:', activity['average_speed'], 'm/s') print('Max speed:', activity['max_speed'], 'm/s') print('Moving time:', round(activity['moving_time'] / 60, 2), 'minutes') print('Location:', activity['location_city'], activity['location_state'], activity['location_country'])

The code is similar to the previous one, the only thing that changes is the RESTful API request. In this example, I print out a single activity, but you can iterate the response.json() and print all the activities you want with desired info.
Do you like music during sports?
Python easy way to get your data from Spotify
Refresh the token
Do you know Access Token has a time limit? If you have no idea about it, I’m explaining you.
Access Tokens usually have an expiration time, in other words, these tokens don’t live forever. This is a sort of security mechanism. Because of this, you need to refresh your token after a given time interval.
# If access_token has expired then # use the refresh_token to get the new access_token with open('strava_token.json', 'r') as token: data = json.load(token) if data['expires_at'] < time.time(): token = requests.post(url='https://www.strava.com/api/v3/oauth/token', data={'client_id': client_id, 'client_secret': client_secret, 'grant_type': 'refresh_token', 'refresh_token': data['refresh_token']}) # Let's save the new token strava_token = token.json() with open('strava_token.json', 'w') as outfile: json.dump(strava_token, outfile)
Put them all together
Finally, we can put it all together for our future projects. Here is the final Python script.
import json import os import requests import time client_id = 'XXXXXXX' client_secret = 'XXXXXXX' redirect_uri = 'http://localhost/' def request_token(client_id, client_secret, code): response = requests.post(url='https://www.strava.com/oauth/token', data={'client_id': client_id, 'client_secret': client_secret, 'code': code, 'grant_type': 'authorization_code'}) return response def refresh_token(client_id, client_secret, refresh_token): response = requests.post(url='https://www.strava.com/api/v3/oauth/token', data={'client_id': client_id, 'client_secret': client_secret, 'grant_type': 'refresh_token', 'refresh_token': refresh_token}) return response def write_token(token): with open('strava_token.json', 'w') as outfile: json.dump(token, outfile) def get_token(): with open('strava_token.json', 'r') as token: data = json.load(token) return data if not os.path.exists('./strava_token.json'): request_url = f'http://www.strava.com/oauth/authorize?client_id={client_id}' \ f'&response_type=code&redirect_uri={redirect_uri}' \ f'&approval_prompt=force' \ f'&scope=profile:read_all,activity:read_all' print('Click here:', request_url) print('Please authorize the app and copy&paste below the generated code!') print('P.S: you can find the code in the URL') code = input('Insert the code from the url: ') token = request_token(client_id, client_secret, code) #Save json response as a variable strava_token = token.json() # Save tokens to file write_token(strava_token) data = get_token() if data['expires_at'] < time.time(): print('Refreshing token!') new_token = refresh_token(client_id, client_secret, data['refresh_token']) strava_token = new_token.json() # Update the file write_token(strava_token) data = get_token() access_token = data['access_token'] athlete_url = f"https://www.strava.com/api/v3/athlete?" \ f"access_token={access_token}" response = requests.get(athlete_url) athlete = response.json() print('RESTful API:', athlete_url) print('='* 5, 'ATHLETE INFO', '=' * 5) print('Name:', athlete['firstname'], '"' + athlete['username'] + '"', athlete['lastname']) print('Gender:', athlete['sex']) print('City:', athlete['city'], athlete['country']) print('Strava athlete from:', athlete['created_at']) activities_url = f"https://www.strava.com/api/v3/athlete/activities?" \ f"access_token={access_token}" print('RESTful API:', activities_url) response = requests.get(activities_url) activity = response.json()[5] print('='*5, 'SINGLE ACTIVITY', '='*5) print('Athlete:', athlete['firstname'], athlete['lastname']) print('Name:', activity['name']) print('Date:', activity['start_date']) print('Disance:', activity['distance'], 'm') print('Average Speed:', activity['average_speed'], 'm/s') print('Max speed:', activity['max_speed'], 'm/s') print('Moving time:', round(activity['moving_time'] / 60, 2), 'minutes') print('Location:', activity['location_city'], activity['location_state'], activity['location_country'])
Now, the whole process of getting your data from Strava is fully automated, except for the first run when you have to insert the authorization code. Next step? You can save data in a CSV file through Pandas and visualize the data with your preferred visualization tool. I like Plotly.
Conclusion
I hope this helps you! It is a simple and elegant solution to interact with Strava’s API using basic Python libraries. Moreover, if you find a library that makes this work for us or you want to create your own, let me know in a comment, and I’ll be glad to try it!
2 Comments
Great idea, i want to apply this example for challenge ride ( https://bike.akkerman.club/challenge ). Thx
Wonderful idea! Good Luck 🙂