def internal_error500(error): logger.logUnknownError( "Annotation Storage REST Service Unknown Critical" " Error", str(error), 50000) return error_response(httplib.INTERNAL_SERVER_ERROR, "Internal Server Error", "", "Server can not currently process requests")
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(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e)
def _processCommonException(e): """ This function is used to generate exception codes. It will create absolute codes for reference """ if (isinstance(e, StorageException)): return error_response(httplib.SERVICE_UNAVAILABLE, "Service Unavailable", 53000 + e.code, "Error connecting to the backend storage") elif (isinstance(e, MongoDocumentException)): if (e.code == 0): return error_response(httplib.INTERNAL_SERVER_ERROR, "Internal Server Error", 52000, "Server can not currently process requests") else: return error_response(httplib.UNPROCESSABLE_ENTITY, "Cannot process Entity", 52000 + e.code, str(e)) elif (isinstance(e, AnnotationException)): if (e.code == 0): return error_response(httplib.INTERNAL_SERVER_ERROR, "Internal Server Error", 51000, "Server can not currently process requests") else: return error_response(httplib.UNPROCESSABLE_ENTITY, "Cannot process Entity", 51000 + e.code, str(e)) elif (isinstance(e, StorageRestExceptions)): if (e.code == 2 or e.code == 3): return error_response(httplib.NOT_FOUND, "Not Found", 50100 + e.code, str(e)) else: return error_response(httplib.UNPROCESSABLE_ENTITY, "Cannot process entity", 50100 + e.code, str(e)) elif (isinstance(e, BadRequest)): # Flask error return error_response(httplib.BAD_REQUEST, "Bad Request", "", "") else: logger.logUnknownError("Annotation Storage REST Service Unknown Error", str(e), 50000) return error_response(httplib.INTERNAL_SERVER_ERROR, "Internal Server Error", "", "Server can not currently process requests")
def annotationSchema(schema_id): """ :route: **/annotationSchema/<schema_id>** Used to store annotation schemas. Same implementation as for the document. """ man = StorageManager() try: man.setCollection( settings.GetConfigValue("ServiceStockageAnnotations", "SchemaCollection")) man.connect() if request.method == 'GET': logger.logUnknownDebug("Get Schema", "Id: {0}".format(schema_id)) doc = man.getMongoDocument(schema_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"] != schema_id: raise (StorageRestExceptions(1)) else: logger.logUnknownDebug("Update Schema", "Id: {0}".format(schema_id)) docId = man.updateMongoDocument(request.json) if (docId is None): raise (StorageRestExceptions(3)) return jsonify({"id": docId}) elif request.method == 'DELETE': logger.logUnknownDebug("Delete Schema", "Id: {0}".format(schema_id)) man.deleteMongoDocument(schema_id) # Whenever it is true or false we don't care, if there is no # exception return jsonify({}), 204 else: return error_response(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e)
def createAnnotationSchema(): """ :route: **/annotationSchema** Used to store Annotation schemas Same implementation as for the document. """ man = DocumentManager() try: man.setCollection( settings.GetConfigValue("ServiceStockageAnnotations", "SchemaCollection")) man.connect() if request.method == 'POST': docId = man.createMongoDocument(request.json) logger.logUnknownDebug("Create Schema", "Id: {0}".format(docId)) return jsonify({"id": docId}), 201 else: return error_response(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e)
def createDocument(): """ :route: **/document** :POST creates a new document: :Request: :: Preconditions: Here are the minimum required elements by the document. { @context: context describing the format of the document } All the other parameters will be saved as is. Erases "_id", "id" fields if they exists. :Response: Same as in, plus creates a field "id" to identify the document :http status code: | OK: 200 | Error: See Error Codes """ man = DocumentManager() try: man.setCollection( settings.GetConfigValue("ServiceStockageAnnotations", "documentCollection")) man.connect() if request.method == 'POST': docId = man.createMongoDocument(request.json) logger.logUnknownDebug("Create Document", "Id: {0}".format(docId)) return jsonify({"id": docId}), 201 else: return error_response(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e)
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(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e)
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 = simplejson.loads(jsonSelect) if not storageType: storageType = 0 else: storageType = int(storageType) if not batchFormat: batchFormat = 0 else: batchFormat = int(batchFormat) except Exception, 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(httplib.BAD_REQUEST, "Bad Request", "", "")
def document(document_id): """ :route: **/document/<document_id>** Get/Put/Delete for the documents. :param document_id: The id of the document we want to access :GET returns a document: :Response JSON: Here are minimum document contents: :: { id: Id of the document = document_id @context: Complex object containing JSON_LD info. } Other custom fields which were created would be returned too. :http status code: | OK: 200 | Error: See Error Codes :PUT updates a document by replacing whole document contents: :Request: The document must exists and contains the following contents at minimum: :: { id: Id of the document = document_id @context: Complex object containing JSON_LD info. } Other custom fields which were created would be saved too. Erases "_id" field. :Response: :http status code: | OK: 200 | Error: See Error Codes :DELETE deletes the document. If the document not found do nothing.: :Response JSON: {} :http status code: | OK: 200 | Error: See Error Codes """ man = DocumentManager() try: man.setCollection( settings.GetConfigValue("ServiceStockageAnnotations", "documentCollection")) man.connect() if request.method == 'GET': logger.logUnknownDebug("Get Document", "Id: {0}".format(document_id)) doc = man.getMongoDocument(document_id) _convStorageIdToDocId(doc) if (doc is None): raise (StorageRestExceptions(2)) else: return jsonify(doc) elif request.method == 'PUT': logger.logUnknownDebug("Update Document", "Document {0}".format(document_id)) doc = request.json _convDocIdToStorageId(doc) if '_id' in doc and doc["_id"] != document_id: raise (StorageRestExceptions(1)) else: docId = man.updateMongoDocument(doc) return jsonify({"id": docId}) elif request.method == 'DELETE': logger.logUnknownDebug("Delete Document", "Id: {0}".format(document_id)) man.deleteMongoDocument(document_id) # Whenever it is true or false we don't care, if there is no # exception return jsonify({}), 204 else: return error_response(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e)
def internal_error400(error): return error_response(httplib.BAD_REQUEST, "Bad Request", "", "")
storageType = 0 else: storageType = int(storageType) except Exception, 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(httplib.BAD_REQUEST, "Bad Request", "", "") except Exception, e: return _processCommonException(e) finally: man.disconnect() # TODO Update @APP.route('/document/<document_id>/annotation', methods=['POST']) 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