zcbor - CDDL Code Generation and Data Validation

0.9.1 · active · verified Mon Apr 13

zcbor is a Python library for code generation and data validation based on CDDL (Concise Data Definition Language) schemas. It enables developers to generate Python code for encoding and decoding CBOR (Concise Binary Object Representation) data, ensuring compliance with specified CDDL schemas. The library is currently at version 0.9.1 and receives updates periodically, with significant releases often including migration guides for breaking changes.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a simple CDDL schema, use the `zcbor` command-line tool to generate Python encoding/decoding functions, and then import and use these generated functions to serialize and deserialize data according to the schema.

import os
import subprocess
import sys
import shutil

# 1. Define a simple CDDL schema in a temporary file
cddl_schema_content = """
my_map = {
    ? "label" => tstr,
    ? "value" => int,
}
"""
schema_file = "my_schema.cddl"
with open(schema_file, "w") as f:
    f.write(cddl_schema_content)

output_dir = "generated_code"
# Clean up previous runs if any
if os.path.exists(output_dir):
    shutil.rmtree(output_dir)
os.makedirs(output_dir, exist_ok=True)

print(f"Generating code from {schema_file} into {output_dir}...")
# 2. Run zcbor to generate Python code using the command-line interface
try:
    # Use sys.executable to ensure the correct Python environment's zcbor is used
    result = subprocess.run(
        [sys.executable, "-m", "zcbor.main", schema_file, output_dir],
        capture_output=True,
        check=True,
        text=True
    )
    print("Code generation successful.")
except subprocess.CalledProcessError as e:
    print(f"Error during code generation: {e}")
    print("STDERR:", e.stderr)
    sys.exit(1)

# Add the output directory to the Python path to import generated modules
sys.path.insert(0, output_dir)

try:
    # 3. Import from the generated code and use encode/decode
    # The generated module name will typically be the CDDL filename without extension, lowercased.
    # Function names are snake_case from v0.9.0 onwards.
    from my_schema import my_map_encode, my_map_decode

    data = {"label": "test", "value": 123}
    print(f"Original data: {data}")

    encoded_cbor = my_map_encode(data)
    print(f"Encoded CBOR (hex): {encoded_cbor.hex()}")

    decoded_data, _ = my_map_decode(encoded_cbor) # decode returns (data, remaining_bytes)
    print(f"Decoded data: {decoded_data}")

    assert data == decoded_data
    print("Encoding and decoding successful and data matches.")

except ImportError as e:
    print(f"Could not import generated module: {e}")
    print("Ensure zcbor.main successfully generated 'my_schema.py' in the 'generated_code' directory.")
except Exception as e:
    print(f"An error occurred during encoding/decoding: {e}")
finally:
    # Clean up temporary files and directories
    if os.path.exists(schema_file):
        os.remove(schema_file)
    if os.path.exists(output_dir):
        shutil.rmtree(output_dir)
    # Remove from sys.path
    if output_dir in sys.path:
        sys.path.remove(output_dir)

view raw JSON →