Skip to main content

A library for analyzing data from distance runners

Project description

The Running API

The Running API is a python library intended to provide functionality for organizing and understanding data from various running activities. Funcitons and classes for both trainig runs and races are included as well as helpers for implementing functions from the Strava API.

Strava Client

The Running API comes with classes that automate the interaction with the Strava REST API. This allows The Running API to quickly grab runs that have been posted to Strava profiles and clubs assuming the user has an available application registered with Strava.

Let's see an example of how to instance a Strava activities client to pull data from a series of runs.

Note: You will need to set up a Strava application first and get the Client ID and Client Secret at well as the authorization token and other information related to the athlete profile. Strava has instructions on how to set this up here.

from running_api.utils.strava_utils import StravaActivitiesClient
from running_api.schemas.schemas import AthleteStravaAccessToken, StravaClientConfig

# set up some pre-requisites
# you will need to substitue your own values
athlete_token = AthleteStravaAccessToken(
    athlete_name = "Test Athlete",
    token_type = "Bearer",
    access_token = "Test Token",
    expires_at = 100000,
    expires_in = 100000,
    refresh_token = "Test Refresh Token",
)

client_config = StravaClientConfig(
    client_id = 10000,
    client_secret = "Test Secret",
)

# initialize the client
client = StravaActivitiesClient(
    athlete_token,
    client_config
)

# now let's grab some activity data!
single_activity = client.get_individual_activity_stats(
    "Test Activity ID"
)

# we can also grab a series of runs in a time range
many_activities = client.get_activities_in_time_range(
    start = "2023-10-10T00:00:00",
    end = "2023-10-15T00:00:00",
)

Note that all of the data returned from these functions are in json format. This can be occasionally cumbersome to work with, so The Running API has provided the user with some custom workout datatypes to load these activities into.

Note: A particular quirk in how authentication is handled with the Strava API requires that the access token be refreshed after 6 hours. The StravaActivitiesClient handles this automatically, but the new values for the access_token, refresh_token, and the expiration timeout values will need to be stored somewhere for the next use otherwise the user will need to generate a fresh set of tokens as outlined in the Strava API documentation. It is suggested that these updated values are continuously saved into a file and loaded any time a new set of activities is pulled. Simply pull the up-to-date access token information by getting the StravaActivitiesClient.athlete_token attribute and then save to a file.

Loading Workout Activities

As mentioned above, if one would like a simple interface to organize and load many workouts into a list of custom datatypes, we have a specialized function to do just that.

from running_api.utils.training_utils import get_training_runs

# reuse the client created in the previous section
# initialize the client
client = StravaActivitiesClient(
    athlete_token,
    client_config
)

training_runs = get_training_runs(
    client, 
    start = "2023-10-10T00:00:00",
    end = "2023-10-15T00:00:00",
)

The training_runs object is a list storing each activity as a TrainingRun class. This hopefully will be a little easier to manage than the dict\json object. In addition, functions such as convert_training_runs_to_df are provided to convert lists of TrainingRun objects into dataframes for even more flexibility.

Racing Tools

There are also some niffty ways to organize and track racing data. Let's suppose we want to note down what an athlete has done for a particular race. We can use a real-life example from the 2024 US Olympic Trials.

from running_api.utils.race_utils import Race, RaceType
from farcaster.utils.data_utils import save_races

# let's log a track race
individual_race = Race(
    athlete = "Grant Fisher",
    race_name = "U.S. Olympic Trials",
    date = "2024-06-21T22:27:00",
    tot_time = 1669.47, #s
    tot_distance = 10000, #m
    location = "Eugine, OR",
    race_type = RaceType.OUTDOOR_TRACK,
)

# let's add the first 400m as a split
individual_race.add_split(
    time = 64.43,
    start_loc = 0.0,
    end_loc = 400.0,
)

# now we can can save this race to a json file for later analysis
race_collection = [individual_race] # this can be a list of many races

save_races(race_collection, "races.json")

Analysis

There are a few ways that these training and racing activities can be processed. One of the first ways that one can evaluate a set of training runs would be to find the total volume of a collection of workouts.

Currently, The Running API calculates volume by $V = mileage*intensity$. Practically, over a collection of runs, this is computed using $V=\sum_{i=0}^{N} m(i)pe(i)$ where $m(i)$ is the total miles for run $i$ and $pe(i)$ is the percieved effort, usually expressed as a range from 1-10. There are certainly many other ways to compute volume, but this appears simple enough to be useful to a broad range of users.

Let's take a collection of training runs over the course of a week runs, collected using the get_training_runs function, and calculate the volume using the above fomula assuming percieved effort values are included.

from running_api.analysis.metrics import collection_volume

weekly_volume = collection_volume(runs)

The user can also set flags based on volume to evaluate if some volume or mileage limit has been reached.

from running_api.analysis.flags import is_high_volume_collection, is_high_mileage_collection

high_volume = is_high_volume_collection(
    runs, 
    volume_limit = 500, 
    distance_units = "km", # set distance to km
)
high_mileage = is_high_mileage_collection(
    runs, 
    mileage_limit = 40, 
    distance_units = "mi", # distance in miles
)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

the_running_api-0.2.0.tar.gz (4.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

the_running_api-0.2.0-py3-none-any.whl (4.5 kB view details)

Uploaded Python 3

File details

Details for the file the_running_api-0.2.0.tar.gz.

File metadata

  • Download URL: the_running_api-0.2.0.tar.gz
  • Upload date:
  • Size: 4.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for the_running_api-0.2.0.tar.gz
Algorithm Hash digest
SHA256 39ee102695cdcbdba6927d1b852e026a0fcb6f729d1f1de2d1941dd281dcac88
MD5 f9865248cd9d335144b4d662d1e29f7a
BLAKE2b-256 3b71d99675733ddee67422494debdd56b17a06cb71b4c7999a8363e045dc6f2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for the_running_api-0.2.0.tar.gz:

Publisher: publish.yml on csacco1/running-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file the_running_api-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for the_running_api-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93b7d9ae60955a15eab44a1c9833521190dc11039043285a2fa985ec4aaea478
MD5 4dccfef3bf1f39d32b1e81e0e53c6132
BLAKE2b-256 5fd2ef8f33ea4cff72392db4f54852c863d8d3bb16ff433d12ee5a76cfbdbaaa

See more details on using hashes here.

Provenance

The following attestation bundles were made for the_running_api-0.2.0-py3-none-any.whl:

Publisher: publish.yml on csacco1/running-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page