Skip to main content

Read CAN bus capture logs in different formats into one common frame stream

Project description

capkit

PyPI CI Python versions License: MIT

capkit is a Python library that reads CAN bus capture logs into one common frame stream. Every supported format parses into the same frozen Frame dataclass, so code that consumes frames never depends on which tool captured the log.

Use it to:

  • read captures from different tools as one lazy stream of typed Frame objects
  • probe a file for header metadata without scanning the frame body
  • detect the log format from the file extension or the file content
  • skip real-world log noise by default, or reject it with strict=True
  • feed frames into dbckit for DBC signal decoding
Format Reader name Extensions Status Dependency
Kvaser CanKing TXT kvaser-txt .txt Supported none
candump text candump .log Planned none
Vector ASC vector-asc .asc Planned none
PCAN TRC pcan-trc .trc Planned none
Generic CSV csv-table .csv Planned none
Vector BLF vector-blf .blf Planned adapter python-can
ASAM MF4 asam-mf4 .mf4 Planned adapter asammdf

See format support for the exact dialect each reader accepts, and the roadmap for sequencing.

Install

pip install capkit

Requires Python >=3.11. capkit has no runtime dependencies.

Design

  • Frame and LogMeta are frozen, slotted dataclasses.
  • read() is lazy and keeps constant parser state, so file size does not matter.
  • Timestamps are returned exactly as recorded in the source, never rebased or converted to absolute time.
  • A format is added only when a real captured fixture pins its dialect under tests/fixtures/; unsupported dialects fail clearly instead of parsing approximately.

Quick Start

import capkit

# stream frames
for frame in capkit.read("trace.txt"):
    print(frame.timestamp, hex(frame.arbitration_id), frame.data.hex())

# header metadata only
meta = capkit.probe("trace.txt")
print(meta.format, meta.start_time)

# registered reader names
print(capkit.available_formats())   # ['kvaser-txt']

The public API is six names: read, probe, available_formats, register_reader, Frame, and LogMeta.

Features

Format detection

An explicit format= names a reader and takes precedence over the file extension:

frames = capkit.read("capture.bin", format="kvaser-txt")

Without format=, capkit matches the extension against registered readers and sniffs the first 4 KiB when the extension is unknown or ambiguous.

Add your own reader

Register a zero-argument reader class to make it available to read(), probe(), and format detection:

from collections.abc import Iterator
from pathlib import Path

import capkit


class MyReader:
    name: str = "my-format"
    extensions: tuple[str, ...] = (".mylog",)

    def __init__(self, *, strict: bool = False) -> None:
        self.strict = strict

    def sniff(self, sample: str) -> bool:
        return sample.startswith("MYLOG")

    def probe(self, path: Path) -> capkit.LogMeta:
        return capkit.LogMeta(format=self.name)

    def read(self, path: Path) -> Iterator[capkit.Frame]:
        # Parse path lazily and yield capkit.Frame objects here.
        yield from ()


capkit.register_reader(MyReader)

Registration is process-global and is normally performed at import time. dbckit's .txt entry point sniffs among all registered readers, so a reader whose sniff() uniquely matches the content of a .txt log is used there too, regardless of the extensions it claims.

Dirty logs and strict mode

Readers skip headers, trailers, comments, blank lines, and unrelated noise by default. Pass strict=True to raise a line-numbered ValueError on the first unrecognized nonblank line instead:

frames = capkit.read("trace.txt", strict=True)

A frame record whose DLC disagrees with its data bytes raises in both modes; corrupt frames are never silently dropped.

Use with dbckit

dbckit decodes CAN frames against a DBC database. capkit and dbckit are separate packages — neither depends on or imports the other — with adjacent jobs: capkit turns bytes on disk into frames, dbckit turns frames plus a DBC into signals.

import capkit
import dbckit

db = dbckit.load("truck.dbc")
for decoded in dbckit.decode_frames(db, capkit.read("trace.txt")):
    print(decoded.timestamp, decoded.signals)

capkit also registers its readers in dbckit's dbckit.readers entry-point group. With both packages installed, dbckit.decode_log() reads .txt logs through capkit directly:

for decoded in dbckit.decode_log(db, "trace.txt"):
    print(decoded.signals)

Scope and Caveats

  • Kvaser dialects with absolute start-time headers are not supported; probe() returns start_time=None for kvaser-txt.
  • capkit reads frames only: no DBC or signal awareness (that is dbckit's job), no hardware I/O, no log writing, no dataframe export, no CLI.

Documentation

  • Format support — supported formats and the exact dialect each reader accepts
  • API reference — the public API contract
  • Recipes — counting IDs, filtering, time windows, CSV export, and dataframes in a few lines of standard library

Development

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest

The dev extra includes dbckit so the entry-point integration tests run; the core and contract suites pass without it.

License

MIT

Project details


Download files

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

Source Distribution

capkit-0.1.0.tar.gz (24.9 kB view details)

Uploaded Source

Built Distribution

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

capkit-0.1.0-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file capkit-0.1.0.tar.gz.

File metadata

  • Download URL: capkit-0.1.0.tar.gz
  • Upload date:
  • Size: 24.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for capkit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 51da72e21dd3febd3c64cfc43f01cdf4a9c1733cc50ea60f383abe5fb2b01490
MD5 f1aa26219b995044aa6567a6dccca985
BLAKE2b-256 606cef571d6fb0f16cd74af11d6172ad96d006f9b2026dd1620810ff04f4d148

See more details on using hashes here.

Provenance

The following attestation bundles were made for capkit-0.1.0.tar.gz:

Publisher: release.yml on canforge/capkit

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

File details

Details for the file capkit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: capkit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for capkit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0e422e7d9e76a10d3793f425ed5d64286b3b759dcf6214b8690949607d39fd9b
MD5 352c056f02e4cad3142e39381dc30fa4
BLAKE2b-256 f8630f7344ec77e28596ea1819da5eee522a73ddfd1cf7ceaf7d102df471fe5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for capkit-0.1.0-py3-none-any.whl:

Publisher: release.yml on canforge/capkit

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