diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 757988f..aed9cd2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.13.1] + python-version: [3.11] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.13.1] + python-version: [3.11] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -67,20 +67,42 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.13.1] + python-version: [3.11] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - name: Cache DeepFace weights + uses: actions/cache@v4 + with: + path: ~/.deepface/weights + key: deepface-weights-${{ runner.os }}-py${{ matrix.python-version }} + restore-keys: | + deepface-weights-${{ runner.os }}- - name: Install dependencies run: | python -m pip install --upgrade pip pip install pytest - # sending files in form data throwing error in flask 3 while running tests - pip install Werkzeug==2.0.2 flask==2.0.2 pip install . + - name: Remove corrupted DeepFace weights (if any) + run: | + python - <<'PY' + import os, glob + weights_dir = os.path.expanduser("~/.deepface/weights") + if not os.path.isdir(weights_dir): + raise SystemExit(0) + + # Remove suspiciously small files (often indicates truncated downloads) + for p in glob.glob(os.path.join(weights_dir, "*.h5")): + try: + if os.path.getsize(p) < 1024 * 100: # <100KB is definitely broken for these models + print("Removing tiny weight file:", p) + os.remove(p) + except OSError: + pass + PY - name: Test with pytest run: | cd tests/unit diff --git a/requirements.txt b/requirements.txt index 7b7189d..81d6c69 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,8 @@ opencv-python>=4.13.0.92 tensorflow>=2.21.0 tf-keras>=2.21.0 keras>=3.13.2 -Flask>=3.1.3 +Flask==2.2.5 +Werkzeug==2.2.3 flask_cors>=6.0.2 mtcnn>=1.0.0 retina-face>=0.0.17 diff --git a/tests/unit/test_api.py b/tests/unit/test_api.py index a1cbde8..0c731e6 100644 --- a/tests/unit/test_api.py +++ b/tests/unit/test_api.py @@ -599,18 +599,36 @@ def is_form_data_file_testable() -> bool: """ Sending a file from form data fails in unit test with 415 unsupported media type error for flask 3.X - but it is working for flask 2.0.2 + but it is working for flask 2.2.5 Returns: is_form_data_file_testable (bool) """ + try: + from importlib.metadata import version as get_version, PackageNotFoundError + except ImportError: # Python < 3.8 + from importlib_metadata import version as get_version, PackageNotFoundError + flask_version = version.parse(flask.__version__) - werkzeus_version = version.parse(werkzeug.__version__) - threshold_version = version.parse("2.0.2") - is_testable = flask_version <= threshold_version and werkzeus_version <= threshold_version + threshold_version = version.parse("2.3.0") + try: + werkzeug_version_str = get_version("werkzeug") + except PackageNotFoundError: + # If werkzeug version is unknown, assume it's compatible and + # base testability only on the Flask version. + is_testable = flask_version < threshold_version + if is_testable is False: + logger.warn( + "sending file in form data is not testable because werkzeug version is unknown " + f"and Flask version is {flask_version} (expected < {threshold_version})." + ) + return is_testable + + werkzeus_version = version.parse(werkzeug_version_str) + is_testable = flask_version < threshold_version and werkzeus_version < threshold_version if is_testable is False: logger.warn( - "sending file in form data is not testable because of flask, werkzeus versions." - f"Expected <= {threshold_version}, but {flask_version=} and {werkzeus_version}." + "sending file in form data is not testable because of Flask, Werkzeug versions." + f"Expected < {threshold_version}, but {flask_version=} and {werkzeus_version}." ) return is_testable