Skip to main content

Packet definitions from CSV

CCSDSPy lets you describe a packet layout entirely in Python by building a list of PacketField and PacketArray objects. As an alternative, it can also read the same layout from a CSV (comma-separated value) file. This is useful when packet definitions live alongside mission documentation, are maintained by non-developers, or are generated from a spreadsheet.

The CSV feature is supported for both packet classes through the from_file() classmethod.

note

The CSV loader is officially documented but still evolving. The upstream User's Guide notes that the CSV format "is in development and is currently limited" — for example, it cannot express byte order or array order. Where you need that level of control, define the packet in Python instead. See Sources for the current upstream documentation.

Loading a definition

The API is identical for fixed-length and variable-length packets. Call from_file() on the class and pass the path to the CSV:

import ccsdspy

# Fixed-length packets
pkt = ccsdspy.FixedLength.from_file('packet_definition.csv')

# Variable-length packets
pkt = ccsdspy.VariableLength.from_file('packet_definition.csv')

# The returned object behaves exactly like one built in Python:
result = pkt.load('mypackets.bin')

The object returned by from_file() is a normal FixedLength or VariableLength instance, so everything else — load(), decoding to NumPy arrays, and so on — works the same as a definition written in code.

CSV layouts

The first row of the CSV must be a header naming the columns. Each subsequent row defines one packet field. CCSDSPy accepts two layouts.

Basic layout (three columns)

The basic layout uses the columns name, data_type, and bit_length. CCSDSPy automatically calculates each field's bit offset, assuming the rows are listed in packet order.

ColumnMeaning
nameField name (used as the key in decoded output)
data_typeField type — see Data types below
bit_lengthWidth of the field in bits

Illustrative example (packet_definition.csv):

name,data_type,bit_length
SHCOARSE,uint,32
SHFINE,uint,20
OPMODE,uint,3
SPACER,fill,1
VOLTAGE,int,8

Extended layout (four columns)

The extended layout adds a bit_offset column, giving you explicit control over where each field begins. Use this when fields are not strictly contiguous or you want to be unambiguous about positioning.

ColumnMeaning
nameField name
data_typeField type
bit_lengthWidth of the field in bits
bit_offsetExplicit starting bit position of the field

Illustrative example (packet_definition.csv):

name,data_type,bit_length,bit_offset
SHCOARSE,uint,32,0
SHFINE,uint,20,32
OPMODE,uint,3,52
SPACER,fill,1,55
VOLTAGE,int,8,56
info

The extended layout is not available for VariableLength packets, because a bit_offset cannot be specified once the packet contains a variable-length field. Variable-length packets must therefore use the basic three-column layout.

Data types

The data_type column accepts the same type names used by PacketField in Python, including:

data_typeDescription
uintUnsigned integer
intSigned integer
floatFloating-point value
strString value
fillPadding / spacer bits that are skipped

Defining arrays in CSV

To express a PacketArray, write the array shape in parentheses directly in the data_type column. The type name comes first, followed by the shape.

name,data_type,bit_length
SHCOARSE,uint(4),16
SENSOR_GRID,int(12, 24),16

In this illustrative example, uint(4) declares an array of shape (4) and int(12, 24) declares a two-dimensional array of shape (12, 24).

For VariableLength packets, the parenthetical syntax also accepts the variable-length forms used in code — for instance uint(expand) for an expanding array, or referencing another field by name (such as uint(SHFINE)) to size the array from a previously decoded field.

tip

If your layout uses features the CSV format cannot yet express — such as explicit byte order or array order — keep that definition in Python using PacketField and PacketArray. You can mix approaches across a project: simple, stable layouts in CSV and the more complex ones in code.

Choosing between CSV and code

Use CSV when…Use Python when…
Definitions are shared with non-developersYou need byte order or array order control
Layouts are generated from spreadsheetsYou build definitions dynamically at runtime
You want a simple, reviewable text artifactYou need features still missing from the CSV format

Sources