Skip to content

Commit

Permalink
Fix test of CLI tool across OSes and Python versions (#1)
Browse files Browse the repository at this point in the history
* add runs-on

* make ~/wsi directory

* add "from __future__ import annotations"

* quiet wget + test only on ubuntu temporarily

* set cache key + test wsinfer-mil twice

* install jsonschema in main deps

* run ruff once per pr

* mk ~/wsi only if it does not exist

* run only on ubuntu

* rename to Linux

* add tests on windows and macos

* add mypy workflow

* [skip ci] rename job

* use invoke webrequest for windows

* use dir other than /tmp

* set default num_workers=-1
  • Loading branch information
kaczmarj authored Mar 7, 2024
1 parent 6a069d4 commit 32ccace
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
name: Test CLI
name: Linux
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
Test-CLI:
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
steps:
- name: Cache sample WSI
uses: actions/cache@v3
with:
path: ~/wsi/
key: sample-wsi
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
Expand All @@ -24,14 +25,17 @@ jobs:
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu
python -m pip install .[dev]
python -m pip install .
- name: Download sample WSI
run: |
mkdir -p ~/wsi
cd ~/wsi
wget -nc https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1.svs
wget -nc -q https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1.svs
cd -
- name: Run tests
# Go to a different directory to test that WSInfer-MIL still finds everything it needs.
# Test it twice so the second time we get cache hits.
run: |
cd /tmp
wsinfer-mil run -m kaczmarj/pancancer-tissue-classifier.tcga -i ~/wsi/CMU-1.svs
wsinfer-mil run -m kaczmarj/pancancer-tissue-classifier.tcga -i ~/wsi/CMU-1.svs
41 changes: 41 additions & 0 deletions .github/workflows/cli-test-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: macOS
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
Test-CLI:
runs-on: macos-latest
strategy:
matrix:
python-version: ["3.10"]
steps:
- name: Cache sample WSI
uses: actions/cache@v3
with:
path: ~/wsi/
key: sample-wsi
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install WSInfer-CLI
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu
python -m pip install .
- name: Download sample WSI
run: |
mkdir -p ~/wsi
cd ~/wsi
wget -nc -q https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1.svs
cd -
- name: Run tests
# Go to a different directory to test that WSInfer-MIL still finds everything it needs.
# Test it twice so the second time we get cache hits.
run: |
cd /tmp
wsinfer-mil run -m kaczmarj/pancancer-tissue-classifier.tcga -i ~/wsi/CMU-1.svs
wsinfer-mil run -m kaczmarj/pancancer-tissue-classifier.tcga -i ~/wsi/CMU-1.svs
44 changes: 44 additions & 0 deletions .github/workflows/cli-test-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Windows
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
Test-CLI:
runs-on: windows-latest
strategy:
matrix:
python-version: ["3.10"]
steps:
- name: Cache sample WSI
id: cache-wsi
uses: actions/cache@v3
with:
path: ~/wsi/
key: sample-wsi
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install WSInfer-CLI
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu
python -m pip install .
- name: Download sample WSI
if: steps.cache-wsi.outputs.cache-hit != 'true'
run: |
mkdir -p ~/wsi
cd ~/wsi
Invoke-WebRequest -URI https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1.svs -OutFile CMU-1.svs
cd -
- name: Run tests
# Go to a different directory to test that WSInfer-MIL still finds everything it needs.
# Test it twice so the second time we get cache hits.
run: |
mkdir -p ~/foobar
cd ~/foobar
wsinfer-mil run -m kaczmarj/pancancer-tissue-classifier.tcga -i ~/wsi/CMU-1.svs
wsinfer-mil run -m kaczmarj/pancancer-tissue-classifier.tcga -i ~/wsi/CMU-1.svs
25 changes: 25 additions & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Static Analysis
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
MyPy:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install WSInfer-CLI
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu
python -m pip install .[dev] mypy
- name: Run mypy
run: python -m mypy --install-types --non-interactive wsinfer_mil
6 changes: 5 additions & 1 deletion .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Ruff
on: [push, pull_request]
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
ruff:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ dependencies = [
"click>=8.0,<9,!=8.1.4,!=8.1.5",
"h5py",
"huggingface_hub",
"jsonschema",
# This is when numpy.typing.NDArray was introduced.
"numpy>=1.21.0",
"opencv-python-headless>=4.0.0",
Expand Down Expand Up @@ -64,7 +65,6 @@ dynamic = ["version"]
[project.optional-dependencies]
dev = [
"geojson",
"jsonschema",
"mypy",
"pre-commit",
"pytest",
Expand Down
2 changes: 2 additions & 0 deletions wsinfer_mil/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from wsinfer_mil.cli import cli

if __name__ == "__main__":
Expand Down
11 changes: 8 additions & 3 deletions wsinfer_mil/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Command line interface for WSInfer MIL."""

from __future__ import annotations

import logging
import os
from pathlib import Path
Expand Down Expand Up @@ -80,9 +82,10 @@ def cli() -> None:
@click.option(
"-j",
"--num-workers",
help="Number of workers to use during patch feature extraction",
type=click.IntRange(min=0, max=os.cpu_count()),
default=4,
help="Number of workers to use during patch feature extraction. -1 (default) uses"
" all cores.",
type=click.IntRange(min=-1, max=os.cpu_count()),
default=-1,
show_default=True,
)
@click.option(
Expand All @@ -104,6 +107,8 @@ def run(
json: bool,
) -> None:
model = load_torchscript_model_from_hf(hf_repo_id, hf_repo_revision)
if num_workers == -1:
num_workers = os.cpu_count() or 0
_run_impl(
wsi_path=wsi_path,
model=model,
Expand Down
1 change: 1 addition & 0 deletions wsinfer_mil/client/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from __future__ import annotations
2 changes: 2 additions & 0 deletions wsinfer_mil/defaults.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from pathlib import Path

from platformdirs import user_cache_dir
Expand Down
2 changes: 2 additions & 0 deletions wsinfer_mil/errors.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Errors for WSInfer MIL."""

from __future__ import annotations


class WSInferMILException(Exception):
"""Base exception for WSInfer MIL."""
Expand Down
2 changes: 2 additions & 0 deletions wsinfer_mil/wsi_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import tiffslide
from tiffslide.tiffslide import PROPERTY_NAME_MPP_X
from tiffslide.tiffslide import PROPERTY_NAME_MPP_Y
Expand Down

0 comments on commit 32ccace

Please sign in to comment.