Skip to content

Drop conda dependency: replace hmmer/prodigal/seqkit with pyhmmer/pyrodigal/Python#98

Merged
Robaina merged 4 commits into
mainfrom
issue97-drop-conda-pyhmmer-pyrodigal
Jun 18, 2026
Merged

Drop conda dependency: replace hmmer/prodigal/seqkit with pyhmmer/pyrodigal/Python#98
Robaina merged 4 commits into
mainfrom
issue97-drop-conda-pyhmmer-pyrodigal

Conversation

@Robaina

@Robaina Robaina commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Closes #97.

Replaces the three conda-only external binaries Pynteny shelled out to with pure-Python, pip-installable equivalents, so Pynteny can be installed via pip without conda.

Changes

Engine swap (no more subprocess):

  • wrappers.run_HMM_search → runs searches with pyhmmer and writes a standard HMMER3 --tblout file, so the existing Bio.SearchIO("hmmer3-tab") parser and reuse_hmmer_results caching are unchanged. Includes a translator for common hmmsearch_args (--cut_ga/_nc/_tc, -E/-T/--domE/-Z, …).
  • wrappers.run_seqkit_nodup → reimplements seqkit rmdup -s with pyfastx.
  • GeneAnnotator.annotate → predicts genes in-process with pyrodigal (threaded; GIL released during find_genes), writing prodigal-format FASTA so from_prodigal_output is unchanged. Removes the split-by-contigs + multiprocessing dance.
  • FASTA.filter_by_IDs → replaces seqkit grep with a case-insensitive pyfastx ID filter.
  • FASTAmerger.merge → replaces the printf | xargs cat shell-out with Python file concatenation.

Packaging:

  • Declare runtime deps in pyproject.toml (previously they lived only in the conda recipe).
  • Drop hmmer/prodigal/seqkit from both conda recipes and the dev env (pyhmmer/pyrodigal via pip).
  • Convert the Dockerfile to a pure-pip build; update README install + dependency sections.

Bonus bug fix:
FASTA.add_prefix_to_records opened output_file with "w+" while pyfastx read the same path lazily, truncating the source whenever output_file == self.file_path — so pynteny build --prefix produced an empty database. It now writes to a temp file and moves it into place. This was pre-existing on main and masked because test_build_fasta only asserted the return type; that test is now strengthened to assert non-empty, prefixed output.

Verification (local)

  • unittest/pytest suite: 24/24 pass against the edited code (editable install).
  • Faithfulness: pyrodigal produces identical gene coordinates to the prodigal binary; pyhmmer reproduces the exact golden synteny-hit labels in test_integration_search.
  • Conda-free proof: ran search + build with hmmsearch/prodigal/seqkit removed from PATH — both succeeded, confirming nothing shells out to the binaries.

🤖 Generated with Claude Code

…odigal/Python

Pynteny shelled out to three conda-only binaries (hmmsearch/hmmscan, prodigal
and seqkit). This replaces all of them with pure-Python, pip-installable
equivalents so Pynteny can be installed via pip without conda.

- wrappers.run_HMM_search: run searches with pyhmmer and write a standard
  HMMER3 tabular (--tblout) file, so the existing Bio.SearchIO parser and
  result reuse are unchanged. Adds a translator for common hmmsearch_args
  (--cut_ga/_nc/_tc, -E/-T/--domE/-Z, ...).
- wrappers.run_seqkit_nodup: reimplement seqkit rmdup -s with pyfastx.
- GeneAnnotator.annotate: predict genes in-process with pyrodigal (threaded;
  GIL released during find_genes), writing prodigal-format FASTA so
  from_prodigal_output is unchanged. Removes run_prodigal and the
  split-by-contigs + multiprocessing dance.
- FASTA.filter_by_IDs: replace seqkit grep with a case-insensitive pyfastx
  ID filter.
- FASTAmerger.merge: replace the `printf | xargs cat` shell-out with Python
  file concatenation.

Packaging: declare runtime deps in pyproject.toml (previously only in the
conda recipe); drop hmmer/prodigal/seqkit from both conda recipes and the dev
env (pyhmmer/pyrodigal via pip); convert the Dockerfile to a pure-pip build;
update README install and dependency sections.

Also fixes a pre-existing bug in FASTA.add_prefix_to_records: it opened
output_file with "w+" while pyfastx read the same path lazily, truncating the
source whenever output_file == self.file_path (so `pynteny build --prefix`
produced an empty database). It now writes to a temp file and moves it into
place. test_build_fasta is strengthened to assert non-empty, prefixed output.

Closes #97

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Robaina Robaina self-assigned this Jun 18, 2026
Robaina and others added 3 commits June 18, 2026 18:24
- tests.yml: replace the conda env (conda-incubator/setup-miniconda +
  bioconda) with a pure-pip matrix (actions/setup-python, `pip install .`)
  over Python 3.9/3.12 on ubuntu + macos. Conda is no longer required after
  the pyhmmer/pyrodigal migration, and this also fixes the macOS job, which
  failed creating a py3.8/bioconda env on the ARM64 runner. Add `synchronize`
  to the pull_request triggers so pushes to a PR re-run the tests.
- filter.py: reformat with black 24.8.0 to satisfy the quality check
  (pre-existing drift; file otherwise unchanged).
- preprocessing.py: make Database.is_fasta/is_gbk tolerant of parse errors.
  Biopython >=1.85 raises (instead of returning no records) when a file is not
  valid FASTA (e.g. a GenBank file with leading comments), which broke
  build() on GenBank input once biopython is pulled from PyPI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DataFrame.applymap was deprecated in pandas 2.1 and removed in pandas 3.0,
breaking get_meta_info_for_HMM on Python 3.12 (which pulls pandas 3.x). The
applymap call only replaced NaN with "", which fillna("") does directly and
works across all supported pandas versions.

Verified: full suite passes in a clean Python 3.12 venv (pandas 3.0.3,
biopython 1.87, pyfastx 2.3.1, pyhmmer 0.12.1, pyrodigal 3.7.1).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- docs/index.md: lead with `pip install pynteny`; drop the conda-required
  framing and the obsolete macOS ARM64 conda workaround (pip wheels now work
  on Apple Silicon).
- CONTRIBUTING.md: remove the "HMMER and Prodigal are not available in pip"
  claim; switch the developer setup to a venv + `pip install -e .` (conda env
  file kept as optional).
- docs/examples/example_api_colab.ipynb: replace the miniconda bootstrap cell
  with a plain `pip install pynteny`.

Also drop paths-ignore from the tests workflow's pull_request trigger: the
matrix jobs are required status checks, so a docs-only PR would otherwise skip
them and deadlock waiting for a status that never reports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Robaina
Robaina merged commit 81240cb into main Jun 18, 2026
6 checks passed
@Robaina
Robaina deleted the issue97-drop-conda-pyhmmer-pyrodigal branch June 19, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop conda dependency: replace hmmer/prodigal/seqkit with pyhmmer/pyrodigal/Python so Pynteny installs via pip

1 participant