Skip to content
Back to top
View this page

# Usage

`msgspec` supports multiple serialization protocols, accessed through separate submodules:

- `msgspec.json` (JSON)

- `msgspec.msgpack` (MessagePack)

- `msgspec.yaml` (YAML)

- `msgspec.toml` (TOML)

Each supports a consistent interface, making it simple to switch between protocols as needed.

## Encoding

Each submodule has an `encode` method for encoding Python objects using the respective protocol.

    >>> import msgspec

    >>> # Encode as JSON
    ... msgspec.json.encode({"hello": "world"})
    b'{"hello":"world"}'

    >>> # Encode as msgpack
    ... msgspec.msgpack.encode({"hello": "world"})
    b'\x81\xa5hello\xa5world'

Note that if you’re making multiple calls to `encode`, it’s more efficient to create an `Encoder` once and use the `Encoder.encode` method instead.

    >>> import msgspec

    >>> # Create a JSON encoder
    ... encoder = msgspec.json.Encoder()

    >>> # Encode as JSON using the encoder
    ... encoder.encode({"hello": "world"})
    b'{"hello":"world"}'

## Decoding

Each submodule has `decode` method for decoding messages using the respective protocol.

    >>> import msgspec

    >>> # Decode JSON
    ... msgspec.json.decode(b'{"hello":"world"}')
    {'hello': 'world'}

    >>> # Decode msgpack
    ... msgspec.msgpack.decode(b'\x81\xa5hello\xa5world')
    {'hello': 'world'}

Note that if you’re making multiple calls to `decode`, it’s more efficient to create a `Decoder` once and use the `Decoder.decode` method instead.

    >>> import msgspec

    >>> # Create a JSON decoder
    ... decoder = msgspec.json.Decoder()

    >>> # Decode JSON using the decoder
    ... decoder.decode(b'{"hello":"world"}')
    {'hello': 'world'}

## Typed Decoding

`msgspec` optionally supports specifying the expected output types during decoding. This serves a few purposes:

- Often serialized data has a fixed schema (e.g. a request handler in a REST api expects a certain JSON structure). Specifying the expected types allows `msgspec` to perform validation during decoding, with no added runtime cost.

- Python has a much richer type system than serialization protocols like JSON or MessagePack. Specifying the output types lets `msgspec` decode messages into types other than the defaults described above (e.g. decoding JSON objects into a Struct instead of the default `dict`).

- The type annotations used to describe the expected types are compatible with tools like mypy or pyright, providing excellent editor integration.

`msgspec` uses Python type annotations to describe the expected types. A wide variety of builtin types are supported.

Here we define a user schema as a Struct type. We then pass the type to `decode` via the `type` keyword argument:

    >>> import msgspec

    >>> class User(msgspec.Struct):
    ...     name: str
    ...     groups: set[str] = set()
    ...     email: str | None = None

    >>> msgspec.json.decode(
    ...     b'{"name": "alice", "groups": ["admin", "engineering"]}',
    ...     type=User
    ... )
    User(name='alice', groups={'admin', 'engineering'}, email=None)

If a message doesn’t match the expected type, an error is raised.

    >>> msgspec.json.decode(
    ...     b'{"name": "bill", "groups": ["devops", 123]}',
    ...     type=User
    ... )
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[1]`

### “Strict” vs “Lax” Mode

Unlike some other libraries (e.g. pydantic), `msgspec` won’t perform any unsafe implicit conversion by default (“strict” mode). For example, if an integer is specified and a string is provided instead, an error is raised rather than attempting to cast the string to an int.

    >>> msgspec.json.decode(b'[1, 2, "3"]', type=list[int])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    msgspec.ValidationError: Expected `int`, got `str` - at `$[2]`

For cases where you’d like a more lax set of conversion rules, you can pass `strict=False` to any `decode` function or `Decoder` class (“lax” mode). See Supported Types for information on how this affects individual types.

    >>> msgspec.json.decode(b'[1, 2, "3"]', type=list[int], strict=False)
    [1, 2, 3]