Source code for pytool.json

"""
This module contains helpers for working with JSON data.

Tries to use the `simplejson` module if it exists, otherwise falls back to the
`json` module.

If the `bson` module exists, it allows `bson.ObjectId` objects to be decoded
into JSON automatically.

"""

from datetime import datetime

import simplejson as json

# Conditionally handle bson import so we don't have to depend on pymongo
try:
    import bson
except ImportError:
    # Make a mock bson module (as a class object)
    bson = type("bson", (object,), {"ObjectId": type("ObjectId", (object,), {})})


__all__ = [
    "as_json",
    "from_json",
]


def _default(obj):
    """Handle encoding of an object which isn't JSON serializable by the
    regular encoder."""
    # Datetime objects get encoded according to the ISO standard
    if isinstance(obj, datetime):
        return obj.strftime("%a %b %d %Y %H:%M:%S %z").strip()
    # BSON ObjectId types get encoded as their hex string
    if isinstance(obj, bson.ObjectId):
        return str(obj)
    # This will raise a TypeError, which is what we want at this point
    raise TypeError(repr(obj) + " is not JSON serializable")


[docs] def as_json(obj, **kwargs): """ Returns an object JSON encoded properly. This method allows you to implement a hook method ``for_json()`` on your objects if you want to allow arbitrary objects to be encoded to JSON. A ``for_json()`` hook must return a basic JSON type (dict, list, int, float, string, unicode, float or None), or a basic JSON type which contains other objects which implement the ``for_json()`` hook. If an object implements both ``_asdict()`` and ``for_json()`` the latter is given preference. Also adds additional encoders for :class:`~datetime.datetime` and :class:`bson.ObjectId`. :param object obj: An object to encode. :param kwargs: Any optional keyword arguments to pass to the \ JSONEncoder :returns: JSON encoded version of `obj`. .. versionadded:: 2.4 Objects which have an ``_asdict()`` method will have that method called as part of encoding to JSON, even when not using simplejson. .. versionadded:: 2.4 Objects which have a ``for_json()`` method will have that method called and the return value used for encoding instead. .. versionchanged:: 3.0 simplejson (``>= 3.2.0``) is now required, and relied upon for the ``_asdict()`` and ``for_json()`` hooks. This change may break backwards compatibility in any code that uses these hooks. """ return json.dumps(obj, default=_default, for_json=True)
[docs] def from_json(value): """Decodes a JSON string into an object. :param str value: String to decode :returns: Decoded JSON object """ return json.loads(value)