Skip to main content

trainingload

CI PyPI Python License: MIT

Training-load metrics and Strava archive parsing for endurance sport — with zero runtime dependencies.

trainingload is a small, typed Python toolkit for the math behind endurance training analytics: Training Stress Score (TSS) for swim/bike/run/strength, the Performance Management Chart (CTL / ATL / TSB), and a parser for Strava's bulk data export. It's the load engine extracted from the production codebase of Motus — an AI triathlon coach — and packaged so you can drop it into a notebook, a script, or your own app.

No NumPy, no pandas, no web framework. Just the standard library.


Install

pip install trainingload

Requires Python 3.10+.

Quick start

from datetime import date
from trainingload import calculate_pmc

# Daily Training Stress Score -> fitness (CTL), fatigue (ATL), form (TSB)
series = calculate_pmc({
    date(2026, 1, 1): 80.0,
    date(2026, 1, 2): 120.0,
    date(2026, 1, 3): 0.0,    # rest day
})
today = series[-1]
print(today.ctl, today.atl, today.tsb)

What's inside

Three independent modules — use one or all three.

1. trainingload.tss — Training Stress Score

Sport-aware TSS from whatever data you have (power, pace, heart rate, or just duration), with sensible fallbacks.

from trainingload import TSSCalculator, TrainingZones

zones = TrainingZones(bike_ftp=250, run_threshold_pace=300, swim_css=95)

# Cycling from normalized power:
TSSCalculator.calculate_bike_tss(duration_seconds=3600, normalized_power=200, ftp=250)  # 64.0

# Or let it pick the best method for the sport and data available:
TSSCalculator.estimate_tss(sport_type="run", duration_seconds=3600,
                           distance_meters=10000, zones=zones)  # 69.4

# Show your work — which method, inputs and formula were used:
TSSCalculator.explain_tss_calculation(sport_type="bike", duration_seconds=3600,
                                      tss=64.0, normalized_power=200, zones=zones)

2. trainingload.pmc — Performance Management Chart

CTL/ATL/TSB time series and a current-fitness snapshot from a map of daily TSS.

from datetime import date
from trainingload import fitness_summary, interpret_tsb, recommend_training

summary = fitness_summary(daily_tss)          # {date: tss} -> ctl/atl/tsb + ramp rate
print(interpret_tsb(summary.tsb))             # e.g. "fresh"
print(recommend_training(summary.tsb, target_event_days=7))
  • CTL (Chronic Training Load) — 42-day EMA of TSS → fitness
  • ATL (Acute Training Load) — 7-day EMA of TSS → fatigue
  • TSB (Training Stress Balance) — CTL − ATL → form

3. trainingload.strava — bulk-export parser

Turn the activities.csv from a Strava data export into typed records. Accepts a file path or an in-memory stream (e.g. an upload), so it works server-side or in a worker without touching disk.

from trainingload import StravaArchiveParser

parser = StravaArchiveParser()
activities = parser.parse_zip_activities("strava_export.zip")
meta = parser.parse_zip("strava_export.zip")   # totals, date range, sport breakdown

End-to-end: Strava export → fitness curve

See examples/strava_to_pmc.py for the full flow — parse the archive, score every activity, and print your current CTL/ATL/TSB:

python examples/strava_to_pmc.py path/to/strava_export.zip

Accuracy & credits

TSS, NP/IF, and the CTL/ATL/TSB model come from the endurance-training literature popularised by Hunter Allen & Andrew Coggan (Training and Racing with a Power Meter) and the TrainingPeaks Performance Management Chart. The implementations here are independent and intentionally transparent — every formula is documented in the source and covered by tests.

Trademark note. "TSS", "CTL", "ATL", "TSB", "NP" and "IF" are used in this project descriptively to refer to widely-documented training-load concepts. They are trademarks of Peaksware, LLC (TrainingPeaks). This project is not affiliated with, sponsored by, or endorsed by TrainingPeaks or Strava.

Built by Motus

trainingload powers the analytics inside Motus, an AI coach for runners and triathletes. If you want the metrics in this library turned into adaptive training plans, race predictions and a coach in your pocket, give Motus a try — and read the training-science guides on the Motus blog.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md.

License

MIT © Motus

Release files for trainingload 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trainingload 0.1.0
File Size Uploaded
trainingload-0.1.0.tar.gz 23.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for trainingload 0.1.0
File Interpreter ABI Platform
trainingload-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.9 kB

Release files / trainingload-0.1.0.tar.gz

Download URL trainingload-0.1.0.tar.gz
Size 23.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2d1e50111b27b21593343791d3e4bc13147e549a62edaf28eaa5e658cfab271b
BLAKE2b-256 checksum
How to use checksums
4b61ebf40dc5603f994bf647f58bbcc72c321b15c1ece4af61e99c79893357ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.

Transparency log

Release files / trainingload-0.1.0-py3-none-any.whl

Download URL trainingload-0.1.0-py3-none-any.whl
Size 17.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
60bc5eabe9c92924bbb10b0a2f0b9da23245de5dcc39fddeb3e851d7a0c0f703
BLAKE2b-256 checksum
How to use checksums
fb8170cba1ca1d28441b8fd7b5df9942eb0533742f3dc24512f6123e89c3ca53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page