示例#1
0
    def setUp(self):
        settings.Settings.Instance().LoadConfig(
            os.path.join(os.path.dirname(__file__), "..", "..", "configs",
                         "test", "config.ini"))

        c = MongoClient(settings.GetConfigValue("ServiceStockageAnnotations",
                                                "MONGO_HOST"),
                        int(
                            settings.GetConfigValue(
                                "ServiceStockageAnnotations", "MongoPort")),
                        connect=False)
        c.drop_database(
            settings.GetConfigValue("ServiceStockageAnnotations", "MongoDb"))
        c.close()
        self.d = AnnotationManager()
        self.d.setCollection(
            settings.GetConfigValue("ServiceStockageAnnotations",
                                    "HumanAnnotationCollection"))
        self.d.addStorageCollection(
            1,
            settings.GetConfigValue("ServiceStockageAnnotations",
                                    "HumanAnnotationCollection"))
        self.d.addStorageCollection(
            2,
            settings.GetConfigValue("ServiceStockageAnnotations",
                                    "BatchAnnotationCollection"))
        self.d.connect()
示例#2
0
def search_annotations_grouped():
    """
    Search manual annotations (storageType 1) and group them by timeline.
    The body of the request is a JSON query passed to
    https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/

    Limit is mandatory when skip is specified.

    :return: The text index fields and an array of annotation matches grouped by timeline (annotationSetId).
     Each match contains the annotation and score matching the query, sorted descending by score.
     Groups are also sorted descending by score.
    """
    man = AnnotationManager()

    try:
        hac = settings.GetConfigValue("ServiceStockageAnnotations", "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        man.connect()

        query = request.get_json(force=True).get('query')
        if query is None:
            return json.dumps({"error": "body with query is mandatory."}), 400
        skip = request.json.get('skip')
        limit = request.json.get('limit')
        if limit is None and skip is not None:
            return json.dumps({"error": "Limit is mandatory when skip is specified."}), 400

        results = man.grouped_search_annotations(query, skip=skip, limit=limit)
        indexed_fields = man.get_text_index_fields()

        return jsonify({"results": results, "indexedFields": indexed_fields})
    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#3
0
def search_annotations():
    """
    Search manual annotations (storageType 1)
    The body of the request is a JSON query passed to https://docs.mongodb.com/manual/reference/method/db.collection.find/

    :return: JSON Array of results containing the annotation and score matching the query, sorted descending by score.
    """
    man = AnnotationManager()

    try:
        hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        man.connect()

        query = request.json.get('query')
        if query is None:
            return json.dumps({"error": "body with query is mandatory"}), 400
        skip = request.json.get('skip')
        limit = request.json.get('limit')

        results = man.search_annotations(query, skip=skip, limit=limit)

        return jsonify(results)
    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#4
0
def createDocumentAnnotation(document_id):
    """
    :route: **/document/<document_id>/annotation**

    :param document_id: The id of the document for which we want to access the annotation

    :POST Creates an annotation.:
        :Request:
            :preconditions:

                Here are minimum annotations contents:
                ::

                    {
                      @context: Complex object containing JSON_LD info.
                    }

                Other custom fields which were created would be returned too.

            The annotation using this method is created in HumanStorage.
        :Response JSON:

            Here are minimum annotations contents which will be after creation:
            ::

                 {
                    doc_id: to describe the id of the document containing the
                            annotation. Equals to strDocId.
                    @context: a field linking the context of the document.
                    id:  a unique id identifying the annotation.
                 }

            :http status code:
                |    OK: 200
                |    Error: See Error Codes
    """
    man = AnnotationManager()
    hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                  "HumanAnnotationCollection")
    man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
    try:
        man.connect()
        if request.method == 'POST':
            logger.logUnknownDebug("Create Annotation",
                                   " For document Id: {0}".format(document_id))
            docId = man.createAnnotation(request.json, document_id)
            return jsonify({"id": docId}), 201
        else:
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request",
                                  "", "")

    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#5
0
def search_annotations():
    """
    Search manual annotations (storageType 1)
    The body of the request is a JSON query passed to https://docs.mongodb.com/manual/reference/method/db.collection.find/

    :return: JSON Array of results containing the annotation and score matching the query, sorted descending by score.
    """
    man = AnnotationManager()

    try:
        hac = settings.GetConfigValue("ServiceStockageAnnotations", "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        man.connect()

        query = request.json.get('query')
        if query is None:
            return json.dumps({"error": "body with query is mandatory"}), 400
        skip = request.json.get('skip')
        limit = request.json.get('limit')

        results = man.search_annotations(query, skip=skip, limit=limit)

        return jsonify(results)
    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#6
0
def createDocumentAnnotation(document_id):
    """
    :route: **/document/<document_id>/annotation**

    :param document_id: The id of the document for which we want to access the annotation

    :POST Creates an annotation.:
        :Request:
            :preconditions:

                Here are minimum annotations contents:
                ::

                    {
                      @context: Complex object containing JSON_LD info.
                    }

                Other custom fields which were created would be returned too.

            The annotation using this method is created in HumanStorage.
        :Response JSON:

            Here are minimum annotations contents which will be after creation:
            ::

                 {
                    doc_id: to describe the id of the document containing the
                            annotation. Equals to strDocId.
                    @context: a field linking the context of the document.
                    id:  a unique id identifying the annotation.
                 }

            :http status code:
                |    OK: 200
                |    Error: See Error Codes
    """
    man = AnnotationManager()
    hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                  "HumanAnnotationCollection")
    man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
    try:
        man.connect()
        if request.method == 'POST':
            logger.logUnknownDebug("Create Annotation", " For document Id: {0}".format(document_id))
            docId = man.createAnnotation(request.json, document_id)
            return jsonify({"id": docId}), 201
        else:
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request", "", "")

    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#7
0
def search_annotations_grouped():
    """
    Search manual annotations (storageType 1) and group them by timeline.
    The body of the request is a JSON query passed to
    https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/

    Limit is mandatory when skip is specified.

    :return: The text index fields and an array of annotation matches grouped by timeline (annotationSetId).
     Each match contains the annotation and score matching the query, sorted descending by score.
     Groups are also sorted descending by score.
    """
    man = AnnotationManager()

    try:
        hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        man.connect()

        query = request.get_json(force=True).get('query')
        if query is None:
            return json.dumps({"error": "body with query is mandatory."}), 400
        skip = request.json.get('skip')
        limit = request.json.get('limit')
        if limit is None and skip is not None:
            return json.dumps(
                {"error": "Limit is mandatory when skip is specified."}), 400

        results = man.grouped_search_annotations(query, skip=skip, limit=limit)
        indexed_fields = man.get_text_index_fields()

        return jsonify({"results": results, "indexedFields": indexed_fields})
    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#8
0
    def setUp(self):
        settings.Settings.Instance().LoadConfig(
            os.path.join(os.path.dirname(__file__), "..", "..", "configs", "test", "config.ini"))

        c = MongoClient(settings.GetConfigValue("ServiceStockageAnnotations", "MONGO_HOST"),
                        int(settings.GetConfigValue("ServiceStockageAnnotations", "MongoPort")),
                        connect=False)
        c.drop_database(settings.GetConfigValue("ServiceStockageAnnotations", "MongoDb"))
        c.close()
        self.d = AnnotationManager()
        self.d.setCollection(settings.GetConfigValue("ServiceStockageAnnotations", "HumanAnnotationCollection"))
        self.d.addStorageCollection(1,
                                    settings.GetConfigValue("ServiceStockageAnnotations", "HumanAnnotationCollection"))
        self.d.addStorageCollection(2,
                                    settings.GetConfigValue("ServiceStockageAnnotations", "BatchAnnotationCollection"))
        self.d.connect()
示例#9
0
class TestAnnotationsManager(unittest.TestCase):
    d = None

    def setUp(self):
        settings.Settings.Instance().LoadConfig(
            os.path.join(os.path.dirname(__file__), "..", "..", "configs",
                         "test", "config.ini"))

        c = MongoClient(settings.GetConfigValue("ServiceStockageAnnotations",
                                                "MONGO_HOST"),
                        int(
                            settings.GetConfigValue(
                                "ServiceStockageAnnotations", "MongoPort")),
                        connect=False)
        c.drop_database(
            settings.GetConfigValue("ServiceStockageAnnotations", "MongoDb"))
        c.close()
        self.d = AnnotationManager()
        self.d.setCollection(
            settings.GetConfigValue("ServiceStockageAnnotations",
                                    "HumanAnnotationCollection"))
        self.d.addStorageCollection(
            1,
            settings.GetConfigValue("ServiceStockageAnnotations",
                                    "HumanAnnotationCollection"))
        self.d.addStorageCollection(
            2,
            settings.GetConfigValue("ServiceStockageAnnotations",
                                    "BatchAnnotationCollection"))
        self.d.connect()

    def test_connect(self):
        self.assertEqual(self.d.isConnected(), True)

    def l(self, strContent):
        # shortcut to load json
        return json.loads(strContent)

    def test_createAnnotationsS(self):
        jsonBatch = self.l(
            '{"common":{"@context":"test"},"data":[{"a":1},{"b":2}]}')
        id = self.d.createMongoDocument(
            self.l('{"@context":"testing_context"}'))
        self.assertRaises(AnnotationException,
                          lambda: self.d.createAnnotationS(
                              jsonBatch, "yolo", 1, 1))  # bad id
        self.assertRaises(AnnotationException,
                          lambda: self.d.createAnnotationS(
                              jsonBatch, id, 1, 3))  # bad storage
        self.assertRaises(AnnotationException,
                          lambda: self.d.createAnnotationS(
                              jsonBatch, id, 1, 0))  # bad storage
        self.assertRaises(AnnotationException,
                          lambda: self.d.createAnnotationS(
                              jsonBatch, id, 2, 1))  # Bad format
        self.assertEqual(0, self.d.createAnnotationS(self.l("{}"), id))
        jsonInvalidBatch = self.l(
            '{"data":[{"a":1,"@context":"test"},{"b":2}]}')
        self.assertRaises(
            AnnotationException,
            lambda: self.d.createAnnotationS(jsonInvalidBatch, id, 1, 1))
        jsonBatch = self.l(
            '{"data":[{"a":1,"@context":"test"},{"b":2,"@context":"test"}]}')
        resDifferentBatchFormat = self.d.createAnnotationS(jsonBatch, id, 0, 2)
        self.assertEqual(
            2, resDifferentBatchFormat,
            "Expected to get 2, but got {0} created with batch format 0".
            format(resDifferentBatchFormat))

    def test_getAnnotationsS(self):
        id = self.d.createMongoDocument(
            self.l('{"@context":"testing_context"}'))
        id2 = self.d.createMongoDocument(
            self.l('{"@context":"testing_context"}'))
        jsonBatch = self.l(
            '{"common":{"@context":"test"},"data":[{"a":1,"b":1},{"a":2,"b":1}]}'
        )
        jsonBatch2 = self.l(
            '{"common":{"@context":"test"},"data":[{"a":1,"c":1},{"a":2,"c":1}]}'
        )
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch, id, 1, 1))
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch2, id2, 1, 1))
        #
        res = self.d.getAnnotationS([id], {}, 0, 1)
        self.assertEqual(2, len(res["data"]))
        res = self.d.getAnnotationS([id], {"a": 1}, 0, 1)
        self.assertEqual(
            1, len(res["data"]),
            "Filter a:1 for one docs should return 1 result. Results: {0}".
            format(str(res)))

        res = self.d.getAnnotationS([id, id2], {"a": 1}, 0, 1)
        self.assertEqual(
            2, len(res["data"]),
            "Filter a:1 for two docs should return 2 result. Results: {0}".
            format(str(res)))

        largeJsonBatch = self.l(
            '{"common":{"@context":"test"},"data":[{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3}]}'
        )

        self.assertEqual(27, self.d.createAnnotationS(largeJsonBatch, id2, 1,
                                                      1))
        res = self.d.getAnnotationS([id, id2], {"e": {"$gt": 0}}, 0, 1)
        self.assertEqual(
            27, len(res["data"]),
            "Filter e:1 for largebatch should return 27 result. Returned: {0}".
            format(len(res["data"])))
        # testing by getting
        # Change for large batch
        largeJsonBatch1 = self.l(
            '{"common":{"@context":"test","k":1},"data":[{"a":1,"b":1},{"a":2,"b":1},{"a":3,"b":1}]}'
        )
        largeJsonBatch2 = self.l(
            '{"common":{"@context":"test","k":2},"data":[{"a":4,"c":1},{"a":5,"c":1}]}'
        )
        largeJsonBatch3 = self.l(
            '{"common":{"@context":"test","k":2},"data":[{"a":1,"c":1},{"a":2,"c":1},{"a":3,"c":1},{"a":4,"c":1}]}'
        )
        # id, 2 batches total 5 anno
        # id2, 1 batch total 4 anno
        self.assertEqual(3, self.d.createAnnotationS(largeJsonBatch1, id, 1,
                                                     2))
        self.assertEqual(2, self.d.createAnnotationS(largeJsonBatch2, id, 1,
                                                     2))
        self.assertEqual(4, self.d.createAnnotationS(largeJsonBatch3, id2, 1,
                                                     2))
        # get all annotations in both documents
        res = self.d.getAnnotationS([id, id2], {}, 0, 2)
        self.assertEqual(9, len(res["data"]))
        # get all annotations of doc with id
        res = self.d.getAnnotationS([id], {}, 0, 2)
        self.assertEqual(5, len(res["data"]))
        res = self.d.getAnnotationS([id], {"k": 2}, 0, 2)
        self.assertEqual(2, len(res["data"]))
        # get all batch annotations with key k = 2 for both documents
        res = self.d.getAnnotationS([id, id2], {"k": 2}, 0, 2)
        self.assertEqual(6, len(res["data"]))

    def test_deleteAnnotationsS(self):
        id = self.d.createMongoDocument(
            self.l('{"@context":"testing_context"}'))
        jsonBatch = self.l(
            '{"common":{"@context":"test"},"data":[{"a":1},{"b":2}]}')
        jsonLargeBatch1 = self.l(
            '{"common":{"@context":"test","batch":1},"data":[{"a":1},{"b":2}]}'
        )
        jsonLargeBatch2 = self.l(
            '{"common":{"@context":"test","batch":2},"data":[{"a":1},{"b":2}]}'
        )
        self.assertEqual(0, self.d.deleteAnnotationS([id], {}))
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch, id))
        self.assertEqual(2, self.d.deleteAnnotationS([id], {}))
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch, id, 1, 1))
        self.assertEqual(2, self.d.createAnnotationS(jsonLargeBatch1, id, 1,
                                                     2))
        res = self.d.deleteAnnotationS([id], {}, 1)
        self.assertEqual(
            2, res,
            "Should only delete 2 since we created 2 per storage type, but we got {0}"
            .format(res))
        res = self.d.deleteAnnotationS([id], {}, 2)
        self.assertEqual(
            1, res, "Should delete 1 since we only have one batch".format(res))
        self.assertEqual(2, self.d.createAnnotationS(jsonLargeBatch1, id, 1,
                                                     2))
        self.assertEqual(2, self.d.createAnnotationS(jsonLargeBatch2, id, 1,
                                                     2))
        res = self.d.deleteAnnotationS([id], {"batch": 1}, 2)
        self.assertEqual(
            1, res,
            "Should delete 1 (only the first batch of 2 batches) we got {0}".
            format(res))
示例#10
0
def documentAnnotation(document_id, annotation_id):
    """
    :route: **/document/<document_id>/annotation/<annotation_id>**

    Get/Update/Delete an annotation:

    :param document_id: The id of the document for which we want to access the
                        annotation
    :param annotation_id: The id of the annotation we want to access

    :GET Returns an annotation:
        :Request:
             :precondtions:

                 Can only get annotations from HumanStorage.

        :Response json:

            Here are minimum annotations contents which will be after
            creation:
            ::

                {
                    doc_id: to describe the id of the document containing the
                            annotation. Equals to strDocId.
                    @context: a field linking the context of the document.
                    id:  a unique id identifying the annotation.
                }

    :PUT Updates an annotation:
        Updates are made by changing the content of the old annotation with the new one

        :Request:
            :precondtions:
                Can only get annotations from HumanStorage.
        :Response:
            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :DELETE deletes an annotation.:
        :Request:
             :precondtions:
                 Can only get annotations from HumanStorage.

        :Response:
            :http status code:
                |    OK: 204
                |    Error: See Error Codes
    """
    man = AnnotationManager()

    try:

        hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        man.connect()
        if (not _getStorageTypeFromId(AnnotationManager.HUMAN_STORAGE)):
            raise (StorageRestExceptions(4))

        if request.method == 'GET':
            logger.logUnknownDebug("Get Annotation",
                                   " For document Id: {0}".format(document_id))
            doc = man.getAnnotation(annotation_id)
            _convStorageIdToDocId(doc)
            if (doc is None):
                raise (StorageRestExceptions(2))
            else:
                return jsonify(doc)
        elif request.method == 'PUT':
            doc = request.json
            _convDocIdToStorageId(doc)
            if '_id' in doc and doc["_id"] != annotation_id:
                raise (StorageRestExceptions(1))
            else:
                logger.logUnknownDebug(
                    "Update Annotation",
                    " For document Id: {0}".format(document_id))
                man.updateAnnotation(doc, annotation_id)
                return jsonify({})
        elif request.method == 'DELETE':
            logger.logUnknownDebug("Delete Annotation",
                                   " For document Id: {0}".format(document_id))
            man.deleteAnnotation(annotation_id)
            # Whenever it is true or false we don't care, if there is no
            # exception
            return jsonify({}), 204
        else:
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request",
                                  "", "")

    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#11
0
def documentAnnotationS(document_id):
    """
    :route: **/document/<document_id>/annotations**

    In case storageType = 2, annotations will be stored in batches. All operations impact
    each batch (Example a PUT operation will replace all annotations in a batch).
    By default each document have 1 annotation batch. To have multiple batches,
    post/put batch of annotations using batchFormat = 1, and use common section to
    to identify uniquely a batch. Fields "doc_id_batch", "file_fs_id_batch" are reserved,
    thus will be ignored if added in common section.

    :param document_id: The id of the document from which we want to access
                        multiple annotations

    :POST Create annotations in batch.:
        :Request:

            :preconditions:

               All must be valid annotations.
               If one annotation fails, it will return an error message and
               fail all create.
            :params supported:

                |   batchFormat = 0,1
                |   storageType = 1,2
            :params default:

                |   batchFormat = 1
                |   storageType = 1
        :Response json:

            |    returns {"nInserted":nbAnnotationsInserted}

            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :PUT Updates annotations related for the document.:
        :Request:

            When we update we replace old contents with new ones. jsonSelect

            :params supported:
                |    jsonSelect (only contains contents in the "common" fields for storageType = 2.)
                |    storageType = 2

            :params default:

                |    storageType = 2
                |    jsonSelect = {}
        :Response json:
            |    Returns number of annotations deleted
            |    {"nDeleted":nbAnnotationsDeleted}

            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :DELETE Deletes annotations related for the document.:
        :Request:

            :params supported:

                |    jsonSelect
                |    storageType = 1,2
            :params default:

                |    storageType = 1
                |    jsonSelect = {}
        :Response json:
            |    Returns number of annotations deleted
            |    {"nDeleted":nbAnnotationsDeleted}

            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :GET Returns annotations for the current document.:
        :Request:

            :params supported:

                |    jsonSelect
                |    storageType = 0,1,2
                |    batchFormat = 0

            :params default:
                |    batchFormat = 0
                |    storageType = 0
                |    jsonSelect = {}
        :Response json:

            An array of annotations check batch format for how they will be
            formatted.

            :http status code:
                |    OK: 200
                |    Error: See Error Codes


    """
    man = AnnotationManager()

    try:
        hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        bac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "BatchAnnotationCollection")
        man.addStorageCollection(AnnotationManager.BATCH_STORAGE, bac)
        man.connect()

        jsonSelect = request.args.get('jsonSelect')
        storageType = request.args.get('storageType')
        batchFormat = request.args.get('batchFormat')

        # Note for batch operations all ids are replaced in man
        if request.method == 'GET':
            try:
                if not jsonSelect:
                    jsonSelect = {}
                else:
                    jsonSelect = json.loads(jsonSelect)
                if not storageType:
                    storageType = 0
                else:
                    storageType = int(storageType)
                if not batchFormat:
                    batchFormat = 0
                else:
                    batchFormat = int(batchFormat)
            except Exception as e:
                raise (StorageRestExceptions(5))
            batch = man.getAnnotationS([document_id], jsonSelect, batchFormat,
                                       storageType)
            return jsonify(batch)

        elif request.method == 'PUT':
            logger.logUnknownDebug("Update Annotations",
                                   " For document Id: {0}".format(document_id))
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request",
                                  "", "")

        elif request.method == 'POST':
            jsonBatch = request.json
            try:
                if not storageType:
                    storageType = 1
                else:
                    storageType = int(storageType)
                if not batchFormat:
                    batchFormat = 1
                else:
                    batchFormat = int(batchFormat)
                logger.logUnknownDebug(
                    "Create Annotations",
                    " For document Id: {0} StorageType :{1},BatchFormat:{2}, jsonBatch: {3}"
                    .format(document_id, str(storageType), str(batchFormat),
                            str(jsonBatch)))
            except Exception as e:
                raise (StorageRestExceptions(5))

            nbAnnotationsCreated = man.createAnnotationS(
                jsonBatch, document_id, batchFormat, storageType)
            return jsonify({"nCreated": nbAnnotationsCreated})

        elif request.method == 'DELETE':
            # Whenever it is true or false we don't care, if there is no
            # exception
            try:
                logger.logUnknownDebug(
                    "Delete Annotations",
                    " For document Id: {0}".format(document_id))
                if not jsonSelect:
                    jsonSelect = {}
                else:
                    jsonSelect = json.loads(jsonSelect)
                if not storageType:
                    storageType = 0
                else:
                    storageType = int(storageType)
            except Exception as e:
                raise (StorageRestExceptions(5))

            nbAnnotationsDeleted = man.deleteAnnotationS([document_id],
                                                         jsonSelect,
                                                         storageType)
            logger.logUnknownDebug(
                "Delete Annotations",
                " Number of deleted annotations {0} For document Id: {1}".
                format(str(nbAnnotationsDeleted), document_id))
            return jsonify({"nDeleted": nbAnnotationsDeleted}), 200
        else:
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request",
                                  "", "")

    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#12
0
def documentAnnotation(document_id, annotation_id):
    """
    :route: **/document/<document_id>/annotation/<annotation_id>**

    Get/Update/Delete an annotation:

    :param document_id: The id of the document for which we want to access the
                        annotation
    :param annotation_id: The id of the annotation we want to access

    :GET Returns an annotation:
        :Request:
             :precondtions:

                 Can only get annotations from HumanStorage.

        :Response json:

            Here are minimum annotations contents which will be after
            creation:
            ::

                {
                    doc_id: to describe the id of the document containing the
                            annotation. Equals to strDocId.
                    @context: a field linking the context of the document.
                    id:  a unique id identifying the annotation.
                }

    :PUT Updates an annotation:
        Updates are made by changing the content of the old annotation with the new one

        :Request:
            :precondtions:
                Can only get annotations from HumanStorage.
        :Response:
            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :DELETE deletes an annotation.:
        :Request:
             :precondtions:
                 Can only get annotations from HumanStorage.

        :Response:
            :http status code:
                |    OK: 204
                |    Error: See Error Codes
    """
    man = AnnotationManager()

    try:

        hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        man.connect()
        if (not _getStorageTypeFromId(AnnotationManager.HUMAN_STORAGE)):
            raise (StorageRestExceptions(4))

        if request.method == 'GET':
            logger.logUnknownDebug("Get Annotation", " For document Id: {0}".format(document_id))
            doc = man.getAnnotation(annotation_id)
            _convStorageIdToDocId(doc)
            if (doc is None):
                raise (StorageRestExceptions(2))
            else:
                return jsonify(doc)
        elif request.method == 'PUT':
            doc = request.json
            _convDocIdToStorageId(doc)
            if '_id' in doc and doc["_id"] != annotation_id:
                raise (StorageRestExceptions(1))
            else:
                logger.logUnknownDebug("Update Annotation", " For document Id: {0}".format(document_id))
                man.updateAnnotation(doc, annotation_id)
                return jsonify({})
        elif request.method == 'DELETE':
            logger.logUnknownDebug("Delete Annotation", " For document Id: {0}".format(document_id))
            man.deleteAnnotation(annotation_id)
            # Whenever it is true or false we don't care, if there is no
            # exception
            return jsonify({}), 204
        else:
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request", "", "")

    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#13
0
def documentAnnotationS(document_id):
    """
    :route: **/document/<document_id>/annotations**

    In case storageType = 2, annotations will be stored in batches. All operations impact
    each batch (Example a PUT operation will replace all annotations in a batch).
    By default each document have 1 annotation batch. To have multiple batches,
    post/put batch of annotations using batchFormat = 1, and use common section to
    to identify uniquely a batch. Fields "doc_id_batch", "file_fs_id_batch" are reserved,
    thus will be ignored if added in common section.

    :param document_id: The id of the document from which we want to access
                        multiple annotations

    :POST Create annotations in batch.:
        :Request:

            :preconditions:

               All must be valid annotations.
               If one annotation fails, it will return an error message and
               fail all create.
            :params supported:

                |   batchFormat = 0,1
                |   storageType = 1,2
            :params default:

                |   batchFormat = 1
                |   storageType = 1
        :Response json:

            |    returns {"nInserted":nbAnnotationsInserted}

            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :PUT Updates annotations related for the document.:
        :Request:

            When we update we replace old contents with new ones. jsonSelect

            :params supported:
                |    jsonSelect (only contains contents in the "common" fields for storageType = 2.)
                |    storageType = 2

            :params default:

                |    storageType = 2
                |    jsonSelect = {}
        :Response json:
            |    Returns number of annotations deleted
            |    {"nDeleted":nbAnnotationsDeleted}

            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :DELETE Deletes annotations related for the document.:
        :Request:

            :params supported:

                |    jsonSelect
                |    storageType = 1,2
            :params default:

                |    storageType = 1
                |    jsonSelect = {}
        :Response json:
            |    Returns number of annotations deleted
            |    {"nDeleted":nbAnnotationsDeleted}

            :http status code:
                |    OK: 200
                |    Error: See Error Codes

    :GET Returns annotations for the current document.:
        :Request:

            :params supported:

                |    jsonSelect
                |    storageType = 0,1,2
                |    batchFormat = 0

            :params default:
                |    batchFormat = 0
                |    storageType = 0
                |    jsonSelect = {}
        :Response json:

            An array of annotations check batch format for how they will be
            formatted.

            :http status code:
                |    OK: 200
                |    Error: See Error Codes


    """
    man = AnnotationManager()

    try:
        hac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "HumanAnnotationCollection")
        man.addStorageCollection(AnnotationManager.HUMAN_STORAGE, hac)
        bac = settings.GetConfigValue("ServiceStockageAnnotations",
                                      "BatchAnnotationCollection")
        man.addStorageCollection(AnnotationManager.BATCH_STORAGE, bac)
        man.connect()

        jsonSelect = request.args.get('jsonSelect')
        storageType = request.args.get('storageType')
        batchFormat = request.args.get('batchFormat')

        # Note for batch operations all ids are replaced in man
        if request.method == 'GET':
            try:
                if not jsonSelect:
                    jsonSelect = {}
                else:
                    jsonSelect = json.loads(jsonSelect)
                if not storageType:
                    storageType = 0
                else:
                    storageType = int(storageType)
                if not batchFormat:
                    batchFormat = 0
                else:
                    batchFormat = int(batchFormat)
            except Exception as e:
                raise (StorageRestExceptions(5))
            batch = man.getAnnotationS([document_id], jsonSelect, batchFormat,
                                       storageType)
            return jsonify(batch)

        elif request.method == 'PUT':
            logger.logUnknownDebug("Update Annotations", " For document Id: {0}".format(document_id))
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request", "", "")

        elif request.method == 'POST':
            jsonBatch = request.json
            try:
                if not storageType:
                    storageType = 1
                else:
                    storageType = int(storageType)
                if not batchFormat:
                    batchFormat = 1
                else:
                    batchFormat = int(batchFormat)
                logger.logUnknownDebug("Create Annotations",
                                       " For document Id: {0} StorageType :{1},BatchFormat:{2}, jsonBatch: {3}".format(
                                           document_id, str(storageType), str(batchFormat), str(jsonBatch)))
            except Exception as e:
                raise (StorageRestExceptions(5))

            nbAnnotationsCreated = man.createAnnotationS(jsonBatch,
                                                         document_id,
                                                         batchFormat,
                                                         storageType)
            return jsonify({"nCreated": nbAnnotationsCreated})

        elif request.method == 'DELETE':
            # Whenever it is true or false we don't care, if there is no
            # exception
            try:
                logger.logUnknownDebug("Delete Annotations", " For document Id: {0}".format(document_id))
                if not jsonSelect:
                    jsonSelect = {}
                else:
                    jsonSelect = json.loads(jsonSelect)
                if not storageType:
                    storageType = 0
                else:
                    storageType = int(storageType)
            except Exception as e:
                raise (StorageRestExceptions(5))

            nbAnnotationsDeleted = man.deleteAnnotationS([document_id],
                                                         jsonSelect,
                                                         storageType)
            logger.logUnknownDebug("Delete Annotations",
                                   " Number of deleted annotations {0} For document Id: {1}".format(
                                       str(nbAnnotationsDeleted), document_id))
            return jsonify({"nDeleted": nbAnnotationsDeleted}), 200
        else:
            return error_response(http.HTTPStatus.BAD_REQUEST, "Bad Request", "", "")

    except Exception as e:
        return _processCommonException(e)
    finally:
        man.disconnect()
示例#14
0
class TestAnnotationsManager(unittest.TestCase):
    d = None

    def setUp(self):
        settings.Settings.Instance().LoadConfig(
            os.path.join(os.path.dirname(__file__), "..", "..", "configs", "test", "config.ini"))

        c = MongoClient(settings.GetConfigValue("ServiceStockageAnnotations", "MONGO_HOST"),
                        int(settings.GetConfigValue("ServiceStockageAnnotations", "MongoPort")),
                        connect=False)
        c.drop_database(settings.GetConfigValue("ServiceStockageAnnotations", "MongoDb"))
        c.close()
        self.d = AnnotationManager()
        self.d.setCollection(settings.GetConfigValue("ServiceStockageAnnotations", "HumanAnnotationCollection"))
        self.d.addStorageCollection(1,
                                    settings.GetConfigValue("ServiceStockageAnnotations", "HumanAnnotationCollection"))
        self.d.addStorageCollection(2,
                                    settings.GetConfigValue("ServiceStockageAnnotations", "BatchAnnotationCollection"))
        self.d.connect()

    def test_connect(self):
        self.assertEqual(self.d.isConnected(), True)

    def l(self, strContent):
        # shortcut to load json
        return json.loads(strContent)

    def test_createAnnotationsS(self):
        jsonBatch = self.l('{"common":{"@context":"test"},"data":[{"a":1},{"b":2}]}')
        id = self.d.createMongoDocument(self.l('{"@context":"testing_context"}'))
        self.assertRaises(AnnotationException, lambda: self.d.createAnnotationS(jsonBatch, "yolo", 1, 1))  # bad id
        self.assertRaises(AnnotationException, lambda: self.d.createAnnotationS(jsonBatch, id, 1, 3))  # bad storage
        self.assertRaises(AnnotationException, lambda: self.d.createAnnotationS(jsonBatch, id, 1, 0))  # bad storage
        self.assertRaises(AnnotationException, lambda: self.d.createAnnotationS(jsonBatch, id, 2, 1))  # Bad format
        self.assertEqual(0, self.d.createAnnotationS(self.l("{}"), id))
        jsonInvalidBatch = self.l('{"data":[{"a":1,"@context":"test"},{"b":2}]}')
        self.assertRaises(AnnotationException, lambda: self.d.createAnnotationS(jsonInvalidBatch, id, 1, 1))
        jsonBatch = self.l('{"data":[{"a":1,"@context":"test"},{"b":2,"@context":"test"}]}')
        resDifferentBatchFormat = self.d.createAnnotationS(jsonBatch, id, 0, 2)
        self.assertEqual(2, resDifferentBatchFormat,
                         "Expected to get 2, but got {0} created with batch format 0".format(resDifferentBatchFormat))

    def test_getAnnotationsS(self):
        id = self.d.createMongoDocument(self.l('{"@context":"testing_context"}'))
        id2 = self.d.createMongoDocument(self.l('{"@context":"testing_context"}'))
        jsonBatch = self.l('{"common":{"@context":"test"},"data":[{"a":1,"b":1},{"a":2,"b":1}]}')
        jsonBatch2 = self.l('{"common":{"@context":"test"},"data":[{"a":1,"c":1},{"a":2,"c":1}]}')
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch, id, 1, 1))
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch2, id2, 1, 1))
        #
        res = self.d.getAnnotationS([id], {}, 0, 1)
        self.assertEqual(2, len(res["data"]))
        res = self.d.getAnnotationS([id], {"a": 1}, 0, 1)
        self.assertEqual(1, len(res["data"]),
                         "Filter a:1 for one docs should return 1 result. Results: {0}".format(str(res)))

        res = self.d.getAnnotationS([id, id2], {"a": 1}, 0, 1)
        self.assertEqual(2, len(res["data"]),
                         "Filter a:1 for two docs should return 2 result. Results: {0}".format(str(res)))

        largeJsonBatch = self.l(
            '{"common":{"@context":"test"},"data":[{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3},{"e":1},{"e":2},{"e":3}]}')

        self.assertEqual(27, self.d.createAnnotationS(largeJsonBatch, id2, 1, 1))
        res = self.d.getAnnotationS([id, id2], {"e": {"$gt": 0}}, 0, 1)
        self.assertEqual(27, len(res["data"]),
                         "Filter e:1 for largebatch should return 27 result. Returned: {0}".format(len(res["data"])))
        # testing by getting
        # Change for large batch
        largeJsonBatch1 = self.l(
            '{"common":{"@context":"test","k":1},"data":[{"a":1,"b":1},{"a":2,"b":1},{"a":3,"b":1}]}')
        largeJsonBatch2 = self.l('{"common":{"@context":"test","k":2},"data":[{"a":4,"c":1},{"a":5,"c":1}]}')
        largeJsonBatch3 = self.l(
            '{"common":{"@context":"test","k":2},"data":[{"a":1,"c":1},{"a":2,"c":1},{"a":3,"c":1},{"a":4,"c":1}]}')
        # id, 2 batches total 5 anno
        # id2, 1 batch total 4 anno 
        self.assertEqual(3, self.d.createAnnotationS(largeJsonBatch1, id, 1, 2))
        self.assertEqual(2, self.d.createAnnotationS(largeJsonBatch2, id, 1, 2))
        self.assertEqual(4, self.d.createAnnotationS(largeJsonBatch3, id2, 1, 2))
        # get all annotations in both documents
        res = self.d.getAnnotationS([id, id2], {}, 0, 2)
        self.assertEqual(9, len(res["data"]))
        # get all annotations of doc with id
        res = self.d.getAnnotationS([id], {}, 0, 2)
        self.assertEqual(5, len(res["data"]))
        res = self.d.getAnnotationS([id], {"k": 2}, 0, 2)
        self.assertEqual(2, len(res["data"]))
        # get all batch annotations with key k = 2 for both documents
        res = self.d.getAnnotationS([id, id2], {"k": 2}, 0, 2)
        self.assertEqual(6, len(res["data"]))

    def test_deleteAnnotationsS(self):
        id = self.d.createMongoDocument(self.l('{"@context":"testing_context"}'))
        jsonBatch = self.l('{"common":{"@context":"test"},"data":[{"a":1},{"b":2}]}')
        jsonLargeBatch1 = self.l('{"common":{"@context":"test","batch":1},"data":[{"a":1},{"b":2}]}')
        jsonLargeBatch2 = self.l('{"common":{"@context":"test","batch":2},"data":[{"a":1},{"b":2}]}')
        self.assertEqual(0, self.d.deleteAnnotationS([id], {}))
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch, id))
        self.assertEqual(2, self.d.deleteAnnotationS([id], {}))
        self.assertEqual(2, self.d.createAnnotationS(jsonBatch, id, 1, 1))
        self.assertEqual(2, self.d.createAnnotationS(jsonLargeBatch1, id, 1, 2))
        res = self.d.deleteAnnotationS([id], {}, 1)
        self.assertEqual(2, res, "Should only delete 2 since we created 2 per storage type, but we got {0}".format(res))
        res = self.d.deleteAnnotationS([id], {}, 2)
        self.assertEqual(1, res, "Should delete 1 since we only have one batch".format(res))
        self.assertEqual(2, self.d.createAnnotationS(jsonLargeBatch1, id, 1, 2))
        self.assertEqual(2, self.d.createAnnotationS(jsonLargeBatch2, id, 1, 2))
        res = self.d.deleteAnnotationS([id], {"batch": 1}, 2)
        self.assertEqual(1, res, "Should delete 1 (only the first batch of 2 batches) we got {0}".format(res))