Claude Code for orjson: Fast JSON Serialization in Python — Claude Skills 360 Blog
Blog / AI / Claude Code for orjson: Fast JSON Serialization in Python
AI

Claude Code for orjson: Fast JSON Serialization in Python

Published: April 6, 2028
Read time: 5 min read
By: Claude Skills 360

orjson is the fastest Python JSON library — serializes dataclasses, datetimes, numpy arrays, and UUIDs natively. pip install orjson. Dump: import orjson; data = orjson.dumps({"key": "value"}) → bytes. Load: orjson.loads(data) → dict. String: orjson.dumps(obj).decode(). Options: orjson.dumps(obj, option=orjson.OPT_INDENT_2). OPT_SORT_KEYS: sort dict keys. OPT_NON_STR_KEYS: allow non-string keys. OPT_SERIALIZE_NUMPY: numpy arrays as JSON arrays. OPT_SERIALIZE_UUID: UUID to string. OPT_PASSTHROUGH_DATETIME: skip datetime → use default. OPT_UTC_Z: datetime UTC as “Z” suffix. OPT_NAIVE_UTC: naive datetime treated as UTC. OPT_STRICT_INTEGER: raise on int > 64-bit. OPT_APPEND_NEWLINE: append \n. Stack: option=OPT_A | OPT_B. Default: def default(obj): if isinstance(obj, Decimal): return str(obj). Django/Flask: return HttpResponse(orjson.dumps(data), content_type="application/json"). FastAPI: class OResponse(JSONResponse): def render(self, content): return orjson.dumps(content). Pydantic: orjson.dumps(model.model_dump()). Dataclass: @dataclass instances serialize field-by-field natively. numpy: import numpy as np; orjson.dumps(arr, option=orjson.OPT_SERIALIZE_NUMPY). UUID: auto-serialized to string. datetime: auto → ISO 8601. datetime.datetime datetime.date datetime.time. decimal.Decimal via default. Speed: 3–10× faster than stdlib json. orjson.dumps returns bytes (not str) — str() or .decode() if needed. Claude Code generates orjson serialization helpers, FastAPI response classes, and high-throughput data pipeline encoders.

CLAUDE.md for orjson

## orjson Stack
- Version: orjson >= 3.9 | pip install orjson
- Dump: orjson.dumps(obj) → bytes | orjson.dumps(obj).decode() → str
- Load: orjson.loads(data) → Python object (accepts bytes, str, memoryview)
- Options: OPT_INDENT_2 | OPT_SORT_KEYS | OPT_NON_STR_KEYS | OPT_SERIALIZE_NUMPY
- Native: datetime → ISO 8601; UUID → str; dataclass/attrs → fields; numpy → array
- Custom: orjson.dumps(obj, default=fn) — raise TypeError to reject unknown
- FastAPI: subclass JSONResponse, override render() to use orjson.dumps

orjson Fast JSON Pipeline

# app/json_utils.py — orjson fast serialization, custom types, and FastAPI helpers
from __future__ import annotations

import dataclasses
import datetime
import decimal
import io
import uuid
from pathlib import Path
from typing import Any, Callable

import orjson


# ─────────────────────────────────────────────────────────────────────────────
# 1. Core helpers
# ─────────────────────────────────────────────────────────────────────────────

def dumps(
    obj: Any,
    *,
    indent: bool = False,
    sort_keys: bool = False,
    append_newline: bool = False,
    default: Callable | None = None,
    option: int | None = None,
) -> bytes:
    """
    Serialize obj to JSON bytes using orjson.
    Convenience wrapper with named keyword args for common options.
    """
    opt = option or 0
    if indent:
        opt |= orjson.OPT_INDENT_2
    if sort_keys:
        opt |= orjson.OPT_SORT_KEYS
    if append_newline:
        opt |= orjson.OPT_APPEND_NEWLINE
    kw: dict[str, Any] = {}
    if opt:
        kw["option"] = opt
    if default:
        kw["default"] = default
    return orjson.dumps(obj, **kw)


def dumps_str(obj: Any, **kwargs) -> str:
    """Serialize to JSON string (decoded from bytes)."""
    return dumps(obj, **kwargs).decode()


def loads(data: bytes | str | memoryview) -> Any:
    """Deserialize JSON bytes or string to Python object."""
    return orjson.loads(data)


def round_trip(obj: Any, **kwargs) -> Any:
    """Pack then immediately unpack — useful for type normalization."""
    return loads(dumps(obj, **kwargs))


# ─────────────────────────────────────────────────────────────────────────────
# 2. Custom type default encoder
# ─────────────────────────────────────────────────────────────────────────────

def default_encoder(obj: Any) -> Any:
    """
    orjson default function supporting extra types.
    Pass as: orjson.dumps(obj, default=default_encoder)
    """
    if isinstance(obj, decimal.Decimal):
        return str(obj)
    if isinstance(obj, (set, frozenset)):
        return sorted(obj, key=str)
    if isinstance(obj, bytes):
        return obj.hex()
    if isinstance(obj, Path):
        return str(obj)
    if isinstance(obj, complex):
        return {"real": obj.real, "imag": obj.imag}
    if hasattr(obj, "__dict__"):
        return obj.__dict__
    raise TypeError(f"Object of type {type(obj).__name__!r} is not JSON serializable")


def dumps_extended(obj: Any, indent: bool = False, sort_keys: bool = False) -> bytes:
    """Serialize with extended type support (Decimal, set, bytes, Path, etc.)."""
    return dumps(obj, indent=indent, sort_keys=sort_keys, default=default_encoder)


def dumps_extended_str(obj: Any, **kwargs) -> str:
    return dumps_extended(obj, **kwargs).decode()


# ─────────────────────────────────────────────────────────────────────────────
# 3. Numpy / scientific data
# ─────────────────────────────────────────────────────────────────────────────

def dumps_numpy(obj: Any, indent: bool = False) -> bytes:
    """
    Serialize object with numpy array support.
    Requires: pip install numpy
    Arrays become JSON arrays; dtype information is discarded.
    """
    opt = orjson.OPT_SERIALIZE_NUMPY
    if indent:
        opt |= orjson.OPT_INDENT_2
    return orjson.dumps(obj, option=opt)


def serialize_dataframe(df, orient: str = "records") -> bytes:
    """
    Serialize a pandas DataFrame using orjson.
    orient: "records" | "columns" (dict of lists)
    """
    if orient == "records":
        records = df.to_dict(orient="records")
    else:
        records = df.to_dict(orient="list")
    return dumps(records, default=default_encoder)


# ─────────────────────────────────────────────────────────────────────────────
# 4. File helpers
# ─────────────────────────────────────────────────────────────────────────────

def load_json_file(path: str | Path) -> Any:
    """Fast-load a JSON file using orjson."""
    return orjson.loads(Path(path).read_bytes())


def save_json_file(
    obj: Any,
    path: str | Path,
    indent: bool = True,
    sort_keys: bool = False,
    default: Callable | None = None,
) -> None:
    """Save obj as a JSON file using orjson."""
    data = dumps(obj, indent=indent, sort_keys=sort_keys, default=default or default_encoder)
    Path(path).write_bytes(data)


def update_json_file(path: str | Path, update_fn: Callable[[Any], Any]) -> Any:
    """Read, transform, and write a JSON file atomically."""
    p = Path(path)
    try:
        current = orjson.loads(p.read_bytes())
    except (FileNotFoundError, orjson.JSONDecodeError):
        current = {}
    new = update_fn(current)
    p.write_bytes(dumps(new, indent=True))
    return new


def load_jsonl(path: str | Path) -> list[Any]:
    """Load a JSON Lines file — one JSON object per line."""
    lines = Path(path).read_text(encoding="utf-8").splitlines()
    return [orjson.loads(line) for line in lines if line.strip()]


def save_jsonl(path: str | Path, records: list[Any]) -> None:
    """Write records as JSON Lines."""
    lines = [orjson.dumps(r).decode() for r in records]
    Path(path).write_text("\n".join(lines) + "\n", encoding="utf-8")


# ─────────────────────────────────────────────────────────────────────────────
# 5. FastAPI / Starlette response classes
# ─────────────────────────────────────────────────────────────────────────────

def make_orjson_response_class():
    """
    Return an orjson-powered FastAPI JSONResponse subclass.

    Usage:
        ORJSONResponse = make_orjson_response_class()

        app = FastAPI(default_response_class=ORJSONResponse)

        @app.get("/data")
        async def data():
            return {"timestamp": datetime.datetime.utcnow(), "values": [1,2,3]}
    """
    try:
        from starlette.responses import JSONResponse

        class ORJSONResponse(JSONResponse):
            media_type = "application/json"

            def render(self, content: Any) -> bytes:
                return orjson.dumps(
                    content,
                    option=(
                        orjson.OPT_SERIALIZE_NUMPY
                        | orjson.OPT_NON_STR_KEYS
                    ),
                    default=default_encoder,
                )

        return ORJSONResponse
    except ImportError:
        return None


# ─────────────────────────────────────────────────────────────────────────────
# 6. Redis / cache helpers
# ─────────────────────────────────────────────────────────────────────────────

class OrjsonCache:
    """
    Redis (or dict) cache that stores values as orjson bytes.
    orjson is faster than json for cache get/set hot paths.

    Usage:
        cache = OrjsonCache(redis_client)
        cache.set("key", {"data": [1, 2, 3]}, ttl=60)
        obj = cache.get("key")
    """

    def __init__(self, backend, prefix: str = ""):
        self._b = backend
        self._p = prefix

    def _k(self, key: str) -> str:
        return f"{self._p}{key}" if self._p else key

    def set(self, key: str, value: Any, ttl: int | None = None) -> None:
        data = orjson.dumps(value, default=default_encoder)
        k = self._k(key)
        if hasattr(self._b, "setex") and ttl:
            self._b.setex(k, ttl, data)
        elif hasattr(self._b, "set"):
            self._b.set(k, data)
        else:
            self._b[k] = data  # dict backend

    def get(self, key: str, default: Any = None) -> Any:
        k = self._k(key)
        data = self._b.get(k)
        if data is None:
            return default
        return orjson.loads(data)

    def delete(self, key: str) -> None:
        k = self._k(key)
        if hasattr(self._b, "delete"):
            self._b.delete(k)
        else:
            self._b.pop(k, None)


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    import json
    import time

    print("=== Basic usage ===")
    obj = {"name": "Alice", "score": 98.5, "active": True, "tags": ["python", "api"]}
    b = dumps(obj)
    print(f"  bytes: {b}")
    print(f"  loaded: {loads(b)}")

    print("\n=== Native types ===")
    native = {
        "now":      datetime.datetime.now(tz=datetime.timezone.utc),
        "today":    datetime.date.today(),
        "uid":      uuid.uuid4(),
        "duration": datetime.timedelta(hours=1, minutes=30),
    }
    packed = dumps_extended(native)
    print(f"  JSON: {packed.decode()}")

    print("\n=== Dataclass ===")
    @dataclasses.dataclass
    class User:
        name: str
        age: int
        created: datetime.datetime

    u = User("Bob", 30, datetime.datetime.utcnow())
    print(f"  {dumps(u).decode()}")

    print("\n=== Extended types ===")
    ext_obj = {
        "price": decimal.Decimal("19.99"),
        "features": frozenset(["fast", "safe", "simple"]),
        "path": Path("/tmp/data"),
        "checksum": b"\xde\xad\xbe\xef",
    }
    print(f"  {dumps_extended_str(ext_obj, indent=True)}")

    print("\n=== Options ===")
    d = {"z": 1, "a": 2, "m": 3}
    print(f"  sorted: {dumps_str(d, sort_keys=True)}")
    print(f"  indented:\n{dumps_str(d, indent=True)}")

    print("\n=== Speed comparison ===")
    payload = {
        "id":    12345,
        "items": [{"name": f"item-{i}", "price": i * 0.99} for i in range(50)],
        "ts":    datetime.datetime.utcnow().isoformat(),
    }
    N = 50_000

    t0 = time.perf_counter()
    for _ in range(N):
        json.dumps(payload).encode()
    json_t = time.perf_counter() - t0

    t0 = time.perf_counter()
    for _ in range(N):
        orjson.dumps(payload)
    orjson_t = time.perf_counter() - t0

    print(f"  json.dumps   {N:,}x: {json_t*1000:.1f}ms")
    print(f"  orjson.dumps {N:,}x: {orjson_t*1000:.1f}ms ({json_t/orjson_t:.1f}x faster)")

For the ujson alternative — ujson is another fast JSON library but hasn’t been actively maintained and has known precision bugs with floats; orjson is maintained, correct, and typically faster; both return different types (ujson returns str, orjson returns bytes — always decode or use .decode() when you need str). For the stdlib json alternative — stdlib json is safe, predictable, and zero-dependency; orjson is 3–10× faster, natively handles dataclasses, datetimes, UUIDs, and numpy arrays without a custom encoder, and produces correct float output; upgrade to orjson whenever JSON serialization is on a hot path. The Claude Skills 360 bundle includes orjson skill sets covering orjson.dumps()/loads() core API, dumps() wrapper with indent/sort_keys options, default_encoder() for Decimal/set/bytes/Path, dumps_extended()/dumps_extended_str(), OPT_SERIALIZE_NUMPY for arrays, serialize_dataframe() pandas helper, load_json_file()/save_json_file()/update_json_file(), load_jsonl()/save_jsonl() JSON Lines, make_orjson_response_class() FastAPI response, and OrjsonCache Redis/dict backend. Start with the free tier to try fast JSON serialization code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free