Layer Io
app.application.services.helpers.layer_ioShared JSON/CSV serialisation helpers for BBoxViewModel layer data.
This module is an internal utility — it is not exposed through any __init__.py.
Both the detection and tracking import/export services import from here so that
the wire format is defined in exactly one place.
Wire format
JSON
{
"meta": {
"exported_layer": "B",
"format_version": "1.0",
"total_frames": 5,
"total_boxes": 42
},
"frames": {
"0": [
{
"id": "yolo-1",
"source": "Detection",
"label": "person",
"bbox_xyxy": [100, 200, 300, 400],
"color_hex": "#00ff00",
"confidence": 0.95,
"key": "detection:yolo-1"
}
]
}
}
CSV
Columns (tab/comma-separated): frame_index, id, source, label, x1, y1, x2, y2, confidence, color_hex, key
source is stored as its value string (e.g. "Detection") because
BoxSource is a str-based enum.
confidence is left blank when None.
Design notes
format_versionin the JSON meta block enables forward-compatible migrations.- All keys are preserved verbatim on round-trips.
apply_import_to_layerhandles collision resolution according to the chosenImportMode.
Layer: Application. Context: Coordinates domain state and infrastructure to complete application use cases.
serialize_layer_to_json(layer_name_str: str, data: dict[int, ListOfBoxes], file_path: str) -> int
Write data as a JSON file. Returns the number of boxes written.
| PARAMETER | DESCRIPTION |
|---|---|
layer_name_str
|
Layer name recorded in the JSON metadata.
TYPE:
|
data
|
Boxes grouped by zero-based frame index.
TYPE:
|
file_path
|
Destination path for the JSON file.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int
|
Number of boxes serialized. |
serialize_layer_to_csv(layer_name_str: str, data: dict[int, ListOfBoxes], file_path: str) -> int
Write data as a CSV file. Returns the number of boxes written.
| PARAMETER | DESCRIPTION |
|---|---|
layer_name_str
|
Unused compatibility argument retained to match the JSON helper.
TYPE:
|
data
|
Boxes grouped by zero-based frame index.
TYPE:
|
file_path
|
Destination path for the CSV file.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int
|
Number of boxes written to the CSV file. |
deserialize_layer_from_json(file_path: str) -> dict[int, ListOfBoxes]
Read a JSON file and return {frame_index: [BBoxViewModel, ...]}.
Note
Unknown source values that are not registered in BoxSource will
raise ValueError. The calling service should catch and surface this
as a user-friendly error.
deserialize_layer_from_csv(file_path: str) -> dict[int, ListOfBoxes]
Read a CSV file and return {frame_index: [BBoxViewModel, ...]}.
Note
Rows with an empty confidence field are loaded with confidence=None.
apply_import_to_layer(store: SessionDataStore, layer: VideoDataLayer, incoming: dict[int, ListOfBoxes], mode: ImportMode) -> int
Apply incoming data into store's layer according to mode.
| RETURNS | DESCRIPTION |
|---|---|
int
|
Total number of boxes written into the layer.
TYPE:
|
Note
MERGE_RENAME uses a "imp-" prefix on both key and id for
each box whose key already exists in the target frame. This makes
re-imported boxes distinguishable and avoids silent data loss.
Consider future improvement: expose a configurable rename prefix so callers can pass a session-specific or timestamp-based prefix.