Repository: brisvag/blik (language: python)

Issue:
Napari plugin
Now that `npe2` and the napari hub are getting pretty good, it would be nice to at least have `blik` show up in the hub.

This PR introduces some big infrastructural changes, migrating away from the clunky dataset + depictor model into a more native plugin system. Yippie!

I also take this chance to update all the testing and packaging stuff to better reflect napari plugins and napari itself. EDIT: moved it to #126 and merged separately.

Features in this PR:
- [x] separated the io stuff out into [naaf](https://github.com/gutsche-lab/naaf). It can now be used as a library and gives reasonably simple outputs. Here, we have a simple wrapper that reshapes the output of `naaf.read` into napari layers. 
- [x] reader plugin
    - [x] reader widget with additional options that are otherwise impossible from the napari reader interface
- [x] volume selector widget as plugin. Works with some black magic
    - [x] update automatically when new layers are added
- [x] simple filter widgets that help a tiny bit

TODO, maybe in a later PR:
- put layers in groups, rather than having to use a widget for browsing through volumes. Needs layergroups in core napari :)

Napari plugin
Now that `npe2` and the napari hub are getting pretty good, it would be nice to at least have `blik` show up in the hub.

This PR introduces some big infrastructural changes, migrating away from the clunky dataset + depictor model into a more native plugin system. Yippie!

I also take this chance to update all the testing and packaging stuff to better reflect napari plugins and napari itself. EDIT: moved it to #126 and merged separately.

Features in this PR:
- [x] separated the io stuff out into [naaf](https://github.com/gutsche-lab/naaf). It can now be used as a library and gives reasonably simple outputs. Here, we have a simple wrapper that reshapes the output of `naaf.read` into napari layers. 
- [x] reader plugin
    - [x] reader widget with additional options that are otherwise impossible from the napari reader interface
- [x] volume selector widget as plugin. Works with some black magic
    - [x] update automatically when new layers are added
- [x] simple filter widgets that help a tiny bit

TODO, maybe in a later PR:
- put layers in groups, rather than having to use a widget for browsing through volumes. Needs layergroups in core napari :)



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/make_docs.yml b/.github/workflows/make_docs.yml
index 92f15da5..270b6e01 100644
--- a/.github/workflows/make_docs.yml
+++ b/.github/workflows/make_docs.yml
@@ -2,6 +2,8 @@ name: Make docs
 
 on:
   push:
+    branches:
+      - main
     tags:
       - 'v[0-9]+.[0-9]+.[0-9]+'  # accept all tags of the format vX.X.X
 
@@ -12,11 +14,11 @@ jobs:
     if: github.repository == 'gutsche-lab/blik'
     steps:
     - name: Checkout code
-      uses: actions/checkout@master
+      uses: actions/checkout@main
     - name: Install Python
       uses: actions/setup-python@v2
       with:
-        python-version: 3.8
+        python-version: 3.9
     - name: Install Dependencies
       working-directory: ./docs
       run: |
diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml
deleted file mode 100644
index 225f319c..00000000
--- a/.github/workflows/publish_pypi.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: Upload to pypi
-
-on:
-  push:
-    tags:
-      - 'v[0-9]+.[0-9]+.[0-9]+'  # accept all tags of the format vX.X.X
-
-jobs:
-  deploy:
-    name: Create Release
-    runs-on: ubuntu-latest
-    if: github.repository == 'gutsche-lab/blik'
-    steps:
-    - name: Checkout code
-      uses: actions/checkout@master
-    - name: Install Python
-      uses: actions/setup-python@v2
-      with:
-        python-version: 3.8
-    - name: Install Dependencies
-      run: |
-        python -m pip install --upgrade pip
-        python -m pip install pep517
-    - name: Build Distribution
-      run: |
-        python -m pep517.build .
-    - name: Publish PyPI Package
-      uses: pypa/gh-action-pypi-publish@master
-      with:
-        user: ${{ secrets.PYPI_USERNAME }}
-        password: ${{ secrets.PYPI_PASSWORD }}
diff --git a/.github_changelog_generator b/.github_changelog_generator
new file mode 100644
index 00000000..e050930a
--- /dev/null
+++ b/.github_changelog_generator
@@ -0,0 +1,5 @@
+user=gutsche-lab
+project=blik
+issues=false
+exclude-labels=duplicate,question,invalid,wontfix,hide
+add-sections={"tests":{"prefix":"**Tests & CI:**","labels":["tests"]}, "documentation":{"prefix":"**Documentation:**", "labels":["documentation"]}}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..27381008
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,21 @@
+repos:
+-   repo: https://github.com/pycqa/isort
+    rev: 5.10.1
+    hooks:
+    - id: isort
+-   repo: https://github.com/psf/black
+    rev: 21.12b0
+    hooks:
+    - id: black
+      pass_filenames: true
+-   repo: https://github.com/PyCQA/flake8
+    rev: 4.0.1
+    hooks:
+    - id: flake8
+      additional_dependencies: [flake8-typing-imports==1.11.0]
+      pass_filenames: true
+-   repo: https://github.com/asottile/pyupgrade
+    rev: v2.31.0
+    hooks:
+    - id: pyupgrade
+      args: ["--py38-plus", "--keep-runtime-typing"]
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..e69de29b
diff --git a/README.md b/README.md
index 23d91f2f..423f00f4 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
 
 # `blik`
 
-![Codecov branch](https://img.shields.io/codecov/c/github/gutsche-lab/blik/master?label=codecov)
+![Codecov branch](https://img.shields.io/codecov/c/github/gutsche-lab/blik/main?label=codecov)
 ![PyPI](https://img.shields.io/pypi/v/blik)
 ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/blik)
 
diff --git a/docs/_config.yml b/docs/_config.yml
index abdebfa1..75d7b98e 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -16,7 +16,7 @@ execute:
 repository:
   url: https://github.com/gutsche-lab/blik # Online location of your book
   path_to_book: docs # Optional path to your book, relative to the repository root
-  branch: master # Which branch of the repository should be used when creating links (optional)
+  branch: main # Which branch of the repository should be used when creating links (optional)
 
 # Add GitHub buttons to your book
 # See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 466b5faf..237f1d18 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,2 +1,2 @@
-jupyter-book>=0.11
+jupyter-book>=0.12.1
 sphinx_material
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 525e3e70..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,1 +0,0 @@
--e ".[dev]"
diff --git a/setup.cfg b/setup.cfg
index 6f5f1dfa..d593ab29 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,10 +1,11 @@
 [metadata]
 name = blik
 url = https://github.com/gutsche-lab/blik
+download_url = https://github.com/gutsche-lab/blik
 license = GNU General Public License v3 (GPLv3)
 license_file = LICENSE
 description = Python tool for visualising and interacting with cryo-ET and subtomogram averaging data.
-long_description = file: README.md
+long_description = file: README.md, CHANGELOG.md
 long_description_content_type = text/markdown
 author = Blik Team
 author_email = blik-team@googlegroups.com
@@ -18,6 +19,8 @@ classifiers =
     Programming Language :: Python :: 3 :: Only
     Programming Language :: Python :: 3.7
     Programming Language :: Python :: 3.8
+    Programming Language :: Python :: 3.9
+    Programming Language :: Python :: 3.10
     Topic :: Scientific/Engineering
     Topic :: Scientific/Engineering :: Visualization
     Topic :: Scientific/Engineering :: Information Analysis
@@ -27,13 +30,21 @@ classifiers =
     Operating System :: POSIX
     Operating System :: Unix
     Operating System :: MacOS
-
+    Framework :: napari
+project_urls =
+    Bug Tracker = https://github.com/gutsche-lab/blik/issues
+    Documentation = https://github.com/gutsche-lab/blik#README.md
+    Source Code = https://github.com/gutsche-lab/blik
+    User Support = https://github.com/gutsche-lab/blik/issues
+    Changelog = https://github.com/gutsche-lab/blik/blob/main/CHANGELOG.md
 
 [options]
 zip_safe = False
 packages = find:
 python_requires = >= 3.8
 include_package_data = True
+setup_requires =
+    setuptools_scm
 install_requires =
     napari>=0.4.12
     numpy
@@ -50,10 +61,17 @@ install_requires =
 
 
 [options.extras_require]
-dev =
+testing =
+    tox
     pytest
     pytest-qt
     pyqt5
+dev =
+    black
+    flake8
+    isort
+    pre-commit
+    %(testing)s
 
 
 [options.entry_points]
@@ -64,9 +82,14 @@ console_scripts =
 [options.package_data]
 * = *.txt, *.md
 
+[bdist_wheel]
+universal = 1
 
 [flake8]
-# E116, E117: unexpected indentations in comment (happens when commenting out code)
-ignore = E116,E117
-exclude = __init__.py,docs,examples
+exclude = docs,_version.py,.eggs,examples
 max-line-length = 120
+docstring-convention = numpy
+
+[isort]
+profile = black
+src_paths = blik
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 419fa401..00000000
--- a/setup.py
+++ /dev/null
@@ -1,10 +0,0 @@
-"""
-PEP 517 doesn’t support editable installs
-so this file is currently here to support "pip install -e ."
-"""
-from setuptools import setup
-
-setup(
-    use_scm_version={"write_to": "blik/_version.py"},
-    setup_requires=["setuptools_scm"],
-)
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 00000000..71462558
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,66 @@
+[tox]
+envlist = py{38,39,310}-{linux,macos,windows}
+toxworkdir=/tmp/.tox
+isolated_build = True
+
+[gh-actions]
+python =
+    3.8: py38
+    3.9: py39
+    3.10: py310
+
+[gh-actions:env]
+PLATFORM =
+    ubuntu-latest: linux
+    macos-latest: macos
+    windows-latest: windows
+
+[testenv]
+platform =
+    macos: darwin
+    linux: linux
+    windows: win32
+passenv =
+    CI
+    GITHUB_ACTIONS
+    DISPLAY
+    XAUTHORITY
+setenv =
+    PYTHONPATH = {toxinidir}
+deps =
+    pytest-cov
+extras =
+    testing
+commands =
+    pytest -v --color=yes --cov-report=xml --cov=blik --basetemp={envtmpdir} {posargs}
+
+[testenv:isort]
+skip_install = True
+deps = pre-commit
+commands = pre-commit run isort --all-files
+
+[testenv:flake8]
+skip_install = True
+deps = pre-commit
+commands = pre-commit run flake8 --all-files
+
+[testenv:black]
+skip_install = True
+deps = pre-commit
+commands = pre-commit run black --all-files
+
+[testenv:import-lint]
+skip_install = True
+deps = pre-commit
+commands = pre-commit run --hook-stage manual import-linter --all-files
+
+[testenv:package]
+isolated_build = true
+skip_install = true
+deps =
+    wheel
+    twine
+    build
+commands =
+    python -m build
+    python -m twine check dist/*


Test patch:
diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml
new file mode 100644
index 00000000..5fa12fd5
--- /dev/null
+++ b/.github/workflows/test_and_deploy.yml
@@ -0,0 +1,74 @@
+name: tests
+
+on:
+  push:
+    branches:
+      - main
+    tags:
+      - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10
+  pull_request:
+    branches:
+      - main
+  workflow_dispatch:
+
+jobs:
+  test:
+    name: ${{ matrix.platform }} (${{ matrix.python-version }})
+    runs-on: ${{ matrix.platform }}
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: ["3.8", "3.9", "3.10"]
+        platform: [ubuntu-latest, macos-latest, windows-latest]
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python ${{ matrix.python-version }}
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Set up QT libraries
+        uses: tlambert03/setup-qt-libs@v1
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install setuptools tox tox-gh-actions
+      - name: Test with tox
+        run: tox
+        env:
+          PLATFORM: ${{ matrix.platform }}
+      - name: Coverage
+        if: runner.os == 'Linux'
+        uses: codecov/codecov-action@v2
+        with:
+          files: ./coverage.xml
+          fail_ci_if_error: true
+
+  deploy:
+    needs: test
+    runs-on: ubuntu-latest
+    if: ${{ github.repository == 'gutsche-lab/naaf' && contains(github.ref, 'tags') }}
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: "3.x"
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install -U setuptools setuptools_scm wheel twine build
+      - name: Build
+        run: |
+          git tag
+          python -m build
+          twine check dist/*
+      - name: Create Release
+        uses: softprops/action-gh-release@v1
+        with:
+          files: dist/*
+          body_path: ${{ github.workspace }}/CHANGELOG.md
+      - name: Publish
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }}
+        run: twine upload dist/*
diff --git a/.github/workflows/test_pr.yml b/.github/workflows/test_pr.yml
deleted file mode 100644
index 86d00b62..00000000
--- a/.github/workflows/test_pr.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Test PR
-
-on:
-  pull_request:
-    branches:
-      - master
-
-jobs:
-  pytest:
-    name: Test Pull Request
-    runs-on: ubuntu-latest
-    if: github.repository == 'gutsche-lab/blik'
-    steps:
-    - name: Checkout code
-      uses: actions/checkout@v2
-      with:
-        fetch-depth: 2
-    - name: Install Python
-      uses: actions/setup-python@v2
-      with:
-        python-version: 3.8
-    - name: Install qt libraries
-      run: |
-        sudo apt-get install -y libdbus-1-3 libxkbcommon-x11-0 libxcb-icccm4 \
-          libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 \
-          libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 xvfb
-    - name: Install Dependencies
-      run: |
-        python -m pip install --upgrade pip
-        python -m pip install pytest-cov pytest-qt codecov PyQt5
-        python -m pip install -r requirements.txt
-    - name: Run Tests
-      run: |
-        xvfb-run pytest --cov=./blik
-        codecov
-    - name: Upload report to codecov
-      run: |
-        bash <(curl -s https://codecov.io/bash)
diff --git a/blik/gui/_tests/test_viewer.py b/blik/gui/_tests/test_viewer.py
deleted file mode 100644
index d549cd8f..00000000
--- a/blik/gui/_tests/test_viewer.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from blik.dataset import DataSet
-from blik.datablocks import PointBlock
-
-
-def test_viewer(make_napari_viewer):
-    dataset = DataSet(PointBlock(data=[[0, 0, 0]]))
-    viewer = make_napari_viewer(strict_qt=False)
-    dataset.show(napari_viewer=viewer)
-    dataset.viewer.toggle_plots()
-    dataset.viewer.update_blik_widget()
-    dataset.viewer.previous_volume()
-    dataset.viewer.next_volume()
-    dataset.purge_gui()