diff --git a/.gitignore b/.gitignore index b8359b9..865403c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ Pipfile Pipfile.lock .mypy_cache/ .idea/ +.vscode/ deepface.egg-info/ tests/dataset/*.pkl tests/*.ipynb diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index 803616f..6813691 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -16,7 +16,7 @@ import tensorflow as tf # package dependencies from deepface.commons import package_utils, folder_utils -from deepface.commons import logger as log +from deepface.commons.logger import Logger from deepface.modules import ( modeling, representation, @@ -29,7 +29,7 @@ from deepface.modules import ( ) from deepface import __version__ -logger = log.get_singletonish_logger() +logger = Logger() # ----------------------------------- # configurations for dependencies diff --git a/deepface/api/src/app.py b/deepface/api/src/app.py index 37d6784..d88a232 100644 --- a/deepface/api/src/app.py +++ b/deepface/api/src/app.py @@ -5,9 +5,9 @@ from flask_cors import CORS # project dependencies from deepface import DeepFace from deepface.api.src.modules.core.routes import blueprint -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def create_app(): diff --git a/deepface/api/src/modules/core/routes.py b/deepface/api/src/modules/core/routes.py index 8d68acc..4830bec 100644 --- a/deepface/api/src/modules/core/routes.py +++ b/deepface/api/src/modules/core/routes.py @@ -1,9 +1,9 @@ from flask import Blueprint, request from deepface import DeepFace from deepface.api.src.modules.core import service -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() blueprint = Blueprint("routes", __name__) diff --git a/deepface/basemodels/ArcFace.py b/deepface/basemodels/ArcFace.py index 43dd424..1ed2a93 100644 --- a/deepface/basemodels/ArcFace.py +++ b/deepface/basemodels/ArcFace.py @@ -3,9 +3,9 @@ import gdown from deepface.commons import package_utils, folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=unsubscriptable-object diff --git a/deepface/basemodels/DeepID.py b/deepface/basemodels/DeepID.py index b68b379..99a0676 100644 --- a/deepface/basemodels/DeepID.py +++ b/deepface/basemodels/DeepID.py @@ -2,9 +2,9 @@ import os import gdown from deepface.commons import package_utils, folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() tf_version = package_utils.get_tf_major_version() diff --git a/deepface/basemodels/Dlib.py b/deepface/basemodels/Dlib.py index f13b7ca..07cad0d 100644 --- a/deepface/basemodels/Dlib.py +++ b/deepface/basemodels/Dlib.py @@ -5,9 +5,9 @@ import gdown import numpy as np from deepface.commons import folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=too-few-public-methods diff --git a/deepface/basemodels/Facenet.py b/deepface/basemodels/Facenet.py index bcbb7b7..1349bfb 100644 --- a/deepface/basemodels/Facenet.py +++ b/deepface/basemodels/Facenet.py @@ -2,9 +2,9 @@ import os import gdown from deepface.commons import package_utils, folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # -------------------------------- # dependency configuration diff --git a/deepface/basemodels/FbDeepFace.py b/deepface/basemodels/FbDeepFace.py index f51a511..b8e4338 100644 --- a/deepface/basemodels/FbDeepFace.py +++ b/deepface/basemodels/FbDeepFace.py @@ -3,9 +3,9 @@ import zipfile import gdown from deepface.commons import package_utils, folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # -------------------------------- # dependency configuration diff --git a/deepface/basemodels/GhostFaceNet.py b/deepface/basemodels/GhostFaceNet.py index 1917833..90474cc 100644 --- a/deepface/basemodels/GhostFaceNet.py +++ b/deepface/basemodels/GhostFaceNet.py @@ -8,9 +8,9 @@ import tensorflow as tf # project dependencies from deepface.commons import package_utils, folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() tf_major = package_utils.get_tf_major_version() if tf_major == 1: diff --git a/deepface/basemodels/OpenFace.py b/deepface/basemodels/OpenFace.py index cc335b6..e9f8345 100644 --- a/deepface/basemodels/OpenFace.py +++ b/deepface/basemodels/OpenFace.py @@ -3,9 +3,9 @@ import gdown import tensorflow as tf from deepface.commons import package_utils, folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() tf_version = package_utils.get_tf_major_version() if tf_version == 1: diff --git a/deepface/basemodels/SFace.py b/deepface/basemodels/SFace.py index ddd9360..ee9a6e2 100644 --- a/deepface/basemodels/SFace.py +++ b/deepface/basemodels/SFace.py @@ -10,9 +10,9 @@ import gdown # project dependencies from deepface.commons import folder_utils from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=line-too-long, too-few-public-methods diff --git a/deepface/basemodels/VGGFace.py b/deepface/basemodels/VGGFace.py index 819150e..d61f702 100644 --- a/deepface/basemodels/VGGFace.py +++ b/deepface/basemodels/VGGFace.py @@ -5,9 +5,9 @@ import numpy as np from deepface.commons import package_utils, folder_utils from deepface.modules import verification from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # --------------------------------------- diff --git a/deepface/commons/file_utils.py b/deepface/commons/file_utils.py index b5b0169..b79076a 100644 --- a/deepface/commons/file_utils.py +++ b/deepface/commons/file_utils.py @@ -5,9 +5,9 @@ import os import gdown # project dependencies -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def download_external_file(file_name: str, exact_file_path: str, url: str) -> None: diff --git a/deepface/commons/folder_utils.py b/deepface/commons/folder_utils.py index ef5fbc7..88a8a48 100644 --- a/deepface/commons/folder_utils.py +++ b/deepface/commons/folder_utils.py @@ -1,8 +1,8 @@ import os from pathlib import Path -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def initialize_folder() -> None: diff --git a/deepface/commons/logger.py b/deepface/commons/logger.py index 4533953..c42c950 100644 --- a/deepface/commons/logger.py +++ b/deepface/commons/logger.py @@ -4,18 +4,34 @@ from datetime import datetime # pylint: disable=broad-except class Logger: - def __init__(self, module=None): - self.module = module - log_level = os.environ.get("DEEPFACE_LOG_LEVEL", str(logging.INFO)) - try: - self.log_level = int(log_level) - except Exception as err: - self.dump_log( - f"Exception while parsing $DEEPFACE_LOG_LEVEL." - f"Expected int but it is {log_level} ({str(err)})." - "Setting app log level to info." - ) - self.log_level = logging.INFO + """ + A Logger class for logging messages with a specific log level. + + The class follows the singleton design pattern, ensuring that only one + instance of the Logger is created. The parameters of the first instance + are preserved across all instances. + """ + + __instance = None + + def __new__(cls): + if cls.__instance is None: + cls.__instance = super(Logger, cls).__new__(cls) + return cls.__instance + + def __init__(self): + if not hasattr(self, "_singleton_initialized"): + self._singleton_initialized = True # to prevent multiple initializations + log_level = os.environ.get("DEEPFACE_LOG_LEVEL", str(logging.INFO)) + try: + self.log_level = int(log_level) + except Exception as err: + self.dump_log( + f"Exception while parsing $DEEPFACE_LOG_LEVEL." + f"Expected int but it is {log_level} ({str(err)})." + "Setting app log level to info." + ) + self.log_level = logging.INFO def info(self, message): if self.log_level <= logging.INFO: @@ -39,16 +55,3 @@ class Logger: def dump_log(self, message): print(f"{str(datetime.now())[2:-7]} - {message}") - - -def get_singletonish_logger(): - # singleton design pattern - global model_obj - - if not "model_obj" in globals(): - model_obj = {} - - if "logger" not in model_obj.keys(): - model_obj["logger"] = Logger(module="Singleton") - - return model_obj["logger"] diff --git a/deepface/commons/package_utils.py b/deepface/commons/package_utils.py index c35db8b..e7e3bd4 100644 --- a/deepface/commons/package_utils.py +++ b/deepface/commons/package_utils.py @@ -2,9 +2,9 @@ import tensorflow as tf # package dependencies -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def get_tf_major_version() -> int: diff --git a/deepface/detectors/CenterFace.py b/deepface/detectors/CenterFace.py index 84db334..5e58e58 100644 --- a/deepface/detectors/CenterFace.py +++ b/deepface/detectors/CenterFace.py @@ -10,9 +10,9 @@ import gdown # project dependencies from deepface.commons import folder_utils from deepface.models.Detector import Detector, FacialAreaRegion -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=c-extension-no-member diff --git a/deepface/detectors/DetectorWrapper.py b/deepface/detectors/DetectorWrapper.py index 1210f62..75f82a6 100644 --- a/deepface/detectors/DetectorWrapper.py +++ b/deepface/detectors/DetectorWrapper.py @@ -15,9 +15,9 @@ from deepface.detectors import ( YuNet, CenterFace, ) -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def build_model(detector_backend: str) -> Any: diff --git a/deepface/detectors/Dlib.py b/deepface/detectors/Dlib.py index 9be3c76..d1c800a 100644 --- a/deepface/detectors/Dlib.py +++ b/deepface/detectors/Dlib.py @@ -5,9 +5,9 @@ import gdown import numpy as np from deepface.commons import folder_utils from deepface.models.Detector import Detector, FacialAreaRegion -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() class DlibClient(Detector): diff --git a/deepface/detectors/Ssd.py b/deepface/detectors/Ssd.py index a8d68eb..3dc1c01 100644 --- a/deepface/detectors/Ssd.py +++ b/deepface/detectors/Ssd.py @@ -7,9 +7,9 @@ import numpy as np from deepface.detectors import OpenCv from deepface.commons import folder_utils from deepface.models.Detector import Detector, FacialAreaRegion -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=line-too-long, c-extension-no-member diff --git a/deepface/detectors/Yolo.py b/deepface/detectors/Yolo.py index cf9f9de..807d8e1 100644 --- a/deepface/detectors/Yolo.py +++ b/deepface/detectors/Yolo.py @@ -4,9 +4,9 @@ import numpy as np import gdown from deepface.models.Detector import Detector, FacialAreaRegion from deepface.commons import folder_utils -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # Model's weights paths PATH = "/.deepface/weights/yolov8n-face.pt" diff --git a/deepface/detectors/YuNet.py b/deepface/detectors/YuNet.py index c43b80f..a522bac 100644 --- a/deepface/detectors/YuNet.py +++ b/deepface/detectors/YuNet.py @@ -10,9 +10,9 @@ import gdown # project dependencies from deepface.commons import folder_utils from deepface.models.Detector import Detector, FacialAreaRegion -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() class YuNetClient(Detector): diff --git a/deepface/extendedmodels/Age.py b/deepface/extendedmodels/Age.py index 2e99995..8d0f0cf 100644 --- a/deepface/extendedmodels/Age.py +++ b/deepface/extendedmodels/Age.py @@ -4,9 +4,9 @@ import numpy as np from deepface.basemodels import VGGFace from deepface.commons import package_utils, folder_utils from deepface.models.Demography import Demography -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # ---------------------------------------- # dependency configurations diff --git a/deepface/extendedmodels/Emotion.py b/deepface/extendedmodels/Emotion.py index e0b93bf..7338131 100644 --- a/deepface/extendedmodels/Emotion.py +++ b/deepface/extendedmodels/Emotion.py @@ -9,9 +9,9 @@ import cv2 # project dependencies from deepface.commons import package_utils, folder_utils from deepface.models.Demography import Demography -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # ------------------------------------------- # pylint: disable=line-too-long diff --git a/deepface/extendedmodels/Gender.py b/deepface/extendedmodels/Gender.py index 84cb446..cb766fe 100644 --- a/deepface/extendedmodels/Gender.py +++ b/deepface/extendedmodels/Gender.py @@ -9,9 +9,9 @@ import numpy as np from deepface.basemodels import VGGFace from deepface.commons import package_utils, folder_utils from deepface.models.Demography import Demography -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # ------------------------------------- # pylint: disable=line-too-long diff --git a/deepface/extendedmodels/Race.py b/deepface/extendedmodels/Race.py index 1943dea..6f9e643 100644 --- a/deepface/extendedmodels/Race.py +++ b/deepface/extendedmodels/Race.py @@ -9,9 +9,9 @@ import numpy as np from deepface.basemodels import VGGFace from deepface.commons import package_utils, folder_utils from deepface.models.Demography import Demography -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # -------------------------- # pylint: disable=line-too-long diff --git a/deepface/modules/detection.py b/deepface/modules/detection.py index 0c32aa4..9edb0f2 100644 --- a/deepface/modules/detection.py +++ b/deepface/modules/detection.py @@ -11,9 +11,9 @@ from deepface.modules import modeling from deepface.models.Detector import DetectedFace, FacialAreaRegion from deepface.detectors import DetectorWrapper from deepface.commons import image_utils -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=no-else-raise diff --git a/deepface/modules/recognition.py b/deepface/modules/recognition.py index 4eda51f..4b94ad9 100644 --- a/deepface/modules/recognition.py +++ b/deepface/modules/recognition.py @@ -12,9 +12,9 @@ from tqdm import tqdm # project dependencies from deepface.commons import image_utils from deepface.modules import representation, detection, verification -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def find( diff --git a/deepface/modules/streaming.py b/deepface/modules/streaming.py index b6b579d..fe27464 100644 --- a/deepface/modules/streaming.py +++ b/deepface/modules/streaming.py @@ -10,9 +10,9 @@ import cv2 # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # dependency configuration os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2" diff --git a/deepface/modules/verification.py b/deepface/modules/verification.py index 8b03ed4..7bd3c6b 100644 --- a/deepface/modules/verification.py +++ b/deepface/modules/verification.py @@ -8,9 +8,9 @@ import numpy as np # project dependencies from deepface.modules import representation, detection, modeling from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def verify( diff --git a/deepface/spoofmodels/FasNet.py b/deepface/spoofmodels/FasNet.py index 8d1f988..4f2c195 100644 --- a/deepface/spoofmodels/FasNet.py +++ b/deepface/spoofmodels/FasNet.py @@ -9,9 +9,10 @@ import cv2 import numpy as np # project dependencies -from deepface.commons import folder_utils, file_utils, logger as log +from deepface.commons import folder_utils, file_utils +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # pylint: disable=line-too-long, too-few-public-methods class Fasnet: diff --git a/tests/face-recognition-how.py b/tests/face-recognition-how.py index 22bbf81..f33e1af 100644 --- a/tests/face-recognition-how.py +++ b/tests/face-recognition-how.py @@ -7,9 +7,9 @@ import cv2 from deepface import DeepFace from deepface.modules import verification from deepface.models.FacialRecognition import FacialRecognition -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # ---------------------------------------------- # build face recognition model diff --git a/tests/test_analyze.py b/tests/test_analyze.py index 3e3d3e1..bad4426 100644 --- a/tests/test_analyze.py +++ b/tests/test_analyze.py @@ -3,9 +3,9 @@ import cv2 # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() detectors = ["opencv", "mtcnn"] diff --git a/tests/test_api.py b/tests/test_api.py index 0eeafc8..ef2db73 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -4,9 +4,9 @@ import unittest # project dependencies from deepface.api.src.app import create_app -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() class TestVerifyEndpoint(unittest.TestCase): diff --git a/tests/test_enforce_detection.py b/tests/test_enforce_detection.py index db73ce1..5360563 100644 --- a/tests/test_enforce_detection.py +++ b/tests/test_enforce_detection.py @@ -4,9 +4,9 @@ import numpy as np # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def test_enabled_enforce_detection_for_non_facial_input(): diff --git a/tests/test_extract_faces.py b/tests/test_extract_faces.py index 0ddd9d5..492fa2d 100644 --- a/tests/test_extract_faces.py +++ b/tests/test_extract_faces.py @@ -9,9 +9,9 @@ import pytest # project dependencies from deepface import DeepFace from deepface.commons import image_utils -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() detectors = ["opencv", "mtcnn"] diff --git a/tests/test_find.py b/tests/test_find.py index 83d9964..b6845a4 100644 --- a/tests/test_find.py +++ b/tests/test_find.py @@ -9,9 +9,9 @@ import pandas as pd from deepface import DeepFace from deepface.modules import verification from deepface.commons import image_utils -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() threshold = verification.find_threshold(model_name="VGG-Face", distance_metric="cosine") diff --git a/tests/test_represent.py b/tests/test_represent.py index b702d62..085dff2 100644 --- a/tests/test_represent.py +++ b/tests/test_represent.py @@ -3,9 +3,9 @@ import cv2 # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def test_standard_represent(): diff --git a/tests/test_singleton.py b/tests/test_singleton.py new file mode 100644 index 0000000..f2e4ea1 --- /dev/null +++ b/tests/test_singleton.py @@ -0,0 +1,8 @@ +from deepface.commons.logger import Logger + +logger = Logger() + + +def test_singleton_same_object(): + assert Logger() == Logger() + logger.info("✅ id's of instances of \"singletoned\" class Logger are the same") diff --git a/tests/test_verify.py b/tests/test_verify.py index 01e7e4a..ab894fa 100644 --- a/tests/test_verify.py +++ b/tests/test_verify.py @@ -4,9 +4,9 @@ import cv2 # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() models = ["VGG-Face", "Facenet", "Facenet512", "ArcFace", "GhostFaceNet"] metrics = ["cosine", "euclidean", "euclidean_l2"] diff --git a/tests/test_version.py b/tests/test_version.py index 08e3bbf..21e0065 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -3,9 +3,9 @@ import json # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() def test_version(): diff --git a/tests/visual-test.py b/tests/visual-test.py index eb016b5..9149bc5 100644 --- a/tests/visual-test.py +++ b/tests/visual-test.py @@ -3,9 +3,9 @@ import matplotlib.pyplot as plt # project dependencies from deepface import DeepFace -from deepface.commons import logger as log +from deepface.commons.logger import Logger -logger = log.get_singletonish_logger() +logger = Logger() # some models (e.g. Dlib) and detectors (e.g. retinaface) do not have test cases # because they require to install huge packages