ProvenPin Install

dataclasses-json camelCase serialization: working versions (tested 2026-10-16)

Serialize dataclasses to camelCase JSON with dataclasses-json, handling nested types, datetimes and unknown keys via LetterCase and Undefined.

passed6 passed · 0 failed2026-10-16 21:56 UTC
Status
passed
Last passed
2026-10-16 21:56 UTC
Tests
6 / 6
Language
Python
Runtime
Python 3.13.16
pinned versions2
dataclasses-json@0.6.7pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 38972656245

The code

Exactly the files that passed. Your agent can pull them with get_recipe("dataclasses-json-camelcase") (install), or see them on GitHub.

requirements.txt
dataclasses-json==0.6.7
pytest==9.1.1
models.py
from dataclasses import dataclass, field
from datetime import datetime

from dataclasses_json import (
    CatchAll,
    LetterCase,
    Undefined,
    dataclass_json,
)


@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class Address:
    street_name: str
    zip_code: str


@dataclass
class Contact:
    # Left undecorated on purpose: LetterCase does not reach nested classes.
    phone_number: str


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.RAISE)
@dataclass
class User:
    user_id: int
    full_name: str
    created_at: datetime
    address: Address
    contact: Contact
    tags: list[str] = field(default_factory=list)


@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class Note:
    note_id: int
    body: str


@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.INCLUDE)
@dataclass
class Webhook:
    event_id: str
    rest: CatchAll = None
tests/test_serialization.py
import json
from datetime import datetime, timezone

import pytest
from dataclasses_json.undefined import UndefinedParameterError

from models import Address, Contact, Note, User, Webhook


def make_user() -> User:
    return User(
        user_id=1,
        full_name="Ada Lovelace",
        created_at=datetime(2026, 1, 2, 3, 4, 5, tzinfo=timezone.utc),
        address=Address("Main St", "N1 1AA"),
        contact=Contact("555-0100"),
        tags=["math"],
    )


def test_camel_case_keys_and_aware_roundtrip():
    user = make_user()
    payload = json.loads(user.to_json())
    assert set(payload) == {"userId", "fullName", "createdAt", "address", "contact", "tags"}
    assert user.to_dict()["address"] == {"streetName": "Main St", "zipCode": "N1 1AA"}
    assert User.from_json(user.to_json()) == user


def test_undecorated_nested_class_keeps_snake_case():
    payload = json.loads(make_user().to_json())
    assert payload["contact"] == {"phone_number": "555-0100"}


def test_datetime_is_encoded_as_epoch_seconds():
    payload = json.loads(make_user().to_json())
    assert isinstance(payload["createdAt"], float)
    with pytest.raises(TypeError):
        User.from_dict({**payload, "createdAt": "2026-01-02T03:04:05+00:00"})


def test_naive_datetime_comes_back_timezone_aware():
    user = make_user()
    user.created_at = datetime(2026, 1, 2, 3, 4, 5)
    restored = User.from_json(user.to_json())
    assert restored.created_at.tzinfo is not None
    assert restored != user


def test_undefined_keys_are_ignored_or_raise():
    assert Note.from_dict({"noteId": 1, "body": "hi", "typo": True}).body == "hi"
    with pytest.raises(UndefinedParameterError):
        User.from_dict({**json.loads(make_user().to_json()), "typo": True})


def test_catch_all_collects_extras():
    hook = Webhook.from_dict({"eventId": "e1", "source": "github", "attempt": 2})
    assert hook.rest == {"source": "github", "attempt": 2}
    assert json.loads(hook.to_json()) == {"eventId": "e1", "source": "github", "attempt": 2}
pytest.ini
[pytest]
pythonpath = .

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.