def get_enrollments_errors(response: dict) -> dict:
    # $.enrollments.importSummaries[*][?(@.status='ERROR')].description
    jsonpath_expr = Child(
        Where(
            Child(Child(Fields("enrollments"), Fields("importSummaries")),
                  Slice()), Cmp(Fields("status"), eq, "ERROR")),
        Fields("description"))
    matches = jsonpath_expr.find(response)
    return {str(match.full_path): match.value for match in matches}
def get_entity_errors(response: dict) -> dict:
    # $[?(@.status='ERROR')].description
    jsonpath_expr = Child(Where(Root(), Cmp(Fields("status"), eq, "ERROR")),
                          Fields("description"))
    # We write the JSONPath expression programmatically because
    # currently jsonpath-rw does not support parsing comparison
    # expressions like ``[?(@.status='ERROR')]``
    matches = jsonpath_expr.find(response)
    return {str(match.full_path): match.value for match in matches}
Esempio n. 3
0
 def test_find_where(self):
     # "([*] where spam ge 2).bacon"
     jsonpath = Child(
         Where(Slice(), Cmp(Fields('spam'), ge, 2)),
         Fields('bacon')
     )
     matches = jsonpath.find(MENU)
     self.assertEqual(len(matches), 2)  # There are two menu items with bacon where spam >= 2
Esempio n. 4
0
 def get_jsonpath(self, attr_type_uuid):
     return 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'))))
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_rw offers programmatic JSONPath expressions. For details on how to create JSONPath
        # expressions programmatically see the
        # `jsonpath_rw documentation <https://github.com/kennknowles/python-jsonpath-rw#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
Esempio n. 6
0
    def set_property_map(self, case_config):
        """
        Set self._property_map to map OpenMRS properties and attributes
        to case properties.
        """
        # Example value of case_config::
        #
        #     {
        #         "person_properties": {
        #             "birthdate": {
        #                 "doc_type": "CaseProperty",
        #                 "case_property": "dob"
        #             }
        #         },
        #         "person_preferred_name": {
        #             "givenName": {
        #                 "doc_type": "CaseProperty",
        #                 "case_property": "given_name"
        #             },
        #             "familyName": {
        #                 "doc_type": "CaseProperty",
        #                 "case_property": "family_name"
        #             }
        #         },
        #         "person_preferred_address": {
        #             "address1": {
        #                 "doc_type": "CaseProperty",
        #                 "case_property": "address_1"
        #             },
        #             "address2": {
        #                 "doc_type": "CaseProperty",
        #                 "case_property": "address_2"
        #             }
        #         },
        #         "person_attributes": {
        #             "c1f4239f-3f10-11e4-adec-0800271c1b75": {
        #                 "doc_type": "CaseProperty",
        #                 "case_property": "caste"
        #             },
        #             "c1f455e7-3f10-11e4-adec-0800271c1b75": {
        #                 "doc_type": "CasePropertyMap",
        #                 "case_property": "class",
        #                 "value_map": {
        #                     "sc": "c1fcd1c6-3f10-11e4-adec-0800271c1b75",
        #                     "general": "c1fc20ab-3f10-11e4-adec-0800271c1b75",
        #                     "obc": "c1fb51cc-3f10-11e4-adec-0800271c1b75",
        #                     "other_caste": "c207073d-3f10-11e4-adec-0800271c1b75",
        #                     "st": "c20478b6-3f10-11e4-adec-0800271c1b75"
        #                 }
        #             }
        #         }
        #         // ...
        #     }
        #
        for person_prop, value_source in case_config['person_properties'].items():
            jsonpath = parse('person.' + person_prop)
            self._property_map.update(get_caseproperty_jsonpathvaluemap(jsonpath, value_source))

        for attr_uuid, value_source in case_config['person_attributes'].items():
            # jsonpath_rw offers programmatic JSONPath expressions. For details on how to create JSONPath
            # expressions programmatically see the
            # `jsonpath_rw documentation <https://github.com/kennknowles/python-jsonpath-rw#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 below is the equivalent of::
            #
            #     (person.attributes[*] where attributeType.uuid eq attr_uuid).value
            #
            # This `for` loop will let us extract the person attribute values where their attribute type UUIDs
            # match those configured in case_config['person_attributes']
            jsonpath = Child(
                Where(
                    Child(Child(Fields('person'), Fields('attributes')), Slice()),
                    Cmp(Child(Fields('attributeType'), Fields('uuid')), eq, attr_uuid)
                ),
                Fields('value')
            )
            self._property_map.update(get_caseproperty_jsonpathvaluemap(jsonpath, value_source))

        for name_prop, value_source in case_config['person_preferred_name'].items():
            jsonpath = parse('person.preferredName.' + name_prop)
            self._property_map.update(get_caseproperty_jsonpathvaluemap(jsonpath, value_source))

        for addr_prop, value_source in case_config['person_preferred_address'].items():
            jsonpath = parse('person.preferredAddress.' + addr_prop)
            self._property_map.update(get_caseproperty_jsonpathvaluemap(jsonpath, value_source))

        for id_type_uuid, value_source in case_config['patient_identifiers'].items():
            if id_type_uuid == 'uuid':
                jsonpath = parse('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')
                )
            self._property_map.update(get_caseproperty_jsonpathvaluemap(jsonpath, value_source))
Esempio n. 7
0
 def test_find_many(self):
     jsonpath = Cmp(Child(Slice(), Fields('spam')), gt, 0)  # "[*].spam gt 0"
     self.assertEqual(str(jsonpath), '[*].spam gt 0')
     values = [match.value for match in jsonpath.find(MENU)]
     self.assertEqual(values, [1, 1, 1, 2, 4, 4, 10])