# `json_util` – Tools for using Python’s `json` module with BSON documents

Tools for using Python’s `json` module with BSON documents.

This module provides two helper methods dumps and loads that wrap the native `json` methods and provide explicit BSON conversion to and from JSON. `JSONOptions` provides a way to control how JSON is emitted and parsed, with the default being the Relaxed Extended JSON format. `json_util` can also generate Canonical or legacy Extended JSON when `CANONICAL_JSON_OPTIONS` or `LEGACY_JSON_OPTIONS` is provided, respectively.

Example usage (deserialization):

    >>> from bson.json_util import loads
    >>> loads(
    ...     '[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$scope": {}, "$code": "function x() { return 1; }"}}, {"bin": {"$type": "80", "$binary": "AQIDBA=="}}]'
    ... )
    [{'foo': [1, 2]}, {'bar': {'hello': 'world'}}, {'code': Code('function x() { return 1; }', {})}, {'bin': Binary(b'...', 128)}]

Example usage with `RELAXED_JSON_OPTIONS` (the default):

    >>> from bson import Binary, Code
    >>> from bson.json_util import dumps
    >>> dumps(
    ...     [
    ...         {"foo": [1, 2]},
    ...         {"bar": {"hello": "world"}},
    ...         {"code": Code("function x() { return 1; }")},
    ...         {"bin": Binary(b"")},
    ...     ]
    ... )
    '[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$code": "function x() { return 1; }"}}, {"bin": {"$binary": {"base64": "AQIDBA==", "subType": "00"}}}]'

Example usage (with `CANONICAL_JSON_OPTIONS`):

    >>> from bson import Binary, Code
    >>> from bson.json_util import dumps, CANONICAL_JSON_OPTIONS
    >>> dumps(
    ...     [
    ...         {"foo": [1, 2]},
    ...         {"bar": {"hello": "world"}},
    ...         {"code": Code("function x() { return 1; }")},
    ...         {"bin": Binary(b"")},
    ...     ],
    ...     json_options=CANONICAL_JSON_OPTIONS,
    ... )
    '[{"foo": [{"$numberInt": "1"}, {"$numberInt": "2"}]}, {"bar": {"hello": "world"}}, {"code": {"$code": "function x() { return 1; }"}}, {"bin": {"$binary": {"base64": "AQIDBA==", "subType": "00"}}}]'

Example usage (with `LEGACY_JSON_OPTIONS`):

    >>> from bson import Binary, Code
    >>> from bson.json_util import dumps, LEGACY_JSON_OPTIONS
    >>> dumps(
    ...     [
    ...         {"foo": [1, 2]},
    ...         {"bar": {"hello": "world"}},
    ...         {"code": Code("function x() { return 1; }", {})},
    ...         {"bin": Binary(b"")},
    ...     ],
    ...     json_options=LEGACY_JSON_OPTIONS,
    ... )
    '[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$code": "function x() { return 1; }", "$scope": {}}}, {"bin": {"$binary": "AQIDBA==", "$type": "00"}}]'

Alternatively, you can manually pass the default to `json.dumps()`. It won’t handle `Binary` and `Code` instances (as they are extended strings you can’t provide custom defaults), but it will be faster as there is less recursion.

Note

If your application does not need the flexibility offered by `JSONOptions` and spends a large amount of time in the json_util module, look to python-bsonjs for a nice performance improvement. python-bsonjs is a fast BSON to MongoDB Extended JSON converter for Python built on top of libbson. python-bsonjs works best with PyMongo when using `RawBSONDocument`.

class bson.json_util.DatetimeRepresentation
  LEGACY = 0

    Legacy MongoDB Extended JSON datetime representation.

    `datetime.datetime` instances will be encoded to JSON in the format {“$date”: <dateAsMilliseconds>}, where dateAsMilliseconds is a 64-bit signed integer giving the number of milliseconds since the Unix epoch UTC. This was the default encoding before PyMongo version 3.4.

    Added in version 3.4.

  NUMBERLONG = 1

    NumberLong datetime representation.

    `datetime.datetime` instances will be encoded to JSON in the format {“$date”: {“$numberLong”: “<dateAsMilliseconds>”}}, where dateAsMilliseconds is the string representation of a 64-bit signed integer giving the number of milliseconds since the Unix epoch UTC.

    Added in version 3.4.

  ISO8601 = 2

    ISO-8601 datetime representation.

    `datetime.datetime` instances greater than or equal to the Unix epoch UTC will be encoded to JSON in the format {“$date”: “<ISO-8601>”}. `datetime.datetime` instances before the Unix epoch UTC will be encoded as if the datetime representation is `NUMBERLONG`.

    Added in version 3.4.

class bson.json_util.JSONMode
  LEGACY = 0

    Legacy Extended JSON representation.

    In this mode, `dumps()` produces PyMongo’s legacy non-standard JSON output. Consider using `RELAXED` or `CANONICAL` instead.

    Added in version 3.5.

  RELAXED = 1

    Relaxed Extended JSON representation.

    In this mode, `dumps()` produces Relaxed Extended JSON, a mostly JSON-like format. Consider using this for things like a web API, where one is sending a document (or a projection of a document) that only uses ordinary JSON type primitives. In particular, the `int`, `Int64`, and `float` numeric types are represented in the native JSON number format. This output is also the most human readable and is useful for debugging and documentation.

    See also

    The specification for Relaxed Extended JSON.

    Added in version 3.5.

  CANONICAL = 2

    Canonical Extended JSON representation.

    In this mode, `dumps()` produces Canonical Extended JSON, a type preserving format. Consider using this for things like testing, where one has to precisely specify expected types in JSON. In particular, the `int`, `Int64`, and `float` numeric types are encoded with type wrappers.

    See also

    The specification for Canonical Extended JSON.

    Added in version 3.5.

class bson.json_util.JSONOptions(strict_number_long=None, datetime_representation=None, strict_uuid=None, json_mode=1, *args, **kwargs)

  Encapsulates JSON options for `dumps()` and `loads()`.

  Parameters:

    - strict_number_long (bool) – If `True`, `Int64` objects are encoded to MongoDB Extended JSON’s Strict mode type NumberLong, ie `'{"$numberLong": "<number>" }'`. Otherwise they will be encoded as an int. Defaults to `False`.

    - datetime_representation (int) – The representation to use when encoding instances of `datetime.datetime`. Defaults to `LEGACY`.

    - strict_uuid (bool) – If `True`, `uuid.UUID` object are encoded to MongoDB Extended JSON’s Strict mode type Binary. Otherwise it will be encoded as `'{"$uuid": "<hex>" }'`. Defaults to `False`.

    - json_mode (int) – The `JSONMode` to use when encoding BSON types to Extended JSON. Defaults to `LEGACY`.

    - document_class – BSON documents returned by `loads()` will be decoded to an instance of this class. Must be a subclass of `collections.MutableMapping`. Defaults to `dict`.

    - uuid_representation – The `UuidRepresentation` to use when encoding and decoding instances of `uuid.UUID`. Defaults to `UNSPECIFIED`.

    - tz_aware – If `True`, MongoDB Extended JSON’s Strict mode type Date will be decoded to timezone aware instances of `datetime.datetime`. Otherwise they will be naive. Defaults to `False`.

    - tzinfo – A `datetime.tzinfo` subclass that specifies the timezone from which `datetime` objects should be decoded. Defaults to `utc`.

    - datetime_conversion – Specifies how UTC datetimes should be decoded within BSON. Valid options include ‘datetime_ms’ to return as a DatetimeMS, ‘datetime’ to return as a datetime.datetime and raising a ValueError for out-of-range values, ‘datetime_auto’ to return DatetimeMS objects when the underlying datetime is out-of-range and ‘datetime_clamp’ to clamp to the minimum and maximum possible datetimes. Defaults to ‘datetime’. See handling out of range datetimes for details.

    - args (Any) – arguments to `CodecOptions`

    - kwargs (Any) – arguments to `CodecOptions`

  Return type:

    JSONOptions

  See also

  The specification for Relaxed and Canonical Extended JSON.

  Changed in version 4.0: The default for json_mode was changed from `JSONMode.LEGACY` to `JSONMode.RELAXED`. The default for uuid_representation was changed from `PYTHON_LEGACY` to `UNSPECIFIED`.

  Changed in version 3.5: Accepts the optional parameter json_mode.

  Changed in version 4.0: Changed default value of tz_aware to False.

  json_mode: int
  strict_number_long: bool
  datetime_representation: int
  strict_uuid: bool
  with_options(**kwargs)

    Make a copy of this JSONOptions, overriding some options:

        >>> from bson.json_util import CANONICAL_JSON_OPTIONS
        >>> CANONICAL_JSON_OPTIONS.tz_aware
        True
        >>> json_options = CANONICAL_JSON_OPTIONS.with_options(tz_aware=False, tzinfo=None)
        >>> json_options.tz_aware
        False

    Added in version 3.12.

    Parameters:

      kwargs (Any)

    Return type:

      JSONOptions

bson.json_util.LEGACY_JSON_OPTIONS: JSONOptions = (<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME)

  `JSONOptions` for encoding to PyMongo’s legacy JSON format.

  See also

  The documentation for `bson.json_util.JSONMode.LEGACY`.

  Added in version 3.5.

bson.json_util.CANONICAL_JSON_OPTIONS: JSONOptions = (<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME)

  `JSONOptions` for Canonical Extended JSON.

  See also

  The documentation for `bson.json_util.JSONMode.CANONICAL`.

  Added in version 3.5.

bson.json_util.RELAXED_JSON_OPTIONS: JSONOptions = (<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME)

  `JSONOptions` for Relaxed Extended JSON.

  See also

  The documentation for `bson.json_util.JSONMode.RELAXED`.

  Added in version 3.5.

bson.json_util.DEFAULT_JSON_OPTIONS: JSONOptions = (<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME)

  The default `JSONOptions` for JSON encoding/decoding.

  The same as `RELAXED_JSON_OPTIONS`.

  Changed in version 4.0: Changed from `LEGACY_JSON_OPTIONS` to `RELAXED_JSON_OPTIONS`.

  Added in version 3.4.

bson.json_util.dumps(obj, *args, **kwargs)

  Helper function that wraps `json.dumps()`.

  Recursive function that handles all BSON types including `Binary` and `Code`.

  Parameters:

    - json_options – A `JSONOptions` instance used to modify the encoding of MongoDB Extended JSON types. Defaults to `DEFAULT_JSON_OPTIONS`.

    - obj (Any)

    - args (Any)

    - kwargs (Any)

  Return type:

    str

  Changed in version 4.0: Now outputs MongoDB Relaxed Extended JSON by default (using `DEFAULT_JSON_OPTIONS`).

  Changed in version 3.4: Accepts optional parameter json_options. See `JSONOptions`.

bson.json_util.loads(s, *args, **kwargs)

  Helper function that wraps `json.loads()`.

  Automatically passes the object_hook for BSON type conversion.

  Raises `TypeError`, `ValueError`, `KeyError`, or `InvalidId` on invalid MongoDB Extended JSON.

  Parameters:

    - json_options – A `JSONOptions` instance used to modify the decoding of MongoDB Extended JSON types. Defaults to `DEFAULT_JSON_OPTIONS`.

    - s (str | bytes | bytearray)

    - args (Any)

    - kwargs (Any)

  Return type:

    Any

  Changed in version 4.0: Now loads `datetime.datetime` instances as naive by default. To load timezone aware instances utilize the json_options parameter. See tz_aware defaults to False for an example.

  Changed in version 3.5: Parses Relaxed and Canonical Extended JSON as well as PyMongo’s legacy format. Now raises `TypeError` or `ValueError` when parsing JSON type wrappers with values of the wrong type or any extra keys.

  Changed in version 3.4: Accepts optional parameter json_options. See `JSONOptions`.

bson.json_util.object_pairs_hook(pairs, json_options=(<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME))
  Parameters:

    - pairs (Sequence[Tuple[str, Any]])

    - json_options (JSONOptions)

  Return type:

    Any

bson.json_util.object_hook(dct, json_options=(<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME))
  Parameters:

    - dct (Mapping[str, Any])

    - json_options (JSONOptions)

  Return type:

    Any

bson.json_util.default(obj, json_options=(<class 'dict'>, False, 0, 'strict', None, TypeRegistry(type_codecs=[], fallback_encoder=None), DatetimeConversion.DATETIME))
  Parameters:

    - obj (Any)

    - json_options (JSONOptions)

  Return type:

    Any

bson.json_util.get_size(obj, max_size, current_size=0)

  Recursively finds size of objects

  Parameters:

    - obj (Any)

    - max_size (int)

    - current_size (int)

  Return type:

    int