From d4e3bc9092875006d8d2e9df6f00b09ef6e1472c Mon Sep 17 00:00:00 2001 From: Iuri de Silvio Date: Thu, 11 Jul 2024 13:23:10 +0200 Subject: [PATCH 1/3] Add warning for mismatched mimetype and filename extension --- requirements.txt | 2 +- roboflow/core/project.py | 27 ++++++++++++++++++--------- roboflow/models/video.py | 17 +++++++++++++---- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/requirements.txt b/requirements.txt index b55b0a85..f10ea913 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,4 +15,4 @@ urllib3>=1.26.6 tqdm>=4.41.0 PyYAML>=5.3.1 requests_toolbelt -python-magic +filetype diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 55478a6d..91faa192 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -1,13 +1,14 @@ import datetime import json +import mimetypes import os import sys import time import warnings from typing import Dict, List, Optional, Union +import filetype import requests -from PIL import Image, UnidentifiedImageError from roboflow.adapters import rfapi from roboflow.config import API_URL, DEMO_KEYS @@ -15,7 +16,12 @@ from roboflow.util.general import Retry from roboflow.util.image_utils import load_labelmap -ACCEPTED_IMAGE_FORMATS = ["PNG", "JPEG"] +ACCEPTED_IMAGE_FORMATS = { + "image/bmp", + "image/jpeg", + "image/png", + "image/webp", +} def custom_formatwarning(msg, *args, **kwargs): @@ -346,15 +352,18 @@ def check_valid_image(self, image_path: str): Returns: bool: whether the image is valid or not - """ # noqa: E501 // docs - try: - img = Image.open(image_path) - valid = img.format in ACCEPTED_IMAGE_FORMATS - img.close() - except UnidentifiedImageError: + """ + kind = filetype.guess(image_path) + + if kind is None: return False - return valid + extension_mimetype, _ = mimetypes.guess_type(image_path) + + if extension_mimetype and extension_mimetype != kind.mime: + print(f"[{image_path}] file type ({kind.mime}) does not match filename extension.") + + return kind.mime in ACCEPTED_IMAGE_FORMATS def upload( self, diff --git a/roboflow/models/video.py b/roboflow/models/video.py index 1d474a56..03fdec19 100644 --- a/roboflow/models/video.py +++ b/roboflow/models/video.py @@ -3,7 +3,7 @@ from typing import Optional, Tuple from urllib.parse import urljoin -import magic +import filetype import requests from roboflow.config import API_URL @@ -24,11 +24,20 @@ }, } +ACCEPTED_VIDEO_FORMATS = { + "video/mp4", + "video/x-msvideo", # AVI + "video/webm", +} + def is_valid_mime(filename): - mime = magic.Magic(mime=True) - file_type = mime.from_file(filename) - return file_type in ["video/mp4", "video/avi", "video/webm"] + kind = filetype.guess(filename) + + if kind is None: + return False + + return kind.mime in ACCEPTED_VIDEO_FORMATS def is_valid_video(filename): From d8616495f61b0fd204d92880bb8f465d6ee115c8 Mon Sep 17 00:00:00 2001 From: Iuri de Silvio Date: Thu, 11 Jul 2024 13:28:56 +0200 Subject: [PATCH 2/3] Make mypy happy --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index ef74ce07..9c8bdec0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,6 +101,7 @@ exclude = ["^build/"] [[tool.mypy.overrides]] module = [ "_datetime.*", + "filetype.*", # IPython is an optional dependency "IPython.display.*", # ipywidgets is an optional dependency From 60c6571c67a7cc0002a4e732926eeeb375721494 Mon Sep 17 00:00:00 2001 From: Iuri de Silvio Date: Thu, 11 Jul 2024 14:44:59 +0200 Subject: [PATCH 3/3] Add typing --- roboflow/core/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roboflow/core/project.py b/roboflow/core/project.py index 91faa192..dcebdc79 100644 --- a/roboflow/core/project.py +++ b/roboflow/core/project.py @@ -343,7 +343,7 @@ def version(self, version_number: int, local: Optional[str] = None): raise RuntimeError(f"Version number {version_number} is not found.") - def check_valid_image(self, image_path: str): + def check_valid_image(self, image_path: str) -> bool: """ Check if an image is valid. Useful before attempting to upload an image to Roboflow.