def format_state_output(self, result): """ Applies OutputPath """ if not self.output_path: return result output_path = parse_jsonpath(self.output_path) if str(output_path) == "$": # From docs: # If the OutputPath has the default value of $, this matches the entire input completely. # In this case, the entire input is passed to the next state. return result else: output_matches = output_path.find(result) if output_matches: # From docs: # If the OutputPath matches an item in the state's input, only that input item is selected. # This input item becomes the state's output. assert len(output_matches) == 1 return output_matches[0].value else: # From docs: # If the OutputPath doesn't match an item in the state's input, # an exception specifies an invalid path. raise NotImplementedError()
def format_state_input(self, input): """ Applies InputPath """ if self.input_path: return parse_jsonpath(self.input_path).find(input)[0].value return input
def get_parseexpr(self, name): if name in JSONParser.EXPR_CACHE: expr = JSONParser.EXPR_CACHE[name] else: expr = parse_jsonpath(name) JSONParser.EXPR_CACHE[name] = expr return expr
def matches(self, input) -> bool: if self.name == "Not": return not self.value[0].matches(input) elif self.name == "Or": return any(v.matches(input) for v in self.value) elif self.name == "And": return all(v.matches(input) for v in self.value) else: path = parse_jsonpath(self.variable) check_value = path.find(input)[0].value return Operators.ALL[self.name].impl(self.value, check_value)
def format_result(self, input, resource_result): """ Applies ResultPath """ if self.result_path: result_path = parse_jsonpath(self.result_path) if not result_path.find(input): # A quick hack to set a non-existent key (assuming the parent of the path is a dictionary). result_path.left.find(input)[0].value[str( result_path.right)] = resource_result return input elif str(result_path) == "$": return resource_result else: result_path.update(input, resource_result) return input return resource_result
def parse_json(input, value, name, new_array=None): parsed = parse_jsonpath(value) found = parsed.find(input) name_temp = remove_alias(name[:-3]) if found and isinstance(found, list) and "[*]" in value: if new_array is None: new_array = [] for item in found: new_value = item.value if name.endswith('[*]'): index = find_indexes(item.full_path, True) indexes = find_indexes(item.full_path) add_to_array_inner(new_array, int(index), indexes, name_temp, new_value) else: index = find_index(item.full_path) add_to_array(new_array, index, name, new_value) return new_array if found: value = found[0].value return value
def __init__(self, jsonpath, logger=__logger__): if isinstance(jsonpath, (str, )): jsonpath = parse_jsonpath(jsonpath) self.jsonpath = jsonpath self.logger = logger
def get_property_map(case_config): """ Returns a map of case properties to OpenMRS patient properties and attributes, and a value source dict to deserialize them. """ property_map = {} for person_prop, value_source_dict in case_config['person_properties'].items(): if 'case_property' in value_source_dict: jsonpath = parse_jsonpath('person.' + person_prop) property_map[value_source_dict['case_property']] = (jsonpath, value_source_dict) for attr_type_uuid, value_source_dict in case_config['person_attributes'].items(): # jsonpath-ng offers programmatic JSONPath expressions. For details on how to create JSONPath # expressions programmatically see the # `jsonpath-ng documentation <https://github.com/h2non/jsonpath-ng#programmatic-jsonpath>`__ # # The `Where` JSONPath expression "*jsonpath1* `where` *jsonpath2*" returns nodes matching *jsonpath1* # where a child matches *jsonpath2*. `Cmp` does a comparison in *jsonpath2*. It accepts a # comparison operator and a value. The JSONPath expression for matching simple attribute values is:: # # (person.attributes[*] where attributeType.uuid eq attr_type_uuid).value # # This extracts the person attribute values where their attribute type UUIDs match those configured in # case_config['person_attributes']. # # Person attributes with Concept values have UUIDs. The following JSONPath uses Union to match both simple # values and Concept values. if 'case_property' in value_source_dict: jsonpath = Union( # Simple values: Return value if it has no children. # (person.attributes[*] where attributeType.uuid eq attr_type_uuid).(value where not *) Child( Where( Child(Child(Fields('person'), Fields('attributes')), Slice()), Cmp(Child(Fields('attributeType'), Fields('uuid')), eq, attr_type_uuid) ), WhereNot(Fields('value'), Fields('*')) ), # Concept values: Return value.uuid if value.uuid exists: # (person.attributes[*] where attributeType.uuid eq attr_type_uuid).value.uuid Child( Where( Child(Child(Fields('person'), Fields('attributes')), Slice()), Cmp(Child(Fields('attributeType'), Fields('uuid')), eq, attr_type_uuid) ), Child(Fields('value'), Fields('uuid')) ) ) property_map[value_source_dict['case_property']] = (jsonpath, value_source_dict) for name_prop, value_source_dict in case_config['person_preferred_name'].items(): if 'case_property' in value_source_dict: jsonpath = parse_jsonpath('person.preferredName.' + name_prop) property_map[value_source_dict['case_property']] = (jsonpath, value_source_dict) for addr_prop, value_source_dict in case_config['person_preferred_address'].items(): if 'case_property' in value_source_dict: jsonpath = parse_jsonpath('person.preferredAddress.' + addr_prop) property_map[value_source_dict['case_property']] = (jsonpath, value_source_dict) for id_type_uuid, value_source_dict in case_config['patient_identifiers'].items(): if 'case_property' in value_source_dict: if id_type_uuid == 'uuid': jsonpath = parse_jsonpath('uuid') else: # The JSONPath expression below is the equivalent of:: # # (identifiers[*] where identifierType.uuid eq id_type_uuid).identifier # # Similar to `person_attributes` above, this will extract the person identifier values where # their identifier type UUIDs match those configured in case_config['patient_identifiers'] jsonpath = Child( Where( Child(Fields('identifiers'), Slice()), Cmp(Child(Fields('identifierType'), Fields('uuid')), eq, id_type_uuid) ), Fields('identifier') ) property_map[value_source_dict['case_property']] = (jsonpath, value_source_dict) return property_map
def jsonpath(self, items): path = parse_jsonpath(items[0]) #return lambda obj: _condense([match.value for match in path.find(obj)]) return JsonPath(path)