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.7.0.tar.gz (16.2 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.7.0-py3-none-any.whl (21.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cbor_model-0.7.0.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","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.7.0.tar.gz
Algorithm Hash digest
SHA256 2149ba4b6aa48d00611d75b0d32904a77d4367b8c63df4c250a6db083d59a974
MD5 03bdc9b5d05403b4458d0e762d96b0c1
BLAKE2b-256 28b60d6b019a6f06debb319813fe9ea5b70087d03a216b54993ba89309632836

See more details on using hashes here.

File details

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

File metadata

  • Download URL: cbor_model-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 21.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","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.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f4a05b61cda1b8e4dc6b2b5241bd16ea64d2f865bba116be09349cdd8de424a1
MD5 a4801a8faf2931525e57cf64706494e4
BLAKE2b-256 89131b4a6432a9594a9858746adae99532fe7e093c32c725316db36167fab347

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