Skip to main content

Python library for the Strava API v3

Project description

strava

CI codecov PyPI Python License

A modern, fully-typed Python SDK for the Strava API v3.

Features

  • Sync and async clients built on httpx
  • Full type annotations and py.typed support
  • 34 API endpoints across 9 resource groups
  • 50+ dataclass models with automatic serialization
  • OAuth2 authentication with automatic token refresh
  • Lazy pagination iterators
  • Custom exception hierarchy with rate limit details

Installation

pip install strava

Quick Start

from strava import Strava

with Strava(access_token="your_token") as client:
    # Get authenticated athlete
    athlete = client.athletes.retrieve_authenticated()
    print(f"{athlete.firstname} {athlete.lastname}")

    # List recent activities
    for activity in client.activities.list(per_page=10):
        print(f"{activity.name} - {activity.distance}m")

Async

from strava import AsyncStrava

async with AsyncStrava(access_token="your_token") as client:
    athlete = await client.athletes.retrieve_authenticated()
    activities = await client.activities.list(per_page=10).collect()

OAuth2 Authentication

Get an authorization URL

from strava import build_authorization_url

url = build_authorization_url(
    client_id="your_client_id",
    redirect_uri="http://localhost:8000/callback",
    scopes=["read", "activity:read_all"],
)
# Redirect the user to `url`

Exchange the code for tokens

from strava import exchange_token

tokens = exchange_token(
    client_id="your_client_id",
    client_secret="your_secret",
    code="code_from_callback",
)
print(tokens.access_token, tokens.refresh_token, tokens.expires_at)

Refresh a token manually

from strava import refresh_access_token

tokens = refresh_access_token(
    client_id="your_client_id",
    client_secret="your_secret",
    refresh_token="current_refresh_token",
)
print(tokens.access_token, tokens.refresh_token, tokens.expires_at)

Automatic token refresh

from strava import Strava

def save_tokens(access_token, refresh_token, expires_at):
    # Persist the new tokens to your database
    ...

client = Strava(
    access_token="...",
    client_id="your_client_id",
    client_secret="your_secret",
    refresh_token="...",
    expires_at=1700000000,
    on_token_refresh=save_tokens,
)

Revoke tokens

from strava import revoke_token

revoke_token(
    client_id="your_client_id",
    client_secret="your_secret",
    token="access_or_refresh_token",
    token_type_hint="access_token",
)

deauthorize(access_token=...) remains available for compatibility, but it is deprecated because Strava will retire oauth/deauthorize on June 1, 2027. Prefer revoke_token() for new code.

API Coverage

Resource Methods
Activities create, retrieve, update, list, list_comments, list_kudoers, list_laps, list_zones
Athletes retrieve_authenticated, update_authenticated, retrieve_zones, retrieve_stats
Clubs retrieve, list_activities, list_admins, list_members, list_authenticated
Gear retrieve
Routes retrieve, export_gpx, export_tcx, list_by_athlete
Segments retrieve, explore, list_starred, star
Segment Efforts retrieve, list
Streams get_activity_streams, get_route_streams, get_segment_effort_streams, get_segment_streams
Uploads create, retrieve

Strava API Changes

The default API host is https://www.api-v3.strava.com, matching Strava's June 1, 2027 migration from https://www.strava.com/api/v3.

Some methods remain in the SDK for compatibility but are affected by Strava's 2026 Developer Program changes:

  • clubs.list_activities(), clubs.list_admins(), and clubs.list_members() are deprecated by Strava effective September 1, 2026.
  • segments.explore() is restricted to approved Extended Access applications effective September 1, 2026.
  • deauthorize() is deprecated; use revoke_token() with your client credentials instead.

Pagination

List endpoints return lazy paginators:

# Iterate one item at a time (fetches pages on demand)
for activity in client.activities.list():
    print(activity.name)

# Collect all results eagerly
all_activities = client.activities.list().collect()

# Limit results
first_50 = client.activities.list().collect(max_items=50)

# Iterate page by page
for page in client.activities.list(per_page=50).pages():
    print(f"Got {len(page)} activities")

Error Handling

from strava import (
    StravaError,
    AuthenticationError,
    AuthorizationError,
    NotFoundError,
    RateLimitError,
    TokenExpiredError,
    ValidationError,
    ServerError,
)

try:
    activity = client.activities.retrieve(123)
except TokenExpiredError:
    print("Access token has expired — refresh it")
except AuthenticationError:
    print("Invalid or missing access token")
except AuthorizationError:
    print("Insufficient permissions")
except NotFoundError:
    print("Activity not found")
except ValidationError as e:
    print(f"Bad request: {e.message}")
except RateLimitError as e:
    print(f"Rate limited. 15-min usage: {e.usage_15min}/{e.limit_15min}")
except ServerError:
    print("Strava server error — try again later")
except StravaError as e:
    print(f"API error {e.status_code}: {e.message}")

Development

# Install dependencies
uv sync

# Run tests
make test

# Run tests with coverage
make coverage

# Lint and format
make lint
make format

Python Version

Supports Python 3.11 through 3.14.

Contributing

Contributions are welcome! Please read the Contributing Guide before opening a pull request.

Found a bug? Open an issue. Have an idea? Request a feature.

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

strava-0.5.1.tar.gz (33.5 kB view details)

Uploaded Source

Built Distribution

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

strava-0.5.1-py3-none-any.whl (44.3 kB view details)

Uploaded Python 3

File details

Details for the file strava-0.5.1.tar.gz.

File metadata

  • Download URL: strava-0.5.1.tar.gz
  • Upload date:
  • Size: 33.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for strava-0.5.1.tar.gz
Algorithm Hash digest
SHA256 b2237d3313492e5a5fb30a5bdb0aa6b3eff03c0d81b6ff132adc5914730f1174
MD5 1ca3d96a03c18b1342df51a5d4d521e8
BLAKE2b-256 fd89d211a1255928d9ccace6d06dfa7e24b9ef0447eb04efa80de8b6d52ebe20

See more details on using hashes here.

Provenance

The following attestation bundles were made for strava-0.5.1.tar.gz:

Publisher: publish.yml on ragnarok22/strava-python

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

File details

Details for the file strava-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: strava-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 44.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for strava-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 41061bb522e031cff0160f810523de557ec7f7a37f83265bc07fbd88b3019662
MD5 4fed82f1fccbb4dbabf334006038fbf4
BLAKE2b-256 e65fee179e323b107a3daf852fd3132a428eaa2a9a3a669d9c14317cf7f3463f

See more details on using hashes here.

Provenance

The following attestation bundles were made for strava-0.5.1-py3-none-any.whl:

Publisher: publish.yml on ragnarok22/strava-python

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