Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support openslide-bin #267

Merged
merged 2 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13-dev"]
openslide: [system, wheel]
include:
- os: ubuntu-latest
python-version: "3.12"
openslide: system
sdist: sdist
# Python 3.8 is too old to support universal binaries, and
# setup-python's Python 3.9 and 3.10 won't build them. Use the
Expand Down Expand Up @@ -86,7 +88,8 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install auditwheel build jinja2 pytest
- name: Install OpenSlide
- name: Install OpenSlide (system)
if: matrix.openslide == 'system'
run: |
case "${{ matrix.os }}" in
ubuntu-latest)
Expand All @@ -99,6 +102,9 @@ jobs:
brew install openslide
;;
esac
- name: Install OpenSlide (wheel)
if: matrix.openslide == 'wheel'
run: pip install openslide-bin
- name: Build dist
run: |
if [ -z "${{ matrix.sdist }}" ]; then
Expand All @@ -124,9 +130,10 @@ jobs:
fi
mkdir -p "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
mv dist/* "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
# save version-specific wheels and oldest abi3 wheel
# from system builds, save version-specific wheels and oldest abi3 wheel
python -c 'import sys
if sys.version_info < (3, 12): print("archive_wheel=1")' >> $GITHUB_ENV
if sys.version_info < (3, 12) and "${{ matrix.openslide }}" == "system":
print("archive_wheel=1")' >> $GITHUB_ENV
- name: Install
run: pip install artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}/*.whl
- name: Run tests
Expand Down Expand Up @@ -158,6 +165,7 @@ jobs:
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13-dev"]
openslide: [zip, wheel]
steps:
- name: Check out repo
uses: actions/checkout@v4
Expand All @@ -169,7 +177,8 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install build flask pytest
- name: Install OpenSlide
- name: Install OpenSlide (zip)
if: matrix.openslide == 'zip'
env:
GH_TOKEN: ${{ github.token }}
run: |
Expand All @@ -184,14 +193,18 @@ jobs:
--pattern "${zipname}.zip"
7z x ${zipname}.zip
echo "OPENSLIDE_PATH=c:\\openslide\\${zipname}\\bin" >> $GITHUB_ENV
- name: Install OpenSlide (wheel)
if: matrix.openslide == 'wheel'
run: pip install openslide-bin
- name: Build wheel
run: |
python -m build -w
mkdir -p "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
mv dist/*.whl "artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}"
# save version-specific wheels and oldest abi3 wheel
# from zip builds, save version-specific wheels and oldest abi3 wheel
python -c 'import sys
if sys.version_info < (3, 12): print("archive_wheel=1")' >> $GITHUB_ENV
if sys.version_info < (3, 12) and "${{ matrix.openslide }}" == "zip":
print("archive_wheel=1")' >> $GITHUB_ENV
- name: Install
run: pip install artifacts/whl/${{ needs.pre-commit.outputs.dist-base }}/*.whl
- name: Run tests
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@ OpenSlide can read virtual slides in several formats:

## Installation

OpenSlide Python requires [OpenSlide]. For instructions on installing both
components so OpenSlide Python can find OpenSlide, see the package
[documentation][installing].
OpenSlide Python requires [OpenSlide]. Install both components from PyPI
with:

```console
pip install openslide-python openslide-bin
```

Or, see the [OpenSlide Python documentation][installing] for instructions on
installing so OpenSlide Python can find OpenSlide.

[installing]: https://openslide.org/api/python/#installing

Expand Down
14 changes: 9 additions & 5 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,20 @@ Installing
==========

OpenSlide Python requires OpenSlide_, which must be installed separately.
If you intend to use OpenSlide only with Python, the easiest way to get it
is to install the openslide-bin_ Python package with
``pip install openslide-bin``.

On Linux and macOS, the easiest way to get both components is to install_
with a package manager that packages both, such as Anaconda_, DNF or Apt on
Linux systems, or MacPorts_ on macOS systems. You can also install
On Linux and macOS, you can also install_ both OpenSlide and OpenSlide
Python with a package manager that packages both, such as Anaconda_, DNF or
Apt on Linux systems, or MacPorts_ on macOS systems. Or, you can install
OpenSlide Python with pip_ after installing OpenSlide with a package manager
or from source_. Except for pip, do not mix OpenSlide and OpenSlide Python
from different package managers (for example, OpenSlide from MacPorts and
OpenSlide Python from Anaconda), since you'll get library conflicts.

On Windows, download the OpenSlide `Windows binaries`_ and extract them
to a known path. Then, import ``openslide`` inside a
On Windows, you can also download the OpenSlide `Windows binaries`_ and
extract them to a known path. Then, import ``openslide`` inside a
``with os.add_dll_directory()`` statement::

# The path can also be read from a config file, etc.
Expand All @@ -73,6 +76,7 @@ to a known path. Then, import ``openslide`` inside a
else:
import openslide

.. _openslide-bin: https://pypi.org/project/openslide-bin/
.. _install: https://openslide.org/download/#distribution-packages
.. _Anaconda: https://anaconda.org/
.. _MacPorts: https://www.macports.org/
Expand Down
27 changes: 22 additions & 5 deletions openslide/lowlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@


def _load_library():
try:
import openslide_bin

return openslide_bin.libopenslide1
except (AttributeError, ModuleNotFoundError):
pass

def try_load(names):
for name in names:
try:
Expand All @@ -65,8 +72,10 @@ def try_load(names):
return try_load(['libopenslide-1.dll', 'libopenslide-0.dll'])
except FileNotFoundError:
raise ModuleNotFoundError(
"Couldn't locate OpenSlide DLL. "
"Did you call os.add_dll_directory()? "
"Couldn't locate OpenSlide DLL. "
"Try `pip install openslide-bin`, "
"or if you're using an OpenSlide binary package, "
"ensure you've called os.add_dll_directory(). "
"https://openslide.org/api/python/#installing"
)
elif platform.system() == 'Darwin':
Expand All @@ -81,12 +90,20 @@ def try_load(names):
lib = ctypes.util.find_library('openslide')
if lib is None:
raise ModuleNotFoundError(
"Couldn't locate OpenSlide dylib. Is OpenSlide installed "
"correctly? https://openslide.org/api/python/#installing"
"Couldn't locate OpenSlide dylib. "
"Try `pip install openslide-bin`. "
"https://openslide.org/api/python/#installing"
)
return cdll.LoadLibrary(lib)
else:
return try_load(['libopenslide.so.1', 'libopenslide.so.0'])
try:
return try_load(['libopenslide.so.1', 'libopenslide.so.0'])
except OSError:
raise ModuleNotFoundError(
"Couldn't locate OpenSlide shared library. "
"Try `pip install openslide-bin`. "
"https://openslide.org/api/python/#installing"
)


_lib = _load_library()
Expand Down
Loading