def generate_iris_changeset(): res_dict['create'] = [] res_dict['modify'] = [] res_dict['delete'] = [] with open('static/iris.data', 'r') as fp: csv_file = csv.reader(fp) for row in csv_file: print(row) if not len(row): continue new_data_item = { 'data': { 'sepal_length': float(row[0]), 'sepal_width': float(row[1]), 'petal_length': float(row[2]), 'petal_width': float(row[3]), }, 'annotations': { 'label': row[4] } } print(jsonpatch.make_patch({}, new_data_item).patch) res_dict['create'].append( jsonpatch.make_patch({}, new_data_item).patch ) print(res_dict) with open('static/patchfile_iris.json', 'w') as wout: json.dump(res_dict, wout, indent=True)
def get_full_patches(): """Return all the record patches resulting from the last run.""" for recid, modified_record in invenio_records['temporary'].items(): original_record = invenio_records['original'][recid] patch = jsonpatch.make_patch(original_record, modified_record) if patch: yield make_fullpatch(recid, hash(original_record), patch, redis_worker.task_id)
def test_patch(self): with FakeModelContext() as context: MyModel, settings = context client = settings.RIAK_CLIENT bucket = client.bucket() old_data = { 'a': 'a' } new_data = { 'b': 'b' } patch_data = jsonpatch.make_patch(old_data, new_data) old_get_side_effect = bucket.get.side_effect def get_with_data(key): instance = old_get_side_effect(key) instance.data = old_data return instance bucket.get.side_effect = get_with_data instance = MyModel('test_key') result = instance.patch(patch_data) self.assertEqual(MyModel._meta.storage_validator.call_count, 1) self.assertEqual(result._state.riak_object.store.call_count, 1) self.assertEqual(len(result.data), 1) self.assertEqual(result.data, new_data)
def test_array_add_remove(self): # see https://github.com/stefankoegl/python-json-patch/issues/4 src = {'numbers': [], 'other': [1, 5, 3, 4]} dst = {'numbers': [1, 3, 4, 5], 'other': []} patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def test_escape(self): src = {"x/y": 1} dst = {"x/y": 2} patch = jsonpatch.make_patch(src, dst) self.assertEqual([{"path": "/x~1y", "value": 2, "op": "replace"}], patch.patch) res = patch.apply(src) self.assertEqual(res, dst)
def update_trigger(self, unmodified_trigger, modified_trigger): """ :type unmodified_trigger: dart.model.trigger.Trigger :type modified_trigger: dart.model.trigger.Trigger """ client = boto3.client('events') patch_list = jsonpatch.make_patch(unmodified_trigger.to_dict(), modified_trigger.to_dict()) target = { 'Id': modified_trigger.id, 'Arn': self._dart_config['triggers']['scheduled']['cloudwatch_scheduled_events_sns_arn'], 'Input': json.dumps({ 'call': TriggerCall.PROCESS_TRIGGER, 'trigger_type_name': self._trigger_type.name, 'message': { 'trigger_id': modified_trigger.id, 'user_id': modified_trigger.data.user_id, 'workflow_id': modified_trigger.data.workflow_ids[0] }, }), } for patch in patch_list: if patch['path'] == '/data/state': if modified_trigger.data.state == TriggerState.ACTIVE: rule_name = self._create_rule_if_needed(client, modified_trigger) self._add_target_to_rule(client, rule_name, target) elif modified_trigger.data.state == TriggerState.INACTIVE: self._remove_target_from_prefix(client, unmodified_trigger) else: raise Exception('unrecognized trigger state "%s"' % modified_trigger.data.state) elif patch['path'] == '/data/args/cron_pattern' and patch['op'] == 'replace': self._remove_target_from_prefix(client, unmodified_trigger) rule_name = self._create_rule_if_needed(client, modified_trigger) self._add_target_to_rule(client, rule_name, target) return modified_trigger
def test_fail_prone_list_2(self): """ Test making and applying a patch of the root is a list """ src = ["a", "r", "b", "x", "m", "n"] dst = ["b", "o", "m", "n"] patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def test_root_list(self): """ Test making and applying a patch of the root is a list """ src = [{"foo": "bar", "boo": "qux"}] dst = [{"baz": "qux", "foo": "boo"}] patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def test_fail_prone_list_4(self): """ Test making and applying a patch of the root is a list """ src = ["bar1", 59, "foo1", "foo"] dst = ["foo", "bar", "foo1"] patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def test_arrays_with_keys(self): # elements started with "__" won't be replicated # elements "@<column_name>" or will be used has list index src = { 'numbers': [1, 2, 3], 'other': [1, 3, 4, 5], 'complex': [{'id': 10, 'entry': 'baa'}], '@complex': ['id'], } dst = { 'numbers': [1, 3, 4, 5], 'other': [1, 3, 4], 'complex': [{'id': 10, 'entry': 'bbb'}, {'id':20, 'entry': 'faa'}] } path_obj = [ {"path": "/complex/[@id=10]/entry", "value": "bbb", "op": "replace"}, {"path": "/complex/-", "value": {"entry": "faa", "id": 20}, "op": "add"}, {"path": "/other/3", "op": "remove"}, {"path": "/@complex", "op": "remove"}, {"path": "/numbers/1", "value": 3, "op": "replace"}, {"path": "/numbers/2", "value": 4, "op": "replace"}, {"path": "/numbers/-", "value": 5, "op": "add"}, ] patch = jsonpatch.make_patch(src, dst) self.assertEqual(str(patch), str(jsonpatch.JsonPatch(path_obj))) res = patch.apply(src) self.assertEqual(res, dst)
def fn(_src, _dst): patch = list(jsonpatch.make_patch(_src, _dst)) # Check if there are only 'move' operations for p in patch: self.assertEqual(p['op'], 'move') res = jsonpatch.apply_patch(_src, patch) self.assertEqual(res, _dst)
def prepare_body(self, metadata, source_metadata, target, priority, append): priority = 0 if not priority else priority if not source_metadata: r = requests.get(self.url) source_metadata = r.json().get(target.split("/")[0], {}) if "metadata" in target: destination_metadata = source_metadata.copy() prepared_metadata = prepare_metadata(metadata, source_metadata, append) destination_metadata.update(prepared_metadata) elif "files" in target: filename = "/".join(target.split("/")[1:]) for f in source_metadata: if f.get("name") == filename: source_metadata = f break destination_metadata = source_metadata.copy() prepared_metadata = prepare_metadata(metadata, source_metadata, append) destination_metadata.update(prepared_metadata) else: raise ValueError('"{0}" is not a supported metadata target.'.format(target)) # Delete metadata items where value is REMOVE_TAG. destination_metadata = dict((k, v) for (k, v) in destination_metadata.items() if v != "REMOVE_TAG") patch = json.dumps(make_patch(source_metadata, destination_metadata).patch) self.data = {"-patch": patch, "-target": target, "priority": priority} super(MetadataPreparedRequest, self).prepare_body(self.data, None)
def test_root_list(self): """ Test making and applying a patch of the root is a list """ src = [{'foo': 'bar', 'boo': 'qux'}] dst = [{'baz': 'qux', 'foo': 'boo'}] patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def document_needs_updating(enrollment): """ Get the document from elasticsearch and see if it matches what's in the database Args: enrollment (ProgramEnrollment): A program enrollment Returns: bool: True if the document needs to be updated via reindex """ index = get_default_alias(PRIVATE_ENROLLMENT_INDEX_TYPE) conn = get_conn() try: document = conn.get(index=index, id=enrollment.id) except NotFoundError: return True serialized_enrollment = serialize_program_enrolled_user(enrollment) del serialized_enrollment['_id'] source = document['_source'] if serialized_enrollment != source: # Convert OrderedDict to dict reserialized_enrollment = json.loads(json.dumps(serialized_enrollment)) diff = make_patch(source, reserialized_enrollment).patch serialized_diff = json.dumps(diff, indent=" ") log.info("Difference found for enrollment %s: %s", enrollment, serialized_diff) return True return False
def test_fail_prone_list_4(self): """ Test making and applying a patch of the root is a list """ src = ['bar1', 59, 'foo1', 'foo'] dst = ['foo', 'bar', 'foo1'] patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def test_fail_prone_list_2(self): """ Test making and applying a patch of the root is a list """ src = ['a', 'r', 'b', 'x', 'm', 'n'] dst = ['b', 'o', 'm', 'n'] patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def test_make_patch_unicode(self): """ Test if unicode keys and values are handled correctly """ src = {} dst = {'\xee': '\xee'} patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def prepare_body(self, metadata, source_metadata, target, priority, append): target = 'metadata' if not target else target priority = 0 if not priority else priority if not source_metadata: r = requests.get(self.url) source_metadata = r.json().get(target, {}) destination_metadata = source_metadata.copy() prepared_metadata = prepare_metadata(metadata, source_metadata, append) destination_metadata.update(prepared_metadata) # Delete metadata items where value is REMOVE_TAG. destination_metadata = dict( (k, v) for (k, v) in destination_metadata.items() if v != 'REMOVE_TAG' ) patch = json.dumps(make_patch(source_metadata, destination_metadata).patch) self.data = { '-patch': patch, '-target': target, 'priority': priority, } super(MetadataPreparedRequest, self).prepare_body(self.data, None)
def test_use_move_instead_of_add_remove(self): src = {'foo': [1, 2, 3]} dst = {'foo': [3, 1, 2]} patch = list(jsonpatch.make_patch(src, dst)) self.assertEqual(len(patch), 1) self.assertEqual(patch[0]['op'], 'move') res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def test_use_replace_instead_of_remove_add_nested(self): src = {'foo': [{'bar': 1, 'baz': 2}, {'bar': 2, 'baz': 3}]} dst = {'foo': [{'bar': 1}, {'bar': 2, 'baz': 3}]} patch = list(jsonpatch.make_patch(src, dst)) self.assertEqual(len(patch), 1) self.assertEqual(patch[0]['op'], 'replace') res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def test_should_just_add_new_item_not_rebuild_all_list(self): src = {'foo': [1, 2, 3]} dst = {'foo': [3, 1, 2, 3]} patch = list(jsonpatch.make_patch(src, dst)) self.assertEqual(len(patch), 1) self.assertEqual(patch[0]['op'], 'add') res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def test_use_move_instead_of_remove_add(self): src = {"foo": [4, 1, 2, 3]} dst = {"foo": [1, 2, 3, 4]} patch = list(jsonpatch.make_patch(src, dst)) self.assertEqual(len(patch), 1) self.assertEqual(patch[0]["op"], "move") res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def test_arrays_one_element_sequences(self): """ Tests the case of multiple common one element sequences inside an array """ # see https://github.com/stefankoegl/python-json-patch/issues/30#issuecomment-155070128 src = [1,2,3] dst = [3,1,4,2] patch = jsonpatch.make_patch(src, dst) res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def propagate(self, typeL="update"): print("in propagate") changes = json.loads(jsonpatch.make_patch(self.last_propagated_content, self.getContentsAsObject()).to_string()) subs = self.getSubscriptions() print(subs) for sub in subs: sub.sendUpdate(changes, typeL) self.last_propagated_content = self.content
def diffDict(self): #compare two dictionaries and return to the result in the form of a list #diff = json_tools.diff(self.old, self.new) diff = jsonpatch.make_patch(self.old, self.new) diff = list(diff) if diff: return diff else: return False
def update(self): patch = jsonpatch.make_patch(self._original_obj, self.obj) r = self.api.patch(**self.api_kwargs( headers={"Content-Type": "application/json-patch+json"}, data=str(patch), )) r.raise_for_status() self.set_obj(r.json())
def commit(self, new_doc, meta_data={}): """add a revision to the history. the new_doc will replace the current doc and a patch will be stored in the history which can be used to calculate the previous state of the document""" self.doc['history'].append({ 'patch': jsonpatch.make_patch(new_doc, self.doc['current']).patch, 'meta': meta_data }) self.doc['current'] = new_doc
def test_list_in_dict(self): """ Test patch creation with a list within a dict, as reported in #74 https://github.com/stefankoegl/python-json-patch/issues/74 """ old = {'key': [{'someNumber': 0, 'someArray': [1, 2, 3]}]} new = {'key': [{'someNumber': 0, 'someArray': [1, 2, 3, 4]}]} patch = jsonpatch.make_patch(old, new) new_from_patch = jsonpatch.apply_patch(old, patch) self.assertEqual(new, new_from_patch)
def test_minimal_patch(self): """ Test whether a minimal patch is created, see #36 """ src = [{"foo": 1, "bar": 2}] dst = [{"foo": 2, "bar": 2}] patch = jsonpatch.make_patch(src, dst) exp = [{"path": "/0/foo", "value": 2, "op": "replace"}] self.assertEqual(patch.patch, exp)
def test_complex_object(self): src = {'data': [ {'foo': 1}, {'bar': [1, 2, 3]}, {'baz': {'1': 1, '2': 2}} ]} dst = {'data': [ {'foo': [42]}, {'bar': []}, {'baz': {'boo': 'oom!'}} ]} patch = jsonpatch.make_patch(src, dst) res = patch.apply(src) self.assertEqual(res, dst)
def diff_files(): """ Diffs two JSON files and prints a patch """ args = parser.parse_args() doc1 = json.load(args.FILE1) doc2 = json.load(args.FILE2) patch = jsonpatch.make_patch(doc1, doc2) if patch.patch: patch.patch.sort(key=lambda op: op["path"]) print(json.dumps(patch.patch, indent=args.indent)) sys.exit(1)
def patch(self): """Return a jsonpatch object representing the delta.""" original = copy.deepcopy(self.__dict__["__original__"]) new = dict(self) if self.__dict__["schema"]: for prop in self.schema["properties"]: if prop not in original and prop in new: original[prop] = None return jsonpatch.make_patch(original, dict(self)).to_string()
def get_patch_tasks_status(deposit): """Get the patch to apply to update record tasks status.""" old_status = deposit['_cds']['state'] new_status = deposit._current_tasks_status() # create tasks status patch patches = jsonpatch.make_patch(old_status, new_status).patch # make it suitable for the deposit for patch in patches: patch['path'] = '/_cds/state{0}'.format(patch['path']) return patches
def diff(self, hash1, hash2=None, txid=None): branch = self._branches[txid] rev1 = branch[hash1] rev2 = branch[hash2] if hash2 else branch._latest if rev1.hash == rev2.hash: return JsonPatch([]) else: dict1 = message_to_dict(rev1.data) dict2 = message_to_dict(rev2.data) return make_patch(dict1, dict2)
def test_json_patch(self): old = { 'queue': {'teams_out': [{'id': 3, 'reason': 'If tied'}, {'id': 5, 'reason': 'If tied'}]}, } new = { 'queue': {'teams_out': [{'id': 5, 'reason': 'If lose'}]} } patch = jsonpatch.make_patch(old, new) new_from_patch = jsonpatch.apply_patch(old, patch) self.assertEqual(new, new_from_patch)
def patch(self): """Return a jsonpatch object representing the delta.""" original = copy.deepcopy(self.__dict__['__original__']) new = dict(self) if self.__dict__['schema']: for prop in self.schema['properties']: if prop not in original and prop in new: original[prop] = None return jsonpatch.make_patch(original, dict(self)).to_string()
def test_issue76(self): """ Make sure op:remove does not include a 'value' field """ src = { "name": "fred", "friend": "barney", "spouse": "wilma" } dst = { "name": "fred", "spouse": "wilma" } expected = [{"path": "/friend", "op": "remove"}] patch = jsonpatch.make_patch(src, dst) self.assertEqual(patch.patch, expected) res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def test_use_replace_instead_of_remove_add_nested(self): src = {'foo': [{'bar': 1, 'baz': 2}, {'bar': 2, 'baz': 3}]} dst = {'foo': [{'bar': 1}, {'bar': 2, 'baz': 3}]} patch = list(jsonpatch.make_patch(src, dst)) exp = [{'op': 'remove', 'path': '/foo/0/baz'}] self.assertEqual(patch, exp) res = jsonpatch.apply_patch(src, patch) self.assertEqual(res, dst)
def propagate(self, typeL="update"): print("in propagate") changes = json.loads( jsonpatch.make_patch(self.last_propagated_content, self.getContentsAsObject()).to_string()) subs = self.getSubscriptions() print(subs) for sub in subs: sub.sendUpdate(changes, typeL) self.last_propagated_content = self.content
def diff_lists(self, attr, title, old, new): old = old or [] new = new or [] if old == new: return diffs = [{ 'html_old': html.escape(x), 'html_new': html.escape(x), } for x in old] remove_offset = 0 for patch in jsonpatch.make_patch(old, new): # eg. "/0" index = int(patch['path'].split("/", 1)[1]) if patch['op'] == 'add': v = patch['value'] diffs.insert( index, { 'old': None, 'new': v, 'html_old': '', 'html_new': "<ins>{}</ins>".format(html.escape(v)), }) elif patch['op'] == 'replace': old_v = old[index] new_v = patch['value'] html_old, html_new = self.html_diff(old_v, new_v) diffs[index] = { 'old': old_v, 'new': new_v, 'html_old': html_old, 'html_new': html_new, } elif patch['op'] == 'remove': index += remove_offset v = old[index] diffs[index] = { 'old': v, 'new': None, 'html_old': "<del>{}</del>".format(html.escape(v)), 'html_new': '', } # subsequent remove operations will need to be offset remove_offset += 1 return { 'attr': attr, 'title': title, 'changes': diffs, 'type': 'list', }
def test_escape(self): src = {"x/y": 1} dst = {"x/y": 2} patch = jsonpatch.make_patch(src, dst) self.assertEqual([{ "path": "/x~1y", "value": 2, "op": "replace" }], patch.patch) res = patch.apply(src) self.assertEqual(res, dst)
def setUp(self): super().setUp() self.payload = self.load_file(CASE_PATH) self.model = CaseModel self.case_id = self.create_new_row(CASE_URL, self.model, self.payload) self.payloads = [self.load_file(f) for f in CASES_LIST] self.items_to_check = ["name", "description", "schema"] self.url = CASE_URL self.patch = dict(data_patch=jsonpatch.make_patch( self.payloads[0]["data"], self.payloads[1]["data"]).patch) self.patch_file = self.load_file(JSON_PATCH_GOOD_PATH)