Kaitai Struct Python Runtime
Kaitai Struct provides a declarative parsing framework for binary data. This library serves as the Python runtime component, allowing users to load and interpret binary files based on `.ksy` specifications compiled into Python classes. The current version is 0.11, and releases are generally stable, focusing on compatibility with the Kaitai Struct compiler.
Warnings
- gotcha The `kaitaistruct` Python library is a *runtime* component. It does not perform the code generation itself. You MUST use the separate, Java-based Kaitai Struct Compiler (`ksc`) to convert your `.ksy` specifications into Python code before you can use this library.
- gotcha Generated Python parser files (e.g., `my_parser.py`) must be discoverable by Python's import mechanism. If you get `ModuleNotFoundError`, it's likely Python cannot find the generated module.
- breaking Major internal changes occurred between Kaitai Struct compiler/runtime versions 0.9 and 0.10, particularly affecting how `_parent` and `_root` contexts are handled in `.ksy` specifications. Older specifications might fail or produce incorrect results with newer runtimes.
Install
-
pip install kaitaistruct
Imports
- KaitaiStream
from kaitaistruct import KaitaiStream
- KaitaiStruct
from kaitaistruct import KaitaiStruct
- GeneratedParserClass
from my_parser import MyParserClass
Quickstart
import os
# Assuming 'test.py' was generated from 'test.ksy' by the ksc compiler.
# The 'test.ksy' and 'test.bin' files would typically be created externally.
# For this runnable example, we'll create them in a temporary manner.
# 1. Create a dummy binary file to parse
binary_data = b'\x01\x02\x03\x04'
with open('test.bin', 'wb') as f:
f.write(binary_data)
print(f"Created test.bin with data: {binary_data.hex()}")
# 2. Simulate the presence of a generated parser class 'Test'
# In a real scenario, this would come from `ksc --target python test.ksy`
# and you'd simply `from test import Test`.
# For this example, we mock the class directly.
from kaitaistruct import KaitaiStream, KaitaiStruct
class Test(KaitaiStruct):
def __init__(self, _io, _parent=None, _root=None):
self._io = _io
self._parent = _parent
self._root = _root if _root else self
self._read()
def _read(self):
self.my_field = self._io.read_u4le()
@property
def get_my_field(self):
return self.my_field
# 3. Use the generated (or mocked) parser to read the binary data
with open('test.bin', 'rb') as f_obj:
io_stream = KaitaiStream(f_obj)
parsed_data = Test(io_stream)
print(f"Parsed value: {parsed_data.my_field} (0x{parsed_data.my_field:x})")
# Clean up generated/dummy files
os.remove('test.bin')