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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fit_tool-0.9.16.tar.gz (301.0 kB view details)

Uploaded Source

Built Distribution

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

fit_tool-0.9.16-py3-none-any.whl (497.2 kB view details)

Uploaded Python 3

File details

Details for the file fit_tool-0.9.16.tar.gz.

File metadata

  • Download URL: fit_tool-0.9.16.tar.gz
  • Upload date:
  • Size: 301.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fit_tool-0.9.16.tar.gz
Algorithm Hash digest
SHA256 716b75b2fdfc66ca7b82df65f750c1427fd984c558284753f43e2bf8d2188f61
MD5 d404858cbbcb52b3389443d7e4e09a11
BLAKE2b-256 fc4fbe06a443553f5e74b4e9360724aaf41d0d09dceb0bc69d8faf3fe0f398f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for fit_tool-0.9.16.tar.gz:

Publisher: publish.yml on shaonianche/python_fit_tool

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

File details

Details for the file fit_tool-0.9.16-py3-none-any.whl.

File metadata

  • Download URL: fit_tool-0.9.16-py3-none-any.whl
  • Upload date:
  • Size: 497.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fit_tool-0.9.16-py3-none-any.whl
Algorithm Hash digest
SHA256 3403c61663cc205da101a9952edcdc31cf9634dce2eb5c12a397eb24cf4aacf0
MD5 e6c89c3f0ba3d962e3fc18282645f2b4
BLAKE2b-256 2f4ff0b1bfbc260007870aa0b05e07bdcdebc6080bfbc52dd680011ab0daa44b

See more details on using hashes here.

Provenance

The following attestation bundles were made for fit_tool-0.9.16-py3-none-any.whl:

Publisher: publish.yml on shaonianche/python_fit_tool

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 Sentry Error logging StatusPage Status page