Пример #1
0
 def _message_handler(self, message):
     if message.kind == 'pmessage':
         channel_key = re.search(REDIS_GENERAL_CHANNEL % '(.*)',
                                 message.channel)
         channel_callbacks = []
         if channel_key is not None:
             channel_key = channel_key.group(0)
             if channel_key in self._subscribers:
                 channel_callbacks[0] = self._subscribers.get(channel_key)
             else:
                 for subscriber_channel_key in self._subscribers.keys():
                     re_channel_key = subscriber_channel_key.replace(
                         '*', '.*')
                     if re.match(re_channel_key, channel_key):
                         channel_callbacks.append(
                             self._subscribers.get(subscriber_channel_key))
         if len(channel_callbacks):
             for channel_callback in channel_callbacks:
                 try:
                     tornado.ioloop.IOLoop.instance().call_later(
                         callback=channel_callback,
                         delay=0,
                         message=message)
                 except Exception as e:
                     worker_logger.warn('Failed to run channel callback')
                     worker_logger.exception(e)
Пример #2
0
    def _parse_result_get_callback(self,
                                   result_key,
                                   callback_code,
                                   algo_result=False):
        result = self._rq_redis_storage.get_data(result_key)
        worker_logger.debug('Raw result - %s' % result)
        try:
            result = ast.literal_eval(result) if result is not None else {}
        except ValueError as e:
            worker_logger.exception(msg=str(e))
            result = {}
        if algo_result:
            result = result.get('result', False)
        worker_logger.debug('Result dictionary - %s' % result)

        callback = self._subscribed_callbacks.get(callback_code)
        return callback, result
Пример #3
0
def pre_training_helper(images, probe_id, settings, callback_code, try_type, ai_code):
    worker_logger.info('Running training for user - %s, with given parameters - %s' % (settings.get('userID'),
                                                                                       settings))
    ai_response_type = dict()
    try:
        worker_logger.info('Telling AI that we are starting training with code - %s' % ai_code)
        ai_response_type.update({'status': TRAINING_STARTED_STATUS, 'message': TRAINING_STARTED_MESSAGE})
        response_type = base64.b64encode(json.dumps(ai_response_type))
        register_biometrics_url = biomio_settings.ai_rest_url % (REST_REGISTER_BIOMETRICS % (ai_code, response_type))
        response = requests.post(register_biometrics_url)
        try:
            response.raise_for_status()
            worker_logger.info('AI should now know that training started with code - %s and response type - %s' %
                               (ai_code, response_type))
        except HTTPError as e:
            worker_logger.exception(e)
            worker_logger.exception('Failed to tell AI that training started, reason - %s' % response.reason)
    except Exception as e:
        worker_logger.error('Failed to build rest request to AI - %s' % str(e))
        worker_logger.exception(e)
    ai_response_type.update({'status': TRAINING_SUCCESS_STATUS, 'message': TRAINING_SUCCESS_MESSAGE})
    result = False
    error = None
    if AlgorithmsDataStore.instance().exists(key=REDIS_UPDATE_TRAINING_KEY % probe_id):
        settings.update({'database': get_algo_db(probe_id=probe_id)})
        AlgorithmsDataStore.instance().delete_data(key=REDIS_UPDATE_TRAINING_KEY % probe_id)
    temp_image_path = tempfile.mkdtemp(dir=APP_ROOT)
    try:
        image_paths = save_images(images, temp_image_path)

        # Store photos for test purposes
        store_test_photo_helper(APP_ROOT, image_paths)

        settings.update({'data': image_paths})
        settings.update({'general_data': {'data_path': temp_image_path,
                                          'ai_code': ai_code,
                                          'try_type': try_type,
                                          'probe_id': probe_id}})
        return settings
    except:
        final_helper(temp_image_path, probe_id, error, callback_code, result, ai_response_type, try_type, ai_code)
        return None
Пример #4
0
def _tell_ai_training_results(result, ai_response_type, try_type, ai_code):
    if isinstance(result, bool) and result:
        ai_response_type.update(get_ai_training_response(try_type))
    try:
        worker_logger.info('Telling AI that training is finished with code - %s and result - %s' %
                           (ai_code, result))
        response_type = base64.b64encode(json.dumps(ai_response_type))
        register_biometrics_url = biomio_settings.ai_rest_url % (REST_REGISTER_BIOMETRICS %
                                                                 (ai_code, response_type))
        response = requests.post(register_biometrics_url)
        try:
            response.raise_for_status()
            worker_logger.info(
                'AI should now know that training is finished with code - %s and response type - %s' %
                (ai_code, response_type))
        except HTTPError as e:
            worker_logger.exception(e)
            worker_logger.exception(
                'Failed to tell AI that training is finished, reason - %s' % response.reason)
    except Exception as e:
        worker_logger.error('Failed to build rest request to AI - %s' % str(e))
        worker_logger.exception(e)
Пример #5
0
def result_training_helper(algo_result, callback_code, probe_id, temp_image_path, try_type, ai_code):
    ai_response_type = dict()
    ai_response_type.update({'status': TRAINING_SUCCESS_STATUS, 'message': TRAINING_SUCCESS_MESSAGE})
    result = False
    error = None
    try:
        if isinstance(algo_result, dict) and algo_result.get('status', '') == "update":
            # record = dictionary:
            # key          value
            #      'status'     "update"
            #      'userID'     Unique user identificator
            #      'algoID'     Unique algorithm identificator
            #      'database'   BLOB data of user, with userID, for verification algorithm algoID
            #
            # Need update record in algorithms database or create record for user userID and algorithm
            # algoID if it doesn't exists
            database = algo_result.get('database', None)
            if database is not None:
                store_training_db(database, probe_id)
                result = True
                ai_response_type.update(dict(
                    status=TRAINING_SUCCESS_STATUS,
                    message=TRAINING_SUCCESS_MESSAGE
                ))
        elif isinstance(algo_result, list):
            for algo_result_item in algo_result:
                if algo_result_item.get('status', '') == "error":
                    worker_logger.exception('Error during education - %s, %s, %s' % (algo_result_item.get('status'),
                                                                                     algo_result_item.get('type'),
                                                                                     algo_result_item.get('details')))
                    if 'Internal Training Error' in algo_result_item.get('type', ''):
                        error = algo_result_item.get('details', {}).get('message', '')
                        ai_response_type.update(dict(
                            status=TRAINING_RETRY_STATUS,
                            message=TRAINING_RETRY_MESSAGE
                        ))
                    else:
                        ai_response_type.update({'status': 'error'})

                elif algo_result_item.get('status', '') == 'update':
                    database = algo_result_item.get('database', None)
                    if database is not None:
                        store_training_db(database, probe_id)
                        result = True
                        ai_response_type.update(dict(
                            status=TRAINING_SUCCESS_STATUS,
                            message=TRAINING_SUCCESS_MESSAGE
                        ))
            # record = dictionary:
            # key          value
            #      'status'     "error"
            #      'type'       Type of error
            #      'userID'     Unique user identificator
            #      'algoID'     Unique algorithm identificator
            #      'details'    Error details dictionary
            #
            # Algorithm can have three types of errors:
            #       "Algorithm settings are empty"
            #        in this case fields 'userID', 'algoID', 'details' are empty
            #       "Invalid algorithm settings"
            #        in this case 'details' dictionary has following structure:
            #               key         value
            #               'params'    Parameters key ('data')
            #               'message'   Error message (for example "File <path> doesn't exists")
            #       "Internal algorithm error"
            # Need save to redis
            pass
        elif algo_result.get('status', '') == "error":
            worker_logger.exception('Error during education - %s, %s, %s' % (algo_result.get('status'),
                                                                             algo_result.get('type'),
                                                                             algo_result.get('details')))
            if 'Internal Training Error' in algo_result.get('type', ''):
                error = algo_result.get('details', {}).get('message', '')
                ai_response_type.update(dict(
                    status=TRAINING_RETRY_STATUS,
                    message=TRAINING_RETRY_MESSAGE
                ))
            else:
                ai_response_type.update({'status': 'error'})
                ai_response_type.update(dict(
                    status=TRAINING_FAILED_STATUS,
                    message=TRAINING_FAILED_MESSAGE
                ))
            # record = dictionary:
            # key          value
            #      'status'     "error"
            #      'type'       Type of error
            #      'userID'     Unique user identificator
            #      'algoID'     Unique algorithm identificator
            #      'details'    Error details dictionary
            #
            # Algorithm can have three types of errors:
            #       "Algorithm settings are empty"
            #        in this case fields 'userID', 'algoID', 'details' are empty
            #       "Invalid algorithm settings"
            #        in this case 'details' dictionary has following structure:
            #               key         value
            #               'params'    Parameters key ('data')
            #               'message'   Error message (for example "File <path> doesn't exists")
            #       "Internal algorithm error"
            # Need save to redis
            pass
    except Exception as e:
        worker_logger.exception(e)
    finally:
        final_helper(temp_image_path, probe_id, error, callback_code, result, ai_response_type, try_type, ai_code)
Пример #6
0
def verification_job(image, probe_id, settings, callback_code):
    """
        Runs verification for user with given image
    :param image: to run verification for
    :param probe_id: app_id
    :param settings: settings with values for algoId and userID
    :param callback_code: code of the callback which should be executed after job is finished.
    """
    worker_logger.info(
        'Running verification for user - %s, with given parameters - %s' %
        (settings.get('userID'), settings))
    if RedisStorage.persistence_instance().exists(key=REDIS_JOB_RESULTS_ERROR %
                                                  callback_code):
        worker_logger.info(
            'Job interrupted because of job_results_error key existence.')
        return
    result = False
    database = get_algo_db(probe_id=probe_id)
    settings.update({'database': database})
    settings.update({'action': 'verification'})
    temp_image_path = tempfile.mkdtemp(dir=ALGO_ROOT)
    error = None
    try:
        temp_image = save_image(image, temp_image_path)
        settings.update({'data': temp_image})

        # Store photos for test purposes
        store_test_photo_helper(ALGO_ROOT, [temp_image])

        algo_result = AlgorithmsInterface.verification(**settings)
        if algo_result.get('status', '') == "result":
            # record = dictionary:
            # key          value
            #      'status'     "result"
            #      'result'     bool value: True is verification successfully, otherwise False
            #      'userID'     Unique user identifier
            #
            # Need save to redis
            result = algo_result.get('result', False)
        elif algo_result.get('status', '') == "data_request":
            # record = dictionary:
            # key          value
            #      'status'     "data_request"
            #      'userID'     Unique user identifier
            #      'algoID'     Unique algorithm identifier
            #
            # Need save to redis as data request (for this we can use this dictionary)
            pass
        elif algo_result.get('status', '') == "error":
            worker_logger.exception(
                'Error during verification - %s, %s, %s' %
                (algo_result.get('status'), algo_result.get('type'),
                 algo_result.get('details')))
            if 'Internal algorithm' in algo_result.get('type', ''):
                error = algo_result.get('details', {}).get('message', '')
            # record = dictionary:
            # key          value
            #      'status'     "error"
            #      'type'       Type of error
            #      'userID'     Unique user identifier
            #      'algoID'     Unique algorithm identifier
            #      'details'    Error details dictionary
            #
            # Algorithm can have three types of errors:
            #       "Algorithm settings are empty"
            #        in this case fields 'userID', 'algoID', 'details' are empty
            #       "Invalid algorithm settings"
            #        in this case 'details' dictionary has following structure:
            #               key         value
            #               'params'    Parameters key ('data')
            #               'message'   Error message (for example "File <path> doesn't exists")
            #       "Internal algorithm error"
            # Need save to redis
            pass
    except Exception as e:
        worker_logger.exception(e)
    finally:
        if error is not None or RedisStorage.persistence_instance().exists(
                key=REDIS_JOB_RESULTS_ERROR % callback_code):
            if not RedisStorage.persistence_instance().exists(
                    key=REDIS_JOB_RESULTS_ERROR % callback_code):
                result = dict(verified=False, error=error)
                RedisStorage.persistence_instance().store_data(
                    key=REDIS_JOB_RESULTS_ERROR % callback_code,
                    ex=300,
                    result=result)
                store_verification_results(result=result,
                                           callback_code=callback_code,
                                           probe_id=probe_id)
            if error is not None:
                worker_logger.info(
                    'Job was finished with internal algorithm error %s ' %
                    error)
            else:
                worker_logger.info(
                    'Job was not stored because of job_results_error key existence.'
                )
        else:
            RedisStorage.persistence_instance().append_value_to_list(
                key=REDIS_PARTIAL_RESULTS_KEY % callback_code, value=result)
            results_counter = RedisStorage.persistence_instance(
            ).decrement_int_value(REDIS_RESULTS_COUNTER_KEY % callback_code)
            if results_counter <= 0:
                gathered_results = RedisStorage.persistence_instance(
                ).get_stored_list(REDIS_PARTIAL_RESULTS_KEY % callback_code)
                worker_logger.debug(
                    'All gathered results for verification job - %s' %
                    gathered_results)
                if results_counter < 0:
                    worker_logger.exception(
                        'Results count is less than 0, check worker jobs consistency!'
                    )
                    result = dict(verified=False)
                else:
                    true_count = float(gathered_results.count('True'))
                    result = dict(verified=(
                        (true_count / len(gathered_results)) * 100) >= 50)
                store_verification_results(result=result,
                                           callback_code=callback_code,
                                           probe_id=probe_id)
        shutil.rmtree(temp_image_path)
    worker_logger.info(
        'Verification finished for user - %s, with result - %s' %
        (settings.get('userID'), result))
Пример #7
0
def training_job(images, probe_id, settings, callback_code, try_type, ai_code):
    """
        Runs education for given user with given array of images.
    :param images: array of images to run verification on.
    :param probe_id: current app_id
    :param settings: dictionary which contains information about algoId and userID
    :param callback_code: code of the callback that should be executed after job is finished
    """
    worker_logger.info(
        'Running training for user - %s, with given parameters - %s' %
        (settings.get('userID'), settings))
    ai_response_type = dict()
    try:

        worker_logger.info(
            'Telling AI that we are starting training with code - %s' %
            ai_code)
        ai_response_type.update({
            'status': TRAINING_STARTED_STATUS,
            'message': TRAINING_STARTED_MESSAGE
        })
        response_type = base64.b64encode(json.dumps(ai_response_type))
        register_biometrics_url = biomio_settings.ai_rest_url % (
            REST_REGISTER_BIOMETRICS % (ai_code, response_type))
        response = requests.post(register_biometrics_url)
        try:
            response.raise_for_status()
            worker_logger.info(
                'AI should now know that training started with code - %s and response type - %s'
                % (ai_code, response_type))
        except HTTPError as e:
            worker_logger.exception(e)
            worker_logger.exception(
                'Failed to tell AI that training started, reason - %s' %
                response.reason)
    except Exception as e:
        worker_logger.error('Failed to build rest request to AI - %s' % str(e))
        worker_logger.exception(e)
    ai_response_type.update({
        'status': TRAINING_SUCCESS_STATUS,
        'message': TRAINING_SUCCESS_MESSAGE
    })
    result = False
    error = None
    settings.update({'action': 'education'})
    if RedisStorage.persistence_instance().exists(
            key=REDIS_UPDATE_TRAINING_KEY % probe_id):
        settings.update({'database': get_algo_db(probe_id=probe_id)})
        RedisStorage.persistence_instance().delete_data(
            key=REDIS_UPDATE_TRAINING_KEY % probe_id)
    temp_image_path = tempfile.mkdtemp(dir=ALGO_ROOT)
    try:
        image_paths = save_images(images, temp_image_path)

        # Store photos for test purposes
        store_test_photo_helper(ALGO_ROOT, image_paths)

        settings.update({'data': image_paths})
        algo_result = AlgorithmsInterface.verification(**settings)
        if isinstance(algo_result, dict) and algo_result.get('status',
                                                             '') == "update":
            # record = dictionary:
            # key          value
            #      'status'     "update"
            #      'userID'     Unique user identificator
            #      'algoID'     Unique algorithm identificator
            #      'database'   BLOB data of user, with userID, for verification algorithm algoID
            #
            # Need update record in algorithms database or create record for user userID and algorithm
            # algoID if it doesn't exists
            database = algo_result.get('database', None)
            if database is not None:
                store_training_db(database, probe_id)
                result = True
                ai_response_type.update(
                    dict(status=TRAINING_SUCCESS_STATUS,
                         message=TRAINING_SUCCESS_MESSAGE))
        elif isinstance(algo_result, list):
            for algo_result_item in algo_result:
                if algo_result_item.get('status', '') == "error":
                    worker_logger.exception(
                        'Error during education - %s, %s, %s' %
                        (algo_result_item.get('status'),
                         algo_result_item.get('type'),
                         algo_result_item.get('details')))
                    if 'Internal Training Error' in algo_result_item.get(
                            'type', ''):
                        error = algo_result_item.get('details',
                                                     {}).get('message', '')
                        ai_response_type.update(
                            dict(status=TRAINING_RETRY_STATUS,
                                 message=TRAINING_RETRY_MESSAGE))
                    else:
                        ai_response_type.update({'status': 'error'})

                elif algo_result_item.get('status', '') == 'update':
                    database = algo_result_item.get('database', None)
                    if database is not None:
                        store_training_db(database, probe_id)
                        result = True
                        ai_response_type.update(
                            dict(status=TRAINING_SUCCESS_STATUS,
                                 message=TRAINING_SUCCESS_MESSAGE))
            # record = dictionary:
            # key          value
            #      'status'     "error"
            #      'type'       Type of error
            #      'userID'     Unique user identificator
            #      'algoID'     Unique algorithm identificator
            #      'details'    Error details dictionary
            #
            # Algorithm can have three types of errors:
            #       "Algorithm settings are empty"
            #        in this case fields 'userID', 'algoID', 'details' are empty
            #       "Invalid algorithm settings"
            #        in this case 'details' dictionary has following structure:
            #               key         value
            #               'params'    Parameters key ('data')
            #               'message'   Error message (for example "File <path> doesn't exists")
            #       "Internal algorithm error"
            # Need save to redis
            pass
        elif algo_result.get('status', '') == "error":
            worker_logger.exception(
                'Error during education - %s, %s, %s' %
                (algo_result.get('status'), algo_result.get('type'),
                 algo_result.get('details')))
            if 'Internal Training Error' in algo_result.get('type', ''):
                error = algo_result.get('details', {}).get('message', '')
                ai_response_type.update(
                    dict(status=TRAINING_RETRY_STATUS,
                         message=TRAINING_RETRY_MESSAGE))
            else:
                ai_response_type.update({'status': 'error'})
                ai_response_type.update(
                    dict(status=TRAINING_FAILED_STATUS,
                         message=TRAINING_FAILED_MESSAGE))
            # record = dictionary:
            # key          value
            #      'status'     "error"
            #      'type'       Type of error
            #      'userID'     Unique user identificator
            #      'algoID'     Unique algorithm identificator
            #      'details'    Error details dictionary
            #
            # Algorithm can have three types of errors:
            #       "Algorithm settings are empty"
            #        in this case fields 'userID', 'algoID', 'details' are empty
            #       "Invalid algorithm settings"
            #        in this case 'details' dictionary has following structure:
            #               key         value
            #               'params'    Parameters key ('data')
            #               'message'   Error message (for example "File <path> doesn't exists")
            #       "Internal algorithm error"
            # Need save to redis
            pass
    except Exception as e:
        worker_logger.exception(e)
    finally:
        shutil.rmtree(temp_image_path)
        if error is not None:
            retries_count = RedisStorage.persistence_instance(
            ).decrement_int_value(REDiS_TRAINING_RETRIES_COUNT_KEY % probe_id)
            if retries_count == 0:
                RedisStorage.persistence_instance().delete_data(
                    key=REDiS_TRAINING_RETRIES_COUNT_KEY % probe_id)
                worker_logger.debug('Maximum training attempts reached...')
                result = False
                ai_response_type.update(
                    dict(status=TRAINING_MAX_RETRIES_STATUS,
                         message=TRAINING_MAX_RETRIES_MESSAGE))
                # _tell_ai_training_results(result, ai_response_type, try_type, ai_code)
            else:
                RedisStorage.persistence_instance().store_data(
                    key=REDIS_UPDATE_TRAINING_KEY % probe_id, error=error)
                result = dict(result=False, error=error)
            RedisStorage.persistence_instance().store_data(
                key=REDIS_PROBE_RESULT_KEY % callback_code, result=result)
            worker_logger.info(
                'Job was finished with internal algorithm error %s ' % error)
        else:
            RedisStorage.persistence_instance().delete_data(
                key=REDiS_TRAINING_RETRIES_COUNT_KEY % probe_id)
            RedisStorage.persistence_instance().store_data(
                key=REDIS_PROBE_RESULT_KEY % callback_code, result=result)
        _tell_ai_training_results(result, ai_response_type,
                                  try_type.split('_')[0], ai_code)
    worker_logger.info('training finished for user - %s, with result - %s' %
                       (settings.get('userID'), result))