def _extract_cardinalities(bindings, predicate_dict): cardinalities = {} for binding in bindings: property_ = binding["predicate"]["value"] try: range_ = binding["range"]["value"] except KeyError: try: range_ = predicate_dict[property_]["range"]["value"] except KeyError: msg = _(u"The property {0} is not defined properly").format( property_) raise InstanceError(msg) if not property_ in cardinalities: cardinalities[property_] = {} if not range_ in cardinalities[property_] and not range_.startswith( "nodeID://"): cardinalities[property_][range_] = {} current_property = cardinalities[property_] if "min" in binding: min_value = binding["min"]["value"] try: min_value = int(min_value) except ValueError: msg = _( u"The property {0} defines a non-integer owl:minQualifiedCardinality {1}" ).format(property_, min_value) raise InstanceError(msg) else: current_property[range_].update({"minItems": min_value}) if min_value: current_property[range_].update({"required": True}) if "max" in binding: max_value = binding["max"]["value"] try: max_value = int(max_value) except ValueError: msg = _( u"The property {0} defines a non-integer owl:maxQualifiedCardinality {1}" ).format(property_, max_value) raise InstanceError(msg) else: current_property[range_].update({"maxItems": max_value}) return cardinalities
def get_predicates_and_cardinalities(context, query_params, superclasses): query_result = query_cardinalities(query_params) bindings = query_predicates(query_params, superclasses) predicate_dict = bindings_to_dict('predicate', bindings) try: cardinalities = _extract_cardinalities( query_result['results']['bindings'], predicate_dict) except InstanceError as ex: msg = _(u"{0} for class {1}").format(ex.message, query_params.get('class_uri', '')) raise InstanceError(msg) return convert_bindings_dict(context, bindings['results']['bindings'], cardinalities, superclasses)
class ErrorTestCase(unittest.TestCase): @patch("brainiak.instance.edit_instance.create_explicit_triples", side_effect=InstanceError()) @patch("brainiak.instance.edit_instance.get_cached_schema") @patch("brainiak.instance.edit_instance.must_retrieve_graph_and_class_uri", return_value=False) def test_raises_400(self, mock_must, mock_get_cache, mock_create_triples): dummy_query_params = { "instance_uri": 1, "class_uri": 2, "graph_uri": 3 } with self.assertRaises(HTTPError) as exception: edit_instance.edit_instance(dummy_query_params, {}) self.assertEqual(exception.exception.status_code, 400)
def convert_bindings_dict(context, bindings, cardinalities, superclasses): super_predicates = get_super_properties(bindings) assembled_predicates = {} for binding_row in bindings: predicate_uri = binding_row['predicate']['value'] # super_predicate is when we use rdfs:subPropertyOf # this case does not consider inherited predicates if predicate_uri in super_predicates.keys(): continue predicate = assemble_predicate(predicate_uri, binding_row, cardinalities, context) existing_predicate = assembled_predicates.get(predicate_uri, False) if existing_predicate: if 'datatype' in existing_predicate and 'datatype' in predicate: assembled_predicates[ predicate_uri] = most_specialized_predicate( superclasses, existing_predicate, predicate) elif existing_predicate != predicate: assembled_predicates[predicate_uri] = join_predicates( existing_predicate, predicate) else: msg = _( u"The property {0} seems to be duplicated in class {1}") raise InstanceError( msg.format(predicate_uri, predicate["class"])) else: assembled_predicates[predicate_uri] = predicate if "unique_value" in binding_row and binding_row["unique_value"][ "value"] == "1": assembled_predicates[predicate_uri]["unique_value"] = True return assembled_predicates
def assemble_predicate(predicate_uri, binding_row, cardinalities, context): predicate_graph = binding_row["predicate_graph"]['value'] predicate_type = binding_row['type']['value'] range_uri = binding_row['range']['value'] range_graph = binding_row.get('range_graph', {}).get('value', "") range_label = binding_row.get('range_label', {}).get('value', "") class_uri = binding_row["domain_class"]['value'] # build up predicate dictionary predicate = { "class": class_uri, "graph": predicate_graph, "title": binding_row["title"]['value'] } if "predicate_comment" in binding_row: predicate["description"] = binding_row["predicate_comment"]['value'] if predicate_type == OBJECT_PROPERTY: context.add_object_property(predicate_uri, range_uri) predicate["range"] = { '@id': range_uri, 'graph': range_graph, 'title': range_label, 'type': 'string', 'format': 'uri' } max_items = cardinalities.get(predicate_uri, {}).get(range_uri, {}).get('maxItems', 2) min_items = cardinalities.get(predicate_uri, {}).get(range_uri, {}).get('minItems', 2) if (min_items > 1) or (max_items > 1) or (not min_items and not max_items): predicate["type"] = "array" predicate["items"] = {"type": "string", "format": "uri"} else: predicate["type"] = "string" predicate["format"] = "uri" elif predicate_type == DATATYPE_PROPERTY: max_items = cardinalities.get(predicate_uri, {}).get(range_uri, {}).get('maxItems', 1) min_items = cardinalities.get(predicate_uri, {}).get(range_uri, {}).get('minItems', 1) # add predicate['type'] and (optional) predicate['format'] predicate.update(items_from_range(range_uri, min_items, max_items)) else: # TODO: owl:AnnotationProperty msg = _(u"Predicates of type {0} are not supported yet").format( predicate_type) raise InstanceError(msg) if predicate["type"] == "array": if (predicate_uri in cardinalities) and (range_uri in cardinalities[predicate_uri]): predicate_restriction = cardinalities[predicate_uri] predicate.update(predicate_restriction[range_uri]) else: required = cardinalities.get(predicate_uri, {}).get(range_uri, {}).get('required', False) if required: predicate['required'] = True return predicate