Skip to main content

CBOR Model: Add CBOR and CDDL support to Pydantic models

Project description

CBOR Model

cbor-model adds CBOR serialization and CDDL schema generation to Pydantic models.

Installation

pip install cbor-model

or with uv:

uv add cbor-model

Quick start

Map encoding

Fields are encoded as a CBOR map keyed by the integer or string supplied to CBORField(key=...).

from typing import Annotated
from cbor_model import CBORModel, CBORField

class Sensor(CBORModel):
    name: Annotated[str, CBORField(key=0)]
    value: Annotated[float, CBORField(key=1)]

sensor = Sensor(name="temp", value=21.5)
data = sensor.model_dump_cbor()  # a2006474656d7001fb4035800000000000
assert Sensor.model_validate_cbor(data) == sensor

Array encoding

Switch to array encoding by setting CBORConfig(encoding="array") and using CBORField(index=...) — fields are serialized in index order.

from typing import Annotated
from cbor_model import CBORModel, CBORField, CBORConfig

class Point(CBORModel):
    cbor_config = CBORConfig(encoding="array")

    x: Annotated[int, CBORField(index=0)]
    y: Annotated[int, CBORField(index=1)]

pt = Point(x=4, y=2)
data = pt.model_dump_cbor()  # 820402
assert Point.model_validate_cbor(data) == pt

CBOR tags

Wrap a field's value in a CBOR tag using CBORField(tag=...), or tag the entire model with CBORConfig(tag=...).

from typing import Annotated
from cbor_model import CBORModel, CBORField, CBORConfig

class Reading(CBORModel):
    cbor_config = CBORConfig(tag=40001)

    sensor_id: Annotated[int, CBORField(key=0)]
    raw: Annotated[bytes, CBORField(key=1, tag=40002)]

Serialization context

Pass a CBORSerializationContext to control None and empty-collection exclusion:

from cbor_model import CBORSerializationContext

ctx = CBORSerializationContext(exclude_none=False, exclude_empty=False)
data = sensor.model_dump_cbor(context=ctx)

Custom encoders

Register encoders for types not natively supported by cbor2:

import decimal
from cbor_model import CBORConfig

class MyModel(CBORModel):
    cbor_config = CBORConfig(
        encoders={decimal.Decimal: lambda d: str(d)}
    )
    amount: Annotated[decimal.Decimal, CBORField(key=0)]

CDDL generation

Generate a CDDL schema from one or more models:

from cbor_model.cddl import CDDLGenerator

print(CDDLGenerator().generate(Sensor))
# sensor_name = 0
# sensor_value = 1
#
# Sensor = {
#     ? sensor_name: tstr,
#     ? sensor_value: float
# }

Integer constraints are rendered as precise RFC 8610-compatible CDDL. For example, lower-only bounds use numeric controls such as .gt or .ge, and closed integer bounds are emitted as ranges:

from typing import Annotated
from pydantic import Field

from cbor_model import CBORField, CBORModel
from cbor_model.cddl import CDDLGenerator


class Packet(CBORModel):
    count: Annotated[int, CBORField(key=0), Field(gt=0)]
    code: Annotated[int, CBORField(key=1), Field(ge=0, le=255)]


print(CDDLGenerator().generate(Packet))
# packet_count = 0
# packet_code = 1
#
# Packet = {
#     packet_count: int .gt 0,
#     packet_code: 0..255
# }

Map-encoded models always emit a per-model block of integer-key constants (prefix is the model class name converted to snake_case) and reference those constants in the map body. Use CBORField(description=...) to attach a free-text comment that is rendered as ; <text> after the field definition, and CBORField(override_name=...) to override the identifier (used verbatim).

Public type aliases

The package also exposes a small set of reusable integer aliases under cbor_model.types:

from typing import Annotated

from cbor_model import CBORField, CBORModel, types


class Header(CBORModel):
    version: Annotated[types.UInt1, CBORField(key=0)]
    length: Annotated[types.UInt2, CBORField(key=1)]

The currently available aliases are:

  • types.Int1: signed 8-bit integer (-128..127)
  • types.UInt: unsigned integer (ge=0)
  • types.UInt1: unsigned 8-bit integer (0..255)
  • types.UInt2: unsigned 16-bit integer (0..65535)
  • types.UInt4: unsigned 32-bit integer (0..4294967295)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cbor_model-0.4.0.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cbor_model-0.4.0-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

Details for the file cbor_model-0.4.0.tar.gz.

File metadata

  • Download URL: cbor_model-0.4.0.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cbor_model-0.4.0.tar.gz
Algorithm Hash digest
SHA256 13b21eda6aca3db14dbcfc0745fc76c6ea7ee5067be25192e936e6a873b0c89e
MD5 9298bcd20f9155661a07efbfaccde93b
BLAKE2b-256 b7b63db644bea53d8aff9658a79a247f8397090e87349a607029f5283d60aa32

See more details on using hashes here.

File details

Details for the file cbor_model-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: cbor_model-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for cbor_model-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8e44d43c8e815d6e1883e473aaac8cca5f13b7159593f1fa87933c1d98db1c1
MD5 4a1716ab7833274bfa4567fd99d8a3fd
BLAKE2b-256 9fb20d207d7013c72d1b381b0f89bc22585044e53dd8fccb420000639e62715c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page