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 sport’s activities 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
tokens = requests.post(url='https://www.strava.com/oauth/token',
data={'client_id': client_id,
'client_secret': client_secret,
'code': code,
'grant_type': 'authorization_code'})
#Save json response as a variable
strava_tokens = tokens.json()
with open('strava_tokens.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_tokens.json', 'r') as tokens:
data = json.load(tokens)
# 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_tokens.json', 'r') as tokens:
data = json.load(tokens)
# 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 expired 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_tokens.json', 'r') as tokens:
data = json.load(tokens)
if data['expires_at'] < time.time():
tokens = requests.post(url='https://www.strava.com/oauth/token',
data={'client_id': client_id,
'client_secret': client_secret,
'code': code,
'grant_type': 'authorization_code'})
# Let's save the new token
strava_tokens = tokens.json()
with open('strava_tokens.json', 'w') as outfile:
json.dump(strava_tokens, 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 write_token(tokens):
with open('strava_tokens.json', 'w') as outfile:
json.dump(tokens, outfile)
def get_token():
with open('strava_tokens.json', 'r') as tokens:
data = json.load(tokens)
return data
if not os.path.exists('./strava_tokens.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: ')
tokens = request_token(client_id, client_secret, code)
#Save json response as a variable
strava_tokens = tokens.json()
# Save tokens to file
write_token(strava_tokens)
data = get_token()
if data['expires_at'] < time.time():
new_tokens = request_token(client_id, client_secret, code)
# Update the file
write_token(new_tokens)
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 the 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, I’ll be glad to try it!





Leave a Reply