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.
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.
| Column | Meaning |
|---|---|
name | Field name (used as the key in decoded output) |
data_type | Field type — see Data types below |
bit_length | Width 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.
| Column | Meaning |
|---|---|
name | Field name |
data_type | Field type |
bit_length | Width of the field in bits |
bit_offset | Explicit 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
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_type | Description |
|---|---|
uint | Unsigned integer |
int | Signed integer |
float | Floating-point value |
str | String value |
fill | Padding / 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.
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-developers | You need byte order or array order control |
| Layouts are generated from spreadsheets | You build definitions dynamically at runtime |
| You want a simple, reviewable text artifact | You need features still missing from the CSV format |