Skip to main content

Note: This is a community-maintained fork. The original package was removed from PyPI by its author and cannot be restored. This repository continues development and publishing under the same package name.

A Python library for reading and writing Garmin FIT files — practical for common Activity, Workout, and Course workflows.

What works / what we do not claim (capability matrix, validation levels, encode policies): docs/CAPABILITY_BOUNDARY.md.

Long-term strict-conformance roadmap (target architecture, not current guarantees): docs/FIT_CONFORMANCE_DESIGN.md.

Profile in use: 21.212.0 (fit_tool.SDK_VERSION).

Installation

Runtime has no third-party dependencies.

uv add fit-tool
# or
python3 -m pip install --upgrade fit-tool

Optional profile regeneration (maintainers only):

uv add 'fit-tool[gen]'   # openpyxl, inflection, jinja2
uv run gen-profile

CLI

fit-tool activity.fit                 # → CSV
fit-tool -t fit -o out.fit in.fit
fit-tool -h

Public API

Import the stable surface from the package root:

from fit_tool import (
    FitFile,
    FitFileBuilder,
    EncodeMode,
    EncodeOptions,
    ConformanceLevel,
    ProfileScope,
    validate_fit_file,
    FitError,
    FitParseError,
    FitCRCError,
    FitValidationError,
    PROTOCOL_VERSION,
    SDK_VERSION,
)
Symbol Role
FitFile Load, inspect, stream, serialize, validate
FitFileBuilder Build FIT files from messages
EncodeMode / EncodeOptions PRESERVE vs CANONICAL encode policies
validate_fit_file / ConformanceLevel / ProfileScope Composable validation
FitError and subclasses Typed parse / CRC / encode / validation errors
PROTOCOL_VERSION / SDK_VERSION Bundled protocol and Profile version strings

Profile messages are not re-exported at the root:

from fit_tool.profile.messages.file_id_message import FileIdMessage
from fit_tool.profile.messages.record_message import RecordMessage
from fit_tool.profile.profile_type import FileType, Sport
Mode API
Create RecordMessage()
Decode projection RecordMessage.from_definition(definition, ...)

Deep imports (from fit_tool.fit_file import FitFile) still work; prefer the package root for new code.

Examples

Read and convert to CSV

from fit_tool import FitFile

fit = FitFile.from_file("activity.fit")
fit.to_csv("activity.csv")

Stream large files (bounded memory)

from fit_tool import FitFile

for record in FitFile.iter_file("activity.fit"):
    process(record)  # CRC checked when the iterator is exhausted

Build a small Activity

from fit_tool import FitFileBuilder
from fit_tool.profile.messages.file_id_message import FileIdMessage
from fit_tool.profile.messages.record_message import RecordMessage
from fit_tool.profile.profile_type import FileType, Manufacturer

builder = FitFileBuilder(auto_define=True)
file_id = FileIdMessage()
file_id.type = FileType.ACTIVITY
file_id.manufacturer = Manufacturer.DEVELOPMENT
file_id.product = 0
file_id.serial_number = 1
file_id.time_created = 1_700_000_000_000
builder.add(file_id)

record = RecordMessage()
record.timestamp = 1_700_000_000_000
record.heart_rate = 120
builder.add(record)

data = builder.build_bytes()
# FitFileBuilder(strict=True) also runs WIRE + PROFILE(CORE) + FILE_TYPE
# (Activity needs lap/session/activity messages — see examples/).

Validate

from fit_tool import FitFile, ProfileScope, validate_fit_file, ConformanceLevel

fit = FitFile.from_file("activity.fit")
report = fit.validate()
if report.has_errors:
    print(report.errors)

# Opt-in deeper PROFILE rules (never the default for strict)
validate_fit_file(fit, profile_scope=ProfileScope.FULL)

Encode modes

from fit_tool import EncodeMode, FitFile

fit = FitFile.from_bytes(raw)
fit.to_bytes()                              # PRESERVE (default)
fit.to_bytes(mode=EncodeMode.CANONICAL)
fit.to_bytes(mode=EncodeMode.CANONICAL, strict=True)

Details: capability boundary — encode policies.

Repository examples

uv run python fit_tool/examples/read_activity_example.py
uv run python fit_tool/examples/modify_activity_example.py
uv run python fit_tool/examples/write_workout_example.py

write_activity_example.py / write_course_example.py need extra packages (gpxpy, geopy, …).

Further documentation

Doc Contents
docs/CAPABILITY_BOUNDARY.md Supported / partial / incomplete matrix; validation & encode details
docs/FIT_CONFORMANCE_DESIGN.md Target architecture and roadmap
docs/EPIC_SHA12_RELEASE_NOTES.md Protocol-capability epic rollup notes
docs/RELEASING.md Maintainer checklist for PyPI / GitHub releases
fit_tool/tests/data/README.md Fixture inventory and gap map

Metadata

Release files for fit-tool 0.9.16

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fit-tool 0.9.16
File Size Uploaded
fit_tool-0.9.16.tar.gz 301.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fit-tool 0.9.16
File Interpreter ABI Platform
fit_tool-0.9.16-py3-none-any.whl Python 3 none any Details

Total release size: 798.1 kB

Release files / fit_tool-0.9.16.tar.gz

Download URL fit_tool-0.9.16.tar.gz
Size 301.0 kB
Tags Source
SHA-256 checksum
How to use checksums
716b75b2fdfc66ca7b82df65f750c1427fd984c558284753f43e2bf8d2188f61
BLAKE2b-256 checksum
How to use checksums
fc4fbe06a443553f5e74b4e9360724aaf41d0d09dceb0bc69d8faf3fe0f398f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release files / fit_tool-0.9.16-py3-none-any.whl

Download URL fit_tool-0.9.16-py3-none-any.whl
Size 497.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3403c61663cc205da101a9952edcdc31cf9634dce2eb5c12a397eb24cf4aacf0
BLAKE2b-256 checksum
How to use checksums
2f4ff0b1bfbc260007870aa0b05e07bdcdebc6080bfbc52dd680011ab0daa44b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.16 This release

2 release files

0.9.14

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page