예제 #1
0
    def import_model(model_id, source):
        """
        Obtiene los archivos de modelo, los descomprime y obtiene el diccionario de
        configuración del modelo remoto solicitado.

        :model_id: [String] - Id del modelo a importar.

        :return: [Dict] - Dicionario con la configuración del modelo.
        """
        try:
            local_path = '%s/%s/%s' % (CURRENT_BASE_PATH, MODEL_MANAGER_ROOT_DIR, model_id)
            model_cfg_file = '%s/%s' % (local_path, MODEL_CONFIG_FILE_NAME)
            if source['remote']:
                remote_repo_url = '%s/%s%s' % (source['path'], model_id, MODEL_IMPORT_EXT)
                Logger.log('L-0134', [{'text': remote_repo_url, 'color': HIGHLIGHT_COLOR}])
                Repo.clone_from(remote_repo_url, local_path)
            else:
                Logger.log('L-0140', [{'text': source['path'], 'color': HIGHLIGHT_COLOR}])
                copy_dir(source['path'], local_path)
            Logger.log('L-0147')
            Logger.log('L-0154')
            unzip_model(local_path, model_id)
            remove_files(local_path, '%s%s' % (model_id, MODEL_PACKAGING_EXTENSION))
            remove_files(local_path, '%s' % MODEL_TMP_JOINT_FILE_NAME)
            Logger.log('L-0161')
            return load_json_file(model_cfg_file)
        except Exception as e:
            ErrorHandler.raise_error('E-0119', [{'text': e, 'color': ERROR_COLOR}])
예제 #2
0
    def generate_model(self, model_id, model_name, description, author, tokenizer_exceptions, max_dist):
        """
        Crea un nuevo modelo a partir de los datos provistos. El modelo no debe existir previamente.

        :model_id: [String] - Id. del modelo.

        :model_name: [String] - Nombre del modelo (actua como Id).

        :model_path: [String] - Directorio base para el modelo.

        :descripcion: [String] - Descripcion del modelo.

        :author: [String] - Nombre del autor del modelo.

        :tokenizer_exceptions: [Dict] - Conjunto de excepciones a agregar al tokenizer del nuevo modelo.
        """
        Logger.log('L-0001')
        if self.__model_manager.get_model(model_id):
            ErrorHandler.raise_error('E-0025')
        if not validate_model_seed(tokenizer_exceptions):
            ErrorHandler.raise_error('E-0026')
        tokenizer_exceptions_path = self.__tokenizer_rules_generator.generate_model_data(tokenizer_exceptions, model_id, max_dist)
        analyzer_rule_set = self.__analyzer_rules_generator.create_analyzer_rule_set(tokenizer_exceptions)
        self.__model_manager.create_model(model_id, model_name, description, author, tokenizer_exceptions_path, analyzer_rule_set)
        Logger.log('L-0034')
        if remove_dir(tokenizer_exceptions_path, True):
            Logger.log('L-0035')
예제 #3
0
    def save_model(model, path, tmp_files_path, new_model):
        """
        Guarda el modelo en el path solicitado.

        :model: [SpacyModelRef] - Referencia a un modelo de spacy.

        :path: [String] - Ruta en la cual guardar el modelo.

        :tmp_files_path: [String] - Ruta donde se encuentran los archivos temporales del modelo.

        :new_model: [Model] - Objeto que representa el nuevo modelo.
        """
        Logger.log('L-0030')
        base_path = build_path(MODEL_MANAGER_ROOT_DIR, path)
        if check_dir_existence(base_path):
            ErrorHandler.raise_error('E-0030')
        model_storage_path = get_absoulute_path(base_path)
        model.to_disk(model_storage_path)
        custom_model_files_path = build_path(base_path, MODEL_MANAGER_CUSTOM_FILES_DIR)
        create_dir_if_not_exist(custom_model_files_path)
        model_seed_path = build_path(tmp_files_path, TOKEN_RULES_GEN_MODEL_SEED_FILENAME)
        model_seed_copy_path = build_path(custom_model_files_path, TOKEN_RULES_GEN_MODEL_SEED_FILENAME, add_absolute_root=True)
        copy_file(model_seed_path, model_seed_copy_path, is_absolute_path=True)
        cfg_file_path = build_path(model_storage_path, MODEL_CONFIG_FILE_NAME)
        dictionary_to_disk(cfg_file_path, {
            'model_name': new_model.get_model_name(),
            'description': new_model.get_description(),
            'author': new_model.get_author(),
            'analyzer_rule_set': new_model.get_analyser_rules_set()
        }, True)
        Logger.log('L-0032')
예제 #4
0
    def edit_model_data(self, model_id, new_model_name=None, new_description=None):
        """
        Edita los datos de un modelo existente. Si el modelo no existe u ocurre algún error durante
        la edición de sus datos devolverá false.

        :model_id: [String] - Nombre actual del modelo.

        :new_model_name: [String] - Nuevo nombre a asignar al modelo.

        :new_description: [String] - Nueva descripción para el modelo.
        """
        Logger.log('L-0074')
        current_model = self.__model_manager.get_model(model_id)
        if current_model is None:
            ErrorHandler.raise_error('E-0074')
        current_model_name = current_model.get_model_name()
        edited_model_name = new_model_name
        current_description = current_model.get_description()
        edited_description = new_description
        if new_model_name is None or new_model_name == '':
            edited_model_name = current_model_name
        if new_description is None or new_description == '':
            edited_description = current_description
        if edited_model_name == current_model_name and edited_description == current_description:
            ErrorHandler.raise_error('E-0075')
        self.__model_manager.edit_model(model_id, edited_model_name, edited_description)
예제 #5
0
    def generate_model_data(self, model_seed, path, max_dist):
        """
        A partir de una model_seed, crea los archivos de configuración para modificar el tokenizer
        de un modelo de spacy. 

        :model_seed: [Dict] - Semilla para la creación del modelo.

        :base_path: [String] - Directorio base del modelo.

        :max_dist: [int] - Distancia de demerau levenshtein máxima para las deformaciones a los token.
        """
        base_path = build_path(TOKEN_RULES_GEN_TMP_ROOT_PATH, path)
        if check_dir_existence(base_path):
            ErrorHandler.raise_error('E-0027')
        Logger.log('L-0003')
        create_dir_if_not_exist(base_path)
        self.__save_model_seed(model_seed, base_path)
        nouns_path = build_path(base_path, TOKEN_RULES_GEN_TYPE_NOUN)
        create_dir_if_not_exist(nouns_path)
        verbs_path = build_path(base_path, TOKEN_RULES_GEN_TYPE_VERB)
        create_dir_if_not_exist(verbs_path)
        self.__generate_noun_rules(model_seed['nouns'], max_dist, nouns_path)
        self.__generate_verb_rules(model_seed['verbs'], max_dist, verbs_path)
        Logger.log('L-0004')
        return get_absoulute_path(base_path)
예제 #6
0
    def save_model_data(model_id, model_name, description, author, path,
                        analyser_rules_set):
        """
        Guarda información de un modelo.

        :model_id: [String] - Id del modelo.

        :model_name: [String] - Nombre del modelo (actua como id).

        :description: [String] - Descripción del modelo.

        :author: [String] - Nombre del creador del modelo.

        :path: [String] - Ruta relativa para encontrar el modelo.

        :analyser_rules_set: [List(Dict)] - Lista de reglas para el analizador
        """
        Logger.log('L-0026')
        if ModelDataManager.check_existing_model(model_id):
            ErrorHandler.raise_error('E-0029')
        data_dict = {
            'model_id': model_id,
            'model_name': model_name,
            'description': description,
            'author': author,
            'path': path,
            'analyzer_rules_set': analyser_rules_set
        }
        db_insert_item(MODEL_MANAGER_DB, MODEL_MANAGER_MODELS_COLLECTION,
                       data_dict)
        Logger.log('L-0029')
예제 #7
0
 def task_init_hook(self):
     """
     Método hook para completar el template de inicializadion en el padre.
     """
     try:
         adminModule = AdminModuleController()
         adminModule.load_model(self.__model_id)
         for file in self.__files:
             if not validate_file(file):
                 ErrorHandler.raise_error('E-0096')
             file_text = file.read()
             analysis_task = TextAnalysisTask(-1, self.__model_id,
                                              file_text,
                                              self.__only_positives)
             analysis_task.add_observer(self)
             self.__analysis_tasks.append({
                 'file': get_file_name(file),
                 'task': analysis_task
             })
             analysis_task.init()
         while not self.__check_task_finalized():
             time.sleep(5)
         self.set_results(self.__build_results())
     except Exception as e:
         error = ErrorHandler.get_error_dict(e)
         self.set_error_data(error)
예제 #8
0
    def get_examples_history(self, model_id):
        """
        Retorna un listado con todos los ejemplos, sin importar su estado, para un determinado
        modelo.

        :model_id: [String] - Id del modelo.

        :return: [List] - Listado de todos los ejemplos para el modelo solicitado.
        """
        if not self.__find_model(model_id):
            ErrorHandler.raise_error('E-0082')
        results = list([])
        Logger.log('L-0326')
        examples_data = db_get_items(TRAIN_MANAGER_DB,
                                     TRAIN_DATA_EXAMPLES_COLLECTION,
                                     {'model_id': model_id})
        Logger.log('L-0327')
        Logger.log('L-0328')
        for example_data in examples_data:
            example = TrainExample(example_data['example_id'],
                                   example_data['sentence'],
                                   example_data['tags'], example_data['type'],
                                   example_data['status'])
            results.append(example)
        Logger.log('L-0329')
        return results
예제 #9
0
    def update_word_processor_config_theme(self, module_key, theme_name, config_mod, irregular_groups_mod=None):
        """
        Modifica un tema de configuración con los datos provistos. El tema debe existir y no ser el tema
        por defecto. Se modificarse el tema activo actual el comportamiento del modulo se adaptará
        inmediatamente.

        :module_key: [String] - Nombre del submodule del modulo de procesamiento a modificar.

        :theme_name: [String] - Nombre del tema a modificar.

        :config_mod: [Dict] - Opciones actualizadas de la configuración general (no es necesario incluir las
        que no tienen cambio alguno).

        :irregular_groups_mod: [Dict] - Opciones actualizadas de los grupos de verbos irregulares (no es
        necesario incluir los grupos que no tienen cambios).
        """
        if module_key == WORD_PROCESSOR_MODULE_KEY_CONJUGATOR:
            self.__word_processor.update_conjugator_configs(theme_name, config_mod, irregular_groups_mod)
            return
        if module_key == WORD_PROCESSOR_MODULE_KEY_FUZZY_GEN:
            self.__word_processor.update_fuzzy_gen_config(theme_name, config_mod)
            return
        if module_key == WORD_PROCESSOR_MODULE_KEY_NOUN_CONV:
            self.__word_processor.update_noun_conversor_config(theme_name, config_mod)
            return
        ErrorHandler.raise_error('E-0049')
예제 #10
0
    def import_model(self, model_id, source=None):
        """
        Importa un modelo existente desde el repositorio de modelos. No debe existir
        un modelo local con dicho id y, además, el módelo debe existir en el repositorio
        remoto de modelos.

        :model_id: [String] - Id del modelo a importar.

        :source: [Dict] - Fuente de donde obtener el modelo, puede ser un repositorio
        git o un directorio local.
        """
        Logger.log('L-0116')
        model = self.get_model(model_id)
        if model:
            ErrorHandler.raise_error('E-0118')
        if not source:
            source = REMOTE_MODEL_SOURCE
        cfg = ModelLoader.import_model(model_id, source)
        analyzer_exceptions_set_data = cfg['analyzer_exceptions_set']
        Logger.log('L-0179')
        ModelDataManager.save_model_data(model_id, cfg['model_name'], cfg['description'], cfg['author'], model_id, cfg['analyzer_rules_set'])
        remote_model = Model(model_id, cfg['model_name'], cfg['description'], cfg['author'], model_id, cfg['analyzer_rules_set'], [])
        self.__models.append(remote_model)
        for exception in analyzer_exceptions_set_data:
            self.add_analyzer_exception(model_id, exception['base_form'], exception['token_text'], exception['enabled'])
        Logger.log('L-0188')
        Logger.log('L-0197')
예제 #11
0
def db_update_many(db_name, col_name, query, updated_item):
    try:
        search_query = query if query is not None else {}
        col = get_collection(db_name, col_name)
        return col.update_many(search_query, {'$set': updated_item})
    except:
        ErrorHandler.raise_error('E-0008')
예제 #12
0
def db_get_autoincremental_id(col_name):
    try:
        col = get_collection(DB_GENERAL_SETTINGS_DB, DB_AUTOINCREMENTAL_ID_COL)
        next_entry = col.find_and_modify({'collection': col_name},
                                         {'$inc': {
                                             'next_id': 1
                                         }}, True)
        return next_entry['next_id'] if next_entry else 1
    except Exception as e:
        ErrorHandler.raise_error('E-0117', [{'text': e, 'color': ERROR_COLOR}])
예제 #13
0
 def initiate_default_model():
     """
     Inicializa un instancia del modelo por defecto.
 
     :return: [SpacyModelRef] - Referencia al modelo de spacy
     """
     try:
         default_nlp_model = spacy.load(MODEL_MANAGER_DEFAULT_BASE_MODEL)
         return default_nlp_model
     except:
         ErrorHandler.raise_error('E-0028')
예제 #14
0
    def train_model(self, model, examples):
        """
        Aplica un set de ejemplos de entrenamiento a un modelo.

        :model: [Model] - Id del modelo sobre el cual aplicar el set de ejemplos.

        :examples: [List] - Lista de ejemplos de entrenamiento
        """
        if not model:
            ErrorHandler.raise_error('E-0090')
        annotations = self.__build_annotations(examples)
        model.train_model(annotations)
예제 #15
0
    def get_approved_examples(self, model_id):
        """
        Retorna un listado con todos los ejemplos aprobados para un determinado modelo.

        :model_id: [String] - Id del modelo.

        :return: [List] - Lista de los ejemplos aprobados.
        """
        model_train_data = self.__find_model(model_id)
        if not model_train_data:
            ErrorHandler.raise_error('E-0081')
        return model_train_data.get_approved_examples()
예제 #16
0
    def get_task_status(self, task_id):
        """
        Devuelve el status de una tarea, la misma debe existir en la cola de tareas.

        :task_id: [int] - Id de la tarea a buscar

        :return: [Dict] - Diccionario con el estado de la tarea.
        """
        founded_task = self.__get_task(task_id)
        if founded_task is None:
            ErrorHandler.raise_error('E-0097')
        return founded_task.get_task_status_data()
예제 #17
0
    def sanitize_text_for_analysis(text=''):
        """
        Elimina los caracteres no deseados que pueda tener un texto.

        :text: [String] - Texto a preparar.

        :return: [String] - Texto prepatado para el análisis.
        """
        if not isinstance(text, str):
            ErrorHandler.raise_error('E-0094')
        sanitized_text = text.replace('\n', ' ')
        sanitized_text = sanitized_text.replace('\t', ' ')
        return sanitized_text
예제 #18
0
    def get_pending_examples(self, model_id):
        """
        Retorna un listado con todos los ejemplos que tienen su aprobación / rechazo aún
        pendiente para un determinado modelo.

        :model_id: [String] - Id del modelo.

        :return: [List] - Lista de los ejemplos pendientes de una decisión.
        """
        model_train_data = self.__find_model(model_id)
        if not model_train_data:
            ErrorHandler.raise_error('E-0083')
        return model_train_data.get_pending_examples()
예제 #19
0
    def __validate_examples(self, examples):
        """
        Valida un ejemplo de entrenamiento.

        :example: [List] - Ejemplo de entrenamiento a validar.
        """
        for example in examples:
            if not validate_data(TRAIN_MANAGER_SCHEMAS['TRAIN_DATA'], example):
                ErrorHandler.raise_error('E-0086')
            for tag in example['tags']:
                tag_entity = tag['entity']
                if not self.__custom_entity_manager.validate_tag(tag_entity):
                    ErrorHandler.raise_error('E-0087')
예제 #20
0
    def load_model(path):
        """
        Carga el modelo a partir del path.

        :path: [String] - Ruta para acceder al modelo.

        :return: [SpacyModelRef] - Referencia al modelo de spacy, None si no se pdo cargar el modelo.
        """
        try:
            full_path = build_path(MODEL_MANAGER_ROOT_DIR, path, add_absolute_root=True)
            nlp_model = spacy.load(full_path)
            return nlp_model
        except:
            ErrorHandler.raise_error('E-0092')
예제 #21
0
    def remove_model_data(model_id):
        """
        Elimina la entrada para un modelo.

        :model_id: [String] - Id del modelo a eliminar.
        """
        Logger.log('L-0066')
        model_delete_count = db_delete_item(MODEL_MANAGER_DB,
                                            MODEL_MANAGER_MODELS_COLLECTION, {
                                                'model_id': model_id
                                            }).deleted_count
        if model_delete_count <= 0:
            ErrorHandler.raise_error('E-0072')
        db_delete_items(MODEL_MANAGER_DB, ANALYZER_EXCEPTIONS_COLLECTION,
                        {'model_id': model_id})
예제 #22
0
def overwrite_json_file(path_from_root, content):
    """
    Sobreescribe el archivo indicado con el contenido del diccionario recibido.

    :path_from_root: cadena con la ruta relativa a la raíz.

    :content: diccionario con el contenido a escribir en el archivo.
    """
    try:
        absolute_path = get_absoulute_path(path_from_root)
        file = open(absolute_path, 'w')
        file.write(content)
        file.close()
    except Exception as e:
        ErrorHandler.raise_error('E-0014', [{'text': e, 'color': ERROR_COLOR}])
    def discard_training_examples(self, examples_id_list):
        """
        Rechaza el conjunto de ejemplos de entrenamiento que tienen los ids especificados en la lista
        de ids provista. Todos los ids provistos deben existir, de lo contrario, no se descartará
        ninguno.

        :examples_id_list: [List(int)] - Listado con los ids de los ejemplos a rechazar.

        :return: [List(dict)] - Listado indicando los ejemplos de entrenamiento que se han podido
        rechazar y los que no.
        """
        Logger.log('L-0314')
        results = list([])
        for example_id in examples_id_list:
            status = False
            error = None
            try:
                self.__train_data_manager.discard_example(example_id)
                status = True
            except Exception as e:
                error = ErrorHandler.get_error_dict(e)
            finally:
                results.append({
                    'example_id': example_id,
                    'status': status,
                    'error': error
                })
        Logger.log('L-0315')
        return results
    def add_training_examples(self, model_id, examples_list):
        """
        Agrega una lista de ejemplos de entrenamiento. Para que la operación sea exitosa todos los
        ejemplos deben poder ser validados correctamente, en caso contrario no se añadirá ninguno.

        :model_id: [String] - Id del modelo al cual se aplicará el ejemplo.

        :examples_list: [List(Dict)] - Listado de ejemplos de entrenamiento.
        """
        Logger.log('L-0292')
        model = self.__model_manager.get_model(model_id)
        if model is None:
            ErrorHandler.raise_error('E-0084')
        self.__train_data_manager.add_training_examples(
            model_id, examples_list)
        Logger.log('L-0295')
    def approve_traning_examples(self, examples_id_list):
        """
        Aprueba un conjunto de ejemplos de entrenamiento cuyos ids se encuentran en la lista de 
        ids provista. Si alguno de los ids en la lista no existe la operación no se realizará para
        ningún ejemplo.

        :examples_id_list: [List(int)] - Lista con los ids de los ejemplos de entrenamiento a aprobar.

        :return: [List(dict)] - Listado indicando los ejemplos de entrenamiento que se han podido
        aceptar y los que no.
        """
        Logger.log('L-0305')
        results = list([])
        for example_id in examples_id_list:
            status = False
            error = None
            try:
                self.__train_data_manager.approve_example(example_id)
                status = True
            except Exception as e:
                error = ErrorHandler.get_error_dict(e)
            finally:
                results.append({
                    'example_id': example_id,
                    'status': status,
                    'error': error
                })
        Logger.log('L-0306')
        return results
예제 #26
0
def unzip_model(model_path, model_id):
    """
    Descomprime un modelo importado a partir del directorio donde se encuentra
    descargado.

    :model_path: [String] - Directorio donde se encuentran los archivos de modelo.
    """
    try:
        join_zip_model(model_path, model_id)
        model_main_file = '%s%s%s' % (model_path, DIR_PATH_SEPARATOR,
                                      MODEL_TMP_JOINT_FILE_NAME)
        zip_ref = ZipFile(model_main_file, 'r')
        zip_ref.extractall(model_path)
        zip_ref.close()
    except Exception as e:
        ErrorHandler.raise_error('E-0120', [{'text': e, 'color': ERROR_COLOR}])
예제 #27
0
def remove_dir(path_from_root, is_absolute_path=False):
    """
    Elimina el directorio indicado en path del disco.

    :path_from_root: [String] - Ruta relativa al directorio.

    :return: [boolean] - True si el borrado se realizo con exito, False en caso contrario.
    """
    try:
        if not is_absolute_path:
            absolute_path = get_absoulute_path(path_from_root)
            shutil.rmtree(absolute_path)
        else:
            shutil.rmtree(path_from_root)
    except Exception as e:
        ErrorHandler.raise_error('E-0015', [{'text': e, 'color': ERROR_COLOR}])
예제 #28
0
def load_json_file(path_from_root):
    """
    Lee el contenido de un archivo a partir de la ruta relativa a la raíz
    y devuelve su contenido como un diccionario.

    :path_from_root: cadena con la ruta relativa a la raíz.

    :return: diccionario conteniendo el contenido del archivo json
    """
    try:
        with open(path_from_root) as f:
            parsedDict = json.loads(f.read())
        f.close()
        return parsedDict
    except Exception as e:
        ErrorHandler.raise_error('E-0013', [{'text': e, 'color': ERROR_COLOR}])
예제 #29
0
    def __process_incoming_request(self, action, task_check=None):
        """
        Procesa una solicitud entrante al sistema.

        :action: [Function] - Acción a realizar.

        :task_check: [List] - Validaciones a realizar en el administrador de tareas.
        """
        if not self.is_ready():
            return self.__build_response_object(False, error=ErrorHandler.get_error('E-0073', []))
        if task_check:
            if self.__task_manager.check_model_creation_tasks([TASK_KEYS_WORD_PROCESSOR]):
                return self.__build_response_object(False, error=ErrorHandler.get_error('E-0031', []))
        try:
            return action()
        except Exception as e:
            return self.__build_response_object(False, error=ErrorHandler.get_error_dict(e))
예제 #30
0
 def __init(self, available_models):
     """
     Inicializa el modulo.
     """
     try:
         Logger.log('L-0247')
         Logger.log('L-0248')
         for model in available_models:
             model_train_data = ModelTrainData(model, [])
             self.__models.append(model_train_data)
         Logger.log('L-0249')
         Logger.log('L-0250')
         examples_query = {
             '$and': [{
                 'status': {
                     '$ne': TRAIN_EXAMPLE_STATUS_APPLIED
                 }
             }, {
                 'status': {
                     '$ne': TRAIN_EXAMPLE_STATUS_REJECTED
                 }
             }]
         }
         training_examples = db_get_items(TRAIN_MANAGER_DB,
                                          TRAIN_DATA_EXAMPLES_COLLECTION,
                                          examples_query)
         Logger.log('L-0251')
         Logger.log('L-0252')
         for training_example in training_examples:
             model_id = training_example['model_id']
             model_train_data = self.__find_model(model_id)
             if model_train_data is not None:
                 model_train_data.add_training_example(training_example)
         Logger.log('L-0253')
         self.__custom_entity_manager = CustomEntityTagManager()
         if self.__custom_entity_manager.is_ready():
             Logger.log('L-0254')
             self.__init_success = True
             return
         Logger.log('L-0255')
     except Exception as e:
         self.__init_success = False
         ErrorHandler.raise_error('E-0023', [{
             'text': e,
             'color': ERROR_COLOR
         }])