This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Stravalib is a Python library providing easy-to-use tools for accessing and downloading Strava data from the Strava V3 REST API. The library supports authentication, rate limiting, data access/download, and unit conversion through the Pint library.
Run all tests across all supported Python versions (3.10-3.14):
nox -s testsRun tests for a specific Python version:
nox -s tests-3.11Run a single test file:
pytest src/stravalib/tests/unit/test_client.pyRun a specific test:
pytest src/stravalib/tests/unit/test_client.py::test_nameRun mypy type checking:
nox -s mypyThe project uses pre-commit hooks with ruff (linting), black (formatting), and codespell (spell checking).
Install pre-commit hooks:
pre-commit install --install-hooksRun pre-commit on all files:
pre-commit run --all-filesRun a specific hook:
pre-commit run ruff --all-filesBuild docs:
nox -s docsBuild docs with live reload (for local development):
nox -s docs-liveClean doc build artifacts:
nox -s docs-cleanBuild the package (creates wheel and sdist in dist/):
nox -s buildClean build artifacts:
nox -s clean_buildClient (client.py): Main interface for interacting with Strava V3 API. The Client class handles:
- Authentication and token management (including automatic token refresh)
- Rate limiting via
stravalib.util.limiter.RateLimiter - All API method calls (activities, athletes, clubs, segments, etc.)
- Batch iteration over paginated results via
BatchedResultsIterator
Protocol (protocol.py): Low-level HTTP communication with Strava API. ApiV3 class handles:
- HTTP request execution (GET, POST, PUT, DELETE)
- Token refresh logic when tokens expire
- Error handling and response parsing
- OAuth2 authorization flow
Model (model.py): Entity classes representing Strava data types (Activity, Athlete, Gear, etc.). These classes:
- Inherit base fields from auto-generated
strava_model.py(from official Strava API spec) - Add behavior: type enrichment, unit conversion, lazy loading of related entities
- Use Pydantic v2 for validation and serialization
- Support "bound" entities that can lazy-load related data via
bind_client()
Strava Model (strava_model.py): Auto-generated from Strava API specification. DO NOT manually edit this file - it's generated from the official Strava Swagger/OpenAPI spec.
Unit Helper (unit_helper.py, unit_registry.py): Unit conversion utilities using Pint library for handling distances, speeds, elevations, etc.
Exceptions (exc.py): Custom exception classes and warning utilities for Strava API errors and unofficial/deprecated features.
Tests are organized into:
src/stravalib/tests/unit/: Unit tests that don't hit the real APIsrc/stravalib/tests/integration/: Integration tests using the API stub
Mock Fixture: Tests use StravaAPIMock (in integration/strava_api_stub.py) to avoid hitting the real Strava API. This stub intercepts HTTP requests and returns mock responses. The mock_strava_api fixture in conftest.py provides this functionality.
When writing tests:
- Always use the mock fixtures to prevent real API calls
- Unit tests should be fast and isolated
- Integration tests verify end-to-end flows with mocked API responses
- Client is initialized with optional
access_token,refresh_token, andtoken_expires - Before each API call,
ApiV3checks if token is expired (comparing current time totoken_expires) - If expired, automatically calls
refresh_access_token()usingrefresh_token,client_id, andclient_secret(from environment or constructor) - New tokens are stored and used for subsequent requests
The Client uses stravalib.util.limiter.RateLimiter by default to respect Strava's rate limits. The rate limiter:
- Tracks requests in 15-minute and daily windows
- Sleeps when approaching limits
- Can be customized or disabled via constructor
- Line length: 79 characters (enforced by black and ruff)
- Type hints: Required for all function signatures (enforced by mypy with strict settings)
- Docstrings: Use NumPy-style docstrings for public APIs
- Minimum: Python 3.11
- Actively tested: 3.11, 3.12, 3.13, 3.14
- Type checking targets 3.11+ features
The codebase uses Pydantic v2. When working with models:
- All model classes inherit from
pydantic.BaseModel - Use
field_validatorandmodel_validatorfor custom validation - Auto-generated models in
strava_model.pyare the source of truth for Strava API schema
Core dependencies (see pyproject.toml):
- pint: Unit conversion
- arrow: Advanced datetime handling
- requests: HTTP client
- pydantic>=2.0: Data validation and serialization
Note: Timezone handling uses the standard library zoneinfo module (Python 3.9+)
GitHub Actions workflows:
build-test.yml: Runs pytest across all OS (Ubuntu, macOS, Windows) and Python versionstype-check.yml: Runs mypy type checkingbuild-docs.yml: Builds and deploys documentation to ReadTheDocspublish-pypi.yml: Publishes package to PyPI on releases
Pre-commit.ci is configured to automatically run hooks on PRs.