Repository: metagentools/GraphBin (language: python)

Issue:
project refactor to improve portability
Suggest the following structural changes to enable distribution via PyPI and also for Windows users

```
src/
   graph bin/
      __init__.py  # this should be your current graphbin file
      utils/
         ... # all files currently under graphbin_utils
      support/
         ... # all files currently under support
tests/
   data/  # test_data dir renamed to here
   ... test scripts
pyproject.toml  # replace setup.py with this, hook into scripts
```


Discussion / hints:

Fix patch:
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..679bc10
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,34 @@
+syntax:glob
+.svn
+*.pyc
+*.pyo
+*.so
+*.o
+*.DS_Store
+*.tmproj
+*.rej
+*.orig
+*.wpr
+*.pdf
+_build/*
+build
+*htmlcov*
+*.idea
+draw_results
+*.coverage*
+*egg-info*
+*.wpu
+.cache*
+*taskpaper
+*.ipynb_checkpoints*
+*.sublime*
+*.patch
+*.pytest_cache
+*.tox
+*.nox
+*.vscode
+*.code-workspace
+coverage.xml
+__pycache__
+junit-*.xml
+dist/*
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..b88cde5
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,90 @@
+[build-system]
+requires = ["flit_core >=3.2,<4"]
+build-backend = "flit_core.buildapi"
+
+[project]
+name = "graphbin"
+authors = [
+    { name = "Vijini Mallawaarachchi", email = "Vijini.Mallawaarachchi@anu.edu.au"},
+    { name = "Anuradha Wickramarachchi", email = "Anuradha.Wickramarachchi@anu.edu.au"},
+    { name = "Yu Lin", email = "yu.lin@anu.edu.au"},
+]
+keywords = ["genomics", "bioinformatics"]
+readme = "README.md"
+license = { file = "LICENSE" }
+requires-python = ">=3.7"
+dependencies = ["python-igraph", "cogent3", "cairocffi"]
+classifiers = [
+        "Development Status :: 5 - Production/Stable",
+        "Intended Audience :: Science/Research",
+        "License :: OSI Approved :: BSD License",
+        "Topic :: Scientific/Engineering :: Bio-Informatics",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+    ]
+dynamic = ["version", "description"]
+
+[project.urls]
+Documentation = "https://graphbin.readthedocs.io/en/latest/"
+"Bug Tracker" = "https://github.com/metagentools/GraphBin/issues"
+"Source Code" = "https://github.com/metagentools/GraphBin/"
+
+[project.scripts]
+graphbin = "graphbin:main"
+
+[project.optional-dependencies]
+test = [
+    "nox",
+    "pytest",
+    "pytest-cov",
+    "pytest-xdist",
+]
+dev = [
+    "black",
+    "click",
+    "docformatter",
+    "flit",
+    "nox",
+    "isort",
+    "pytest",
+    "pytest-cov",
+    "pytest-xdist",
+]
+
+[tool.flit.sdist]
+include = ["docs/", "requirements.txt", "src/*", "pyproject.toml"]
+exclude = ["docs/*.html"]
+
+[tool.pytest.ini_options]
+addopts = ["--strict-config", "-ra"]
+testpaths = "tests"
+
+[tool.black]
+line-length = 88
+target-version = ['py37', 'py38', 'py39', 'py310']
+exclude = '''
+/(
+    \.eggs
+  | \.git
+  | \.hg
+  | \.mypy_cache
+  | \.tox
+  | \.venv
+  | _build
+  | build
+  | doc
+  | dist
+  | tests/data
+)/
+'''
+
+[tool.isort]
+atomic=true
+force_grid_wrap=0
+include_trailing_comma=true
+lines_after_imports=2
+lines_between_types=1
+multi_line_output=3
+use_parentheses=true
diff --git a/setup.py b/setup.py
deleted file mode 100644
index c4f6d12..0000000
--- a/setup.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-
-from setuptools import find_packages, setup
-
-with open("README.md") as f:
-    long_description = f.read()
-
-packages = find_packages()
-package_data = {
-    "graphbin_utils": [
-        "graphbin_utils/*.py",
-        "graphbin_utils/bidirectionalmap/*.py",
-        "graphbin_utils/labelpropagation/*.py",
-    ]
-}
-data_files = [(".", ["LICENSE", "README.md"])]
-
-setup(
-    name="graphbin",
-    version="1.4",
-    author="Vijini Mallawaarachchi, Anuradha Wickramarachchi, and Yu Lin",
-    author_email="vijini.mallawaarachchi@anu.edu.au",
-    packages=packages,
-    package_data=package_data,
-    data_files=data_files,
-    include_package_data=True,
-    scripts=["graphbin"],
-    url="https://github.com/Vini2/graphbin",
-    license="GPLv2",
-    long_description_content_type="text/markdown",
-    long_description=long_description,
-    description="Refined binning of metagenomic contigs using assembly graphs.",
-    classifiers=[
-        "Development Status :: 5 - Production/Stable",
-        "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
-        "Natural Language :: English",
-        "Programming Language :: Python :: 3.6",
-        "Topic :: Scientific/Engineering :: Bio-Informatics",
-    ],
-    install_requires=["python-igraph", "cogent3", "cairocffi", "setuptools"],
-    zip_safe=False,
-)
diff --git a/graphbin b/src/graphbin/__init__.py
similarity index 98%
rename from graphbin
rename to src/graphbin/__init__.py
index e1b7be1..12a2dc2 100755
--- a/graphbin
+++ b/src/graphbin/__init__.py
@@ -5,7 +5,7 @@
 import os
 import sys
 
-from graphbin_utils import (graphbin_Canu, graphbin_Flye, graphbin_MEGAHIT,
+from graphbin.utils import (graphbin_Canu, graphbin_Flye, graphbin_MEGAHIT,
                             graphbin_Miniasm, graphbin_Options, graphbin_SGA,
                             graphbin_SPAdes)
 
diff --git a/support/bidirectionalmap/bidirectionalmap.py b/src/graphbin/support/bidirectionalmap/bidirectionalmap.py
similarity index 100%
rename from support/bidirectionalmap/bidirectionalmap.py
rename to src/graphbin/support/bidirectionalmap/bidirectionalmap.py
diff --git a/support/gfa2fasta.py b/src/graphbin/support/gfa2fasta.py
similarity index 100%
rename from support/gfa2fasta.py
rename to src/graphbin/support/gfa2fasta.py
diff --git a/support/prep_result.py b/src/graphbin/support/prep_result.py
similarity index 100%
rename from support/prep_result.py
rename to src/graphbin/support/prep_result.py
diff --git a/support/visualise_result_Flye_Canu_Miniasm.py b/src/graphbin/support/visualise_result_Flye_Canu_Miniasm.py
similarity index 100%
rename from support/visualise_result_Flye_Canu_Miniasm.py
rename to src/graphbin/support/visualise_result_Flye_Canu_Miniasm.py
diff --git a/support/visualise_result_MEGAHIT.py b/src/graphbin/support/visualise_result_MEGAHIT.py
similarity index 100%
rename from support/visualise_result_MEGAHIT.py
rename to src/graphbin/support/visualise_result_MEGAHIT.py
diff --git a/support/visualise_result_SGA.py b/src/graphbin/support/visualise_result_SGA.py
similarity index 100%
rename from support/visualise_result_SGA.py
rename to src/graphbin/support/visualise_result_SGA.py
diff --git a/support/visualise_result_SPAdes.py b/src/graphbin/support/visualise_result_SPAdes.py
similarity index 100%
rename from support/visualise_result_SPAdes.py
rename to src/graphbin/support/visualise_result_SPAdes.py
diff --git a/graphbin_utils/__init__.py b/src/graphbin/utils/__init__.py
similarity index 100%
rename from graphbin_utils/__init__.py
rename to src/graphbin/utils/__init__.py
diff --git a/graphbin_utils/bidirectionalmap/__init__.py b/src/graphbin/utils/bidirectionalmap/__init__.py
similarity index 100%
rename from graphbin_utils/bidirectionalmap/__init__.py
rename to src/graphbin/utils/bidirectionalmap/__init__.py
diff --git a/graphbin_utils/bidirectionalmap/bidirectionalmap.py b/src/graphbin/utils/bidirectionalmap/bidirectionalmap.py
similarity index 100%
rename from graphbin_utils/bidirectionalmap/bidirectionalmap.py
rename to src/graphbin/utils/bidirectionalmap/bidirectionalmap.py
diff --git a/graphbin_utils/graphbin_Canu.py b/src/graphbin/utils/graphbin_Canu.py
similarity index 98%
rename from graphbin_utils/graphbin_Canu.py
rename to src/graphbin/utils/graphbin_Canu.py
index d68b06c..0e604d5 100755
--- a/graphbin_utils/graphbin_Canu.py
+++ b/src/graphbin/utils/graphbin_Canu.py
@@ -21,10 +21,10 @@
 from cogent3.parse.fasta import MinimalFastaParser
 from igraph import *
 
-from graphbin_utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
-from graphbin_utils.graphbin_Func import getClosestLabelledVertices
-from graphbin_utils.graphbin_Options import PARSER
-from graphbin_utils.labelpropagation.labelprop import LabelProp
+from graphbin.utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
+from graphbin.utils.graphbin_Func import getClosestLabelledVertices
+from graphbin.utils.graphbin_Options import PARSER
+from graphbin.utils.labelpropagation.labelprop import LabelProp
 
 __author__ = "Vijini Mallawaarachchi"
 __copyright__ = "Copyright 2019-2022, GraphBin Project"
diff --git a/graphbin_utils/graphbin_Flye.py b/src/graphbin/utils/graphbin_Flye.py
similarity index 98%
rename from graphbin_utils/graphbin_Flye.py
rename to src/graphbin/utils/graphbin_Flye.py
index 48934b6..cecd578 100755
--- a/graphbin_utils/graphbin_Flye.py
+++ b/src/graphbin/utils/graphbin_Flye.py
@@ -21,10 +21,10 @@
 from cogent3.parse.fasta import MinimalFastaParser
 from igraph import *
 
-from graphbin_utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
-from graphbin_utils.graphbin_Func import getClosestLabelledVertices
-from graphbin_utils.graphbin_Options import PARSER
-from graphbin_utils.labelpropagation.labelprop import LabelProp
+from graphbin.utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
+from graphbin.utils.graphbin_Func import getClosestLabelledVertices
+from graphbin.utils.graphbin_Options import PARSER
+from graphbin.utils.labelpropagation.labelprop import LabelProp
 
 __author__ = "Vijini Mallawaarachchi"
 __copyright__ = "Copyright 2019-2022, GraphBin Project"
diff --git a/graphbin_utils/graphbin_Func.py b/src/graphbin/utils/graphbin_Func.py
similarity index 100%
rename from graphbin_utils/graphbin_Func.py
rename to src/graphbin/utils/graphbin_Func.py
diff --git a/graphbin_utils/graphbin_MEGAHIT.py b/src/graphbin/utils/graphbin_MEGAHIT.py
similarity index 98%
rename from graphbin_utils/graphbin_MEGAHIT.py
rename to src/graphbin/utils/graphbin_MEGAHIT.py
index 053a023..07c4685 100755
--- a/graphbin_utils/graphbin_MEGAHIT.py
+++ b/src/graphbin/utils/graphbin_MEGAHIT.py
@@ -22,10 +22,10 @@
 from cogent3.parse.fasta import MinimalFastaParser
 from igraph import *
 
-from graphbin_utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
-from graphbin_utils.graphbin_Func import getClosestLabelledVertices
-from graphbin_utils.graphbin_Options import PARSER
-from graphbin_utils.labelpropagation.labelprop import LabelProp
+from graphbin.utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
+from graphbin.utils.graphbin_Func import getClosestLabelledVertices
+from graphbin.utils.graphbin_Options import PARSER
+from graphbin.utils.labelpropagation.labelprop import LabelProp
 
 __author__ = "Vijini Mallawaarachchi"
 __copyright__ = "Copyright 2019-2022, GraphBin Project"
diff --git a/graphbin_utils/graphbin_Miniasm.py b/src/graphbin/utils/graphbin_Miniasm.py
similarity index 98%
rename from graphbin_utils/graphbin_Miniasm.py
rename to src/graphbin/utils/graphbin_Miniasm.py
index c6441a9..2938d4a 100755
--- a/graphbin_utils/graphbin_Miniasm.py
+++ b/src/graphbin/utils/graphbin_Miniasm.py
@@ -21,10 +21,10 @@
 from cogent3.parse.fasta import MinimalFastaParser
 from igraph import *
 
-from graphbin_utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
-from graphbin_utils.graphbin_Func import getClosestLabelledVertices
-from graphbin_utils.graphbin_Options import PARSER
-from graphbin_utils.labelpropagation.labelprop import LabelProp
+from graphbin.utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
+from graphbin.utils.graphbin_Func import getClosestLabelledVertices
+from graphbin.utils.graphbin_Options import PARSER
+from graphbin.utils.labelpropagation.labelprop import LabelProp
 
 __author__ = "Vijini Mallawaarachchi"
 __copyright__ = "Copyright 2019-2022, GraphBin Project"
diff --git a/graphbin_utils/graphbin_Options.py b/src/graphbin/utils/graphbin_Options.py
similarity index 100%
rename from graphbin_utils/graphbin_Options.py
rename to src/graphbin/utils/graphbin_Options.py
diff --git a/graphbin_utils/graphbin_SGA.py b/src/graphbin/utils/graphbin_SGA.py
similarity index 98%
rename from graphbin_utils/graphbin_SGA.py
rename to src/graphbin/utils/graphbin_SGA.py
index e6e86af..9151d05 100755
--- a/graphbin_utils/graphbin_SGA.py
+++ b/src/graphbin/utils/graphbin_SGA.py
@@ -22,10 +22,10 @@
 from cogent3.parse.fasta import MinimalFastaParser
 from igraph import *
 
-from graphbin_utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
-from graphbin_utils.graphbin_Func import getClosestLabelledVertices
-from graphbin_utils.graphbin_Options import PARSER
-from graphbin_utils.labelpropagation.labelprop import LabelProp
+from graphbin.utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
+from graphbin.utils.graphbin_Func import getClosestLabelledVertices
+from graphbin.utils.graphbin_Options import PARSER
+from graphbin.utils.labelpropagation.labelprop import LabelProp
 
 __author__ = "Vijini Mallawaarachchi"
 __copyright__ = "Copyright 2019-2022, GraphBin Project"
diff --git a/graphbin_utils/graphbin_SPAdes.py b/src/graphbin/utils/graphbin_SPAdes.py
similarity index 98%
rename from graphbin_utils/graphbin_SPAdes.py
rename to src/graphbin/utils/graphbin_SPAdes.py
index 24857bb..be4515d 100755
--- a/graphbin_utils/graphbin_SPAdes.py
+++ b/src/graphbin/utils/graphbin_SPAdes.py
@@ -23,10 +23,10 @@
 from cogent3.parse.fasta import MinimalFastaParser
 from igraph import *
 
-from graphbin_utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
-from graphbin_utils.graphbin_Func import getClosestLabelledVertices
-from graphbin_utils.graphbin_Options import PARSER
-from graphbin_utils.labelpropagation.labelprop import LabelProp
+from graphbin.utils.bidirectionalmap.bidirectionalmap import BidirectionalMap
+from graphbin.utils.graphbin_Func import getClosestLabelledVertices
+from graphbin.utils.graphbin_Options import PARSER
+from graphbin.utils.labelpropagation.labelprop import LabelProp
 
 __author__ = "Vijini Mallawaarachchi"
 __copyright__ = "Copyright 2019-2022, GraphBin Project"
diff --git a/graphbin_utils/labelpropagation/__init__.py b/src/graphbin/utils/labelpropagation/__init__.py
similarity index 100%
rename from graphbin_utils/labelpropagation/__init__.py
rename to src/graphbin/utils/labelpropagation/__init__.py
diff --git a/graphbin_utils/labelpropagation/labelprop.py b/src/graphbin/utils/labelpropagation/labelprop.py
similarity index 100%
rename from graphbin_utils/labelpropagation/labelprop.py
rename to src/graphbin/utils/labelpropagation/labelprop.py


Test patch:
diff --git a/.github/workflows/testing_python_app.yml b/.github/workflows/testing_python_app.yml
index 61236d4..ec970f0 100644
--- a/.github/workflows/testing_python_app.yml
+++ b/.github/workflows/testing_python_app.yml
@@ -30,12 +30,11 @@ jobs:
       - name: "Install dependencies on ${{ matrix.os }} for Python ${{ matrix.python-version }}"
         run: |
           python -m pip install --upgrade pip
-          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+          pip install .
       
       - name: "Generate coverage report on ${{ matrix.os }} for Python ${{ matrix.python-version }}"
         run: |
-          pip install pytest
-          pip install pytest-cov
+          pip install pytest pytest-cov
           pytest --cov=tests --cov-report=xml --cov-append
           
       - name: Upload coverage to Codecov
diff --git a/tests/test_graphbin.py b/tests/test_graphbin.py
index eb0ca90..664fe5b 100644
--- a/tests/test_graphbin.py
+++ b/tests/test_graphbin.py
@@ -54,7 +54,7 @@ def test_graphbin_on_spades_dataset(tmp_dir):
     contigs = dir_name / "contigs.fasta"
     paths = dir_name / "contigs.paths"
     binned = dir_name / "initial_binning_res.csv"
-    cmd = f"{EXEC_ROOTDIR}/graphbin --assembler spades --graph {graph} --contigs {contigs} --paths {paths} --binned {binned} --output {tmp_dir}"
+    cmd = f"graphbin --assembler spades --graph {graph} --contigs {contigs} --paths {paths} --binned {binned} --output {tmp_dir}"
     exec_command(cmd)
 
 
@@ -64,7 +64,7 @@ def test_graphbin_on_sga_dataset(tmp_dir):
     graph = dir_name / "default-graph.asqg"
     contigs = dir_name / "default-contigs.fa"
     binned = dir_name / "initial_binning_res.csv"
-    cmd = f"{EXEC_ROOTDIR}/graphbin --assembler sga --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
+    cmd = f"graphbin --assembler sga --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
     exec_command(cmd)
 
 
@@ -74,7 +74,7 @@ def test_graphbin_on_megahit_dataset(tmp_dir):
     graph = dir_name / "final.gfa"
     contigs = dir_name / "final.contigs.fa"
     binned = dir_name / "initial_binning_res.csv"
-    cmd = f"{EXEC_ROOTDIR}/graphbin --assembler megahit --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
+    cmd = f"graphbin --assembler megahit --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
     exec_command(cmd)
 
 
@@ -85,7 +85,7 @@ def test_graphbin_on_flye_dataset(tmp_dir):
     contigs = dir_name / "assembly.fasta"
     paths = dir_name / "assembly_info.txt"
     binned = dir_name / "initial_binning_res.csv"
-    cmd = f"{EXEC_ROOTDIR}/graphbin --assembler flye --graph {graph} --contigs {contigs} --paths {paths} --binned {binned} --output {tmp_dir}"
+    cmd = f"graphbin --assembler flye --graph {graph} --contigs {contigs} --paths {paths} --binned {binned} --output {tmp_dir}"
     exec_command(cmd)
 
 
@@ -95,7 +95,7 @@ def test_graphbin_on_canu_dataset(tmp_dir):
     graph = dir_name / "1y3b.contigs.gfa"
     contigs = dir_name / "1y3b.contigs.fasta"
     binned = dir_name / "initial_binning_res.csv"
-    cmd = f"{EXEC_ROOTDIR}/graphbin --assembler canu --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
+    cmd = f"graphbin --assembler canu --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
     exec_command(cmd)
 
 
@@ -105,5 +105,5 @@ def test_graphbin_on_miniasm_dataset(tmp_dir):
     graph = dir_name / "reads.gfa"
     contigs = dir_name / "unitigs.fasta"
     binned = dir_name / "initial_binning_res.csv"
-    cmd = f"{EXEC_ROOTDIR}/graphbin --assembler miniasm --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
+    cmd = f"graphbin --assembler miniasm --graph {graph} --contigs {contigs} --binned {binned} --output {tmp_dir}"
     exec_command(cmd)