示例#1
0
def get_preview():
    """Get a preview of query

    Returns
    -------
    json
        resultsPreview: Preview of the query results
        headerPreview: Header of the results table
        error: True if error, else False
        errorMessage: the error message of error, else an empty string
    """
    try:
        # If public datasets and queries are protected, dont return anything to unlogged users
        if "user" not in session and current_app.iniconfig.getboolean("askomics", "protect_public"):
            preview = []
            header = []
        else:
            data = request.get_json()

            query = SparqlQuery(current_app, session, data["graphState"])
            query.build_query_from_json(preview=True, for_editor=False)

            endpoints = query.endpoints
            federated = query.federated

            header = query.selects
            preview = []
            if query.graphs:
                query_launcher = SparqlQueryLauncher(current_app, session, get_result_query=True, federated=federated, endpoints=endpoints)
                header, preview = query_launcher.process_query(query.sparql)

    except Exception as e:
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'resultsPreview': [],
            'headerPreview': [],
            'error': True,
            'errorMessage': str(e)
        }), 500
    return jsonify({
        'resultsPreview': preview,
        'headerPreview': header,
        'error': False,
        'errorMessage': ''
    })
示例#2
0
def init():
    """Get the default sparql query

    Returns
    -------
    json
    """
    try:
        # Disk space
        files_utils = FilesUtils(current_app, session)
        disk_space = files_utils.get_size_occupied_by_user(
        ) if "user" in session else None

        # Get graphs and endpoints
        query = SparqlQuery(current_app, session)
        graphs, endpoints = query.get_graphs_and_endpoints(all_selected=True)

        # Default query
        default_query = query.prefix_query(query.get_default_query())

        console_enabled = can_access(session['user'])

    except Exception as e:
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            "error": True,
            "errorMessage": str(e),
            "defaultQuery": "",
            "graphs": {},
            "endpoints": {},
            "diskSpace": None,
            "console_enabled": False
        }), 500

    return jsonify({
        "error": False,
        "errorMessage": "",
        "defaultQuery": default_query,
        "graphs": graphs,
        "endpoints": endpoints,
        "diskSpace": disk_space,
        "console_enabled": console_enabled
    })
示例#3
0
    def update_base_url(self, graph, old_url, new_url):
        """Update base url for a graph
        Parameters
        ----------
        graph : string
            Graph to update
        old_url : string
            Old base_url
        new_url : string
            New base_url

        Returns
        -------
        list
            List of graphs
        """

        query_launcher = SparqlQueryLauncher(self.app, self.session)
        query_builder = SparqlQuery(self.app, self.session)

        query = """
        WITH <{0}>
        DELETE{{
            ?s ?p ?o
        }}
        INSERT{{
            ?s2 ?p2 ?o2
        }}
        WHERE {{
            ?s ?p ?o
            FILTER(REGEX(?s, '{1}', 'i') || REGEX(?p, '{1}', 'i') || REGEX(?o, '{1}', 'i')) .
            BIND(IF (isURI(?o), URI(REPLACE(STR(?o), '{1}', '{2}')), ?o) AS ?o2) .
            BIND(IF (isURI(?s), URI(REPLACE(STR(?s), '{1}', '{2}')), ?s) AS ?s2) .
            BIND(IF (isURI(?p), URI(REPLACE(STR(?p), '{1}', '{2}')), ?p) AS ?p2) .
        }}
        """.format(graph, old_url, new_url)

        header, data = query_launcher.process_query(
            query_builder.prefix_query(query))
示例#4
0
def get_data(uri):
    """Get information about uri

    Returns
    -------
    json
        error: True if error, else False
        errorMessage: the error message of error, else an empty string
    """

    try:
        query = SparqlQuery(current_app, session)
        graphs, endpoints = query.get_graphs_and_endpoints(all_selected=True)

        endpoints = [val['uri'] for val in endpoints.values()]

        data = []

        # If the user do not have access to any endpoint (no viewable graph), skip
        if endpoints:

            uri = urllib.parse.quote(uri)
            base_uri = current_app.iniconfig.get('triplestore',
                                                 'namespace_data')
            full_uri = "<%s%s>" % (base_uri, uri)

            data = query.get_uri_parameters(full_uri, endpoints)

    except Exception as e:
        current_app.logger.error(str(e).replace('\\n', '\n'))
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'error': True,
            'errorMessage': str(e).replace('\\n', '\n'),
            'data': []
        }), 500

    return jsonify({'data': data, 'error': False, 'errorMessage': ""})
示例#5
0
def get_sparql_query():
    """Get sparql query of result for the query editor

    Returns
    -------
    json
        query: the sparql query
        error: True if error, else False
        errorMessage: the error message of error, else an empty string
    """
    try:
        files_utils = FilesUtils(current_app, session)
        disk_space = files_utils.get_size_occupied_by_user(
        ) if "user" in session else None

        file_id = request.get_json()["fileId"]
        result_info = {"id": file_id}

        result = Result(current_app, session, result_info)
        query = SparqlQuery(current_app, session)

        sparql = result.get_sparql_query()

        # get graphs and endpoints used in the query
        graphs = result.graphs
        endpoints = result.endpoints
        # Get all graphs and endpoint, and mark as selected the used one
        graphs, endpoints = query.get_graphs_and_endpoints(
            selected_graphs=graphs, selected_endpoints=endpoints)

        # Build sparql query from json if needed
        if sparql is None:
            query.json = result.get_graph_state()
            query.build_query_from_json(for_editor=True)
            sparql = query.sparql

    except Exception as e:
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'query': {},
            'graphs': [],
            'endpoints': [],
            'diskSpace': 0,
            'error': True,
            'errorMessage': str(e)
        }), 500

    return jsonify({
        'query': sparql,
        'graphs': graphs,
        'endpoints': endpoints,
        'diskSpace': disk_space,
        'error': False,
        'errorMessage': ''
    })
示例#6
0
def query():
    """Perform a sparql query

    Returns
    -------
    json
        query results
    """
    q = request.get_json()['query']
    graphs = request.get_json()['graphs']
    endpoints = request.get_json()['endpoints']

    local_endpoint_f = current_app.iniconfig.get('triplestore', 'endpoint')
    try:
        local_endpoint_f = current_app.iniconfig.get('federation', 'local_endpoint')
    except Exception:
        pass

    # No graph selected in local TS
    if not graphs and local_endpoint_f in endpoints:
        return jsonify({
            'error': True,
            'errorMessage': "No graph selected in local triplestore",
            'header': [],
            'data': []
        }), 500

    # No endpoint selected
    if not endpoints:
        return jsonify({
            'error': True,
            'errorMessage': "No endpoint selected",
            'header': [],
            'data': []
        }), 500

    try:
        query = SparqlQuery(current_app, session)

        query.set_graphs_and_endpoints(graphs=graphs, endpoints=endpoints)

        federated = query.is_federated()
        replace_froms = query.replace_froms()

        sparql = query.format_query(q, replace_froms=replace_froms, federated=federated)
        # header, data = query_launcher.process_query(query)
        header = query.selects
        data = []
        if query.graphs or query.endpoints:
            query_launcher = SparqlQueryLauncher(current_app, session, get_result_query=True, federated=federated, endpoints=endpoints)
            header, data = query_launcher.process_query(sparql)

    except Exception as e:
        current_app.logger.error(str(e).replace('\\n', '\n'))
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'error': True,
            'errorMessage': str(e).replace('\\n', '\n'),
            'header': [],
            'data': []
        }), 500

    return jsonify({
        'header': header,
        'data': data
    })
示例#7
0
def save_query():
    """Perform a sparql query

    Returns
    -------
    json
        query results
    """
    q = request.get_json()['query']
    graphs = request.get_json()['graphs']
    endpoints = request.get_json()['endpoints']

    local_endpoint_f = current_app.iniconfig.get('triplestore', 'endpoint')
    try:
        local_endpoint_f = current_app.iniconfig.get('federation', 'local_endpoint')
    except Exception:
        pass

    # No graph selected in local TS
    if not graphs and local_endpoint_f in endpoints:
        return jsonify({
            'error': True,
            'errorMessage': "No graph selected in local triplestore",
            'task_id': None
        }), 500

    # No endpoint selected
    if not endpoints:
        return jsonify({
            'error': True,
            'errorMessage': "No endpoint selected",
            'task_id': None
        }), 500

    try:
        files_utils = FilesUtils(current_app, session)
        disk_space = files_utils.get_size_occupied_by_user() if "user" in session else None

        if session["user"]["quota"] > 0 and disk_space >= session["user"]["quota"]:
            return jsonify({
                'error': True,
                'errorMessage': "Exceeded quota",
                'task_id': None
            }), 500

        # Is query federated?
        query = SparqlQuery(current_app, session)
        query.set_graphs_and_endpoints(graphs=graphs, endpoints=endpoints)

        federated = query.is_federated()
        replace_froms = query.replace_froms()

        formatted_query = query.format_query(q, limit=None, replace_froms=replace_froms, federated=federated)

        info = {
            "sparql_query": q,  # Store the non formatted query in db
            "graphs": graphs,
            "endpoints": endpoints,
            "federated": federated,
            "celery_id": None
        }

        result = Result(current_app, session, info)
        info["id"] = result.save_in_db()

        # execute the formatted query
        info["sparql_query"] = formatted_query

        session_dict = {"user": session["user"]}
        task = current_app.celery.send_task("sparql_query", (session_dict, info))
        result.update_celery(task.id)

    except Exception as e:
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'error': True,
            'errorMessage': str(e),
            'task_id': None
        }), 500

    return jsonify({
        'error': False,
        'errorMessage': '',
        'task_id': task.id
    })
示例#8
0
def get_graph_and_sparql_query():
    """Get query (graphState or Sparql)

    Returns
    -------
    json
        error: True if error, else False
        errorMessage: the error message of error, else an empty string
    """
    try:
        data = request.get_json()
        if not (data and data.get("fileId")):
            return jsonify({
                'graphState': {},
                'sparqlQuery': "",
                'graphs': [],
                'endpoints': [],
                'diskSpace': 0,
                'error': True,
                'errorMessage': "Missing fileId parameter"
            }), 400

        file_id = data["fileId"]
        result_info = {"id": file_id}
        result = Result(current_app, session, result_info)
        if not result:
            return jsonify({
                'graphState': {},
                'sparqlQuery':
                "",
                'graphs': [],
                'endpoints': [],
                'diskSpace':
                0,
                'error':
                True,
                'errorMessage':
                "You do not have access to this query"
            }), 401

        # Get graph state and sparql query
        graph_state = result.get_graph_state(formated=True)
        sparql_query = result.get_sparql_query()

        # Get disk space
        files_utils = FilesUtils(current_app, session)
        disk_space = files_utils.get_size_occupied_by_user(
        ) if "user" in session else None

        # Get graphs and endpoints
        graphs = result.graphs
        endpoints = result.endpoints
        # Get all graphs and endpoint, and mark as selected the used one
        query = SparqlQuery(current_app, session)
        graphs, endpoints = query.get_graphs_and_endpoints(
            selected_graphs=graphs, selected_endpoints=endpoints)
        console_enabled = can_access(session['user'])

    except Exception as e:
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'graphState': {},
            'sparqlQuery': "",
            'graphs': [],
            'endpoints': [],
            'diskSpace': 0,
            'error': True,
            'errorMessage': str(e)
        }), 500

    return jsonify({
        'graphState': graph_state,
        'sparqlQuery': sparql_query,
        'graphs': graphs,
        'endpoints': endpoints,
        'diskSpace': disk_space,
        'error': False,
        'errorMessage': '',
        'console_enabled': console_enabled
    })
    def get_startpoints(self):
        """Get public and user startpoints

        Returns
        -------
        list
            Startpoints
        """
        filter_user = ""
        if self.logged_user():
            filter_user = "******".format(self.session["user"]["username"])

        query_launcher = SparqlQueryLauncher(self.app, self.session)
        query_builder = SparqlQuery(self.app, self.session)

        query = '''
        SELECT DISTINCT ?endpoint ?graph ?entity ?entity_label ?creator ?public
        WHERE {{
            ?graph askomics:public ?public .
            ?graph dc:creator ?creator .
            GRAPH ?graph {{
                ?graph prov:atLocation ?endpoint .
                ?entity a askomics:entity .
                ?entity a askomics:startPoint .
                ?entity rdfs:label ?entity_label .
            }}
            FILTER (
                ?public = <true>{}
            )
        }}
        '''.format(filter_user)

        header, data = query_launcher.process_query(query_builder.prefix_query(query))

        startpoints = []
        entities = []

        for result in data:

            if result["endpoint"] == self.settings.get("triplestore", "endpoint"):
                endpoint_name = "local"
            else:
                try:
                    endpoint_name = tld.get_fld(result["endpoint"]).split('.')[0]
                except Exception:
                    endpoint_name = urlparse(result["endpoint"]).netloc

            if result["entity"] not in entities:
                # new entity
                entities.append(result['entity'])
                startpoint = {
                    "entity": result["entity"],
                    "entity_label": result["entity_label"],
                    "graphs": [{
                        "uri": result["graph"],
                        "public": result["public"],
                        "creator": result["creator"]
                    }],
                    "endpoints": [{"url": result["endpoint"], "name": endpoint_name}],
                    "public": self.str_to_bool(result["public"]),
                    "private": not self.str_to_bool(result["public"])
                }
                startpoints.append(startpoint)
            else:
                # update existing entity
                index = entities.index(result['entity'])
                graph = {
                    "uri": result["graph"],
                    "public": result["public"],
                    "creator": result["creator"]
                }
                startpoints[index]["graphs"].append(graph)
                startpoints[index]["endpoints"].append({"url": result["endpoint"], "name": endpoint_name})
                if self.str_to_bool(result["public"]):
                    startpoints[index]["public"] = True
                else:
                    startpoints[index]["private"] = True

        return startpoints
示例#10
0
    def get_abstraction_relations(self):
        """Get user abstraction relations from the triplestore

        Returns
        -------
        list
            Relations
        """
        filter_user = ""
        if self.logged_user():
            filter_user = "******".format(self.session["user"]["username"])

        query_launcher = SparqlQueryLauncher(self.app, self.session)
        query_builder = SparqlQuery(self.app, self.session)

        query = '''
        SELECT DISTINCT ?graph ?entity_uri ?entity_faldo ?entity_label ?node_type ?attribute_uri ?attribute_faldo ?attribute_label ?attribute_range ?property_uri ?property_faldo ?property_label ?range_uri ?category_value_uri ?category_value_label
        WHERE {{
            # Graphs
            ?graph askomics:public ?public .
            ?graph dc:creator ?creator .
            GRAPH ?graph {{
                # Property (relations and categories)
                ?property_uri a owl:ObjectProperty .
                ?property_uri a askomics:AskomicsRelation .
                ?property_uri rdfs:label ?property_label .
                ?property_uri rdfs:range ?range_uri .
            }}
            # Relation of entity (or motherclass of entity)
            {{
                ?property_uri rdfs:domain ?mother .
                ?entity_uri rdfs:subClassOf ?mother .
            }} UNION {{
                ?property_uri rdfs:domain ?entity_uri .
            }}
            FILTER (
                ?public = <true>{}
            )
        }}
        '''.format(filter_user)

        header, data = query_launcher.process_query(query_builder.prefix_query(query))

        relations_list = []
        relations = []

        for result in data:
            # Relation
            if "property_uri" in result:
                rel_tpl = (result["property_uri"], result["entity_uri"], result["range_uri"])
                if rel_tpl not in relations_list:
                    relations_list.append(rel_tpl)
                    relation = {
                        "uri": result["property_uri"],
                        "label": result["property_label"],
                        "graphs": [result["graph"], ],
                        "source": result["entity_uri"],
                        "target": result["range_uri"]
                    }
                    relations.append(relation)
                else:
                    # if graph is diff, append it
                    index_relation = relations_list.index(rel_tpl)
                    if result["graph"] not in relations[index_relation]["graphs"]:
                        relations[index_relation]["graphs"].append(result["graph"])

        return relations
示例#11
0
    def get_abstraction_attributes(self):
        """Get user abstraction attributes from the triplestore

        Returns
        -------
        list
            AskOmics attributes
        """
        filter_user = ""
        if self.logged_user():
            filter_user = "******".format(self.session["user"]["username"])

        litterals = (
            "http://www.w3.org/2001/XMLSchema#string",
            "http://www.w3.org/2001/XMLSchema#decimal",
            "http://www.w3.org/2001/XMLSchema#boolean"
        )

        query_launcher = SparqlQueryLauncher(self.app, self.session)
        query_builder = SparqlQuery(self.app, self.session)

        query = '''
        SELECT DISTINCT ?graph ?entity_uri ?attribute_uri ?attribute_type ?attribute_faldo ?attribute_label ?attribute_range ?category_value_uri ?category_value_label
        WHERE {{
            # Graphs
            ?graph askomics:public ?public .
            ?graph dc:creator ?creator .
            GRAPH ?graph {{
                ?attribute_uri a ?attribute_type .
                VALUES ?attribute_type {{ owl:DatatypeProperty askomics:AskomicsCategory }}
                ?attribute_uri rdfs:label ?attribute_label .
                ?attribute_uri rdfs:range ?attribute_range .
                # Faldo
                OPTIONAL {{
                    ?attribute_uri a ?attribute_faldo .
                    VALUES ?attribute_faldo {{ askomics:faldoStart askomics:faldoEnd askomics:faldoStrand askomics:faldoReference }}
                }}
                # Categories (DK)
                OPTIONAL {{
                    ?attribute_range askomics:category ?category_value_uri .
                    ?category_value_uri rdfs:label ?category_value_label .
                }}
            }}
            # Attribute of entity (or motherclass of entity)
            {{
                ?attribute_uri rdfs:domain ?mother .
                ?entity_uri rdfs:subClassOf ?mother .
            }} UNION {{
                ?attribute_uri rdfs:domain ?entity_uri .
            }}
            FILTER (
                ?public = <true>{}
            )
        }}
        '''.format(filter_user)

        header, data = query_launcher.process_query(query_builder.prefix_query(query))
        attributes_list = []

        attributes = []

        for result in data:
            # Attributes
            if "attribute_uri" in result and "attribute_label" in result and result["attribute_type"] != "{}AskomicsCategory".format(self.settings.get("triplestore", "namespace_internal")) and result["attribute_range"] in litterals:
                attr_tpl = (result["attribute_uri"], result["entity_uri"])
                if attr_tpl not in attributes_list:
                    attributes_list.append(attr_tpl)
                    attribute = {
                        "uri": result["attribute_uri"],
                        "label": result["attribute_label"],
                        "graphs": [result["graph"], ],
                        "entityUri": result["entity_uri"],
                        "type": result["attribute_range"],
                        "faldo": result["attribute_faldo"] if "attribute_faldo" in result else None,
                        "categories": []
                    }
                    attributes.append(attribute)
                else:
                    # if graph is different, store it
                    index_attribute = attributes_list.index(attr_tpl)
                    if result["graph"] not in attributes[index_attribute]["graphs"]:
                        attributes[index_attribute]["graphs"].append(result["graph"])

                index_attribute = attributes_list.index(attr_tpl)

            # Categories
            if "attribute_uri" in result and result["attribute_type"] == "{}AskomicsCategory".format(self.settings.get("triplestore", "namespace_internal")) and "category_value_uri" in result:
                attr_tpl = (result["attribute_uri"], result["entity_uri"])
                if attr_tpl not in attributes_list:
                    attributes_list.append(attr_tpl)
                    attribute = {
                        "uri": result["attribute_uri"],
                        "label": result["attribute_label"],
                        "graphs": [result["graph"], ],
                        "entityUri": result["entity_uri"],
                        "type": result["attribute_type"],
                        "faldo": result["attribute_faldo"] if "attribute_faldo" in result else None,
                        "categories": [{
                            "uri": result["category_value_uri"],
                            "label": result["category_value_label"]
                        }]
                    }
                    attributes.append(attribute)
                else:
                    # if graph diff, store it
                    index_attribute = attributes_list.index(attr_tpl)
                    if result["graph"] not in attributes[index_attribute]["graphs"]:
                        attributes[index_attribute]["graphs"].append(result["graph"])
                    # Store value if new
                    value = {
                        "uri": result["category_value_uri"],
                        "label": result["category_value_label"]
                    }
                    if value not in attributes[index_attribute]["categories"]:
                        attributes[index_attribute]["categories"].append(value)

        return attributes
示例#12
0
    def get_abstraction_entities(self):
        """Get abstraction entities

        Returns
        -------
        list
            List of entities available
        """
        filter_user = ""
        if self.logged_user():
            filter_user = "******".format(self.session["user"]["username"])

        query_launcher = SparqlQueryLauncher(self.app, self.session)
        query_builder = SparqlQuery(self.app, self.session)

        query = '''
        SELECT DISTINCT ?endpoint ?graph ?entity_uri ?entity_type ?entity_faldo ?entity_label ?have_no_label
        WHERE {{
            ?graph askomics:public ?public .
            ?graph dc:creator ?creator .
            GRAPH ?graph {{
                ?graph prov:atLocation ?endpoint .
                ?entity_uri a ?entity_type .
                VALUES ?entity_type {{ askomics:entity askomics:bnode }} .
                # Faldo
                OPTIONAL {{
                    ?entity_uri a ?entity_faldo .
                    VALUES ?entity_faldo {{ askomics:faldo }} .
                }}
                # Label
                OPTIONAL {{ ?entity_uri rdfs:label ?entity_label . }}
                OPTIONAL {{ ?entity_uri askomics:instancesHaveNoLabels ?have_no_label . }}
            }}
            FILTER (
                ?public = <true>{}
            )
        }}
        '''.format(filter_user)

        header, data = query_launcher.process_query(query_builder.prefix_query(query))

        entities_list = []  # list of entity uri
        entities = []  # list of entity dict

        for result in data:
            if result["entity_uri"] not in entities_list:
                # New entity
                entities_list.append(result["entity_uri"])
                # Uri, graph and label
                label = "" if "entity_label" not in result else result["entity_label"]
                entity_type = "bnode" if result["entity_type"] == "{}bnode".format(self.settings.get("triplestore", "namespace_internal")) else "node"
                entity = {
                    "uri": result["entity_uri"],
                    "type": entity_type,
                    "label": label,
                    "instancesHaveLabels": True if "have_no_label" not in result else False if result["have_no_label"] == "1" else True,
                    "faldo": True if "entity_faldo" in result else False,
                    "endpoints": [result["endpoint"]],
                    "graphs": [result["graph"]],
                }

                entities.append(entity)
            else:
                # if graph is different, store it
                index_entity = entities_list.index(result['entity_uri'])
                if result["graph"] not in entities[index_entity]["graphs"]:
                    entities[index_entity]["graphs"].append(result["graph"])
                # If endpoint is different, store it
                if result["endpoint"] not in entities[index_entity]["endpoints"]:
                    entities[index_entity]["endpoints"].append(result["endpoint"])

        return entities
示例#13
0
def save_result():
    """Save a query in filesystem and db, using a celery task

    Returns
    -------
    json
        result_id: result id
        error: True if error, else False
        errorMessage: the error message of error, else an empty string
    """
    try:
        files_utils = FilesUtils(current_app, session)
        disk_space = files_utils.get_size_occupied_by_user() if "user" in session else None

        if session["user"]["quota"] > 0 and disk_space >= session["user"]["quota"]:
            return jsonify({
                'error': True,
                'errorMessage': "Exceeded quota",
                'result_id': None
            }), 400

        # Get query and endpoints and graphs of the query
        data = request.get_json()
        if not (data and data.get("graphState")):
            return jsonify({
                'result_id': None,
                'error': True,
                'errorMessage': "Missing graphState parameter"
            }), 400

        query = SparqlQuery(current_app, session, data["graphState"], get_graphs=False)
        query.build_query_from_json(preview=False, for_editor=False)
        federated = query.is_federated()

        info = {
            "graph_state": data["graphState"],
            "query": query.sparql,
            "graphs": query.graphs,
            "endpoints": query.endpoints,
            "federated": federated,
            "celery_id": None,
            "selects": query.selects,
        }

        result = Result(current_app, session, info)
        info["id"] = result.save_in_db()

        session_dict = {"user": session["user"]}
        task = current_app.celery.send_task("query", (session_dict, info))
        result.update_celery(task.id)
    except Exception as e:
        traceback.print_exc(file=sys.stdout)
        return jsonify({
            'error': True,
            'errorMessage': str(e),
            'result_id': None
        }), 500

    return jsonify({
        'error': False,
        'errorMessage': '',
        'result_id': info["id"]
    })