Install StructReader from PyPI:
pip install StructReaderUpdate an existing installation of StructReader:
pip install --upgrade StructReaderStructReader is a binary format parsing framework for Python.
It is designed specifically for structured binary data parsing, where the layout is known or partially known, such as custom file formats.
Instead of manually reading bytes and tracking offsets, you declare the binary format structure, and StructReader handles stream reading, endianness, field dependencies, and control flow.
You define a binary structure as a Python class.
- Each class attribute represents one field
- The attribute value describes how to read the field
The framework:
- Compiles the structure into an internal opcode representation
- Executes the opcodes against a binary stream
- Produces a Python object or dictionary
class Header:
magic = UIntBE[32]
size = UInt[16]
data = Bytes[Var.size]Parsing:
obj = ParseStruct(Header, data)Access fields:
print(obj.magic)
print(obj.size)
print(obj.data)| Type | Description |
|---|---|
Int[n] |
Signed integer, n bits |
UInt[n] |
Unsigned integer, n bits |
IntLE[n] |
Little-endian signed |
IntBE[n] |
Big-endian signed |
UIntLE[n] |
Little-endian unsigned |
UIntBE[n] |
Big-endian unsigned |
Example:
id = UInt[32]
flags = UIntBE[16]| Type | Description |
|---|---|
Float[n] |
Floating point, default endianness |
FloatLE[n] |
Little-endian |
FloatBE[n] |
Big-endian |
Example:
x = Float[32]
y = FloatBE[64]Str[length]
Str[length, encoding]
StrU[length]
StrU[length, encoding]lengthmay be a constant or a previously defined field- Default encoding is UTF-8
Example:
name_len = UInt[8]
name = Str[Var.name_len]
name2_len = UInt[8]
name2 = StrU[Var.name_len2]Bytes[length]Reads raw bytes from the stream.
Example:
payload = Bytes[16]Uvarint
SvarintBoolReads 1 byte and returns True if non-zero.
LenReturns the total length of the input stream (in bytes).
Example:
class File:
size = LenUntil[value]Reads data until a terminator value is encountered.
- The terminator is not included in the result
- Stream position advances past the terminator
Example:
name = Str[Until[b'\x00']]
data = Bytes[Until[b'\xFF\xFF']]Align[n]Returns the number of bytes needed to align the stream position to n.
Usually combined with Seek.
Example:
pad = Align[16]
Seek[Var.pad, 1]List[count, value_type]countmay be a constant or another field
Example:
count = UInt[16]
items = List[Var.count, UInt[32]]Structures can be nested by referencing another structure class.
Example:
class Point:
x = Int[32]
y = Int[32]
class Shape:
center = Point
radius = UInt[16]Var.field_nameAllows a field to reference a previously parsed field.
Example:
class Packet:
length = UInt[16]
data = Bytes[Var.length]PosReturns the current read position in the stream.
Seek[offset, mode]If mode is omitted, it defaults to 0.
| Mode | Meaning |
|---|---|
0 |
Absolute position |
1 |
Relative to current position |
2 |
Relative to end |
Example:
Seek[128] # same as Seek[128, 0]
Seek[128, 0] # absolute position
Seek[16, 1] # relative to current positionPeek[value]Reads a value without advancing the stream position.
Example:
next_type = Peek[UInt[8]]Match[cond, params, results]Selects one parsing branch based on the value of cond.
Example:
class Entry:
type = UInt[8]
data = Match[
lambda t: 1 if t > 1 else 2 if t > 2 else 0,
[Var.type],
[
UInt[32], # index 0
Str[8], # index 1
Bytes[8], # index 2
]
]While[cond, params, body]Repeatedly parses body while the condition cond evaluates to True.
Example:
class Entry:
values = While[
lambda c: c < 128, # cond
[UInt[8]], # params
[UInt[16]] # body
]Select[number, values]Select from values based on the passed value.
Example:
class Entry:
values = Select[
UInt[8],
[0, Uint[32], Uint[8]]
]Func[callable, params...]Calls a Python function with parsed parameters.
Example:
def checksum(a, b):
return a ^ b
class Block:
a = UInt[8]
b = UInt[8]
c = Func[checksum, Var.a, Var.b]Group[param1, param2, ...]Used to group multiple parameters, mainly for function calls.
ParseStruct(struct, data,
ReturnDict=False,
order='little',
encoding='utf-8',
order2=None,
bytesToHex=False)-
struct- A structure class or a compiled structure dictionary
-
databytes,bytearray,memoryview, orBufferedReader
-
ReturnDict(bool)False(default): return an object with attributesTrue: return a dictionary
-
order('little'|'big')- Default integer byte order
-
encoding(str)- Default string encoding
-
order2('<'|'>'| None)- Float byte order override
- If
None, inferred fromorder
-
bytesToHex(bool)- If
True,Bytes[...]fields return hexadecimal strings
- If
obj = ParseStruct(MyStruct, data, ReturnDict=True)Returns a dictionary instead of an object.
The input stream may be:
bytesbytearraymemoryviewBufferedReader
- Parsing errors raise
RuntimeError - The error contains the failing field definition
- Context (
Var) is reset between parse calls
- Explicit support for binary format parsing
- Declarative structure definitions
- Configurable endianness and encoding
- Field dependency via
Var - Conditional parsing (
Match) - Stream control (
Seek,Peek,Pos) - Object or dictionary output modes
- No external dependencies
| Type | Default |
|---|---|
Int |
Int[32] |
UInt |
UInt[32] |
IntLE |
IntLE[32] |
IntBE |
IntBE[32] |
UIntLE |
UIntLE[32] |
UIntBE |
UIntBE[32] |
Float |
Float[32] |
FloatLE |
FloatLE[32] |
FloatBE |
FloatBE[32] |
Str |
Str[UInt[8]] |
Bytes |
Bytes[UInt[8]] |
Seek |
Seek[0] |
Until |
Until[b'\x00'] |
Align |
Align[16] |
from StructReader import ParseStruct
class Example:
a = UInt[16]
b = UInt[16]
obj = ParseStruct(Example, b"\x00\x01\x00\x02")
print(obj.a, obj.b)from StructReader import CompileStruct, ParseStruct
class Example:
a = UInt[16]
b = UInt[16]
myStruct = CompileStruct(Example)
obj = ParseStruct(myStruct, b"\x00\x01\x00\x02")
print(obj.a, obj.b)StructReader focuses on binary format parsing through a declarative, structure‑first approach.
By separating format description from byte reading logic, it allows complex binary layouts to be expressed clearly, maintained easily, and extended safely.
StructReader is especially suitable for projects involving:
- Complex or nested binary formats
- Field‑dependent layouts
- Conditional and dynamic parsing