Coros activity exporter and backup tool for personal data archival
Project description
Corosexport - Coros Activity Exporter
A Python library and command-line tool for downloading and backing up Coros activities to your local machine, similar to the popular garminexport for Garmin devices.
Features
- Incremental Backups - First run downloads all activities, subsequent runs only grab new ones
- Multiple Formats - Export activities as FIT, TCX, GPX, KML or CSV
- Library & CLI - Use as a standalone tool or import into your own Python projects
- Cross-Platform - Works on macOS, Linux, and Windows
- State Tracking - Automatically tracks which activities have been backed up
Quick Start
Installation
With uv (Recommended)
# Clone the repository
git clone https://github.com/rbettermann/corosexport.git
cd corosexport
# Install with uv
uv sync
# Run the CLI
uv run coros-backup
With pip
pip install corosexport
coros-backup --backup-dir=./coros_activities
First Backup
coros-backup --backup-dir=~/coros_activities
The tool will prompt for your Coros email and password, then:
- Authenticate with Coros Training Hub
- Fetch all activities
- Download files in your specified formats
- Save a state file for future incremental backups
Incremental Backups
Run the same command again - it will only download new activities:
coros-backup --backup-dir=~/coros_activities --format fit --format tcx
Development Setup
Prerequisites
- Python 3.9+
- uv (for fast package management)
Setup Development Environment
git clone https://github.com/yourusername/corosexport.git
cd corosexport
# Install all dependencies including dev tools
uv sync
# Run tests
uv run pytest -v
# Run with verbose logging
uv run coros-backup --verbose
# Format code
uv run black src/ tests/
# Lint code
uv run ruff check src/ tests/
# Type checking
uv run mypy src/
API Usage (as Library)
Use corosexport in your own Python projects:
from pathlib import Path
from corosexport import CorosClient, BackupManager
from corosexport.models import ExportFormat
# Create and authenticate client
client = CorosClient(email="user@example.com", password="your_password")
client.authenticate()
# Fetch activities
activities = client.get_activities(limit=50)
for activity in activities:
print(f"{activity.activity_name}: {activity.distance_meters}m")
# Setup backup manager
backup_manager = BackupManager(
client=client,
backup_dir=Path("./coros_activities"),
formats=[ExportFormat.FIT, ExportFormat.TCX],
)
# Run backup
stats = backup_manager.run_backup()
print(f"Downloaded {stats['activities_downloaded']} new activities")
Backup Directory Structure
After running backups, your directory looks like this:
coros_activities/
├── .corosexport_state.json # Internal state file (do not edit)
├── 2025-01-10_activity-001-metadata.json # Activity summary data
├── 2025-01-10_activity-001.fit # Raw FIT file
├── 2025-01-10_activity-001.tcx # TCX format
├── 2025-01-10_activity-001.gpx # GPX format
├── 2025-01-11_activity-002-metadata.json
├── 2025-01-11_activity-002.fit
├── 2025-01-11_activity-002.tcx
├── 2025-01-11_activity-002.gpx
├── ...
metadata.json contains:
- Activity ID, name, type
- Distance (meters)
- Start time, end time, workout duration, total duration
Command-Line Options
coros-backup --help
Options:
--backup-dir TEXT Directory to store activities (default: ./coros_activities)
--email TEXT Coros account email
--password TEXT Coros password (prompts if omitted for security)
--format TEXT Export formats: fit, tcx, gpx, kml or csv
--verbose Enable debug logging
--help Show this message
Examples
# Backup to specific directory
coros-backup --backup-dir ~/fitness_backups
# Download only FIT files
coros-backup --format fit
# Download all formats
coros-backup --format fit --format tcx --format gpx
# Enable verbose output
coros-backup --backup-dir ~/coros --verbose
Architecture Notes
Reverse-Engineered APIs
This project uses reverse-engineered APIs from the Coros Training Hub web interface. The endpoints used are:
POST /account/login- AuthenticationGET /activity/query- List activitiesGET /activity/detail/download- Download activity files
These are not officially documented by Coros. This tool is for personal data backup only.
State Management
Backups are incremental using a .corosexport_state.json file that tracks:
- When the last backup completed
- Which activity IDs have been downloaded
- Total activities backed up
Testing
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=src/corosexport
# Run specific test file
uv run pytest tests/test_client.py -v
# Run with verbose output
uv run pytest -v -s
Disclaimer
This tool is for personal data backup only. While Coros has not explicitly prohibited API access via their Terms of Service, they have not published official APIs either. Use at your own discretion and respect Coros' services.
License
Apache License 2.0 - See LICENSE file for details
Related Projects
- garminexport - Similar tool for Garmin devices
- strava-offline - Strava activity backup
FAQ
Q: Is this tool affiliated with Coros? A: No, this is a community project created for personal data archival.
Q: Does this work with the Coros mobile app? A: No, this tool works with the Coros Training Hub web interface.
Q: Can I upload activities back to Coros? A: Not currently, but this could be added in future versions.
Q: What about my password security? A: Passwords are only used to authenticate and are never stored. They're passed directly to Coros' servers over HTTPS.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file corosexport-0.1.4.tar.gz.
File metadata
- Download URL: corosexport-0.1.4.tar.gz
- Upload date:
- Size: 107.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fa2f5524e0365223b9d5a033364837a411f915387e80c908b327974b99cb2de
|
|
| MD5 |
e659d42ac376c557eb2d116dfbf38dd1
|
|
| BLAKE2b-256 |
5003133f3b1cfcc7dcfd5d4f41eba29f6e728f06c7bae7c7b8d6792f97fefd25
|
Provenance
The following attestation bundles were made for corosexport-0.1.4.tar.gz:
Publisher:
publish.yml on rbettermann/corosexport
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
corosexport-0.1.4.tar.gz -
Subject digest:
8fa2f5524e0365223b9d5a033364837a411f915387e80c908b327974b99cb2de - Sigstore transparency entry: 1914682541
- Sigstore integration time:
-
Permalink:
rbettermann/corosexport@2475824f219a050eb183752b7ad1815db17627c0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rbettermann
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2475824f219a050eb183752b7ad1815db17627c0 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file corosexport-0.1.4-py3-none-any.whl.
File metadata
- Download URL: corosexport-0.1.4-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3438a3d35eac67a9af03802442e41026d7ade4d9e897193ae9ea6421c023e81e
|
|
| MD5 |
0eb62ee63ff19fdbc5746b30c2efe721
|
|
| BLAKE2b-256 |
8ed547278323c523cf33fc32b98da35a773cf9f1ea18a863f04d942ebe6e37a8
|
Provenance
The following attestation bundles were made for corosexport-0.1.4-py3-none-any.whl:
Publisher:
publish.yml on rbettermann/corosexport
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
corosexport-0.1.4-py3-none-any.whl -
Subject digest:
3438a3d35eac67a9af03802442e41026d7ade4d9e897193ae9ea6421c023e81e - Sigstore transparency entry: 1914682682
- Sigstore integration time:
-
Permalink:
rbettermann/corosexport@2475824f219a050eb183752b7ad1815db17627c0 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rbettermann
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2475824f219a050eb183752b7ad1815db17627c0 -
Trigger Event:
workflow_dispatch
-
Statement type: