stravawizard
Purpose
This package offers 2 clients to work with the Strava API:
stravauth_client: Allows users to easily handle Strava OAuth authentication. Requires credentials of a declared Strava app (client ID, client secret, and redirect URI) to work properly.strava_api_client: Allows users to directly use the Strava API, given an access token.
Installation
pip install stravawizard
Usage
Working with stravauth_client
The stravauth_client provides a complete OAuth flow implementation to authenticate with Strava's API. It consists of three main components:
StravauthClient: The main client that orchestrates the authentication processStravauthCredentialsManager: Manages application credentialsStravauthTokenManager: Handles OAuth tokens, including validation and refreshing
Basic Authentication Flow
from stravawizard.clients.oauth_client.stravauth_client import StravauthClient
# Initialize the client
client = StravauthClient()
# Set app credentials using the credentials manager
client.credentials_manager.set_app_credentials(
client_id="your_client_id",
client_secret="your_client_secret",
redirect_uri="your_redirect_uri"
)
# Check if client is ready before proceeding
client.check_if_ready() # Raises exception if not ready
# Generate authorization URL for user to approve access
auth_url = client.get_authorization_url()
# Redirect your user to this URL in your application
# After user approval, exchange the authorization code received via the redirect URI
response = client.exchange_authorization_code("received_authorization_code")
# The response includes athlete data and OAuth tokens that are stored automatically
# Get athlete summary that was obtained during authentication
athlete = client.get_athlete_summary()
Working with Tokens
The token manager handles token lifecycle management:
# Check if access token is still valid
if not client.token_manager.is_access_token_valid():
# Automatically refresh the token using the stored refresh token
client.token_manager.refresh_access_token()
# Get current user tokens (to use with strava_api_client or store in database)
credentials = client.token_manager.get_user_oauth_credentials()
access_token = credentials["access_token"]
refresh_token = credentials["refresh_token"]
expires_at = credentials["expires_at"]
# Set tokens from an existing user object (e.g., from database)
class User:
def __init__(self):
self.strava_access_token = "access_token"
self.strava_refresh_token = "refresh_token"
self.strava_expires_at = 1678901234 # Unix timestamp
user = User()
client.token_manager.set_user_oauth_credentials_from_user(user)
Working with strava_api_client
from stravawizard.clients.api_client.strava_api_client import StravaApiClient
# Initialize client with or without token
client = StravaApiClient()
# or
client = StravaApiClient(strava_access_token="your_access_token")
# You can also set the token after initialization
client.set_strava_access_token("your_access_token")
# Make sure your client is ready before making calls
is_ready = client.check_if_ready()
Athlete Data
Retrieve athlete information using the athlete namespace:
# Get athlete stats
athlete_id = 1234567
stats = client.athlete.get_athlete_stats(athlete_id)
Activity Data
Access activities and related data using the activity namespace:
# Get athlete activities (defaults to most recent 10)
activities = client.activity.get_athlete_activities()
# Get specific page with custom page size
activities = client.activity.get_athlete_activities(page="2", per_page="30")
# Get activities within a date range
from datetime import datetime, timedelta
end_date = datetime.now()
start_date = end_date - timedelta(days=30) # Last 30 days
activities = client.activity.get_athlete_activities(
start_date=start_date,
end_date=end_date
)
# Get photos for a specific activity
activity_id = 1234567890
photos = client.activity.get_activity_photos(activity_id, size=600)
Architecture
StravaWizard is organized into specialized clients for different purposes:
OAuth Authentication (stravauth_client)
StravauthClient: Main client that orchestrates the OAuth authentication flowStravauthCredentialsManager: Manages application credentials (client ID, client secret, redirect URI)StravauthTokenManager: Handles OAuth tokens, their validation, and refreshingStravauthBaseClient: Base class with common OAuth functionality
Strava API Access (strava_api_client)
StravaApiClient: Main client that integrates all specialized API clientsStravaAthleteApiClient: Handles athlete-related endpointsStravaActivityApiClient: Handles activity-related endpointsStravaBaseApiClient: Base class for API clientsStravaRequestHandler: Manages HTTP requests to the Strava API
Integration Flow
A typical workflow using both clients would be:
- Use
stravauth_clientto authenticate the user and obtain tokens - Use those tokens with
strava_api_clientto make API calls
from stravawizard.clients.oauth_client.stravauth_client import StravauthClient
from stravawizard.clients.api_client.strava_api_client import StravaApiClient
# First, authenticate with stravauth_client
auth_client = StravauthClient()
auth_client.credentials_manager.set_app_credentials(
client_id="your_client_id",
client_secret="your_client_secret",
redirect_uri="your_redirect_uri"
)
# Generate an authorization URL and redirect the user
auth_url = auth_client.get_authorization_url()
# (User authorizes via the browser...)
# Exchange the authorization code received via redirect
auth_client.exchange_authorization_code("received_code")
# Retrieve tokens for API usage
tokens = auth_client.token_manager.get_user_oauth_credentials()
# Now use the strava_api_client with the obtained token
api_client = StravaApiClient(strava_access_token=tokens["access_token"])
api_client.check_if_ready()
# Make API calls
activities = api_client.activity.get_athlete_activities()
Error Handling
API Client Errors
API calls through StravaApiClient will return error information in the response:
response = api_client.activity.get_athlete_activities()
if "error" in response:
print(f"Error occurred: {response['error']}")
else:
# Process successful response
pass
OAuth Client Errors
The StravauthClient uses exceptions for error handling:
try:
# Check if all required credentials are set
auth_client.check_if_ready()
# Attempt to refresh an expired token
auth_client.token_manager.refresh_access_token()
except Exception as e:
print(f"Authentication error: {str(e)}")
Requirements
- Python 3.6+
- requests library
Common Usage Patterns
Storing and Reusing Tokens
In most applications, you'll want to store the OAuth tokens in a database:
# After authentication
tokens = auth_client.token_manager.get_user_oauth_credentials()
# Store in your database
user.strava_access_token = tokens["access_token"]
user.strava_refresh_token = tokens["refresh_token"]
user.strava_expires_at = tokens["expires_at"]
user.save()
# Later, when loading from database
auth_client = StravauthClient()
auth_client.credentials_manager.set_app_credentials(...)
auth_client.token_manager.set_user_oauth_credentials_from_user(user)
# Check and refresh token if needed
if not auth_client.token_manager.is_access_token_valid():
auth_client.token_manager.refresh_access_token()
# Update tokens in database
user.strava_access_token = auth_client.token_manager.get_user_oauth_credentials()["access_token"]
user.strava_refresh_token = auth_client.token_manager.get_user_oauth_credentials()["refresh_token"]
user.strava_expires_at = auth_client.token_manager.get_user_oauth_credentials()["expires_at"]
user.save()
Updating package on pypi.org
For maintainers only
Update version to the update's date in pyproject.toml according to YYYY.MM.DD format (e.g., 2024.02.05 for a package made on February 5th, 2024. Versions under development should follow this standard, and add .dev at the end. For instance: 2024.02.05.dev).
python -m build
python3 -m twine upload dist/*
Metadata
Release files for stravawizard 2025.5.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| stravawizard-2025.5.18.tar.gz | 27.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| stravawizard-2025.5.18-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.7 kB
Release files / stravawizard-2025.5.18.tar.gz
| Download URL | stravawizard-2025.5.18.tar.gz |
|---|---|
| Size | 27.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
08fe5f0178badc00e77e67ebbcf9ca435a864896e4692cd49db9ed2dcd3041ff
|
|
BLAKE2b-256 checksum How to use checksums |
1ca48b47058f77aa312d64322807ab8883fb76652eed5c4aa9dd37af74ae6d18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|
Release files / stravawizard-2025.5.18-py3-none-any.whl
| Download URL | stravawizard-2025.5.18-py3-none-any.whl |
|---|---|
| Size | 28.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e33a8dcfb6857527be8939a073706cb78d8ea076179c4df3d4662938809e353e
|
|
BLAKE2b-256 checksum How to use checksums |
4bd8965a5c3f6f336d7fe733975e2689d9b6dc87fdd2fa0b7ab6c86fd60f1fc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|