def get_client_or_authorize_url(): """Get strava client, or authorization URL if not authenticated""" client = Client() authorize_url = None if "strava_refresh_token" in session.keys(): client.refresh_token = session["strava_refresh_token"] LOGGER.debug("{} / {} / {}".format( session["strava_access_token"], session["strava_refresh_token"], session["strava_expires_at"], )) if ("strava_access_token" in session.keys() and int(session["strava_expires_at"]) > datetime.datetime.now().timestamp()): client.access_token = session["strava_access_token"] client.refresh_token = session["strava_refresh_token"] client.token_expires_at = session["strava_expires_at"] else: authorize_url = get_authorization_url() LOGGER.debug("Authorize URL: {}".format(authorize_url)) return client, authorize_url
def create_client(self): self.s3_file_manager.download_file('strava_auth.json', '/tmp/strava_auth.json') with open('/tmp/strava_auth.json') as auth_json: data = json.load(auth_json) access_token = data['access_token'] refresh_token = data['refresh_token'] expires_at = data['expires_at'] client = Client() client.access_token = access_token client.refresh_token = refresh_token client.token_expires_at = expires_at if time.time() > client.token_expires_at: print('Token has expired - refreshing...') refresh_response = client.refresh_access_token( client_id=int(os.getenv('STRAVA_CLIENT_ID', None)), client_secret=os.getenv('STRAVA_CLIENT_SECRET', None), refresh_token=client.refresh_token) with open('/tmp/strava_auth.json', 'w') as outfile: json.dump(refresh_response, outfile) self.s3_file_manager.upload_file('/tmp/strava_auth.json', 'strava_auth.json') return client
def get_strava_client(): token_dict = current_token_dict() if token_dict: client = Client() client.access_token = token_dict['access_token'] client.refresh_token = token_dict['refresh_token'] # If token is old, refresh it if time.time() > token_dict['expires_at']: app.server.logger.debug('Strava tokens expired, refreshing...') refresh_response = client.refresh_access_token(client_id=client_id, client_secret=client_secret, refresh_token=client.refresh_token) # Save to db save_strava_token(refresh_response) # Update client client.access_token = refresh_response['access_token'] client.refresh_token = refresh_response['refresh_token'] else: client = Client() return client
def read_strava(activity_id, access_token, refresh_token=None, client_id=None, client_secret=None, to_df=False, **kwargs): """ This method loads the activity data from Strava into a Pandas DataFrame or runpandas Activity. Column names are translated to runpandas terminology (e.g. "heartrate" > "heart_rate"). Datetimes indexes are replaced by time offsets. All NaN rows are removed. Attention: Two API requests are made to the Strava webservice: 1 to retrieve activity metadata, 1 to retrieve the raw data ("streams"). Parameters ---------- activity_id : str, The id of the activity access_token: str, The Strava access token refresh_token: str, The Strava refresh token, optional client_id: int, The Strava client id used for token refresh, optional client_secret: str, The strava client secret used for token refresh, optional to_df : bool, optional Return a obj:`runpandas.Activity` if `to_df=True`, otherwise a :obj:`pandas.DataFrame` will be returned. Defaults to False. **kwargs : Keyword args to be passed to the `read_strava` Returns ------- Return a obj:`runpandas.Activity` if `to_df=True`, otherwise a :obj:`pandas.DataFrame` will be returned. """ client = Client() client.access_token = access_token client.refresh_token = refresh_token activity = client.get_activity(activity_id) start_datetime = activity.start_date_local streams = client.get_activity_streams(activity_id=activity_id, types=STREAM_TYPES, series_type="time") data = pd.DataFrame(gen_records(streams)) times = data.pop("time") data.columns = map(utils.camelcase_to_snakecase, data.columns) def time_to_datetime(time): return start_datetime + timedelta(seconds=time) timestamps = times.apply(time_to_datetime) timeoffsets = timestamps - timestamps[0] timestamp_index = TimedeltaIndex(timeoffsets, unit="s", name="time") data.index = timestamp_index data.dropna(axis=1, how="all", inplace=True) if to_df: return data return Activity(data, cspecs=COLUMNS_SCHEMA, start=timestamps[0])
def read_strava( activity_id: int, access_token: str, refresh_token: str = None, client_id: int = None, client_secret: str = None, resample: bool = False, interpolate: bool = False, ) -> pd.DataFrame: """This method lets you retrieve activity data from Strava. Columns names are translated to sweat terminology (e.g. "heart_rate" > "heartrate"). Two API calls are made to the Strava API: 1 to retrieve activity metadata, 1 to retrieve the raw data ("streams"). Args: activity_id: The id of the activity access_token: The Strava access token refresh_token: The Strava refresh token. Optional. client_id: The Strava client id. Optional. Used for token refresh. client_secret: The Strava client secret. Optional. Used for token refresh. resample: whether or not the data frame needs to be resampled to 1Hz interpolate: whether or not missing data in the data frame needs to be interpolated Returns: A pandas data frame with all the data. """ client = Client() client.access_token = access_token client.refresh_token = refresh_token activity = client.get_activity(activity_id) start_datetime = activity.start_date_local streams = client.get_activity_streams( activity_id=activity_id, types=STREAM_TYPES, series_type="time", ) raw_data = dict() for key, value in streams.items(): if key == "latlng": latitude, longitude = list(zip(*value.data)) raw_data["latitude"] = latitude raw_data["longitude"] = longitude else: try: key = COLUMN_TRANSLATIONS[key] except KeyError: pass raw_data[key] = value.data data = pd.DataFrame(raw_data) def time_to_datetime(time): return start_datetime + timedelta(seconds=time) data["datetime"] = data["time"].apply(time_to_datetime) data = data.drop(["time"], axis="columns") data = data.set_index("datetime") data = resample_data(data, resample, interpolate) return data
#Open & refresh the access token if necessary access_token = None with open(STRAVA_DATA_DIR + '/access_token.pickle', 'rb') as f: access_token = pickle.load(f) logger.debug('Latest access token read from file: {0}'.format(access_token)) if time.time() > access_token['expires_at']: logger.info('Token has expired, will refresh') refresh_response = client.refresh_access_token(client_id=MY_STRAVA_CLIENT_ID, client_secret=MY_STRAVA_CLIENT_SECRET, refresh_token=access_token['refresh_token']) access_token = refresh_response with open(STRAVA_DATA_DIR + '/access_token.pickle', 'wb') as f: pickle.dump(refresh_response, f) logger.debug('Refreshed token saved to file') client.access_token = refresh_response['access_token'] client.refresh_token = refresh_response['refresh_token'] client.token_expires_at = refresh_response['expires_at'] else: logger.debug('Token still valid, expires at {}' .format(time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime(access_token['expires_at'])))) client.access_token = access_token['access_token'] client.refresh_token = access_token['refresh_token'] client.token_expires_at = access_token['expires_at'] #Start getting some data athlete = client.get_athlete() logger.info("Athlete's name is {} {}, based in {}, {}" .format(athlete.firstname, athlete.lastname, athlete.city, athlete.country)) if (args.list_gear): getusergear(logger, client)
# by providing a different # of days in the command line. # numdays = 14 if (len(sys.argv) > 1): numdays=int(sys.argv[1]) now=datetime.datetime.now() then=now - datetime.timedelta(numdays) # # Authenticate with Strava. # token_response = client.exchange_code_for_token(client_id=client_id, client_secret=client_secret, code=client_code) client.access_token = token_response['access_token'] client.refresh_token = token_response['refresh_token'] client.expires_at = token_response['expires_at'] athlete = client.get_athlete() print("Retrieving records of the past {days} days for {id}: {firstname} {lastname}".format( days=numdays, id=athlete.id, firstname=athlete.firstname, lastname=athlete.lastname)) activities = list(client.get_activities(after=then, before=now)) activities.reverse() for activity in activities: if (activity.gear_id is None): gear_name = "N/A" else: if ((gear is None) or gear.id != activity.gear_id): gear = client.get_gear(activity.gear_id)
def create_strava_client(): client = Client() client.access_token = STRAVA_ACCESS_TOKEN client.refresh_token = STRAVA_REFRESH_TOKEN return client
# make POST request to Strava API req = requests.post( "https://www.strava.com/oauth/token?client_id={}&client_secret={}&refresh_token={}&grant_type=refresh_token" .format(client_id, client_secret, refresh_token)).json() # update API credentials file api_credentials['access_token'] = req['access_token'] api_credentials['refresh_token'] = req['refresh_token'] with open('.secret/api_credentials.json', 'w') as f: json.dump(api_credentials, f) # store new access token client.access_token = api_credentials['access_token'] client.refresh_token = api_credentials['refresh_token'] client.token_expires_at = api_credentials['expires_at'] # athlete = client.get_athlete() # All fields # athlete.to_dict() def get_activity_summaries(date_since=""): if date_since == "": date_since = str(datetime.datetime.now() - datetime.timedelta(1)) df_perm = pd.DataFrame() # initialize empty dataframe activities = client.get_activities(after=date_since) my_cols = [ 'name', 'start_date_local', 'start_date', 'type', 'distance',