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.6.0.tar.gz (15.6 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.6.0-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cbor_model-0.6.0.tar.gz
  • Upload date:
  • Size: 15.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","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.6.0.tar.gz
Algorithm Hash digest
SHA256 94b28e58590f5f5846a089db627a2763567462580f3bfc09a57f86a7871010df
MD5 a2cc21dded9ba23852c607c654047bc8
BLAKE2b-256 5cadf0d6aada3aa2b54417642c78ad8c764584fd5be098b2615c1c6e79ebb079

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cbor_model-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 20.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","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.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 66e1f7a5ef78bc6290163869ebe41768f61080ad96a9dfac31a02f688211e480
MD5 2e631875085818344297ea2c083d3e86
BLAKE2b-256 8d57e8e44fb9240d179d0bc8119f37b2e8da2720ca6cb54a7db2d2a09a4c86da

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