Strava Api upload activity is giving error {"message":"Bad Request","errors":[{"resource":"Upload","field":"data","code":"empty"}]}

247 views Asked by At

I'm working on a personal project that gets input from a user where they choose where they started on a hiking trail and where they finished and it will automatically upload the gps data of that hike to their strava account. That part of the project is already completed and tested, ive uploaded the files to strava manually and they have worked. My current issue is when I try to upload the activity to strava using their uploads api I get this error "{"message":"Bad Request","errors":[{"resource":"Upload","field":"data","code":"empty"}]}". I've gotten other strava api functions to work no problem but this api function is throwing me for a loop because of passing the .gpx file. I've tried online resources but haven't made any progress. If anyone has experience or could guide me in the right direction it would be most appreciated. Here is my code:

import json
import os
import boto3
import urllib3
from io import BytesIO


def lambda_handler(event, context):
http = urllib3.PoolManager()
    
    client_id = 'XXXX'
    client_secret = 'XXXXXXXXXXXX'
    code = 'XXXXXXXXXXXXXXXXXX'
    grant_type = 'authorization_code'
    
    urlToken = 'https://www.strava.com/api/v3/oauth/token'
    headers = {
        'Content-Type': 'application/json'
    }
    body = {
        'client_id': client_id,
        'client_secret': client_secret,
        'code': code,
        'grant_type': grant_type
    }
    
    response = http.request('POST', urlToken, headers=headers, body=json.dumps(body).encode('utf-8'))
    response_data = json.loads(response.data.decode('utf-8'))
    strava_access_token = response_data['access_token']
    print("access token is: "+strava_access_token)
    
    # create an S3 client
    s3 = boto3.client('s3')
    
    # define the bucket and file name
    bucket_name = 'XXXXXXXXX'
    file_name = 'newFile1.gpx'
    
    # download the file from S3 to a temporary file in the /tmp directory
    with open('/tmp/' + file_name, 'wb') as f:
        s3.download_fileobj(bucket_name, file_name, f)
    
    # read the contents of the file
    with open('/tmp/' + file_name, 'rb') as f:
        gpx_data = f.read()
        
    print(gpx_data)
    
    # convert the bytes to a string
    gpx_data_str = gpx_data.decode()
    
    
    # Create the request headers
    headers = {
        'Authorization': f'Bearer {strava_access_token}',
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'multipart/form-data',
        'Content-Disposition': 'attachment; filename="testRoute.gpx"'
    }
    
    # create the data payload
    data = {
        "data_type": "gpx",
        'file': (file_name, gpx_data, 'application/gpx+xml')
    }
    
    # Send the request
    response = http.request(
        method='POST',
        url='https://www.strava.com/api/v3/uploads',
        headers=headers,
        fields=data
    )
    
    # Print the response
    print(response.data.decode())

message = "testing message"
return message


I tried using a different file, ive tried opening the file differently ive tried changing the params, ive tried changing Content-Type and a few other things. I think I might be missing something obvious but at this point I think a fresh set of eyes would help

1

There are 1 answers

0
OzcarsHere On

Figured out the issue. I needed to remove this line from my header

Accept': 'application/json, text/plain, */*',

and all the file names needed to match. I also had to change around what was encoded and decoded but that was dependent on the file being used. Hopefully this helps anyone else who has the same issue.