diff --git a/.conda/meta.yaml b/.conda/meta.yaml index 3755e7f4e..53bb719c7 100644 --- a/.conda/meta.yaml +++ b/.conda/meta.yaml @@ -16,7 +16,7 @@ build: requirements: host: - - python>=3.9, <3.12 + - python>=3.10, <3.12 - setuptools run: diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 7ee17ebbb..15b4a5d7f 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - python: ["3.9", "3.10"] + python: ["3.10", "3.11"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -24,7 +24,7 @@ jobs: uses: actions/setup-python@v5 with: # MacOS issue ref.: https://github.com/actions/setup-python/issues/855 & https://github.com/actions/setup-python/issues/865 - python-version: ${{ matrix.os == 'macos-latest' && '3.11' || matrix.python }} + python-version: ${{ matrix.os == 'macos-latest' && matrix.python == '3.10' && '3.11' || matrix.python }} architecture: x64 - if: matrix.framework == 'tensorflow' name: Cache python modules (TF) @@ -58,7 +58,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.9 + python-version: "3.10" channels: pypdfium2-team,bblanchon,defaults,conda-forge channel-priority: strict - name: Install dependencies diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml index ad5a1045b..875fff8b0 100644 --- a/.github/workflows/demo.yml +++ b/.github/workflows/demo.yml @@ -26,7 +26,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -92,7 +92,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/doc-status.yml b/.github/workflows/doc-status.yml index 294f3dc55..7d2bda22d 100644 --- a/.github/workflows/doc-status.yml +++ b/.github/workflows/doc-status.yml @@ -9,7 +9,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: x64 - name: check status run: | diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 70302c957..99fac9c03 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,16 +12,16 @@ jobs: steps: - uses: actions/checkout@v4 - name: Build docker image - run: docker build -t doctr-tf-py3.9-slim --build-arg SYSTEM=cpu . + run: docker build -t doctr-tf-py3.10-slim --build-arg SYSTEM=cpu . - name: Run docker container - run: docker run doctr-tf-py3.9-slim python3 -c 'import doctr' + run: docker run doctr-tf-py3.10-slim python3 -c 'import doctr' pytest-api: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 79965b560..2b2c056a9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ac34c9cc7..f2c5e212a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -45,7 +45,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -78,7 +78,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/.github/workflows/public_docker_images.yml b/.github/workflows/public_docker_images.yml index 2ccdb6601..8d4e92939 100644 --- a/.github/workflows/public_docker_images.yml +++ b/.github/workflows/public_docker_images.yml @@ -22,7 +22,7 @@ jobs: fail-fast: false matrix: # Must match version at https://www.python.org/ftp/python/ - python: ["3.9.18", "3.10.13", "3.11.8"] + python: ["3.10.13", "3.11.8", "3.12.7"] framework: ["tf", "torch", "tf,viz,html,contrib", "torch,viz,html,contrib"] system: ["cpu", "gpu"] diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b09d8a429..2494fdaa1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -50,7 +50,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -73,7 +73,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.9 + python-version: "3.10" channels: pypdfium2-team,bblanchon,defaults,conda-forge channel-priority: strict - name: Install dependencies @@ -103,7 +103,7 @@ jobs: - uses: conda-incubator/setup-miniconda@v3 with: auto-update-conda: true - python-version: 3.9 + python-version: "3.10" - name: Install package shell: bash -el {0} run: | diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 045c4676f..8d972c855 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -12,7 +12,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9" + python-version: "3.10" architecture: x64 - name: Cache python modules uses: actions/cache@v4 diff --git a/.github/workflows/references.yml b/.github/workflows/references.yml index f79784244..bd614727d 100644 --- a/.github/workflows/references.yml +++ b/.github/workflows/references.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -65,7 +65,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -131,7 +131,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -186,7 +186,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -230,7 +230,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -274,7 +274,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -329,7 +329,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 @@ -375,7 +375,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] framework: [tensorflow, pytorch] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/scripts.yml b/.github/workflows/scripts.yml index d5f45aff2..892a6d3be 100644 --- a/.github/workflows/scripts.yml +++ b/.github/workflows/scripts.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9", "3.10"] + python: ["3.10", "3.11"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -59,7 +59,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9", "3.10"] + python: ["3.10", "3.11"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -105,7 +105,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python: ["3.9", "3.10"] + python: ["3.10", "3.11"] framework: [tensorflow, pytorch] steps: - if: matrix.os == 'macos-latest' @@ -150,14 +150,14 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ["3.9", "3.10"] + python: ["3.10", "3.11"] steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: # MacOS issue ref.: https://github.com/actions/setup-python/issues/855 & https://github.com/actions/setup-python/issues/865 - python-version: ${{ matrix.os == 'macos-latest' && '3.11' || matrix.python }} + python-version: ${{ matrix.os == 'macos-latest' && matrix.python == '3.10' && '3.11' || matrix.python }} architecture: x64 - name: Run environment collection script run: python scripts/collect_env.py diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index c755a06c1..47cc0d6e5 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 - name: Set up Python @@ -31,7 +31,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: ["3.9"] + python: ["3.10"] steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/README.md b/README.md index b0f3b9d5f..7231a64c3 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ The KIE predictor results per page are in a dictionary format with each key repr ### Prerequisites -Python 3.9 (or higher) and [pip](https://pip.pypa.io/en/stable/) are required to install docTR. +Python 3.10 (or higher) and [pip](https://pip.pypa.io/en/stable/) are required to install docTR. ### Latest release diff --git a/api/Dockerfile b/api/Dockerfile index 8038ed28c..6fd83e4eb 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9-slim +FROM tiangolo/uvicorn-gunicorn-fastapi:python3.10-slim WORKDIR /app diff --git a/api/pyproject.toml b/api/pyproject.toml index 9bafb6793..3f2140254 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -10,7 +10,7 @@ authors = ["Mindee "] license = "Apache-2.0" [tool.poetry.dependencies] -python = ">=3.9,<3.12" +python = ">=3.10,<3.13" python-doctr = {git = "https://github.com/mindee/doctr.git", extras = ['tf'], branch = "main" } # Fastapi: minimum version required to avoid pydantic error # cf. https://github.com/tiangolo/fastapi/issues/4168 diff --git a/docs/source/getting_started/installing.rst b/docs/source/getting_started/installing.rst index e764e734a..39e79aa3d 100644 --- a/docs/source/getting_started/installing.rst +++ b/docs/source/getting_started/installing.rst @@ -3,7 +3,7 @@ Installation ************ -This library requires `Python `_ 3.9 or higher. +This library requires `Python `_ 3.10 or higher. Prerequisites diff --git a/doctr/models/_utils.py b/doctr/models/_utils.py index c5dcd9ba8..ab1922c90 100644 --- a/doctr/models/_utils.py +++ b/doctr/models/_utils.py @@ -64,13 +64,13 @@ def estimate_orientation( gray_img = cv2.medianBlur(gray_img, 5) thresh = cv2.threshold(gray_img, thresh=0, maxval=255, type=cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] else: - thresh = img.astype(np.uint8) # type: ignore[assignment] + thresh = img.astype(np.uint8) page_orientation, orientation_confidence = general_page_orientation or (None, 0.0) if page_orientation and orientation_confidence >= min_confidence: # We rotate the image to the general orientation which improves the detection # No expand needed bitmap is already padded - thresh = rotate_image(thresh, -page_orientation) # type: ignore + thresh = rotate_image(thresh, -page_orientation) else: # That's only required if we do not work on the detection models bin map # try to merge words in lines (h, w) = img.shape[:2] diff --git a/doctr/models/detection/differentiable_binarization/base.py b/doctr/models/detection/differentiable_binarization/base.py index 21eceb794..414471146 100644 --- a/doctr/models/detection/differentiable_binarization/base.py +++ b/doctr/models/detection/differentiable_binarization/base.py @@ -114,7 +114,7 @@ def bitmap_to_boxes( contours, _ = cv2.findContours(bitmap.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # Check whether smallest enclosing bounding box is not too small - if np.any(contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0) < min_size_box): # type: ignore[index] + if np.any(contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0) < min_size_box): continue # Compute objectness if self.assume_straight_pages: diff --git a/doctr/models/detection/fast/base.py b/doctr/models/detection/fast/base.py index f98981a82..1b3a02bb2 100644 --- a/doctr/models/detection/fast/base.py +++ b/doctr/models/detection/fast/base.py @@ -111,7 +111,7 @@ def bitmap_to_boxes( contours, _ = cv2.findContours(bitmap.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # Check whether smallest enclosing bounding box is not too small - if np.any(contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0) < 2): # type: ignore[index] + if np.any(contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0) < 2): continue # Compute objectness if self.assume_straight_pages: diff --git a/doctr/models/detection/linknet/base.py b/doctr/models/detection/linknet/base.py index d677048c0..9aeb543fe 100644 --- a/doctr/models/detection/linknet/base.py +++ b/doctr/models/detection/linknet/base.py @@ -111,7 +111,7 @@ def bitmap_to_boxes( contours, _ = cv2.findContours(bitmap.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for contour in contours: # Check whether smallest enclosing bounding box is not too small - if np.any(contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0) < 2): # type: ignore[index] + if np.any(contour[:, 0].max(axis=0) - contour[:, 0].min(axis=0) < 2): continue # Compute objectness if self.assume_straight_pages: diff --git a/doctr/utils/geometry.py b/doctr/utils/geometry.py index 21ad0dd7f..653b9f8b9 100644 --- a/doctr/utils/geometry.py +++ b/doctr/utils/geometry.py @@ -126,7 +126,7 @@ def resolve_enclosing_rbbox(rbboxes: List[np.ndarray], intermed_size: int = 1024 # Convert to absolute for minAreaRect cloud *= intermed_size rect = cv2.minAreaRect(cloud.astype(np.int32)) - return cv2.boxPoints(rect) / intermed_size # type: ignore[return-value] + return cv2.boxPoints(rect) / intermed_size def rotate_abs_points(points: np.ndarray, angle: float = 0.0) -> np.ndarray: @@ -344,7 +344,7 @@ def rotate_image( # Pad height else: h_pad, w_pad = int(rot_img.shape[1] * image.shape[0] / image.shape[1] - rot_img.shape[0]), 0 - rot_img = np.pad(rot_img, ((h_pad // 2, h_pad - h_pad // 2), (w_pad // 2, w_pad - w_pad // 2), (0, 0))) # type: ignore[assignment] + rot_img = np.pad(rot_img, ((h_pad // 2, h_pad - h_pad // 2), (w_pad // 2, w_pad - w_pad // 2), (0, 0))) if preserve_origin_shape: # rescale rot_img = cv2.resize(rot_img, image.shape[:-1][::-1], interpolation=cv2.INTER_LINEAR) @@ -563,4 +563,4 @@ def extract_rcrops( ) for idx in range(_boxes.shape[0]) ] - return crops # type: ignore[return-value] + return crops diff --git a/pyproject.toml b/pyproject.toml index 613eb512e..763e96618 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ maintainers = [ {name = "Felix Dittrich"}, ] readme = "README.md" -requires-python = ">=3.9.0,<4" +requires-python = ">=3.10.0,<4" license = {file = "LICENSE"} keywords=["OCR", "deep learning", "computer vision", "tensorflow", "pytorch", "text detection", "text recognition"] classifiers=[ @@ -25,9 +25,9 @@ classifiers=[ "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] dynamic = ["version"] @@ -183,7 +183,7 @@ ignore_missing_imports = true [tool.ruff] exclude = [".git", "venv*", "build", "**/__init__.py"] line-length = 120 -target-version = "py39" +target-version = "py310" preview=true [tool.ruff.lint] diff --git a/references/detection/utils.py b/references/detection/utils.py index 1a84f2340..265f63ff3 100644 --- a/references/detection/utils.py +++ b/references/detection/utils.py @@ -28,7 +28,7 @@ def plot_samples(images, targets: List[Dict[str, np.ndarray]]) -> None: for box in boxes: if boxes.ndim == 3: - cv2.fillPoly(target, [np.int0(box)], 1) + cv2.fillPoly(target, [np.intp(box)], 1) else: target[int(box[1]) : int(box[3]) + 1, int(box[0]) : int(box[2]) + 1] = 1 if nb_samples > 1: