fitdecode 0.11.0
FIT file parser and decoder
License: MIT
Requires Python: >=3.6
Keywords: fit, fitparse, ant, file, parse, parser, decode, decoder

=========
fitdecode
=========

.. image:: https://readthedocs.org/projects/fitdecode/badge/?version=latest
    :target: https://fitdecode.readthedocs.io/
    :alt: Latest Docs

.. image:: https://github.com/polyvertex/fitdecode/actions/workflows/python-test.yml/badge.svg
    :target: https://github.com/polyvertex/fitdecode/actions/workflows/python-test.yml
    :alt: python-test


A `FIT <https://developer.garmin.com/fit/overview/>`_ file parsing and decoding
library written in `Python <https://www.python.org/>`_ (``>= 3.6``).


Usage Example
=============

Read a FIT file, frame by frame:

.. code:: python

    import fitdecode

    with fitdecode.FitReader('file.fit') as fit:
        for frame in fit:
            # The yielded frame object is of one of the following types:
            # * fitdecode.FitHeader (FIT_FRAME_HEADER)
            # * fitdecode.FitDefinitionMessage (FIT_FRAME_DEFINITION)
            # * fitdecode.FitDataMessage (FIT_FRAME_DATA)
            # * fitdecode.FitCRC (FIT_FRAME_CRC)

            if frame.frame_type == fitdecode.FIT_FRAME_DATA:
                # Here, frame is a FitDataMessage object.
                # A FitDataMessage object contains decoded values that
                # are directly usable in your script logic.
                print(frame.name)


Command line utilities
----------------------

``fitjson`` command converts a FIT file to JSON:

::

    $ fitjson --pretty -o out_file.json in_file.fit

``fittxt`` command converts a FIT file to human-readable text format convenient
to ease FIT data inspection and debugging::

    $ fittxt -o out_file.txt in_file.fit

Both commands accept a ``--filter`` option (or ``-f``) which can be specified
multiples times::

    $ # include only RECORD messages:
    $ fitjson -f=record -o out_file.json in_file.fit

    $ # exclude FILE_ID and EVENT messages:
    $ fitjson -f=-file_id -f=-event -o out_file.json in_file.fit


Installation
============

fitdecode is available on `PyPI <https://pypi.org/project/fitdecode/>`_::

    $ pip install fitdecode


Or, you can clone fitdecode's `source code repository
<https://github.com/polyvertex/fitdecode>`_ before installing it::

    $ git clone git@github.com:polyvertex/fitdecode.git
    $ cd fitdecode
    $ pip install .


Note that for convenience, directory ``cmd`` located at the root of the project
can safely be added to your ``PATH``, such that fitdecode commands can be called
without the package to be installed.


Overview
========

fitdecode is a non-offensive and incompatible rewrite of the fitparse_ library,
with some improvements and additional features, thread-safety, and efforts to
optimize both speed and memory usage.

Main differences between fitdecode and fitparse:

* fitdecode API is not compatible with fitparse
* fitdecode is faster
* fitdecode allows concurrent reading of multiple streams by being thread-safe,
  in the sense that fitdecode's objects keep their state stored locally
* fitdecode does not discard the FIT header and the CRC footer while reading a
  stream so that client code gets a complete 1:1 representation of the stream
  that is being read
* This also allows client code to easily deal with so-called chained FIT files,
  as per FIT SDK definition (i.e. concatenated FIT files)
* CRC computation and matching are both optional. CRC can be either matched, or
  only computed, or just ignored for faster reading.
* fitdecode offers optional access to records, headers and footers in their
  binary form, so to allow FIT file cutting, stitching and filtering at binary
  level


Why a new library?
==================

A new library has been created instead of just offering to patch fitparse_
because many changes and adds in fitdecode break fitparse's backward
compatibilty and because it allowed more freedom during the development of
fitdecode.


Documentation
=============

Documentation is available at `<https://fitdecode.readthedocs.io/>`_


License
=======

This project is distributed under the terms of the MIT license.
See the `LICENSE.txt <LICENSE.txt>`_ file for details.


Credits
=======

fitdecode is largely based on the generic approach adopted by fitparse_ to
define FIT types and to decode raw values. That includes the module
``profile.py`` and all the classes it refers to, as well as the script
``generate_profile.py``.



.. _fitparse: https://github.com/dtcooper/python-fitparse

.. :changelog:

==========
Change Log
==========


v0.11.0 (2025-08-06)
====================

* FIT SDK profile upgraded to v21.171.0
* Fixed: decoding of ``developer_data_index`` field which was not converted to
  an ``int`` due to a typo
* Most of FIT so-called developer fields are now considered optional (should
  fix #22 and #24)
* Support of ``localtime`` fields set to out-of-bound value ``86400`` (thanks to
  @maethub, see python-fitparse#138)
* ``generate_profile`` utility now supports latests FIT SDK Zip archive layout
  and ``Profile.xlsx`` file format (thanks to @fundthmcalculus, see
  python-fitparse#134)
* Minor corrections due to stricter flake8 settings (code quality)
* Overhaul of project files and C/I


v0.10.0 (2021-09-12)
====================

* ``fitjson``: added ``--pretty`` option
* ``fitjson``: added ``--nounk`` option to filter-out *unknown* messages
* ``fitjson``: ``--filter`` option also allows to filter-out messages
* ``fittxt``: ``--filter`` option also allows to filter-out messages
* ``fittxt``: added ``--nounk`` option to filter-out *unknown* messages
* Fixed: `FitReader` does not close a file-like object owned by the user
* Fixed: `FitReader.file_id` gets reset upon FIT footer (CRC frame)
* Fixed: `utils.get_mesg_num()` return value
* Fixed: `utils.get_mesg_field_num()` return value
* Minor corrections, improvements and code cleanup


v0.9.0 (2021-09-10)
===================

* `FitReader` gets new properties ``fit_file_index`` and ``fit_files_count``
* New ``CrcCheck`` policy: ``WARN``
* **BREAKING CHANGE:** ``CrcCheck`` default policy from ``RAISE`` to ``WARN``
* `FitHeaderError` exception messages a bit more helpful
* Minor corrections and code cleanup


v0.8.0 (2021-09-09)
===================

* `FitReader` gets the ``error_handling`` argument to be less strict on
  malformed files (issues #13, #16, #18)
* FIT SDK profile upgraded to v21.60
* Minor corrections, improvements and cleanup on code and documentation


v0.7.0 (2020-10-04)
===================

* Compatibility with Apple Watch improved (issue #10)
* FIT SDK profile upgraded to v21.38
* ``generate_profile`` utility now supports recent SDK file structure
* Minor improvements and cleanup on code and documentation


v0.6.0 (2019-11-02)
===================

* Added `FitReader.last_timestamp` property
* Fixed: `FitReader` was raising `KeyError` instead of `FitParseError` when a
  dev_type was not found
* `FitParseError` message contains more details upon malformed file in some
  cases
* FIT SDK profile upgraded to v21.16
* README's usage example slightly improved


v0.5.0 (2019-04-11)
===================

* Added `fitdecode.DataProcessorBase` class
* ``check_crc`` - the parameter to `fitdecode.FitReader`'s constructor - can now
  be either "enabled", "read-only" or "disabled" (issue #1)
* Minor speed improvements


v0.4.0 (2019-04-10)
===================

* Added `fitdecode.FitDataMessage.has_field`
* `fitdecode.FitDataMessage.get_fields` is now a generator
* `fitdecode.FitDataMessage.get_values` is now a generator
* `fitdecode.DefaultDataProcessor` now converts ``hr.event_timestamp`` values
  that were populated from ``hr.event_timestamp_12`` components to
  `datetime.datetime` objects for convenience
* ``fitjson`` and ``fittxt`` utilities:
  * Added support for input files with Unicode characters
  * Still write output file even if an error occurred while parsing FIT file
* Fixed handling of some FIT fields that are both scaled and components.
  See https://github.com/dtcooper/python-fitparse/issues/84
* Improved support for malformed FIT files.
  See https://github.com/dtcooper/python-fitparse/issues/62
* ``generate_profile`` utility slightly improved
* Added some unit tests
* Minor improvements and corrections


v0.3.0 (2018-07-27)
===================

* Added `fitdecode.utils.get_mesg_field`
* Added `fitdecode.utils.get_mesg_field_num`
* Minor improvements and corrections


v0.2.0 (2018-07-16)
===================

* Added `FieldData.name_or_num`
* Added `FitDataMessage.get_fields`
* Added `FitDataMessage.get_values`
* Improved `FitDataMessage.get_field` (*idx* arg)
* Improved `FitDataMessage.get_value` (*idx* arg)
* Completed documentation of `FitDataMessage`
* Improved documentation of `FieldData`
* `FitReader`'s internal state is reset as well after a `FitCRC` has been
  yielded (i.e. not only when a FIT header is about to be read), in order to
  avoid incorrect behavior due to malformed FIT stream


v0.1.0 (2018-07-14)
===================

* Added class property ``frame_type`` (read-only) to `FitHeader`, `FitCRC`,
  `FitDefinitionMessage` and `FitDataMessage` (``records`` module) to ease and
  speed up type checking
* Added `FitDataMessage.get_value` method
* ``string`` values with no null byte are still decoded (in full length)
* ``cmd`` directory added to the source code tree for convenience


v0.0.1 (2018-07-08)
===================

* First release


v0.0.0 (2018-05-31)
===================

* Birth!