Fast FIT to GPX converter - replacement for fit2gpx
Project description
fit2gpx-lightning ⚡
Simple replacement for the fit2gpx Python library with 400x performance improvements thanks to Rust and parallel processing. I closely mirrored the original fit2gpx API for easy adoption (with a few adaptations and additions).
My motivation here was to both expose the wonderful Rust fit2gpx in python to make it more accessible for those of us who are more comfortable scripting in python. The orignal python fit2gpx library is quite slow for bulk conversions and also doesn't have a simple way to process Garmin bulk exports, only Strava. Here, we fix both those issues
[!INFO] AI Disclaimer: I did use Claude Code for significant portions of the coding and documentation, though I made quite a few manual changes to the final output. I would categorize this as "AI assisted coding" not "Vibecoded." Could I have done this all myself? Yes. Would it have taken too long for me to bother doing. Also yes.
Features
- Convert
.fitfiles to GPX format, one at a time or entire folder - Extract all activity tracks as GPX from Strava bulk export ZIPs
- Supports
.fit,.fit.gz,.gpx.gz, and.gpxfiles in source ZIP - Inject activity names and types from
activities.csv
- Supports
- Extract and convert FIT files to GPX from Garmin bulk export ZIPs
- Matches FIT files to activity metadata from
summarizedActivities.json
- Matches FIT files to activity metadata from
Limitations
- We don't support output to pandas Dataframes, which the original fit2gpx library does.
Installation
pip install fit2gpx-lightning
I have tried to include pre-built wheels for common platforms (Linux x86_64, Linux aarch64, macOS x86_64, macOS arm64, Windows x86_64). If you have trouble installing, please open an issue with your platform details and I will see if I can add support.
Quick Start
Simple Conversion
from fit2gpx_lightning import fit_to_gpx, fit_to_gpx_bulk
# Convert a single file
fit_to_gpx('activity.fit', 'activity.gpx')
# Convert an entire directory
# (processes immediate children only)
stats = fit_to_gpx_bulk('./fit_files/', './gpx_files/')
print(f"✓ Converted {stats['converted']} out of {stats['total']} files")
print(f"✗ Failed: {stats['failed']}")
Strava Export Processing
The strava_fit_to_gpx function not only converts .fit files, but also unzips and converts .fit.gz files, extracts .gpx.gz files, and copies .gpx.
Complete example processing a Strava export:
from fit2gpx_lightning import StravaConverter
# Initialize converter with your Strava export ZIP
# Download from: https://www.strava.com/athlete/delete_your_account
converter = StravaConverter('strava_export.zip')
# Step 1: Convert FIT files to GPX
stats = converter.strava_fit_to_gpx('./gpx_output/')
print(f"✓ Converted: {stats['converted']}")
print(f"✗ Failed: {stats['failed']}")
# Step 2: Add metadata (activity names, types) from activities.csv. In place modification
converter.add_metadata_to_gpx('./gpx_output/')
Garmin Export Processing
Complete example processing a Garmin export:
from fit2gpx_lightning import GarminConverter
# Initialize converter with your Garmin export ZIP
# Download from: https://www.garmin.com/account/datamanagement/exportdata.html
converter = GarminConverter('garmin_export.zip')
# Step 1: Convert to GPX with automatic metadata matching
# Matches FIT files to activities by timestamp (±10 second tolerance)
stats = converter.garmin_fit_to_gpx('./gpx_output/')
print(f"✓ Converted: {stats['converted']}")
print(f"✓ Matched with metadata: {stats['matched']}")
print(f"⚠ Unmatched: {stats['unmatched']}")
print(f"✗ Failed: {stats['failed']}")
# Optional: Update metadata for already-converted files
converter.add_metadata_to_gpx('./gpx_output/')
API Reference
View full API reference at
Performance
Benchmark converting my Strava export of 1354 activities.
| Library | Time | Throughput | Speedup |
|---|---|---|---|
| fit2gpx (Python) | 9 m 25.9s | 2.7 files/s | 1x (baseline) |
| fit2gpx-lightning | 1.39s | 971.8 files/s | 406.1x |
Performance improvements from:
- ✨ Rust's zero-cost abstractions
- 🔒 Memory safety without garbage collection
- ⚡ Parallel processing with Rayon
- 🚀 Efficient binary handling
Development
Building from Source
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone repository
git clone https://github.com/yourusername/fit2gpx-lightning
cd fit2gpx-lightning/fit2gpx-lightning
# Install maturin (Python build tool for Rust extensions)
pip install maturin
# Build and install in development mode
maturin develop --release
# Run tests
cargo test --all-features
Running Tests
Integration tests won't pass unless you download your data and move some .fit files to the test_data/ folder. Strava export zip should be named strava.zip and Garmin export zip should be named garmin.zip.
# Rust unit and integration tests
cargo test
# With output
cargo test -- --nocapture
# Specific test
cargo test test_strava
# Python tests (after maturin develop)
python -m pytest tests/
Contributing
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
cargo test) - Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
For feature suggestions or errors, open an issue.
Changelog
v0.1.0 (2025-12-24)
Initial Release
- Core FIT to GPX conversion functions
- Strava export support (.fit.gz, activities.csv)
- Garmin export support (nested ZIPs, summarizedActivities.json)
- Parallel processing for bulk operations
- Metadata injection from CSV and JSON
- Python bindings via PyO3
- CI/CD pipeline for multi-platform wheels
- Comprehensive documentation and examples
- Unit testing in rust and integration testing in Python using full exports downloaded in December 2025.
Support
- Documentation: This README + inline code documentation
- Issues: GitHub Issues
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
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 fit2gpx_lightning-0.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.1 MB
- Tags: PyPy, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec4cd9a327f51bbc4e29f6a0353155cda06e50223991abcecafb2ef60bb29219
|
|
| MD5 |
8f39b7a4f154bd4f0ad64b45c21347f6
|
|
| BLAKE2b-256 |
e7eaf78396d7d31f6c0b4e2b82f3f094e331612d3d97bd99dcb0dff927c4f44f
|
File details
Details for the file fit2gpx_lightning-0.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.1 MB
- Tags: PyPy, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5fd11a731229c59538019217a5251228bdb0ca2cccc6bb7d5327889f6e6671a7
|
|
| MD5 |
443fe1061fc8f57dd343273360bbe24e
|
|
| BLAKE2b-256 |
ff6d5723a371bfb0c5aed1e06bb25a83776c988b6f00d55641214b06c0660b86
|
File details
Details for the file fit2gpx_lightning-0.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.1 MB
- Tags: PyPy, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cbaca9a3fade3c6daf455d60a1c5307a57b27ffee6d70fb48bcfcefea447d10
|
|
| MD5 |
960f2d479ee3f175ddeeee8209d0bb77
|
|
| BLAKE2b-256 |
fca466d98dece0b51b39b866855f44dfd16a28b6310a38d604d680be6fb8fd13
|
File details
Details for the file fit2gpx_lightning-0.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.1 MB
- Tags: PyPy, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85a8732efac8bdf2587c3c329ebf07784962d24dabb913a6b74f8928254e537e
|
|
| MD5 |
f76d687b7ee01deb00c810068cd11ed1
|
|
| BLAKE2b-256 |
d2f0cc6b614e9aad081621c44134bcc2469482487e84974df7f0de5af1da020b
|
File details
Details for the file fit2gpx_lightning-0.1.1-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 931.3 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52ec2b19d44d88a0e1a03160e16db348e3d0446995b0fdb05bea29df9d396d8e
|
|
| MD5 |
eb45aa34e64df30a6b4e5ead47525626
|
|
| BLAKE2b-256 |
691c932058c10087bd171af997239624b5651f09e82484c6d4d311ebaf158132
|
File details
Details for the file fit2gpx_lightning-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f875555c9b94d560b9d4565ed1c6667cfd5faf5d58510528a158f545bbb5ddbf
|
|
| MD5 |
79d3c82b7757182b7919dc7356fc3382
|
|
| BLAKE2b-256 |
e0fae2cc071334007c751b3a0c230c8d365be275d19cd0c1f1f28a0b230d59ba
|
File details
Details for the file fit2gpx_lightning-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.8+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
051d0843231927811c9a9752a7319e2c8b0d28e16af8c2de9bd382290c95ae38
|
|
| MD5 |
aec4bb3338220a55071dbfa7521c0926
|
|
| BLAKE2b-256 |
12e214ec4f1ccd51089a5e184286842036efe962c5b98e972e13a5175325cae8
|
File details
Details for the file fit2gpx_lightning-0.1.1-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 994.2 kB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e994d2d3571fb1804d986740d6a00fb9ecea482706c67e4087cf936616e271f
|
|
| MD5 |
3d1baee9dea9299cad5f13cba6ce22af
|
|
| BLAKE2b-256 |
ef07f75da9d4485a29a800704ece7ba26ab94abe53db8a5000ae24117a2408e8
|
File details
Details for the file fit2gpx_lightning-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: fit2gpx_lightning-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.8+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
af44e98ab49e0107fa1f236495afcf205bb91904637be20e4cd368c30b28d643
|
|
| MD5 |
bf156a0950945d14209824a3aeb61d9e
|
|
| BLAKE2b-256 |
5014d0c0f3f2aca31dd093d9958ef103496936f72f6b20d184bf031329f18909
|