Skip to main content

Hi,

I'm trying to make an script on python to upload all my old activities.

Created the app on the portal, and got client_id and client secret.

 

 

import os

import requests

import urllib3



urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)



CLIENT_ID = "my_client_id"

CLIENT_SECRET = "my_secret"

REFRESH_TOKEN = "my_refresh"



def get_access_token():

auth_url = "https://www.strava.com/oauth/token"

payload = {

'client_id': CLIENT_ID,

'client_secret': CLIENT_SECRET,

'refresh_token': REFRESH_TOKEN,

'grant_type': "refresh_token",

'scope': 'activity:write',

'f': 'json'

}



print("Requesting Token...

")

res = requests.post(auth_url, data=payload, verify=False)



try:

res.raise_for_status()

access_token = res.json()['access_token']

print("Access Token = {}

".format(access_token))

return access_token

except requests.exceptions.HTTPError as err:

print(f"HTTP Error: {err}")

print("Response content:", res.text)

return None

except KeyError as err:

print("KeyError:", err)

print("Response content:", res.text)

return None



def upload_activities_from_folder(folder_path):

activites_url = "https://www.strava.com/api/v3/uploads"



access_token = get_access_token()

if access_token is None:

print("Failed to obtain access token.")

return



header = {'Authorization': 'Bearer ' + access_token}



for filename in os.listdir(folder_path):

if filename.endswith(".gpx"):

file_path = os.path.join(folder_path, filename)

files = {'file': open(file_path, 'rb')}

res = requests.post(activites_url, headers=header, files=files)

print(res.json())



if __name__ == "__main__":

activities_folder = "C:\Users\z\Desktop\all"

upload_activities_from_folder(activities_folder)

 

 

I am getting an error of permissions, but I'm not sure why

 

 

{'message': 'Authorization Error', 'errors': [{'resource': 'AccessToken', 'field': 'activity:write_permission', 'code': 'missing'}]}

 

 


Also to debug I tried to make it manually, getting the url, authorizing read and write, getting the code and using the code of the result

 

 

from stravalib.client import Client

import os



# Strava application credentials

CLIENT_ID = 'my_client_here'

CLIENT_SECRET = 'my_code_here'

CALLBACK_DOMAIN = 'localhost'





ACTIVITIES_DIR = 'C:\Users\zzzzz\Desktop\all'



# Create client

client = Client()

authorize_url = client.authorization_url(client_id=CLIENT_ID, redirect_uri=f'http://{CALLBACK_DOMAIN}/authorized', scope = ["activity:write", "read"])

print(" go to {authorize_url} and authorize access.')

authorization_code = input('Paste the authorization code here: ')



try:

access_token = client.exchange_code_for_token(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, code=authorization_code)

print("Access token obtained successfully.")

except Exception as e:

print(f"Failed to obtain access token: {e}")

exit()



# Authenticate with the access token

client = Client(access_token=access_token)



# Function to upload activities from a folder

def upload_activities_from_folder(folder_path):

for filename in os.listdir(folder_path):

if filename.endswith('.gpx'):

activity_file = os.path.join(folder_path, filename)

try:

client.upload_activity(activity_file, data_type='gpx')

print(f"Uploaded activity: {filename}")

except Exception as e:

print(f"Failed to upload activity {filename}: {e}")



# Upload activities from the specified directory

upload_activities_from_folder(ACTIVITIES_DIR)

 

 

In this case, I get this

 

 

No rates present in response headers

Access token obtained successfully.

No rates present in response headers

Failed to upload activity activity_11024948997.gpx: [{'resource': 'Athlete', 'field': 'access_token', 'code': 'invalid'}]

No rates present in response headers

Failed to upload activity activity_11442231651.gpx: [{'resource': 'Athlete', 'field': 'access_token', 'code': 'invalid'}]

 

 

 I don't get it 🙂 Any help would be apreciated!

Hey zz,


Take a look at our  Authenication doco which hopefully assist you in your issue. I also found this post that talks about a activity:read error. It seemed similar enough to mention and might shed some light on the issue you've encountered.


 


Reply