Please refer to RFC 6902 for the exact patch syntax.
Patches can be created in two ways. One way is to explicitly create a
JsonPatch object from a list of operations. For convenience, the method
JsonPatch.from_string() accepts a string, parses it and constructs the
patch object from it.
>>> import jsonpatch
>>> patch = jsonpatch.JsonPatch([
{'op': 'add', 'path': '/foo', 'value': 'bar'},
{'op': 'add', 'path': '/baz', 'value': [1, 2, 3]},
{'op': 'remove', 'path': '/baz/1'},
{'op': 'test', 'path': '/baz', 'value': [1, 3]},
{'op': 'replace', 'path': '/baz/0', 'value': 42},
{'op': 'remove', 'path': '/baz/1'},
])
# or equivalently
>>> patch = jsonpatch.JsonPatch.from_string('[{"op": "add", ....}]')Another way is to diff two objects.
>>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]}
>>> dst = {'baz': 'qux', 'numbers': [1, 4, 7]}
>>> patch = jsonpatch.JsonPatch.from_diff(src, dst)
# or equivalently
>>> patch = jsonpatch.make_patch(src, dst)A patch is always applied to an object.
>>> doc = {}
>>> result = patch.apply(doc)
{'foo': 'bar', 'baz': [42]}The apply method returns a new object as a result. If in_place=True the
object is modified in place.
If a patch is only used once, it is not necessary to create a patch object explicitly.
>>> obj = {'foo': 'bar'}
# from a patch string
>>> patch = '[{"op": "add", "path": "/baz", "value": "qux"}]'
>>> res = jsonpatch.apply_patch(obj, patch)
# or from a list
>>> patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}]
>>> res = jsonpatch.apply_patch(obj, patch)Custom JSON dump and load functions can be used to support custom types such as
decimal.Decimal. The following examples shows how the
simplejson package, which has native
support for Python's Decimal type, can be used to create a custom
JsonPatch subclass with Decimal support:
>>> import decimal
>>> import simplejson
>>> class DecimalJsonPatch(jsonpatch.JsonPatch):
@staticmethod
def json_dumper(obj):
return simplejson.dumps(obj)
@staticmethod
def json_loader(obj):
return simplejson.loads(obj, use_decimal=True,
object_pairs_hook=jsonpatch.multidict)
>>> src = {}
>>> dst = {'bar': decimal.Decimal('1.10')}
>>> patch = DecimalJsonPatch.from_diff(src, dst)
>>> doc = {'foo': 1}
>>> result = patch.apply(doc)
{'foo': 1, 'bar': Decimal('1.10')}Instead of subclassing it is also possible to pass a dump function to
from_diff:
>>> patch = jsonpatch.JsonPatch.from_diff(src, dst, dumps=simplejson.dumps)
a dumps function to to_string:
>>> serialized_patch = patch.to_string(dumps=simplejson.dumps) '[{"op": "add", "path": "/bar", "value": 1.10}]'
and load function to from_string:
>>> import functools >>> loads = functools.partial(simplejson.loads, use_decimal=True, object_pairs_hook=jsonpatch.multidict) >>> patch.from_string(serialized_patch, loads=loads) >>> doc = {'foo': 1} >>> result = patch.apply(doc) {'foo': 1, 'bar': Decimal('1.10')}