def __set_options(self, cfg_path): try: cfg = file_folder_operations.read_json_file(cfg_path) # model_options self.predicted_image_action = cfg["predictor_options"]["model_options"]["predicted_image_action"] self.confidence_threshold = cfg["predictor_options"]["model_options"]["confidence_threshold"] self.keras_image_size = (cfg["predictor_options"]["model_options"]["image_w"], cfg["predictor_options"]["model_options"]["image_h"]) self.keras_grayscale = cfg["predictor_options"]["model_options"]["grayscale"] self.keras_topN = cfg["predictor_options"]["model_options"]["return_topN"] # graph for tf 1 session self.tensorflow_version = cfg["predictor_options"]["model_options"]["tensorflow_version"] if(self.tensorflow_version == 1): self.tf_graph = tf.get_default_graph() # model_paths self.predictions_main_folder = cfg["predictor_options"]["model_paths"]["predictions_main_folder"] self.not_confiedent_name = cfg["predictor_options"]["model_paths"]["not_confiedent_folder_name"] self.keras_model_path = cfg["predictor_options"]["model_paths"]["model_path"] self.keras_names_path = cfg["predictor_options"]["model_paths"]["names_path"] return True except: self.logger.error("cfg file error", exc_info=True) return False
def __set_options(self, cfg_path): try: cfg = file_folder_operations.read_json_file(cfg_path) # model info self.model_info = cfg["predictor_options"]["model_info"] self.predictor_backend = cfg["predictor_options"]["model_info"][ "predictor_backend"] self.method = cfg["predictor_options"]["model_info"]["method"] self.model_id = cfg["predictor_options"]["model_info"]["model_id"] return True except: self.logger.error("cfg file error", exc_info=True) return False
def __set_options(self, cfg_path): try: cfg = file_folder_operations.read_json_file(cfg_path) # model_options self.predicted_image_action = cfg["predictor_options"]["model_options"]["predicted_image_action"] self.confidence_threshold = cfg["predictor_options"]["model_options"]["confidence_threshold"] # model_paths self.predictions_main_folder = cfg["predictor_options"]["model_paths"]["predictions_main_folder"] self.not_confiedent_name = cfg["predictor_options"]["model_paths"]["not_confiedent_folder_name"] self.darknet_configPath = cfg["predictor_options"]["model_paths"]["darknet_configPath"] self.darknet_weightPath = cfg["predictor_options"]["model_paths"]["darknet_weightPath"] self.darknet_metaPath = cfg["predictor_options"]["model_paths"]["darknet_metaPath"] return True except: self.logger.error("cfg file error", exc_info=True) return False
def __set_options(self, cfg_path): try: cfg = file_folder_operations.read_json_file(cfg_path) # model_options self.simulate = cfg["predictor_options"]["model_options"][ "simulate"] self.image_class = cfg["predictor_options"]["model_options"][ "image_class"] self.sleep = cfg["predictor_options"]["model_options"]["sleep"] self.predicted_image_action = cfg["predictor_options"][ "model_options"]["predicted_image_action"] # model_paths self.predictions_main_folder = cfg["predictor_options"][ "model_paths"]["predictions_main_folder"] return True except: self.logger.error("cfg file error", exc_info=True) return False
def __set_options(self, cfg_path): try: cfg = file_folder_operations.read_json_file(cfg_path) # model_options self.predicted_image_action = cfg["predictor_options"]["model_options"]["predicted_image_action"] self.tf_yolo_image_size = cfg["predictor_options"]["model_options"]["input_size"] self.iou_threshold = cfg["predictor_options"]["model_options"]["iou_threshold"] self.score_threshold = cfg["predictor_options"]["model_options"]["score_threshold"] self.max_output_size_per_class = cfg["predictor_options"]["model_options"]["max_output_size_per_class"] self.max_total_size = cfg["predictor_options"]["model_options"]["max_total_size"] # model_paths self.predictions_main_folder = cfg["predictor_options"]["model_paths"]["predictions_main_folder"] self.not_confiedent_name = cfg["predictor_options"]["model_paths"]["not_confiedent_folder_name"] self.tf_yolo_model_path = cfg["predictor_options"]["model_paths"]["model_path"] self.tf_yolo_names_path = cfg["predictor_options"]["model_paths"]["names_path"] return True except: self.logger.error("cfg file error", exc_info=True) return False
def create_app(deep_predictor_cfg_path): # create logger logger = logger_creator().flask_logger() logger.info("creating flask app with cfg file on path:{0}".format(deep_predictor_cfg_path)) # set config options cfg = file_folder_operations.read_json_file(deep_predictor_cfg_path) # flask options secret_key = cfg["deep_predictor_options"]["flask_options"]["secret_key"] max_content_length = eval(cfg["deep_predictor_options"]["flask_options"]["max_content_length"]) debug = cfg["deep_predictor_options"]["flask_options"]["debug"] # ---------- production options ---------- # recaptcha_options recaptcha_sitekey = cfg["deep_predictor_options"]["production"]["recaptcha_options"]["recaptcha_sitekey"] recaptcha_secret_key = cfg["deep_predictor_options"]["production"]["recaptcha_options"]["recaptcha_secret_key"] # upload options supported_extensions = cfg["deep_predictor_options"]["production"]["upload_options"]["supported_extensions"] # api options api_key = cfg["deep_predictor_options"]["production"]["api_options"]["api_key"] prediction_id_length = cfg["deep_predictor_options"]["production"]["api_options"]["prediction_id_length"] default_api_response = cfg["deep_predictor_options"]["production"]["api_options"]["default_api_response"] get_prediction_endpoint = cfg["deep_predictor_options"]["production"]["api_options"]["get_prediction_endpoint"] get_predictors_endpoint = cfg["deep_predictor_options"]["production"]["api_options"]["get_predictors_endpoint"] # path options temp_save_path = cfg["deep_predictor_options"]["production"]["path_options"]["temp_save_path"] database_path = cfg["deep_predictor_options"]["production"]["path_options"]["database_path"] # prediction options default_predictor_name = cfg["deep_predictor_options"]["production"]["prediction_options"]["default_predictor_name"] # create instace of db class db = database_handler(database_path = database_path, check_connection = True, create_table = True) # create predictors predictors = {} for predictor in cfg["deep_predictor_options"]["production"]["prediction_options"]["predictors"]: predictors.update({ predictor : deep_predictor(cfg["deep_predictor_options"]["production"]["prediction_options"]["predictors"][predictor]) }) # -------------------------------------------------- # ---------- test options ---------- # upload options TEST_supported_extensions = cfg["deep_predictor_options"]["test"]["upload_options"]["supported_extensions"] # api options TEST_key = cfg["deep_predictor_options"]["test"]["api_options"]["api_key"] TEST_prediction_id_length = cfg["deep_predictor_options"]["test"]["api_options"]["prediction_id_length"] TEST_default_api_response = cfg["deep_predictor_options"]["test"]["api_options"]["default_api_response"] TEST_get_prediction_endpoint = cfg["deep_predictor_options"]["test"]["api_options"]["get_prediction_endpoint"] TEST_get_predictors_endpoint = cfg["deep_predictor_options"]["test"]["api_options"]["get_predictors_endpoint"] # path options TEST_temp_save_path = cfg["deep_predictor_options"]["test"]["path_options"]["temp_save_path"] TEST_database_path = cfg["deep_predictor_options"]["test"]["path_options"]["database_path"] # create instace of db class TEST_db = database_handler(database_path = TEST_database_path, check_connection = True, create_table = True) # create predictors TEST_predictors = {} for predictor in cfg["deep_predictor_options"]["test"]["prediction_options"]["predictors"]: TEST_predictors.update({ predictor : deep_predictor(cfg["deep_predictor_options"]["test"]["prediction_options"]["predictors"][predictor]) }) # -------------------------------------------------- # flask app app = Flask(__name__) app.config["DEBUG"] = debug app.config['MAX_CONTENT_LENGTH'] = max_content_length app.secret_key = secret_key # ---------- regular routes ---------- @app.route('/', methods=['GET']) def home(): logger.debug("function: {0} method: {1}".format("home", request.method)) return render_template("index.html"), 200 @app.route('/result', methods=['GET']) def result(): logger.debug("function: {0} method: {1}".format("result", request.method)) return redirect(url_for("home")), 308 @app.route('/upload', methods=['POST', 'GET']) def upload(): logger.debug("function: {0} method: {1}".format("upload", request.method)) if(request.method == 'POST'): # ---------- check key errors from form ---------- try: uploaded_file = request.files['image'] filename = secure_filename(uploaded_file.filename) model_name = request.form['model_name'] prediction_id = request.form['prediction_id'] except KeyError: logger.warning("KeyError", exc_info=True) abort(400, description="Unknown key received from form") recaptcha_response = request.form.get('g-recaptcha-response') form_api_key = request.form.get('api_key') # -------------------------------------------------- # ---------- check recaptcha or api_key ---------- if(form_api_key): # check api key if(api_key != form_api_key): logger.warning("api key is incorrect") abort(400, description="Api key is incorrect") elif(recaptcha_response): # check recaptcha if(not validate_recaptcha(recaptcha_response, recaptcha_secret_key)): logger.warning("recaptcha is not verified") return render_template("upload.html", models=predictors.keys(), recaptcha_sitekey=recaptcha_sitekey), 400 else: logger.warning("recaptcha or api key is not provided") abort(400, description="Recaptcha or api key is not provided") # -------------------------------------------------- # ---------- check form elements ---------- if(model_name == ""): model_name = default_predictor_name if(filename == "" or prediction_id == ""): logger.warning("required form elements are empty") return render_template("upload.html", models=predictors.keys(), recaptcha_sitekey=recaptcha_sitekey), 400 # prediction_id length if(len(prediction_id) != prediction_id_length): logger.warning("prediction_id length is wrong") abort(400, description="Something went wrong please try again") # model name if(model_name not in predictors): logger.warning("model name is not exists") abort(400, description="This predictor is not exists") # image extension if(not image_operations.validate_extension(supported_extensions, filename, is_case_sensitive=False)): logger.warning("image extension is not supported") abort(400, description="Your image extension is not supported") # -------------------------------------------------- # check for prediction_id collision if(db.is_prediction_exists(prediction_id)): logger.warning("prediction id exists") abort(500, description="Something went wrong please try again") # generate unique id # unique_full_filename = file_folder_operations.create_unique_file_name(os.path.join(temp_save_path, filename)) unique_filename = str(uuid.uuid4()) _, file_extension = os.path.splitext(filename) unique_full_filename = os.path.join(temp_save_path, unique_filename + file_extension) uploaded_file.save(unique_full_filename) # check image resizability status, unique_full_filename = image_operations.validate_image(unique_full_filename, try_to_convert = True, delete_unresizable = True) if(not status): logger.warning("image is not supported") abort(400, description="Your image is not supported") # prepare preediction model_info, model_id = predictors[model_name].get_model_info() db.create_prediction(prediction_id, model_info, model_id) # start prediction on thread pred_thread = prediction_thread( database_path, unique_full_filename, prediction_id, predictor=predictors[model_name] ) pred_thread.start() return render_template("result.html", prediction_id=prediction_id), 201 else: return render_template("upload.html", models=predictors.keys(), recaptcha_sitekey=recaptcha_sitekey), 200 @app.route('/api', methods=['GET']) def api(): logger.debug("function: {0} method: {1}".format("api", request.method)) # get args arguments = request.args prediction_id = arguments.get(get_prediction_endpoint) test_prediction_id = arguments.get(TEST_get_prediction_endpoint) if(prediction_id): prediction = db.get_prediction_json(prediction_id) return prediction, 200 elif(get_predictors_endpoint in arguments): return {get_predictors_endpoint : list(predictors.keys())}, 200 else: logger.warning("prediction_id is not provided") return default_api_response, 400 # -------------------------------------------------- # ---------- error routes ---------- @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): # all to 404 # e.code # e.name abort(404) @app.errorhandler(404) @app.errorhandler(400) @app.errorhandler(413) @app.errorhandler(500) def generic_error(e): logger.debug("function: {0} method: {1}".format("error", request.method)) if(e.code == 404): return render_template('error.html', description="The page you are looking for is not found", code=e.code), e.code elif(e.code == 413): return render_template('error.html', description="Your image is too large", code=e.code), e.code else: return render_template('error.html', description=e.description, code=e.code), e.code # -------------------------------------------------- # ---------- test routes ---------- @app.route('/test-upload', methods=['POST', 'GET']) def test_upload(): if(request.method == 'POST'): logger.debug("function: {0} method: {1}".format("test_upload", request.method)) # ---------- check key errors from form ---------- try: uploaded_file = request.files['image'] filename = secure_filename(uploaded_file.filename) model_name = request.form['model_name'] prediction_id = request.form['prediction_id'] form_api_key = request.form['api_key'] except KeyError: logger.warning("KeyError", exc_info=True) abort(400, description="Unknown key received from form") # -------------------------------------------------- # ---------- check test api key ---------- if(TEST_key != form_api_key): logger.warning("test api key is incorrect") abort(400, description="test api key is incorrect") # -------------------------------------------------- # ---------- check form elements ---------- if(filename == "" or prediction_id == "" or model_name == ""): logger.warning("required form elements are empty") abort(400, description="Required form elements are empty") # prediction_id length if(len(prediction_id) != TEST_prediction_id_length): logger.warning("prediction_id length is wrong") abort(400, description="Something went wrong please try again") # model name if(model_name not in TEST_predictors): logger.warning("model name is not exists") abort(400, description="This predictor is not exists") # image extension if(not image_operations.validate_extension(TEST_supported_extensions, filename, is_case_sensitive=False)): logger.warning("image extension is not supported") abort(400, description="Your image extension is not supported") # -------------------------------------------------- # check for prediction_id collision if(TEST_db.is_prediction_exists(prediction_id)): logger.warning("prediction id exists") abort(500, description="Something went wrong please try again") # generate unique id # unique_full_filename = file_folder_operations.create_unique_file_name(os.path.join(temp_save_path, filename)) unique_filename = str(uuid.uuid4()) _, file_extension = os.path.splitext(filename) unique_full_filename = os.path.join(TEST_temp_save_path, unique_filename + file_extension) uploaded_file.save(unique_full_filename) # check image resizability status, unique_full_filename = image_operations.validate_image(unique_full_filename, try_to_convert = True, delete_unresizable = True) if(not status): logger.warning("image is not supported") abort(400, description="Your image is not supported") # prepare preediction model_info, model_id = TEST_predictors[model_name].get_model_info() TEST_db.create_prediction(prediction_id, model_info, model_id) # start prediction on thread pred_thread = prediction_thread( TEST_database_path, unique_full_filename, prediction_id, predictor=TEST_predictors[model_name] ) pred_thread.start() return "success", 201 else: return redirect(url_for("home")), 308 @app.route('/test-api', methods=['GET']) def test_api(): logger.debug("function: {0} method: {1}".format("test_api", request.method)) # get args arguments = request.args prediction_id = arguments.get(TEST_get_prediction_endpoint) if(prediction_id): prediction = TEST_db.get_prediction_json(prediction_id) return prediction, 200 elif(TEST_get_predictors_endpoint in arguments): return {TEST_get_predictors_endpoint : list(TEST_predictors.keys())}, 200 else: logger.warning("prediction_id is not provided") return TEST_default_api_response, 400 # -------------------------------------------------- @app.route('/admin', methods=['GET']) def roll(): return redirect("https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstleyVEVO") # return flask app for serving return app
def read_cfg_file(self): self.cfg = file_folder_operations.read_json_file(self.cfg_file_path)
def __set_options(self): """reads cfg file and assigns cfg values to local variables""" self.__logger.info("flask_app using cfg file on path:{0}".format( self.__deep_predictor_cfg_path)) # set config options cfg = file_folder_operations.read_json_file( self.__deep_predictor_cfg_path) # flask options self.__secret_key = cfg["deep_predictor_options"]["flask_options"][ "secret_key"] self.__max_content_length = eval( cfg["deep_predictor_options"]["flask_options"] ["max_content_length"]) self.__debug = cfg["deep_predictor_options"]["flask_options"]["debug"] # ---------- production options ---------- # recaptcha_options self.__recaptcha_sitekey = cfg["deep_predictor_options"]["production"][ "recaptcha_options"]["recaptcha_sitekey"] self.__recaptcha_secret_key = cfg["deep_predictor_options"][ "production"]["recaptcha_options"]["recaptcha_secret_key"] # upload options self.__supported_extensions = cfg["deep_predictor_options"][ "production"]["upload_options"]["supported_extensions"] # api options self.__api_key = cfg["deep_predictor_options"]["production"][ "api_options"]["api_key"] self.__prediction_id_length = cfg["deep_predictor_options"][ "production"]["api_options"]["prediction_id_length"] self.__default_api_response = cfg["deep_predictor_options"][ "production"]["api_options"]["default_api_response"] self.__get_prediction_endpoint = cfg["deep_predictor_options"][ "production"]["api_options"]["get_prediction_endpoint"] self.__get_predictors_endpoint = cfg["deep_predictor_options"][ "production"]["api_options"]["get_predictors_endpoint"] # path options self.__temp_save_path = cfg["deep_predictor_options"]["production"][ "path_options"]["temp_save_path"] self.__database_path = cfg["deep_predictor_options"]["production"][ "path_options"]["database_path"] # prediction options self.__default_predictor_name = cfg["deep_predictor_options"][ "production"]["prediction_options"]["default_predictor_name"] # predictor cfg paths self.__predictor_cfgs = cfg["deep_predictor_options"]["production"][ "prediction_options"]["predictors"] # -------------------------------------------------- # ---------- test options ---------- # upload options self.__TEST_supported_extensions = cfg["deep_predictor_options"][ "test"]["upload_options"]["supported_extensions"] # api options self.__TEST_key = cfg["deep_predictor_options"]["test"]["api_options"][ "api_key"] self.__TEST_prediction_id_length = cfg["deep_predictor_options"][ "test"]["api_options"]["prediction_id_length"] self.__TEST_default_api_response = cfg["deep_predictor_options"][ "test"]["api_options"]["default_api_response"] self.__TEST_get_prediction_endpoint = cfg["deep_predictor_options"][ "test"]["api_options"]["get_prediction_endpoint"] self.__TEST_get_predictors_endpoint = cfg["deep_predictor_options"][ "test"]["api_options"]["get_predictors_endpoint"] # path options self.__TEST_temp_save_path = cfg["deep_predictor_options"]["test"][ "path_options"]["temp_save_path"] self.__TEST_database_path = cfg["deep_predictor_options"]["test"][ "path_options"]["database_path"] # predictor cfg paths self.__TEST_predictor_cfgs = cfg["deep_predictor_options"]["test"][ "prediction_options"]["predictors"]