GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - shaonianche/python_fit_tool: https://bitbucket.org/stagescycling/python_fit_tool.git fork

BranchesTags
Open more actions menu

Latest commit

 

History

108 Commits
108 Commits

Folders and files

NameName
Last commit message
Last commit date
.github
.github
 
 
docs
docs
 
 
fit_tool
fit_tool
 
 
news
news
 
 
.gitignore
.gitignore
 
 
AGENTS.md
AGENTS.md
 
 
AUTHORS
AUTHORS
 
 
CHANGELOG.md
CHANGELOG.md
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
pyproject.toml
pyproject.toml
 
 
uv.lock
uv.lock
 
 

Repository files navigation

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.221.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

About

https://bitbucket.org/stagescycling/python_fit_tool.git fork

Resources

Readme
BSD-3-Clause license
Activity

Stars

8 stars

Watchers

0 watching

Forks

1 fork
Report repository

Releases

Packages

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.