Skip to main content

endurance-metrics

Training metrics for endurance sports: CTL/ATL/TSB, ACWR, decoupling, and more.

Zero external dependencies — uses Python standard library only.

Installation

pip install endurance-metrics

Quick start

from endurance_metrics import compute_ctl_atl_tsb, calculate_acwr

# Compute fitness/fatigue/form from daily training loads
activities = [
    {"date": "2026-01-01", "load": 80},
    {"date": "2026-01-02", "load": 65},
    {"date": "2026-01-03", "load": 0},
    {"date": "2026-01-04", "load": 90},
]
ctl, atl, tsb = compute_ctl_atl_tsb(activities)
print(f"CTL={ctl:.1f}, ATL={atl:.1f}, TSB={tsb:.1f}")

# Compute Acute:Chronic Workload Ratio
acwr = calculate_acwr(activities)
print(f"ACWR={acwr:.2f}")

Features

Fitness metrics (endurance_metrics.fitness)

  • compute_ctl_atl_tsb() — Chronic/Acute Training Load and Training Stress Balance
  • compute_ctl_history() — CTL progression over time
  • compute_atl_history() — ATL progression over time
  • compute_tsb_history() — TSB progression over time
  • compute_fitness_summary() — Complete fitness summary
  • compute_form_trend() — Form trend analysis

Advanced metrics (endurance_metrics.advanced)

  • compute_ramp_rate() — CTL ramp rate (fitness loading speed)
  • compute_fitness_trend() — Multi-period fitness trend
  • compute_peak_fitness() — Peak CTL identification
  • detect_overtraining_risk() — Overtraining risk detection
  • compute_training_zones_distribution() — Training zones distribution
  • compute_periodization_score() — Periodization quality score

Workload metrics (endurance_metrics.workload)

  • calculate_acwr() — Acute:Chronic Workload Ratio
  • calculate_monotony_strain() — Training monotony and strain

Decoupling analysis (endurance_metrics.decoupling)

  • calculate_decoupling() — Effort:Cardio decoupling percentage
  • analyze_overtime() — Detailed overtime analysis with pacing assessment
  • compute_normalized_power() — Normalized Power (cycling)

Decoupling supports multiple effort types:

from endurance_metrics import calculate_decoupling

# Cycling (power-based, uses Normalized Power)
dec = calculate_decoupling(watts, hr, effort_type="power")

# Running (pace-based, uses rolling average)
dec = calculate_decoupling(pace, hr, effort_type="pace")

# Pre-normalized data
dec = calculate_decoupling(effort, hr, effort_type="raw")

API reference

Field names

Workload functions accept customizable field names:

from endurance_metrics import calculate_acwr

# Default: looks for "load" and "date" fields
acwr = calculate_acwr(activities)

# Custom field names
acwr = calculate_acwr(
    activities,
    load_field="tss",
    date_field="start_date",
)

Decoupling with threshold

from endurance_metrics import analyze_overtime

result = analyze_overtime(
    effort_data=watts,
    cardio_data=hr,
    prescribed_seconds=3600,
    effort_type="power",
    threshold=280,  # FTP or threshold value
)

Development

git clone https://github.com/stephanejouve/endurance-metrics.git
cd endurance-metrics
poetry install --with dev
poetry run pytest tests/ -v
poetry run black src/ tests/ --check --line-length=100
poetry run ruff check src/
poetry run isort src/ tests/ --check-only --profile black --line-length=100

License

MIT

Metadata

Release files for endurance-metrics 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 endurance-metrics 0.1.0
File Size Uploaded Provenance
endurance_metrics-0.1.0.tar.gz 12.3 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 25.7 kB

Release files / endurance_metrics-0.1.0.tar.gz

Download URL endurance_metrics-0.1.0.tar.gz
Size 12.3 kB
Tags Source
SHA-256 checksum
How to use checksums
73e67e46cf9fbefab1789445a9877aad11fde6893a7247d18c9623b7d0b34f83
BLAKE2b-256 checksum
How to use checksums
8d7d5041260ce287725a25aa1482397cf4e97ffbb705b1ec3ee642e9ac99dee1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.13.11 Darwin/20.6.0

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

Download URL endurance_metrics-0.1.0-py3-none-any.whl
Size 13.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
663f7556e4ef386a4c79433feb22076f58b0802406090a7ec9b5e6569a9c6b43
BLAKE2b-256 checksum
How to use checksums
d3dbdabf15504a58d6556ac8e42eb6a110f3dfdfd4422dd131b7a442fb7bef92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.2.1 CPython/3.13.11 Darwin/20.6.0

Security for endurance-metrics 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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